| I What is needed to have OpenGL support in Wine | |
| =============================================== | |
| Basically, if you have a Linux OpenGL ABI compliant libGL | |
| (http://oss.sgi.com/projects/ogl-sample/ABI/) installed on your | |
| computer, you should 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. | |
| I.1 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 | |
| (http://oss.sgi.com/projects/ogl-sample/ABI/glext.h), and that all | |
| OpenGL should provide one, I decided to keep it here. | |
| I.2 OpenGL library thread-safety | |
| -------------------------------- | |
| After that, the script checks if the OpenGL library relies or not on | |
| the pthread library to provide thread safety (most 'modern' OpenGL | |
| libraries do). | |
| If the OpenGL library explicitely links in libpthread (you can check | |
| it with a 'ldd libGL.so'), you need to force OpenGL support by | |
| starting configure with the '--enable-opengl' flag. | |
| The reason to this is that Wine contains some hacks done by Ove to | |
| cohabit with pthread that are known to work well in most of the cases | |
| (glibc 2.1.x). On the other hand, we never got Wine to work with glibc | |
| 2.0.6. Thus, I deemed preferable to play it safe : by default, I | |
| suppose that the hack won't work and that it's the user's | |
| responsability to enable it. | |
| Anyway, it should be pretty safe to build with '--enable-opengl'. | |
| I.3 OpenGL library itself | |
| ------------------------- | |
| To check for the presence of 'libGL' on the system, the script checks | |
| if it defines the 'glXCreateContext' function. There should be no | |
| problem here. | |
| I.4 glXGetProcAddressARB function | |
| --------------------------------- | |
| The core of Wine's 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. | |
| If your library does not provide it, you are out of luck. | |
| (Note: this is not completely true as one could rewrite a | |
| glXGetProcAddressARB replacement using 'dlopen' and friends, | |
| but well, telling people to upgrade is easier :-) ). | |
| II How to configure | |
| =================== | |
| Configuration is quite easy : once OpenGL support has been built in | |
| Wine, this internal OpenGL driver will be used each time an | |
| application tries to load 'opengl32.dll'. | |
| Due to restrictions (that do not exist in Windows) on OpenGL contexts, | |
| if you want to prevent the screen to flicker when using OpenGL | |
| applications (all games are using double-buffered contexts), you need | |
| to set the following option in your .winerc / wine.ini in the [x11drv] | |
| section : | |
| DesktopDoubleBuffered = Y | |
| and to run Wine with the '--desktop' option. | |
| III 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 | |
| is 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 '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 :-) | |
| III.1 The Windowing system integration | |
| -------------------------------------- | |
| This integration is done at two levels : | |
| - 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). | |
| - in the OpenGL32.DLL itself for all other functionalities (context | |
| creation / deletion, querying of extension functions, ...). This is | |
| done in 'dlls/opengl32/wgl.c'. | |
| III.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 : | |
| - 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 contains human-readable but easily parsed | |
| informations on ALL OpenGL core functions and ALL registered | |
| extensions (for example the prototype, the OpenGL version, ...). | |
| - 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 : | |
| - 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. | |
| - 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. | |
| - 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. | |
| IV Known problems - shortcomings | |
| ================================= | |
| IV.1 Missing GLU32.DLL | |
| ---------------------- | |
| GLU is a library that is layered upon OpenGL. There is a 100 % | |
| corespondance between the libGLU.so that is used on Linux and | |
| GLU32.DLL. | |
| As for the moment, I did not create a set of thunks to support this | |
| library natively in Wine (it would easy to do, but I am waiting for a | |
| better solution than adding another autogenerated thunk file), you can | |
| always download anywhere on the net (it's free) a GLU32.DLL file (by | |
| browsing, for example, http://ftpsearch.lycos.com/). | |
| IV.2 OpenGL not detected at configure time | |
| ------------------------------------------ | |
| See section (I) for a detailed explanation of the configure | |
| requirements. | |
| IV.3 When running an OpenGL application, the screen flickers | |
| ------------------------------------------------------------ | |
| See section (II) for how to create the context double-buffered and | |
| thus preventing this flicker effect. | |
| IV.4 Wine gives me the following 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 (ie the call to glXGetProcAddressARB returns a | |
| non NULL pointer) but that this string was NOT found in Wine's | |
| extension registry. | |
| This can come from two causes : | |
| - the opengl_ext.c file is too old and need 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' and 'glSelectTextureSGIS' 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's extension set. | |
| If you have this, run with --debugmsg +opengl and send me | |
| (lionel.ulmer@free.fr) the TRACE. | |
| IV.5 libopengl32.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 libopengl32 (this | |
| command line supposes that you installed the Wine libraries in | |
| /usr/local/lib, YMMV) : | |
| gcc dummy.c -L/usr/local/lib -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). | |
| Lionel Ulmer (lionel.ulmer@free.fr) | |
| last modification : 2000/06/13 |