Re: Bug? Importing WGL crashes glReadPixel call with "wrong argument type" exception

Matti Kariluoma <[email protected]> Wed, 6 Sep 2017 19:23:53 -0500
Newsgroups gmane.comp.python.opengl.user
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============1033921498485170220==
Content-Type: multipart/alternative;
 boundary="------------8FC2259EFAB3BDA1C1286DC1"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------8FC2259EFAB3BDA1C1286DC1
Content-Type: text/plain; charset=utf-8; format=flowed
Content-Transfer-Encoding: 8bit

Consider using Mesa's software renderer, if your requirements allow it:

$ sudo apt-get install python-opengl libosmesa # maybe libosmesa6?
$ PYOPENGL_PLATFORM=osmesa python your_app.py
$ cat your_app.py
...
   from OpenGL import GL, arrays, platform
   ctx = platform.OSMesaCreateContext(GL.GL_RGBA, None) # requires PYOPENGL_PLATFORM=osmesa
   buf = arrays.GLubyteArray.zeros((height, width, 4))
   p = arrays.ArrayDatatype.dataPointer(buf)
   assert(platform.OSMesaMakeCurrent(ctx, p, GL.GL_UNSIGNED_BYTE, width, height))
   assert(platform.CurrentContextIsValid())
...
   platform.OSMesaDestroyContext(ctx)
...

I understand that you're on Windows. There may be an easy way to install 
Mesa for use with PyOpenGL on your setup, but I'm afraid I'm not 
familiar with the Windows platform so you'll have to do some digging first.

On 9/2/17 2:31 PM, Anton Ovsyannikov wrote:
> Hello.
>
> I am trying to use PyOpengGL for off-screen rendering, so I need WGL 
> to create gl context and then glReadPixels to retrieve data
>
> First I wrote simple app with GLUT, but right after I import 
> OpenGL.WGL (just import, no more), the glReadPixels starts to crash with
>
> ctypes.ArgumentError: argument 7: <type 'exceptions.TypeError'>: wrong 
> type
>
> The app, OpenGL version and stack trace are below. Now some of my 
> investigations
>
> =======================================================
> The crash starts in \OpenGL\GL\images.py line 369
>
> GL_1_1.glReadPixels(
>     x,y,width,height,
>     format,type,
>     imageData
> )
>
> imageData in both cases is completely the same
>
> The only difference in further workflow happens in 
> \OpenGL\platform\baseplatform.py line 125
>
> def finalArgType( self, typ ):
>     """Retrieve a final type for arg-type"""
>     if typ == ctypes.POINTER( None ) and not getattr( typ, 'final',False):
>         from OpenGL.arrays import ArrayDatatype
>         return ArrayDatatype
>     else:
>         return typ
>
> With no WGL the 7th argument (while typ is <class 'ctypes.c_void_p'>) 
> have no "final" attribute set, so final type becomes ArrayDatatype and 
> everything works fine
>
> But if to import WGL "final" flag is set, so <class 'ctypes.c_void_p'> 
> returned leading to "wrong type" exception in GL_1_1.glReadPixels call
>
> I searched for "final" in WGL and found the following in 
> \OpenGL\raw\WGL\_types.py line 72
>
> HANDLE = POINTER(None) # /home/mcfletch/pylive/OpenGL-ctypes/src/wgl.h:60
> # TODO: figure out how to make the handle not appear as a void_p 
> within the code...
> HANDLE.final = True
>
> So we found who set up "final" flag for <class 'ctypes.c_void_p'>
>
> But then I stuck up completely, have no single idea how to solve this 
> type conflict, suppose it's some issue in design
>
> Have any idea how to solve it?
>
>
> =======================================================
> PyOpenGL package is
> http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl 
> <http://www.lfd.uci.edu/%7Egohlke/pythonlibs/#pyopengl>
> PyOpenGL‑3.1.1‑cp27‑cp27m‑win_amd64.whl
>
> OpenGL.__version__
> 3.1.1
> =======================================================
>
> =======================================================
> The App
> =======================================================
> # -*- coding: utf-8 -*-
>
> # Just uncomment following line to reproduce the bug!
> #import OpenGL.WGL
>
> from OpenGL.GL import *
> from OpenGL.GLU import *
> from OpenGL.GLUT import *
>
> from PIL import Image
> import sys
>
> width, height = 300, 300
>
> def init():
>     glClearColor(0.5, 0.5, 0.5, 1.0)
>     glColor(0.0, 1.0, 0.0)
>     gluOrtho2D(-1.0, 1.0, -1.0, 1.0)
>     glViewport(0, 0, width, height)
>
> def render():
>
>     glClear(GL_COLOR_BUFFER_BIT)
>
>     glBegin(GL_LINES)
>     glVertex2d(-0.5, -0.5)
>     glVertex2d(0.5, 0.5)
>     glEnd()
>
>     glFlush()
>
> def draw():
>     render()
>     glutSwapBuffers()
>
> def main():
>     glutInit(sys.argv)
>
>     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
>     glutInitWindowSize(300, 300)
>     glutCreateWindow(b"OpenGL vs WGL")
>
>     init()
>     render()
>
>     glPixelStorei(GL_PACK_ALIGNMENT, 1)
>     data = glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE)
>     image = Image.frombytes("RGBA", (width, height), data)
>     image.save('output.png', 'PNG')
>
>     glutDisplayFunc(draw)
>     glutMainLoop()
>
> main()
> =======================================================
>
>
> =======================================================
> Stack trace with import WGL uncommented
> =======================================================
>
> Traceback (most recent call last):
>   File 
> "C:/Users/Anton/Documents/Dev/PycharmProjects/OpenGL/OpenGLTest.py", 
> line 54, in <module>
>     main()
>   File 
> "C:/Users/Anton/Documents/Dev/PycharmProjects/OpenGL/OpenGLTest.py", 
> line 47, in main
>     data = glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE)
>   File 
> "C:\ProgramData\Anaconda2\lib\site-packages\OpenGL\GL\images.py", line 
> 372, in glReadPixels
>     imageData
>   File 
> "C:\ProgramData\Anaconda2\lib\site-packages\OpenGL\platform\baseplatform.py", 
> line 402, in __call__
>     return self( *args, **named )
> ctypes.ArgumentError: argument 7: <type 'exceptions.TypeError'>: wrong 
> type
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, Slashdot.org! http://sdm.link/slashdot
>
>
> _______________________________________________
> PyOpenGL Homepage
> http://pyopengl.sourceforge.net
> _______________________________________________
> PyOpenGL-Users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/pyopengl-users


--------------8FC2259EFAB3BDA1C1286DC1
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: 8bit

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Consider using Mesa's software renderer, if your requirements
      allow it:</p>
    <pre>$ sudo apt-get install python-opengl libosmesa # maybe libosmesa6?
$ PYOPENGL_PLATFORM=osmesa python your_app.py
$ cat your_app.py
...
  from OpenGL import GL, arrays, platform
  ctx = platform.OSMesaCreateContext(GL.GL_RGBA, None) # requires PYOPENGL_PLATFORM=osmesa
  buf = arrays.GLubyteArray.zeros((height, width, 4))
  p = arrays.ArrayDatatype.dataPointer(buf)
  assert(platform.OSMesaMakeCurrent(ctx, p, GL.GL_UNSIGNED_BYTE, width, height))
  assert(platform.CurrentContextIsValid())
...
  platform.OSMesaDestroyContext(ctx)
...

</pre>
    I understand that you're on Windows. There may be an easy way to
    install Mesa for use with PyOpenGL on your setup, but I'm afraid I'm
    not familiar with the Windows platform so you'll have to do some
    digging first.<br>
    <br>
    <div class="moz-cite-prefix">On 9/2/17 2:31 PM, Anton Ovsyannikov
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAEpUFHKbudfVze-10+KrO6LxEP6jyw5uG8dhF8BiJ=-qnEpT8w@mail.gmail.com">
      <div dir="ltr">Hello.<br>
        <br>
        I am trying to use PyOpengGL for off-screen rendering, so I need
        WGL to create gl context and then glReadPixels to retrieve data<br>
        <br>
        First I wrote simple app with GLUT, but right after I import
        OpenGL.WGL (just import, no more), the glReadPixels starts to
        crash with<br>
        <br>
        ctypes.ArgumentError: argument 7: &lt;type
        'exceptions.TypeError'&gt;: wrong type<br>
        <br>
        The app, OpenGL version and stack trace are below. Now some of
        my investigations<br>
        <br>
        =======================================================<br>
        The crash starts in \OpenGL\GL\images.py line 369<br>
        <br>
        GL_1_1.glReadPixels(<br>
            x,y,width,height,<br>
            format,type,<br>
            imageData<br>
        )<br>
        <br>
        imageData in both cases is completely the same<br>
        <br>
        The only difference in further workflow happens in
        \OpenGL\platform\baseplatform.py line 125<br>
        <br>
        def finalArgType( self, typ ):<br>
            """Retrieve a final type for arg-type"""<br>
            if typ == ctypes.POINTER( None ) and not getattr( typ,
        'final',False):<br>
                from OpenGL.arrays import ArrayDatatype<br>
                return ArrayDatatype<br>
            else:<br>
                return typ<br>
        <br>
        With no WGL the 7th argument (while typ is &lt;class
        'ctypes.c_void_p'&gt;) have no "final" attribute set, so final
        type becomes ArrayDatatype and everything works fine<br>
        <br>
        But if to import WGL "final" flag is set, so &lt;class
        'ctypes.c_void_p'&gt; returned leading to "wrong type" exception
        in GL_1_1.glReadPixels call<br>
        <br>
        I searched for "final" in WGL and found the following in
        \OpenGL\raw\WGL\_types.py line 72<br>
        <br>
        HANDLE = POINTER(None) #
        /home/mcfletch/pylive/OpenGL-ctypes/src/wgl.h:60<br>
        # TODO: figure out how to make the handle not appear as a void_p
        within the code...<br>
        HANDLE.final = True<br>
        <br>
        So we found who set up "final" flag for &lt;class
        'ctypes.c_void_p'&gt;<br>
        <br>
        But then I stuck up completely, have no single idea how to solve
        this type conflict, suppose it's some issue in design<br>
        <br>
        Have any idea how to solve it?<br>
        <br>
        <br>
        =======================================================<br>
        PyOpenGL package is<br>
        <a href="http://www.lfd.uci.edu/%7Egohlke/pythonlibs/#pyopengl"
          moz-do-not-send="true">http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyopengl</a><br>
        PyOpenGL‑3.1.1‑cp27‑cp27m‑win_amd64.whl<br>
        <br>
        OpenGL.__version__<br>
        3.1.1<br>
        =======================================================<br>
        <br>
        =======================================================<br>
        The App<br>
        =======================================================<br>
        # -*- coding: utf-8 -*-<br>
        <br>
        # Just uncomment following line to reproduce the bug!<br>
        #import OpenGL.WGL<br>
        <br>
        from OpenGL.GL import *<br>
        from OpenGL.GLU import *<br>
        from OpenGL.GLUT import *<br>
        <br>
        from PIL import Image<br>
        import sys<br>
        <br>
        width, height = 300, 300<br>
        <br>
        def init():<br>
            glClearColor(0.5, 0.5, 0.5, 1.0)<br>
            glColor(0.0, 1.0, 0.0)<br>
            gluOrtho2D(-1.0, 1.0, -1.0, 1.0)<br>
            glViewport(0, 0, width, height)<br>
        <br>
        def render():<br>
        <br>
            glClear(GL_COLOR_BUFFER_BIT)<br>
        <br>
            glBegin(GL_LINES)<br>
            glVertex2d(-0.5, -0.5)<br>
            glVertex2d(0.5, 0.5)<br>
            glEnd()<br>
        <br>
            glFlush()<br>
        <br>
        def draw():<br>
            render()<br>
            glutSwapBuffers()<br>
        <br>
        def main():<br>
            glutInit(sys.argv)<br>
        <br>
            glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)<br>
            glutInitWindowSize(300, 300)<br>
            glutCreateWindow(b"OpenGL vs WGL")<br>
        <br>
            init()<br>
            render()<br>
        <br>
            glPixelStorei(GL_PACK_ALIGNMENT, 1)<br>
            data = glReadPixels(0, 0, width, height, GL_RGBA,
        GL_UNSIGNED_BYTE)<br>
            image = Image.frombytes("RGBA", (width, height), data)<br>
            image.save('output.png', 'PNG')<br>
        <br>
            glutDisplayFunc(draw)<br>
            glutMainLoop()<br>
        <br>
        main()<br>
        =======================================================<br>
        <br>
        <br>
        =======================================================<br>
        Stack trace with import WGL uncommented<br>
        =======================================================<br>
        <br>
        Traceback (most recent call last):<br>
          File
        "C:/Users/Anton/Documents/Dev/PycharmProjects/OpenGL/OpenGLTest.py",
        line 54, in &lt;module&gt;<br>
            main()<br>
          File
        "C:/Users/Anton/Documents/Dev/PycharmProjects/OpenGL/OpenGLTest.py",
        line 47, in main<br>
            data = glReadPixels(0, 0, width, height, GL_RGBA,
        GL_UNSIGNED_BYTE)<br>
          File
        "C:\ProgramData\Anaconda2\lib\site-packages\OpenGL\GL\images.py",
        line 372, in glReadPixels<br>
            imageData<br>
          File
"C:\ProgramData\Anaconda2\lib\site-packages\OpenGL\platform\baseplatform.py",
        line 402, in __call__<br>
            return self( *args, **named )<br>
        ctypes.ArgumentError: argument 7: &lt;type
        'exceptions.TypeError'&gt;: wrong type<br>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! <a class="moz-txt-link-freetext" href="http://sdm.link/slashdot">http://sdm.link/slashdot</a></pre>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
PyOpenGL Homepage
<a class="moz-txt-link-freetext" href="http://pyopengl.sourceforge.net">http://pyopengl.sourceforge.net</a>
_______________________________________________
PyOpenGL-Users mailing list
<a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
<a class="moz-txt-link-freetext" href="https://lists.sourceforge.net/lists/listinfo/pyopengl-users">https://lists.sourceforge.net/lists/listinfo/pyopengl-users</a>
</pre>
    </blockquote>
    <br>
  </body>
</html>

--------------8FC2259EFAB3BDA1C1286DC1--


--===============1033921498485170220==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
--===============1033921498485170220==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
PyOpenGL Homepage
http://pyopengl.sourceforge.net
_______________________________________________
PyOpenGL-Users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/pyopengl-users

--===============1033921498485170220==--