Re: [PyOpenGL-Users] access violation when calling glGenFramebuffers
Brought to you by:
mcfletch
From: David V. <cod...@ha...> - 2013-04-13 03:12:29
|
Hello, everyone! I'm having a very similar problem to this one and I'd like to help out however I can. I am on Windows 7, I have an Intel HD 4000 chipset, and I have both 32-bit and 64-bit version of Python installed. I get: > "WindowsError: exception: access violation writing 0xFFFFFFFFE1FEFA20" when I call GL.glActiveTexture(GL.GL_TEXTURE0). I can reproduce this with a very small sample program that only calls pygame.set_mode and glActiveTexture, and confirm that the crash only happens with the 64-bit Python. Also, while I did not write a little C program, I can observe something that tells me the graphics drivers aren't outright broken: I can play Minecraft on top of a 64-bit Java runtime, and Minecraft has no problems calling glActiveTexture (via LWJGL, which has to be calling the C natives). glActiveTexture is part of the OpenGL 1.3 feature set. Someone mentioned that features not part of GL 1.1 were being loaded from the wrong DLL (or something?): > In fact I think to remember that, when I was investigating this issue, > it was as if the Python bindings were incorrect, in that PyOpenGL > tried to link to the *native* Windows OpenGL 1.1 drivers functions and > not the graphics card drivers ones. So any call to an OpenGL function > available in, say, OpenGL 2.1 and not OpenGL 1.1 would result in a > crash. glGenFramebuffers is such an example, but there were a lot of > similar other OpenGL commands which yielded the same issue. You could > try to look for such commands not available in OpenGL 1.1 and see if > this observation is correct. So, I looked at a few function objects (GL.glEnable, GL.glTexImage, GL.glActiveTexture and others) using the 64-bit debugger. Each one has a DLL attribute which references the open DLL handle, and every one I looked at refers to "C:\Windows\System32\opengl.dll". I also noticed that different functions had different object types: glActiveTexture = <OpenGL.platform.baseplatform.glActiveTexture object at 0x03DCC5F0> glGenFramebuffers = <OpenGL.platform.baseplatform.glGenFramebuffers object at 0x03E695F8> glEnable = <WinFunctionType object at 0x03CD27B0> glTexImage2d = <ctypes.glTexImage2D object at 0x03DB28A0> I wondered what the difference is, stepped around in the debugger some more, and found out the first two are "null function" placeholders. They are null at first because a GL context is required to check for extensions and GL versions. I stepped through glActiveTexture's lazy loading the first time it is called, and I think I found out what the problem is. In OpenGL/platform/baseplatform.py, constructFunction calls self.getExtensionProcedure and gets a small negative number as a result. I looked at getExtensionProcedure and traced it back to the wglGetProcAddress that is implicitly created in OpenGL/platform/win32.py. This wglGetProcAddress is a _FuncPtr whose restype attribute is ctypes.c_long. If I add another line to OpenGL/platform/win32.py after the `getExtensionProcedure = ` line, that says: OpenGL.wglGetProcAddress.restype = ctypes.c_void_p Then the result of getExtensionProcedure is now a longer positive number, and better yet the call to glActiveTexture doesn't crash with an Access Violation any more! So, my conclusion is that the function pointer to wglGetProcAddress used by the PyOpenGL's win32 platform module has the wrong result type (it is c_long which is only 32 bits when it should be c_void_p which is 64 bits long). Hope this helps, - David Vierra |