Thread: [PyOpenGL-Users] using glGetSynciv
Brought to you by:
mcfletch
From: Henry G. <he...@ca...> - 2011-05-23 08:58:06
|
I'm trying to query the status of a fence I've created using glFenceSync, using the following snippet: my_sync = GL_sync.glFenceSync(GL_sync.GL_SYNC_GPU_COMMANDS_COMPLETE, 0) a = numpy.zeros(10, dtype='uint32') foo = GL_sync.glGetSynciv(my_sync, GL_sync.GL_SYNC_STATUS, 10, None, a) Running it returns the following error that I am having trouble parsing: ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: ("byref() argument must be a ctypes instance, not 'int'", ' If you have ERROR_ON_COPY enabled, remember to pass in an array to array-requiring functions.') The trouble is that I'm not sure to which argument it is referring. I am not sufficiently familiar with the PyOpenGL interface. Any assistance would be much appreciated. Thanks, Henry Gomersall |
From: Mike C. F. <mcf...@vr...> - 2011-05-23 19:08:57
|
On 11-05-23 04:57 AM, Henry Gomersall wrote: > I'm trying to query the status of a fence I've created using > glFenceSync, using the following snippet: > > my_sync = GL_sync.glFenceSync(GL_sync.GL_SYNC_GPU_COMMANDS_COMPLETE, 0) > > a = numpy.zeros(10, dtype='uint32') > foo = GL_sync.glGetSynciv(my_sync, > GL_sync.GL_SYNC_STATUS, > 10, None, a) > > Running it returns the following error that I am having trouble parsing: > > ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: > ("byref() argument must be a ctypes instance, not 'int'", ' If you have > ERROR_ON_COPY enabled, remember to pass in an array to array-requiring > functions.') > > The trouble is that I'm not sure to which argument it is referring. I am > not sufficiently familiar with the PyOpenGL interface. It's a little obtuse there, I believe the problem is the None, it should be a GL.GLsizei() instance (or a single-integer numpy array). It will have its .value set to the number of records written into a. HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |
From: Henry G. <he...@ca...> - 2011-05-23 21:44:33
|
On Mon, 2011-05-23 at 15:08 -0400, Mike C. Fletcher wrote: > > my_sync = GL_sync.glFenceSync(GL_sync.GL_SYNC_GPU_COMMANDS_COMPLETE, > 0) > > > > a = numpy.zeros(10, dtype='uint32') > > foo = GL_sync.glGetSynciv(my_sync, > > GL_sync.GL_SYNC_STATUS, > > 10, None, a) > > > > Running it returns the following error that I am having trouble > parsing: > > > > ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: > > ("byref() argument must be a ctypes instance, not 'int'", ' If you > have > > ERROR_ON_COPY enabled, remember to pass in an array to > array-requiring > > functions.') > > > > The trouble is that I'm not sure to which argument it is referring. > I am > > not sufficiently familiar with the PyOpenGL interface. > It's a little obtuse there, I believe the problem is the None, it > should > be a GL.GLsizei() instance (or a single-integer numpy array). It will > have its .value set to the number of records written into a. > That didn't seem to be the problem. I've had a bit more of a play. Its seems that the problem is *actually* the first argument: my_sync is an integer. I can't find the type that it actually needs as the argument though. I've not idea what GLsync actually is. Cheers, Henry |
From: Mike C. F. <mcf...@vr...> - 2011-05-24 02:56:03
|
On 11-05-23 05:44 PM, Henry Gomersall wrote: ... > That didn't seem to be the problem. > > I've had a bit more of a play. Its seems that the problem is *actually* > the first argument: my_sync is an integer. I can't find the type that it > actually needs as the argument though. I've not idea what GLsync > actually is. > > Cheers, > > Henry Okay, I constructed my own test case so I could see what the problem is. There was a bug in the declaration of GLsync, which was declared to be a c_void_p, it should have been declared as a ctypes.POINTER( structure ). I had thought c_void_p would create an opaque pointer type as a return-type, but apparently ctypes short-circuits it to return an integer. I've checked a fix into bzr, and that should appear in the next release of PyOpenGL. In the meantime, you can patch your copy of PyOpenGL with this: === modified file 'OpenGL/constants.py' --- OpenGL/constants.py 2011-04-12 19:23:44 +0000 +++ OpenGL/constants.py 2011-05-24 02:47:52 +0000 @@ -103,7 +103,9 @@ # GL.ARB.sync extension, GLsync is an opaque pointer to a struct # in the extensions header, basically just a "token" that can be # passed to the various operations... -GLsync = ctypes.c_void_p +class _GLsync( ctypes.Structure ): + """Opaque structure definition to fool ctypes into treating us as a real structure""" +GLsync = ctypes.POINTER( _GLsync ) # ctypes.c_void_p does *not* work as a return type... GLvoidp = ctypes.c_void_p ARRAY_TYPE_TO_CONSTANT = [ HTH, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |
From: Henry G. <he...@ca...> - 2011-05-24 09:33:27
|
On Mon, 2011-05-23 at 22:55 -0400, Mike C. Fletcher wrote: > Okay, I constructed my own test case so I could see what the problem > is. There was a bug in the declaration of GLsync, which was declared > to > be a c_void_p, it should have been declared as a ctypes.POINTER( > structure ). I had thought c_void_p would create an opaque pointer > type > as a return-type, but apparently ctypes short-circuits it to return an > integer. > > I've checked a fix into bzr, and that should appear in the next > release > of PyOpenGL. In the meantime, you can patch your copy of PyOpenGL > with > this: Yeah, that fixes it - thank you. I've got the fence test code working as follows now: from OpenGL.GL.ARB import sync as GL_sync ... my_sync = \ GL_sync.glFenceSync(GL_sync.GL_SYNC_GPU_COMMANDS_COMPLETE, 0) fence_status = GL.GLint(0) GL_sync.glGetSynciv(my_sync, GL_sync.GL_SYNC_STATUS, GL.GLint(1), GL.GLint(0), fence_status) print GL_sync.GL_UNSIGNALED == fence_status.value A couple of things come to light with this code. Firstly, as it is fence_status can only return a single argument. I couldn't work out how to instantiate GLintArray (it allows raises the following exception: TypeError: Cannot create instance: has no _type_ ). This isn't a problem as it stands because all the parameters will only return a single value. Secondly, its pretty unpythonic as it stands. I understand that the PyOpenGL is a pretty thin shim around OpenGL, but this seems like a good opportunity for a little more logic on the python side, returning a datatype that is more conducive to being tested, or even better, a whole wrapper around the sync object. Is there any movement by anyone to make the whole OpenGL experience more pythonic? It strikes me that its starting to make a lot of sense with the buffers and shaders paradigm. I guess there is something towards this end with Qt and PySide/PyQt. Do any of the various game engines offer similar? Cheers, HEnry |
From: Mike C. F. <mcf...@vr...> - 2011-05-24 14:10:01
|
On 11-05-24 05:33 AM, Henry Gomersall wrote: > On Mon, 2011-05-23 at 22:55 -0400, Mike C. Fletcher wrote: >> Okay, I constructed my own test case so I could see what the problem >> is. There was a bug in the declaration of GLsync, which was declared >> to >> be a c_void_p, it should have been declared as a ctypes.POINTER( >> structure ). I had thought c_void_p would create an opaque pointer >> type >> as a return-type, but apparently ctypes short-circuits it to return an >> integer. >> >> I've checked a fix into bzr, and that should appear in the next >> release >> of PyOpenGL. In the meantime, you can patch your copy of PyOpenGL >> with >> this: > Yeah, that fixes it - thank you. I've got the fence test code working as > follows now: > > from OpenGL.GL.ARB import sync as GL_sync > ... > my_sync = \ > GL_sync.glFenceSync(GL_sync.GL_SYNC_GPU_COMMANDS_COMPLETE, 0) > > fence_status = GL.GLint(0) > GL_sync.glGetSynciv(my_sync, > GL_sync.GL_SYNC_STATUS, GL.GLint(1), GL.GLint(0), fence_status) > > print GL_sync.GL_UNSIGNALED == fence_status.value > > A couple of things come to light with this code. Firstly, as it is > fence_status can only return a single argument. I couldn't work out how > to instantiate GLintArray (it allows raises the following exception: > TypeError: Cannot create instance: has no _type_ ). This isn't a problem > as it stands because all the parameters will only return a single value. >>> from OpenGL.arrays import GLintArray >>> GLintArray.zeros( (2,3) ) array([[0, 0, 0], [0, 0, 0]], dtype=int32) > Secondly, its pretty unpythonic as it stands. I understand that the > PyOpenGL is a pretty thin shim around OpenGL, but this seems like a good > opportunity for a little more logic on the python side, returning a > datatype that is more conducive to being tested, or even better, a whole > wrapper around the sync object. > > Is there any movement by anyone to make the whole OpenGL experience more > pythonic? It strikes me that its starting to make a lot of sense with > the buffers and shaders paradigm. I guess there is something towards > this end with Qt and PySide/PyQt. Do any of the various game engines > offer similar? I'm torn on the issue. Historically every time we (or I) have pulled higher-level wrapper functionality into the core package, we have wound up regretting it as the march of years means the APIs become obsolete or broken (or just need to be maintained). That said, I've recently added the VBO and GL.shaders wrappers, mostly because it was so painful working with the low-level APIs that I couldn't get demos/tests written without them. The problem seems to be finding a balance between making it easy to code, and getting so radically far from the underlying API that we've created a new intermediate API. A truly usable/pythonic 3D API should likely be a separate package with PyOpenGL (or just raw OpenGL) as a dependency (i.e. a rendering engine). At least, that's how I feel about it this morning, before I have my coffee :) . The ARB.sync module does appear rather awkward right now, as it appears the ARB is planning for lots more features than are currently available. It would likely be reasonable to provide a glGetsynciv wrapper that creates the arrays for you if you pass None. For reference, here's what my test code looks like: http://bazaar.launchpad.net/~mcfletch/openglcontext/trunk/view/head:/tests/arbsync.py <http://bazaar.launchpad.net/%7Emcfletch/openglcontext/trunk/view/head:/tests/arbsync.py> And here's the convenience wrapper I've just added: http://bazaar.launchpad.net/~mcfletch/pyopengl/trunk/view/head:/OpenGL/GL/ARB/sync.py <http://bazaar.launchpad.net/%7Emcfletch/pyopengl/trunk/view/head:/OpenGL/GL/ARB/sync.py> It doesn't attempt to create a higher-level abstraction, just makes the function easier to call from Python code by providing an alias that auto-allocates the buffers for you. Enjoy, Mike -- ________________________________________________ Mike C. Fletcher Designer, VR Plumber, Coder http://www.vrplumber.com http://blog.vrplumber.com |
From: Henry G. <he...@ca...> - 2011-06-10 15:34:41
|
On Tue, 2011-05-24 at 10:09 -0400, Mike C. Fletcher wrote: > It doesn't attempt to create a higher-level abstraction, just makes > the > function easier to call from Python code by providing an alias that > auto-allocates the buffers for you. > I've been meaning to reply to this thread for a while now. The previous problems were in trying to get a texture streaming object working well within python. To this end, I've written a TextureStream2D object with accompanying python GL sync object. Its all on my github repository at: https://github.com/hgomersall/Blog-Code/tree/master/opengl_utils try it out by running demo.py (after applying the described patch as per previous emails in this thread). I hope it might be useful to somebody. Cheers, Henry |