Thread: 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 |
From: David V. <cod...@ha...> - 2013-04-14 04:26:56
|
My best idea is that the Intel GPU Drivers on 64 bit systems will prefer to load at memory addresses above 4 gigabytes, while the other drivers will load at lower memory addresses. This is pretty much what I found, since the valid addresses returned by wglGetProcAddress on my system are above 4 gigs. On 4/13/2013 9:20 AM, Cyrille Rossant wrote: > > 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). > > > Do you have an idea why this bug seems to appear only on Intel GPUs? > > Cyrille |
From: Cyrille R. <cyr...@gm...> - 2013-04-13 19:20:49
|
> 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). > Do you have an idea why this bug seems to appear only on Intel GPUs? Cyrille |
From: Patrick D. <pyo...@pd...> - 2013-04-14 20:15:55
|
Am 13.04.2013 03:50, schrieb David Vierra: > 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 > I did the same thing and it fixed the problem with glGenFramebuffers, too! Thanks a lot David! Is this a fix which can be added to the official distribution or will it cause problems on other systems? Cheers, Patrick |
From: David V. <cod...@ha...> - 2013-04-14 20:37:36
|
On 4/14/2013 10:15 AM, Patrick Dietrich wrote: > Am 13.04.2013 03:50, schrieb David Vierra: >> 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 >> > I did the same thing and it fixed the problem with glGenFramebuffers, > too! Thanks a lot David! > Is this a fix which can be added to the official distribution or will it > cause problems on other systems? It did not cause problems with my 32-bit Python, at least. I strongly doubt it would cause any problems on other (non-Windows) systems since the change is only made in win32.py. The fix changes the result type of one function pointer, but this hints strongly that the underlying problem is that the default result type for ctypes funcptrs, on 64-bit Python for Windows, is only 32 bits long. |
From: Mike C. F. <mcf...@vr...> - 2013-04-16 01:30:43
|
On 13-04-14 04:37 PM, David Vierra wrote: > On 4/14/2013 10:15 AM, Patrick Dietrich wrote: >> Am 13.04.2013 03:50, schrieb David Vierra: >>> 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 >>> >> I did the same thing and it fixed the problem with glGenFramebuffers, >> too! Thanks a lot David! >> Is this a fix which can be added to the official distribution or will it >> cause problems on other systems? > It did not cause problems with my 32-bit Python, at least. I strongly > doubt it would cause any problems on other (non-Windows) systems since > the change is only made in win32.py. The fix changes the result type of > one function pointer, but this hints strongly that the underlying > problem is that the default result type for ctypes funcptrs, on 64-bit > Python for Windows, is only 32 bits long. It also didn't cause problems on my 64-bit Windows 7, and it seems correct, the return type *should* be a void pointer. I gather it was working for the other drivers because the next 4 bytes were always NULL with the other drivers. bzr head has the fix. HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |
From: David V. <cod...@ha...> - 2013-04-16 01:55:13
|
On 4/15/2013 3:30 PM, Mike C. Fletcher wrote: > On 13-04-14 04:37 PM, David Vierra wrote: >> On 4/14/2013 10:15 AM, Patrick Dietrich wrote: >>> Am 13.04.2013 03:50, schrieb David Vierra: >>>> 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 >>>> >>> I did the same thing and it fixed the problem with glGenFramebuffers, >>> too! Thanks a lot David! >>> Is this a fix which can be added to the official distribution or will it >>> cause problems on other systems? >> It did not cause problems with my 32-bit Python, at least. I strongly >> doubt it would cause any problems on other (non-Windows) systems since >> the change is only made in win32.py. The fix changes the result type of >> one function pointer, but this hints strongly that the underlying >> problem is that the default result type for ctypes funcptrs, on 64-bit >> Python for Windows, is only 32 bits long. > It also didn't cause problems on my 64-bit Windows 7, and it seems > correct, the return type *should* be a void pointer. I gather it was > working for the other drivers because the next 4 bytes were always NULL > with the other drivers. > > bzr head has the fix. > > HTH, > Mike Thanks Mike! But I'm afraid bzr head is slightly broken ;) File "c:\Users\Rio\Documents\src\pyopengl\OpenGL\platform\win32.py", line 67, in Win32Platform getExtensionProcedure.restype = ctypes.c_void_p AttributeError: 'staticmethod' object has no attribute 'restype' |
From: David V. <cod...@ha...> - 2013-04-16 02:05:10
|
On 4/15/2013 3:55 PM, David Vierra wrote: > On 4/15/2013 3:30 PM, Mike C. Fletcher wrote: > >> It also didn't cause problems on my 64-bit Windows 7, and it seems >> correct, the return type *should* be a void pointer. I gather it was >> working for the other drivers because the next 4 bytes were always NULL >> with the other drivers. >> >> bzr head has the fix. >> >> HTH, >> Mike > Thanks Mike! > > But I'm afraid bzr head is slightly broken ;) > > File "c:\Users\Rio\Documents\src\pyopengl\OpenGL\platform\win32.py", > line 67, in Win32Platform > getExtensionProcedure.restype = ctypes.c_void_p > > AttributeError: 'staticmethod' object has no attribute 'restype' > > > Sorry, I should have added that changing it to this line makes it work for me: OpenGL.wglGetProcAddress.restype = ctypes.c_void_p Also, test_core.py runs without any errors after this change is made. - David Vierra |
From: Mike C. F. <mcf...@vr...> - 2013-04-16 03:12:37
|
On 13-04-15 10:05 PM, David Vierra wrote: ... > > Sorry, I should have added that changing it to this line makes it work > for me: > > OpenGL.wglGetProcAddress.restype = ctypes.c_void_p > > Also, test_core.py runs without any errors after this change is made. Thanks David, head is updated. Enjoy, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |