mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
3.01k stars 582 forks source link

Crashed in pyrender's scene render function when texture size/number is large #2091

Open riematrix opened 11 months ago

riematrix commented 11 months ago

Hi, I try to load and render an obj file which contains 16 images as texture. Trimesh load successfully without any error, but pyrender crashed and the stack trace is:

`Traceback (most recent call last): File "/usr/local/lib/python3.9/dist-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): ... renderer.render(scene) File "/usr/local/lib/python3.9/dist-packages/pyrender/offscreen.py", line 102, in render retval = self._renderer.render(scene, flags, seg_node_map) File "/usr/local/lib/python3.9/dist-packages/pyrender/renderer.py", line 125, in render self._update_context(scene, flags) File "/usr/local/lib/python3.9/dist-packages/pyrender/renderer.py", line 755, in _update_context texture._add_to_context() File "/usr/local/lib/python3.9/dist-packages/pyrender/texture.py", line 197, in _add_to_context glTexImage2D( File "/usr/local/lib/python3.9/dist-packages/OpenGL/latebind.py", line 45, in call return self._finalCall( *args, *named ) File "/usr/local/lib/python3.9/dist-packages/OpenGL/wrapper.py", line 875, in wrapperCall raise err File "/usr/local/lib/python3.9/dist-packages/OpenGL/wrapper.py", line 868, in wrapperCall result = wrappedOperation( cArguments ) File "/usr/local/lib/python3.9/dist-packages/OpenGL/error.py", line 228, in glCheckError raise GLError( OpenGL.error.GLError: GLError( err = 1281, description = b'invalid value', baseOperation = glTexImage2D, pyArgs = ( GL_TEXTURE_2D, 0, GL_RGBA, 32768, 2048, 0, GL_RGBA, GL_UNSIGNED_BYTE, array([0, 0, 0, ..., 0, 0, 0], dtype=uint8), ), cArgs = ( GL_TEXTURE_2D, 0, GL_RGBA, 32768, 2048, 0, GL_RGBA, GL_UNSIGNED_BYTE, array([0, 0, 0, ..., 0, 0, 0], dtype=uint8), ), cArguments = ( GL_TEXTURE_2D, 0, GL_RGBA, 32768, 2048, 0, GL_RGBA, GL_UNSIGNED_BYTE, array([0, 0, 0, ..., 0, 0, 0], dtype=uint8), ) ) ` Seems that the packed texture is too large for GL at first glance. But the width/height in arguments does not match exactly with my input. In fact the packed size is nearly 4 times of input 16x1024x1024.

After some debug I found that there is a padding process and a power_resize process in packing. There is nothing wrong with the code, but do we really need to allocate so much memory when the input resolution is exactlly power of 2 like 1024? Because after padding and power_resize, one 1024x1024 image is supposed to take up 2048x2048 memory space.

Best

mikedh commented 11 months ago

Yeah PR's super welcome for this case! I agree it would make sense to fix and unit test for the case where there is a single image that already is a power of two.