OpenGL帧缓冲区使用多个纹理

3
我希望在我的程序中渲染n个纹理并将它们存储以备后用。因此,我使用OpenGL FramebufferObject。
首先,我创建了一个包含128个纹理的数组,如下所示:
self.textures = glGenTexture(128)

第二步是一个循环,有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()

最后一步是另一个循环,即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)

但是出现了问题,屏幕仍然黑屏。
1个回答

5
当用作帧缓冲对象的颜色附件时,纹理不能被绑定。但是,在附加之前您正在绑定它,这当然会破坏整个过程。
正确的代码应该遍历所有多重纹理单元,并确保在其中没有绑定纹理。
由于评论而更新:
在您的代码中,绑定一个纹理名称并为其设置参数。
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);

问题在于,纹理仍然被选为数据源,因为它已经绑定。纹理不能绑定到任何纹理单元,才能作为帧缓冲颜色附加件工作。同时,FBO必须在某个地方被绑定为渲染目标。
renderScene()

这是一个小的帮助函数,可以确保给定的纹理对象没有在任何纹理单元中绑定:

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)

我真的不太理解你的意思。你能提供一些代码吗?这样我会更容易理解。 - glethien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接