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 |