gle*_*ien 3 python opengl framebuffer
我想在我的程序中渲染n纹理并存储它们以供以后使用.因此我使用OpenGL FramebufferObject.
首先,我创建一个包含128个纹理的数组
self.textures = glGenTexture(128)
Run Code Online (Sandbox Code Playgroud)
第二步是一个包含128次迭代的循环,其中我将位置i处的纹理绑定并渲染到其中.
glBindTexture(GL_TEXTURE_2D, self.texture[i])
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.texture[i], 0);
renderScene()
Run Code Online (Sandbox Code Playgroud)
最后一步是另一个循环,MainGameLoop,我在其中使用纹理数组中的一个纹理渲染一个平面.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
gluLookAt(0,0,1,0,0,0,0,1,0)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.texture[i])
glBegin(GL_QUADS)
glNormal3f(0.0, 1.0, 0.0)
glTexCoord2f(0.0, 0.0)
glVertex3f(-1, 1, -1)
glTexCoord2f(1.0, 0.0)
glVertex3f(1, 1, -1)
glTexCoord2f(1.0, 1.0)
glVertex3f(1, -1, -1)
glTexCoord2f(0.0, 1.0)
glVertex3f(-1, -1, -1)
glEnd();
glDisable(GL_TEXTURE_2D)
Run Code Online (Sandbox Code Playgroud)
但出了点问题,屏幕保持黑色.
用作framebuffer对象的颜色附件时,不得绑定纹理.然而,你在绑定之前绑定它当然会打破整个事情.
正确的代码将遍历所有多纹理单元,并确保纹理未绑定在任何单元中.
在代码中绑定纹理名称并为其设置参数
glBindTexture(GL_TEXTURE_2D, self.texture[i])
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_NEAREST)
Run Code Online (Sandbox Code Playgroud)
然后使用null数据初始化纹理对象
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None);
Run Code Online (Sandbox Code Playgroud)
最后将其作为帧缓冲附件附加.
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.texture[i], 0);
Run Code Online (Sandbox Code Playgroud)
问题是,现在纹理仍然被选为数据源,因为它是绑定的.纹理不得绑定到任何纹理单元,以作为帧缓冲颜色附件.此外,FBO必须绑定为渲染目标.
renderScene()
Run Code Online (Sandbox Code Playgroud)
这是一个小辅助函数,可以确保给定的纹理对象不会绑定在任何纹理单元中:
def glhelperUnbindTexture(target, name):
max_units = max(glGetInteger(GL_MAX_TEXTURE_UNITS),
glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS),
glGetInteger(GL_MAX_TEXTURE_COORDS))
current_unit = glGetInteger(GL_ACTIVE_TEXTURE)
for i in range(max_units):
glActiveTexture(GL_TEXTURE0 + i)
binding = glGetInteger( {GL_TEXTURE_1D: GL_TEXTURE_BINDING_1D,
GL_TEXTURE_2D: GL_TEXTURE_BINDING_2D,
GL_TEXTURE_3D: GL_TEXTURE_BINDING_3D,
GL_TEXTURE_CUBE_MAP: GL_TEXTURE_BINDING_CUBE_MAP}[target])
if binding == name:
glBindTexture(target, 0) # this unbinds the texture from the texturing unit
glActiveTexture(current_unit)
Run Code Online (Sandbox Code Playgroud)