mmatl / pyrender

Easy-to-use glTF 2.0-compliant OpenGL renderer for visualization of 3D scenes.
http://pyrender.readthedocs.io/
MIT License
1.31k stars 225 forks source link

"TypeError: 'NoneType' object is not callable" when calling Renderer.render_text() #284

Open sven1904 opened 6 months ago

sven1904 commented 6 months ago

OS: Ubuntu 24.04 pyrender: 0.1.45 pyglet: 2.0.15 PyOpenGL: 3.1.0 trimesh: 4.3.2

When I try to turn rotation on by pressing 'a', I get the following error log:

Traceback (most recent call last):
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/latebind.py", line 41, in __call__
    return self._finalCall( *args, **named )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not callable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 349, in __init__
    self._init_and_start_app()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 1030, in _init_and_start_app
    pyglet.app.run()
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/__init__.py", line 76, in run
    event_loop.run(interval)
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/base.py", line 163, in run
    timeout = self.idle()
              ^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/base.py", line 224, in idle
    self.clock.call_scheduled_functions(dt)
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/clock.py", line 217, in call_scheduled_functions
    item.func(now - item.last_ts, *item.args, **item.kwargs)
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/base.py", line 118, in _redraw_windows
    window.dispatch_event('on_draw')
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/window/__init__.py", line 672, in dispatch_event
    super().dispatch_event(*args)
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/event.py", line 387, in dispatch_event
    if getattr(self, event_type)(*args):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 571, in on_draw
    self._renderer.render_text(
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/renderer.py", line 203, in render_text
    font._add_to_context()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/font.py", line 148, in _add_to_context
    ch.texture._add_to_context()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/texture.py", line 184, in _add_to_context
    self._texid = glGenTextures(1)
                  ^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/latebind.py", line 61, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/GL/exceptional.py", line 178, in glGenTextures
    baseFunction( count, textures)
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/latebind.py", line 45, in __call__
    return self._finalCall( *args, **named )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/wrapper.py", line 657, in wrapperCall
    result = wrappedOperation( *cArguments )
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/platform/baseplatform.py", line 402, in __call__
    return self( *args, **named )
           ^^^^^^^^^^^^^^^^^^^^^^
ctypes.ArgumentError: ("argument 2: TypeError: No array-type handler for type _ctypes.type (value: <cparam 'P' (0x717fab06aea0)>) registered", (1, <cparam 'P' (0x717fab06aea0)>))

That has nothing to do with the actual rotation, but calling render_text(...) on the renderer object causes this problem. Since I use this function in my application to display various crucial information, I need some functional text rendering. Although this problem seems to be related to the PyOpenGL library when loading texture for fonts, do you know if there's any workaround to show text until this bug is fixed in the library?

oarriaga commented 5 months ago

Hi! it seems that the issue is related to using python3.12. Most likely a change in ctype conversion. A similar error seems to have be found and reported here

I upgraded pyopenGL to it's latest version and I can render again with text.

pip install -U PyOpenGL

pyrender might complain about a mismatch version, but at the moment everything is running without any issues.

sven1904 commented 5 months ago

That did not work for me. pyrender does now crash in the Viewer's _render() method:

Exception in thread Thread-1 (_init_and_start_app):
Traceback (most recent call last):
  File "/usr/lib/python3.12/threading.py", line 1073, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.12/threading.py", line 1010, in run
    self._target(*self._args, **self._kwargs)
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 1030, in _init_and_start_app
    pyglet.app.run()
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/__init__.py", line 76, in run
    event_loop.run(interval)
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/app/base.py", line 155, in run
    window.dispatch_pending_events()
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/window/xlib/__init__.py", line 999, in dispatch_pending_events
    EventDispatcher.dispatch_event(self, *self._event_queue.pop(0))
  File "/home/sti/.local/lib/python3.12/site-packages/pyglet/event.py", line 387, in dispatch_event
    if getattr(self, event_type)(*args):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 608, in on_resize
    self.on_draw()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 568, in on_draw
    self._render()
  File "/home/sti/Repositories/Phd/para-serial-structures/misc/../urdf_viz/urdf_viz.py", line 428, in _render
    super()._render()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/viewer.py", line 989, in _render
    self._renderer.render(self.scene, flags)
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/renderer.py", line 134, in render
    self._update_context(scene, flags)
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/renderer.py", line 753, in _update_context
    p._add_to_context()
  File "/home/sti/.local/lib/python3.12/site-packages/pyrender/primitive.py", line 377, in _add_to_context
    glVertexAttribPointer(
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/latebind.py", line 63, in __call__
    return self.wrapperFunction( self.baseFunction, *args, **named )
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/GL/VERSION/GL_2_0.py", line 469, in glVertexAttribPointer
    contextdata.setValue( key, array )
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/contextdata.py", line 58, in setValue
    context = getContext( context )
              ^^^^^^^^^^^^^^^^^^^^^
  File "/home/sti/.local/lib/python3.12/site-packages/OpenGL/contextdata.py", line 40, in getContext
    raise error.Error(
OpenGL.error.Error: Attempt to retrieve context when no valid context

I don't know if this is really related to the version mismatch, but I didn't had that error before.

sven1904 commented 5 months ago

For the moment, I found a workaround which is at least acceptable. In the Renderer, I replaced the content of render_text(...) with

# # workaround for bug in PyOpenGL
try:
  # original content of render_text(...)
except ctypes.ArgumentError:
  label = pyglet.text.Label(text, font_name=font_name, font_size=font_pt, anchor_x=ANCHORS_X[align],
                            x=x, y=y, color=[int(c*255) for c in color], anchor_y=ANCHORS_Y[align])
  label.draw()

using the global arrays

ANCHORS_X = ['center', 'left',   'right',
             'left',   'right',  'center',
             'left',   'right',  'center']
ANCHORS_Y = ['center', 'center', 'center',
             'bottom', 'bottom', 'bottom',
             'top',    'top',    'top']

At least, it works and the text is displayed again, although I know there are some drawbacks:

Hence, this is not a solution but at least a workaround until the underlying problem is fixed.