pyglet.graphics:关于ctypes数组创建的IndexError

时间:2012-02-27 20:12:16

标签: python debugging opengl ctypes pyglet

我正在用pyglet开发一款小游戏。当然,一个核心是绘制彩色矩形标记。我最初是通过在内存中创建图像并blit()来实现这一点的,这很好。在注意到丑陋,迂回和无所事事之后(是的,我描述 - ColorRect.draw()花费了大量时间并且通过这种改变变得高出10倍)这就是,我开始通过pyglet.graphics.Batch创建顶点列表(我从其中一个示例中逐字复制了大部分代码。从那时起,我在一些低级OpenGL代码中遇到了一个奇怪的例外,我没有找到原因或可靠地重现。

与游戏事件没有明显的关系 - 就像在之前,没有什么特别的事情发生在我之前,或者我经常会错过它。由于错误发生在事件循环的某个深处,我无法轻松追踪更新导致它的位置。老实说,我很难过。因此,我会把我所发现的东西铭记于心,并希望有一种善意的心理。

我已经在Windows 7 32位上尝试过了(我可能很快就会在Ubuntu 11.10上尝试使用Python 3.2.2),并使用pyglet修订版043180b64260(从Goggle Code中提取并从源代码构建,1.1 .4发布更难以安装,因为它不会自动运行2to3,虽然它似乎同样是py3k就绪)。我可能会更新到最新的mercurial版本,但它只是一些提交而且这些更改似乎完全不相关。

完整的追溯(原则上审查了一些路径,但请注意它在自己的virtualenv中):

Traceback (most recent call last):
  File "<my main file>", line 152, in <module>
    main()
  File "<my main file>", line 148, in main
    run()
  File "<my main file>", line 125, in run
    pyglet.app.run()
  File "<virtualenv>\Lib\site-packages\pyglet\app\__init__.py", line 123, in run
    event_loop.run()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 135, in run
    self._run_estimated()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 164, in _run_estimated
    timeout = self.idle()
  File "<virtualenv>\Lib\site-packages\pyglet\app\base.py", line 278, in idle
    window.switch_to()
  File "<virtualenv>\Lib\site-packages\pyglet\window\win32\__init__.py", line 305, in switch_to
    self.context.set_current()
  File "<virtualenv>\Lib\site-packages\pyglet\gl\win32.py", line 213, in set_current
    super(Win32Context, self).set_current()
  File "<virtualenv>\Lib\site-packages\pyglet\gl\base.py", line 320, in set_current
    buffers = (gl.GLuint * len(buffers))(*buffers)
IndexError: invalid index

运行验尸(主动逐步执行代码直到它发生,因为FPS从60降到7)pdb显示:

  • buffers是一个整数列表;我不知道它们代表什么或它们来自哪里,但它们是从名为self.object_space._doomed_textures的列表中提取的(其中self是一个窗口对象)。相关评论说这段代码会释放计划删除的纹理。我不认为我在任何地方明确使用纹理,但谁知道pyglet在幕后做了什么。我假设这些整数是ID或要销毁的纹理。
  • gl.GLuintctypes.c_ulong的别名;因此(gl.GLuint * len(buffers))(*buffers)创建一个长度和内容相同的ulong数组
  • 我可以在pdb提示符下评估相同的表达式,而不会出现错误或数据损坏。

使用ctypes进行独立实验(在virtualenv之外并且不导入pyglet)显示如果给数组构造函数提供的参数太多,则会引发IndexError。这没有任何意义,实验和逻辑都表明长度和参数计数必须始终匹配。

  1. 是否还有其他可能发生此异常的情况?这可能是pyglet的错误,还是我滥用了库并错过了相关警告?
  2. 创建和维护顶点列表的代码在调试时是否有用?它可能有某些错误。我已经盯着它了,但由于我对pyglet.graphics的经验不多,所以这个用途有限。如果您想查看ColorRect代码,请发表评论。
  3. 可能导致此问题的任何其他想法?

1 个答案:

答案 0 :(得分:0)

提供真正相关的答案有点困难,因为没有提供代码,但我从错误输出中可以看到。

buffers = (gl.GLuint * len(buffers))(*buffers)

因此,如果我理解正确,您将GLuint(4个字节)的大小乘以实际缓冲区长度(如果已初始化)。也许这就是你的索引无效的原因,因为它太高了?

通常它会没问题,因为缓冲区是以字节为单位的,但是你说它是一个整数列表?

希望有所帮助