11.3. 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 braindead programs (using GL calls without setting-up a context or deleting three time the same context) and you have still some work to do :-)

11.3.1. The Windowing system integration

This integration is done at two levels :

  1. At GDI level for all pixel format selection routines (ie 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 graphics/x11drv/opengl.c (all these functions are part of Wine's graphic driver function pointer table and thus could be reimplented if ever Wine works on another Windowing system than X).

  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.3.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's CVS tree, these thunks are already generated for you. Now, if you want to do it yourself, there is how it all works....

The script is located in dlls/opengl32 and is called make_opengl. It requires Perl5 to work and takes two arguments :

  1. The first is the path to the OpenGL registry. Now, you will all ask 'but what is the OpenGL registry ?' :-) Well, it's part of the OpenGL sample implementation source tree from SGI (more informations at this URL : http://oss.sgi.com/projects/ogl-sample/.

    To summarize, these files contain human-readable but easily parsed information on ALL OpenGL core functions and ALL registered extensions (for example the prototype, the OpenGL version, ...).

  2. the second is the OpenGL 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. Windows is based, for now, on OpenGL 1.1, but the thunks that are in the CVS tree are generated for OpenGL 1.2.

    This option can have three values: 1.0, 1.1 and 1.2.

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 function 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.