11.2. How it all works

The core OpenGL function calls are the same between Windows and Linux. So what is the difficulty to support it in Wine? Well, there are two different problems:

  1. the interface to the windowing system is different for each OS. It's called "GLX" for Linux (well, for X Window) and "wgl" for Windows. Thus, one need first to emulate one (wgl) with the other (GLX).

  2. the calling convention between Windows (the Pascal convention or stdcall) is different from the one used on Linux (the C convention or cdecl). This means that each call to an OpenGL function must be "translated" and cannot be used directly by the Windows program.

Add to this some brain-dead programs (using GL calls without setting-up a context or deleting three times the same context) and you have still some work to do :-)

11.2.1. The Windowing system integration

This integration is done at two levels:

  1. At GDI level for all pixel format selection routines (i.e. choosing if one wants a depth / alpha buffer, the size of these buffers, ...) and to do the "page flipping" in double buffer mode. This is implemented in dlls/winex11.drv/opengl.c.

  2. In the OpenGL32.DLL itself for all other functionalities (context creation / deletion, querying of extension functions, ...). This is done in dlls/opengl32/wgl.c.

11.2.2. The thunks

The thunks are the Wine code that does the calling convention translation and they are auto-generated by a Perl script. In Wine Git tree, these thunks are already generated for you. Now, if you want to do it yourself, here is how it all works....

The script is located in dlls/opengl32 and is called make_opengl. It requires Perl5 to work and takes an OpenGL version as argument. It's the version to "simulate". This fixes the list of functions that the Windows application can link directly to without having to query them from the OpenGL driver.

This option can be 1.0 to 1.5. The default is 1.1.

This script generates three files:

  1. opengl32.spec gives Wine's linker the signature of all function in the OpenGL32.DLL library so that the application can link them. Only 'core' functions are listed here.

  2. opengl_norm.c contains all the thunks for the 'core' functions. Your OpenGL library must provide ALL the functions used in this file as these are not queried at run time.

  3. opengl_ext.c contains all the functions that are not part of the 'core' functions. Contrary to the thunks in opengl_norm.c, these functions do not depend at all on what your libGL provides.

    In fact, before using one of these thunks, the Windows program first needs to "query" the function pointer. At this point, the corresponding thunk is useless. But as we first query the same function in libGL and store the returned function pointer in the thunk, the latter becomes functional.