What is needed to have OpenGL support in Wine
Basically, if you have a Linux OpenGL ABI compliant libGL installed on your computer, you should have everything that is needed.
To be more clear, I will detail one step after another what the configure script checks.
If, after Wine compiles, OpenGL support is not compiled in, you can
always check config.log
to see which of the following points failed.
Header files
The needed header files to build OpenGL support in Wine are:
gl.h
the definition of all OpenGL core functions, types and enumerants
glx.h
how OpenGL integrates in the X Window environment
glext.h
the list of all registered OpenGL extensions
The latter file (glext.h
) is, as of now, not necessary to build
Wine. But as this file can be easily obtained from
SGI, and that
all OpenGL should provide one, I decided to keep it here.
OpenGL library itself
To check for the presence of libGL
on the system, the script checks if
it defines the glXCreateContext
function.
glXGetProcAddressARB
function
The core of Wine OpenGL implementation (at least for all extensions) is
the glXGetProcAddressARB
function. Your OpenGL library needs to have
this function defined for Wine to be able to support OpenGL.
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:
- 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).
- the calling convention between Windows (the
stdcall
convention) is different from the one used on Linux (the C convention orcdecl
). 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
The Windowing system integration
This integration is done at two levels:
- 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
. - In the
OpenGL32.DLL
itself for all other functionalities (context creation / deletion, querying of extension functions, ...). This is done indlls/opengl32/wgl.c
.
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:
-
opengl32.spec
gives Wine's linker the signature of all function in theOpenGL32.DLL
library so that the application can link them. Only 'core' functions are listed here. -
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. -
opengl_ext.c
contains all the functions that are not part of the 'core' functions. Contrary to the thunks inopengl_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.
Known problems
Unknown extension error message
Extension defined in the OpenGL library but NOT in opengl_ext.c...
Please report (lionel.ulmer@free.fr) !
This means that the extension requested by the application is found in
the libGL used by Linux (i.e. the call to glXGetProcAddressARB
returns
a non-NULL
pointer) but that this string was NOT found in Wine
extension registry.
This can come from two causes:
- The
opengl_ext.c
file is too old and needs to be generated again. - Use of obsolete extensions that are not supported anymore by SGI or
of “private” extensions that are not registered. An example of the
former are
glMTexCoord2fSGIS
andglSelectTextureSGIS
as used by Quake 2 (and apparently also by old versions of Half Life). If documentation can be found on these functions, they can be added to Wine extension set.
If you have this, run with WINEDEBUG=+opengl
and send me
lionel.ulmer@free.fr the TRACE.
opengl32.dll.so
is built but it is still not working
This may be caused by some missing functions required by opengl_norm.c
but that your Linux OpenGL library does not provide.
To check for this, do the following steps:
- create a dummy
.c
file:int main(void) { return 0; }
- try to compile it by linking both libwine and opengl32 (this command
line supposes that you installed the Wine libraries in
/usr/local/lib
, YMMV): gcc dummy.c -L/usr/local/lib -L/usr/local/lib/wine -lwine -lopengl32 - if it works, the problem is somewhere else (and you can send me an email). If not, you could re-generate the thunk files for OpenGL 1.1 for example (and send me your OpenGL version so that this problem can be detected at configure time).