3

I want to render n texture in my program and store them for later usage. Therefore I use the OpenGL FramebufferObject.

At first I create an array with 128 textures like this

self.textures = glGenTexture(128)

The second step is a loop with 128 iterations in which I bind the texture at position i and render into it.

    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()

The last step is another loop, the MainGameLoop in which I render a plane with one texture from the texture array.

    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)

But something went wrong, the screen stays black.

4

1 回答 1

5

A texture must not be bound when used as a color attachment to a framebuffer object. You however are binding it before attaching which of course breaks the whole thing.

The correct code would iterate through all multitexturing units and make sure the texture is not bound in any of them.

Update due to comment:

In your code you bind a texture name and set parameters for it

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)

Then you initialize the texture object with null data

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, None);

and finally attach it as a framebuffer attachment.

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,  GL_TEXTURE_2D, self.texture[i], 0);

The problem is, that now the texture is still selected as a data source, because it is bound. The texture must not be bound to any texturing unit, to work as a framebuffer color attachment. Also the FBO must be bound as render target somewhere.

renderScene()

Here's a small helper function that makes sure, a given texture object is not bound in any texturing unit:

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)
于 2012-07-28T14:38:53.073 回答