【问题标题】:PyOpenGL error when rendering a textured Sun with a gluSphere使用 gluSphere 渲染带纹理的太阳时出现 PyOpenGL 错误
【发布时间】:2014-12-08 16:40:17
【问题描述】:

我正在为我的计算机图形项目编写一个程序来模拟我们的太阳系。我使用 Python 作为编程语言和 Pygame(用于控制显示、鼠标和键盘事件)、PyOpenGL(用于 3D 建模和纹理)和 PIL(Python 图像库,用于为 OpenGL 纹理加载图像)。该应用程序的主要目的是能够通过键盘在太阳系中飞来飞去(一种免费的相机游戏)。我使用了“Beginning”的 firstopengl.py 方法 使用 Python 和 Pygame 从新手到专业的游戏开发”一书,由 Will McGugan 编写,用于控制相机。我的问题是,当我运行程序(仅渲染场景中心的纹理太阳)时,它运行良好,直到你移动距离物体太近或太远(旋转到目前为止没有显示任何问题)。错误输出是:

C:\Python27\python.exe E:/Nestor/RESPALDO/NESTOR/DATA/7mo_Semestre/GxC/Proyecto/star-trip/main.py
Traceback (most recent call last):
  File "E:/Nestor/RESPALDO/NESTOR/DATA/7mo_Semestre/GxC/Proyecto/star-trip/main.py", line 235, in <module>
main()
  File "E:/Nestor/RESPALDO/NESTOR/DATA/7mo_Semestre/GxC/Proyecto/star-trip/main.py", line 225, in main
        planets[0].render()
  File "E:\Nestor\RESPALDO\NESTOR\DATA\7mo_Semestre\GxC\Proyecto\star-trip\spaceobjects.py", line 46, in render
    baseline.loadTexture(self.texture)
  File "E:\Nestor\RESPALDO\NESTOR\DATA\7mo_Semestre\GxC\Proyecto\star-trip\baseline.py", line 158, in loadTexture
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
  File "C:\Python27\lib\site-packages\pyopengl-3.1.0-py2.7.egg\OpenGL\latebind.py", line 41, in __call__
    return self._finalCall( *args, **named )
  File "C:\Python27\lib\site-packages\pyopengl-3.1.0-py2.7.egg\OpenGL\wrapper.py",   line 875, in wrapperCall
    raise err
OpenGL.error.GLError

乍一看,我在应用太阳纹理时似乎做错了什么,所以这是我用来做的代码:

def loadTexture(texture_path):

    #Load texture file
    data = open(texture_path)
    ix = data.size[0]
    iy = data.size[1]
    data = data.tostring("raw", "RGBX", 0, -1)

    # Create textures
    textures = glGenTextures(3)

    # Select our current texture
    glBindTexture(GL_TEXTURE_2D, int(textures[0]))   # 2d texture (x and y size)

    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)

    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)

    # Create Linear Filtered Texture
    glBindTexture(GL_TEXTURE_2D, int(textures[1]))

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)

    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)

    # Create a MipMapped Texture
    glBindTexture(GL_TEXTURE_2D, int(textures[2]))

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR)
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST)

    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, ix, iy, GL_RGBA, GL_UNSIGNED_BYTE, data)

    return textures

我还遇到了“内存不足”错误,我不太了解,因此我们将不胜感激。

【问题讨论】:

    标签: python opengl


    【解决方案1】:

    你是否在反复调用 loadTexture?听起来有点像,虽然从您的代码中很难分辨,但异常在您启动后(例如,当您靠近太阳时)发生的事实表明它正在被调用渲染循环。

    如果您在每个渲染循环都调用它,那么您将分配大量相同的纹理贴图(并构建大量 mipmap),这将非常快速地消耗图形内存。确保只调用一次 loadtextures,保存返回的纹理 id,然后只使用这些 id 调用 glBind2D,而不是一遍又一遍地调用 loadtexture。

    【讨论】:

    • 您对 loadTexture 函数的猜测是正确的。我在主循环中每帧调用一次。我不精通如何在 OpenGL 中处理内存使用(或者在计算机图形学中,我正在从头开始学习 :))所以我想我犯了一个典型的菜鸟错误。我会试试你的方法,看看会发生什么。非常感谢...... PS:如果你能推荐一个关于这个问题的好教程,它会派上用场。
    • NeHe的教程一般都不错,大部分都翻译成python了(比如一篇关于纹理映射的:pyopengl.sourceforge.net/context/tutorials/nehe6.html
    • 顺便说一下,如果你觉得这个答案有帮助,请接受它作为答案:)
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-14
    相关资源
    最近更新 更多