Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unhashable type exception when using glVertexAttribPointer with OSMesa and OpenGL 2.1 #33

Open
sabtorres opened this issue Sep 19, 2019 · 4 comments

Comments

@sabtorres
Copy link

I'm getting this exception whenever i call glVertexAttribPointer in an OpenGL 2.1 context with OSMesa. That didn't happen when I was using an OpenGL 4.3 context with GLFW

I'm using openSUSE Tumbleweed with Mesa graphics drivers (19.1.5 version)

This is the full exception message:

Traceback (most recent call last):
  File "main.py", line 165, in <module>
    main()
  File "main.py", line 152, in main
    shape.render()
  File "main.py", line 118, in render
    self.teapot.render(self.material.shader)
  File "main.py", line 66, in render
    glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
  File "/home/guilherme/.local/lib/python3.7/site-packages/OpenGL/latebind.py", line 61, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
  File "/home/guilherme/.local/lib/python3.7/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 426, in glVertexAttribPointer
    contextdata.setValue( key, array )
  File "/home/guilherme/.local/lib/python3.7/site-packages/OpenGL/contextdata.py", line 65, in setValue
    current = storage.get( context )
TypeError: unhashable type

I'm trying to render something in headless mode, that's why I'm using OSMesa and gl2.1. Any help I can get here please?

mcfletch added a commit that referenced this issue Dec 28, 2019
This is an osmesa demo using shaders and vertex attribute pointers
@mcfletch
Copy link
Owner

The basic problem here is that somehow your current context is a non-hashable type, I just don't see how it does.

On OSMesa the contextdata module should be using an OpaquePointer instance which explicitly should have a hash method. Do you have a test case I can use to debug, as my attempt at a recreation is running correctly.

mcfletch added a commit that referenced this issue Jan 4, 2020
* 3e9791f Bump release to 3.1.5
* d06c1ac NUMPY Register intc and uintc as handled scalar types
* 38edb04 WIN FIX GL entry points are NULL on windows initially
* 57b7706 TESTS Run accelerate tests from base tox as well
* 60aec44 BUILD Update cython source with current release
* c26398b TESTS Switch to pytest.mark for skipping numpy handler when not available
* 6ec398d TESTS Switch to assertRaises
* 581d240 TESTS Don't print glget calls, compressed image api call revert
* 8cf737d API More support for using short-string types for convenience
* 1b7c3c3 API In ctypes arrays allow for numpy style short-string type specifiers
* eb9a6b4 FIX Work around weird numpy scalar behaviour (0-dimension arrays)
* d625f8b TESTS reason cannot be passed as a keyword argument in pytest.skip
* f12403b WGL FIX Set the resstyle for getCurrentDC in the wrapper
* 143ecbc GITHUB #7 Use b-strings instead of as_8_bit
* 44a89fe GITIGNORE Ignore .pyd files for Windows develop builds
* a52215f TESTS Fix usage of glCompressedTexImage2D in test_core
* 2f401a0 EGL Allow eglGetDeviceQueryString without display, use to display drm name
* c4cd5d0 BUILD Back out adding python3.8 to the build matrix
* 447fbfa BUILD Continue trying to get sdl to compile
* bdb957b BUILD Add libsdl1.2-dev to get the sld-config utility
* dccbbb6 BUILD Revert attempts to use arm64 (pygame doesn't build) but add python 3.8
* 907ec4a BUILD Experiment with testing on arm64 (loosely related to GH #29)
* 637caf4 TESTS Remove flaky test in favour of more robust one below it
* 144ce85 EGL DEMO Further refactoring of os_egl setup
* a07c956 EGL DEMO Allow for null values in EGL debug table formatting
* 9f115ff EGL Explicitly export EGLError from the EGL namespace
* c58c9c4 EGL Move code to debug, rely on EGLError for display, debug configs
* 93d6f66 EGL DEMO PPM writing and tabular format of configs in EGL debug module
* 9640630 FIX Fix latebind __bool__ definition as __nonzero__ isn't available
* 8628ce1 EGL Allow ErrorCheckers to specify GLError sub-classes, use for EGLError
* 1f1cda4 FORMAT Black formatting for os_egl demo/test script
* 0ed754b FIX for #27 to work on machines where libOpenGL is not present
* 589d3ca EGL Make `eglGetPlatformDisplay` an alternate with `eglGetPlatformDisplayEXT`
* e04bee4 FIX Add on for the fix to #6 to make force_extension functions bool() work
* 2487c21 EGL DEMO Try to create script to query the egl device enumerations
* 41e6f57 EGL DEMO Explicitly delete the DISPLAY environment variable to force offline operation
* 4a40d2b TESTS Ignore the output of osmesa and egl tests
* 3c81386 EGL DEMO Attempt to get an offscreen (pbuffer) render wrapper working
* 8f8d3e8 FIX #27 Load libOpenGL instead of libGL for egl platform
* 4f9cb46 DOCS Add pyrender as a sample source
* d401885 FIX GH #12 Include pxd files in the source-code release
* ca2cbbe DEMO Attempt to recreate github #33 without success
* ce8c5d5 DOCS Update comment to note that we're next to the main checkout now
* f85d8ce DOCS Update tartley projects to github urls, provide first-line links on gh and bb
* e81584a DOCS Skip generation of .xhtml redirect stubs
* 5f206da DEMO provide a running version of code in bug report in #34
* bf3fe7c FIX Explicitly add nonzero methods for base latebind classes
@sabtorres
Copy link
Author

Thanks for your attention, but unfortunately I don't have my test case right now. as we stopped trying to run PyOpenGL in headless mode a few months ago.

But if it's going to help you in the development, I can send you the point where I left off after I go back to work tomorrow (my holidays end today). I think I still have this issue there.

Again thanks for your work, though I'm still curious why I can only use older OpenGL versions with OSMesa. Is it a OSMesa limitation, or the newer GL support for PyOpenGL is still WIP? If it is, there is a chance I'll be able to help with that a little.

@mcfletch
Copy link
Owner

mcfletch commented Jan 6, 2020

OSMesa should expose the underlying OpenGL implementation. On my current mesa/osmesa OpenGL release shows OpenGL 3.1 on an Ubuntu 18.04 machine (i.e. the built-in Mesa software renderer supports OpenGL 3.1). An EGL off-screen context on the VMWare driver shows 3.1, consistent with the driver being provided by mesa.

On an EGL/nVidia off-screen context (on the same machine) OpenGL shows release 4.6. Which is what you would expect from an nVidia binary driver (and what you see if you create an on-screen window instead of an off-screen context).

PyOpenGL support should be current with defined extensions (well, within a month or so at this point), but it is entirely possible to find extensions where the auto-wrapping has resulted in a broken wrapper. That said, this looks like a "the opengl library you're using doesn't support the opengl version you'd like" issue.

@tengshaofeng
Copy link

tengshaofeng commented Jul 1, 2024

Dears @mcfletch ,This is a test case,which comes the error "{TypeError}unhashable type" at the code line "gl.glVertexPointer(2, gl.GL_FLOAT, 0, V_ori_gl_2d_ptr)", and my OSMesa version: 4.5 (Compatibility Profile) Mesa 23.2.1-1ubuntu3.1~22.04.2

import numpy as np
import os


if not os.environ.get('PYOPENGL_PLATFORM'):
    os.environ['PYOPENGL_PLATFORM'] = 'osmesa'
import ctypes
from OpenGL.osmesa import *
from OpenGL import arrays
import OpenGL.GL as gl


class BodyAwareReshaper:
    def __init__(self, reg_coeff_canvas):
        self.reg_coeff_canvas = reg_coeff_canvas

    def draw_body_part_mask(self, mesh_vertices, mesh_faces, projection_mat):
        ver_num = len(mesh_vertices)
        V_home = np.ones((ver_num, 4), dtype=np.float32)
        V_home[:, :3] = mesh_vertices

        projection_mat = np.transpose(projection_mat[:3, :])
        V_proj_3d = np.matmul(V_home, projection_mat)
        V_proj = V_proj_3d[:, :2]
        V_proj[:, 0] = V_proj[:, 0] / V_proj_3d[:, 2]
        V_proj[:, 1] = V_proj[:, 1] / V_proj_3d[:, 2]
        oneVec = np.ones(2, dtype=np.float32)
        V_ori_gl_2d = 2 * V_proj * self.reg_coeff_canvas - oneVec

        # Ensure data type and flatten array
        V_ori_gl_2d = V_ori_gl_2d.flatten().astype(np.float32)
        print(f"V_ori_gl_2d: {V_ori_gl_2d}")

        # OpenGL settings
        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadIdentity()
        gl.glMatrixMode(gl.GL_MODELVIEW)
        gl.glLoadIdentity()

        # Start OpenGL drawing
        gl.glPushMatrix()
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY)
        try:
            # Convert numpy array to a C-contiguous array
            V_ori_gl_2d_ptr = V_ori_gl_2d.ctypes.data_as(ctypes.POINTER(ctypes.c_float))
            print(f"Pointer Type: {type(V_ori_gl_2d_ptr)}")

            # Setting vertex pointer and draw
            gl.glVertexPointer(2, gl.GL_FLOAT, 0, V_ori_gl_2d_ptr)
            gl.glDrawArrays(gl.GL_POINTS, 0, len(V_ori_gl_2d) // 2)
        except Exception as e:
            print(f"Error during OpenGL call: {e}")
        finally:
            gl.glDisableClientState(gl.GL_VERTEX_ARRAY)
            gl.glPopMatrix()

        # Flush to ensure drawing commands are executed
        gl.glFlush()

def display_callback():
    mesh_vertices = np.random.rand(10, 3).astype(np.float32)
    mesh_faces = np.array([0, 1, 2])
    projection_mat = np.eye(4, dtype=np.float32)

    # Initialize and draw
    reshaper = BodyAwareReshaper(reg_coeff_canvas=np.float32([1.0 / canvas_width, 1.0 / canvas_height]))
    reshaper.draw_body_part_mask(mesh_vertices, mesh_faces, projection_mat)

ctx = OSMesaCreateContext(OSMESA_RGBA, None)
canvas_width = 832
canvas_height = 1216
bufRGBA = arrays.GLubyteArray.zeros((canvas_height, canvas_width, 4))

if not OSMesaMakeCurrent(ctx, bufRGBA, gl.GL_UNSIGNED_BYTE, canvas_width, canvas_height):
    raise RuntimeError("OSMesaMakeCurrent failed!")

gl.glViewport(0, 0, canvas_width, canvas_height)
gl.glEnable(gl.GL_DEPTH_TEST)

display_callback()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants