OpenGL

OpenGL

Trying to get my commercial 3-D app to run under WINE using the same binary with the odd workaround or two. It uses OpenGL in various subwindows of the main window as needed. Under WINE, the subwindow graphics all get drawn in the lower left corner of the overall X11 window. In Win32, when you call wglMakeCurrent, the opengl context is configured to match the size/position of the HWND for the HDC, so drawing openGL goes just into the desired subwindow. However, the WINE implementation of wglMakeCurrent just calls glXMakeCurrent (and glXCreateContext), which produces the entire size of the X11 window, resulting in the incorrect behavior observed. In my Mac OS X port, I have a similar issue, resolved by calling aglSetInteger(glContext, AGL_BUFFER_RECT,... I'm not sure what a glX equivalent would be to try, I don't see one offhand. As is, emulating the wglMakeCurrent accurately appears impossible, such that apps that use this Windows behavior can not be run. Suggestions welcome.

Russ


This is basically the problem which is tracked through Bugzilla bug 2398 [http://bugs.winehq.org/show_bug.cgi?id=2398].

News flash: possible fix posted at http://www.winehq.org/pipermail/wine-patches/2006-October/031336.html

In summary, the problem is as follows: due to some 'features' of Win32 handling of windows and DCs, having a Win32 window <=> X11 window one to one mapping is not feasible (it was done once but Alexandre removed it as part of the window management rewrite as it lead to some problems in applications). In the current Wine code, there is only one X11 window for each top-level Win32 window, everything else inside these windows (clipping, ...) is done internally by Wine.

The easiest way to fix the issue would be to 'override' the 'glViewport' call and pass to GLX no the viewport as decided by the Win32 application but the one relative to the X11 window taking into account the Win32 DC position relative to this X11 window (one could do the same with glScissor). This should work ... except that it won't handle the case where the DC is partially obscured by something (i.e. where Wine should do its own clipping) and one would need also to override all the 'buffer' functions (like glReadBuffer / glWriteBuffer). In that case, one could still imagine hacks (like using clip planes or stencil tests) but the big problem with that is that we use GL ressources to do this => if the application itself uses stencilling or clip planes, we are facing a ressource conflict.

So we have two possible solutions:

  • write our own GLX extension that exports to the user the clip-list handling (the drivers must export something like that to the X11 server to be able to do propper window-level clipping, the goal of this extension would just be to enable the actual application to insert in this list its own clip rectangles).
  • use pbuffers for all GL renderings and use Wine's standard GDI functions to 'blit' this on screen. This has the advantage that the application would be completely 'fooled' without having to hack any GL calls. The problem would now only be when to flush this pbuffer on screen (which would lead to changes to the thunks for front-buffer operations or single-buffered operations).

The first solution would clearly be the best but we need some volunteers to:

  • draft the GL extension
  • check with people to see if they think something like that would be acceptable (maybe by coding it in the X.org tree for some cards where the GL driver is open source)
  • push for the extension to be included in the 'commercial' GL drivers (NVIDIA / ATI)

Lionel Ulmer


I'm by no means an OpenGL expert, but the new OpenGL FBO extension (GL_EXT_framebuffer_object) might help? According to the specs, it "defines a simple interface for drawing to rendering destinations other than the buffers provided to the GL by the window-system", which seems to be exactly what we need? It's part of OpenGL 1.5, and supported by recent Nvidia binary drivers.

Willie Sippel


I'm more of an OpenGL export, I would recommend overriding the glViewPort and glScissor calls, as well as gl[En/Dis]able GL_SCISSOR_TEST, and arrange the glViewPort for the proper projection for rendering, but use glScissor to set the region that can be rendered in the current DC, also there should be no slowdown from having scissor test permanently on.

Forest Hale


I'm a maintainer for some affected apps. I'm going to be learning OpenGL and passing the hat around this Summer for dinner (perhaps more) to whoever finishes this. I wrote a couple of test cases under Windows to demonstrate that there's nothing wrong with glViewport and glScissor. Wine renders them perfectly, unless I misunderstand. What I can demonstrate that wine has trouble with is creating one or more OpenGL contexts onto form controls (hDC). Wine's current implimentation creates the context(s) but makes it (them) the same size as the entire window, overlapping the menu bar (and other contexts). See links for screenshots. FBO seems like a decent way to go from my limited perspective. Keep up the good work and don't let this newbie OpenGL programmer beat you to the prize.

Dan Kegel


There seems to be some action on GL_EXT_framebuffer_object support in x.org; see http://www.mail-archive.com/mesa3d-dev@lists.sourceforge.net/msg00447.html

  • Resources

OpenGL(R) Distilled OpenGL Distilled
OpenGL(R) Programming Guide (Red Book)
OpenGL(R) Shading Language (Orange Book)
OpenGL(R) Reference Manual (Blue Book)

Tom Wickline


I dont have much clue about these things, but just want to toss an idea that seems good with my limited knowledge about the internals of Wine. From what i read Wine now doesn't use actual X windows to emulate subwindows (only the top-level window is a X window). Wouldn't it still be possible to use some dummy (invisible) X windows just to do the opengl clipping? These dummy windows could be very local to the opengl subsystem to avoid complications for the entire Wine window management system. When the opengl subsystem is supposed to do clipping according to some clipping data (maybe a set of rectangles?), then instead of (for example) modifying the ScissorRect, it would create some dummy X windows (one per clip rect?), map them over our main window and then issue the opengl drawing commands to the main window. Then maybe destroy the dummy windows (or just unmap them and keep them for further reuse?) What do you guys think, is this idea any good?

Luchezar Belev


Workers: LionelUlmer, RaphaelJunqueira

OpenGL (last edited 2008-06-05 13:18:47 by lucho)