Rendering To Texture and Frame Buffer Object problem

Started by
4 comments, last by GL1zdA 15 years, 10 months ago
Hi! I'am trying to render something to a texture using frame buffer objects. I set up a scene containing a cube with 3D texture coordinates which is processed using a pixel shader which maps the texture coordinates to the color (I will need this later) - works good when rendered to the window. I want to render it to a texture so I added a quad to the scene which will be textured (works with a texture loaded from a file). I bind the FBO before drawing the cube, then unbind it and try to render the quad textured with the texture attached to the FBO. But at best I get some random colours, but most of the time it's black. This is my code: Initializing textures:
int current = 0;
GLuint TMP, DIR, RES, TEST[3];

GLuint Init2DTexture(GLenum internalFormat, GLsizei width, GLsizei height, GLenum format){//, int bytes){
    GLuint texture;
    //unsigned int* data;
    //data = (unsigned int*) malloc(width * height * bytes * sizeof(unsigned int));
    //ZeroMemory(data, (width * height * bytes * sizeof(unsigned int)));
    glGenTextures(1, &texture); //jedna tekstura
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, GL_UNSIGNED_BYTE, NULL);
    //free(data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    return texture;
}

GLuint Init2DTextureFromFile(char* name){
    GLuint texture;
    GLbyte *pBytes;
    GLint nWidth, nHeight, nComponents;
    GLenum format;

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    pBytes = gltLoadTGA(name, &nWidth, &nHeight, &nComponents, &format);
    glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0, format, GL_UNSIGNED_BYTE, pBytes);
    free(pBytes);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glBindTexture(GL_TEXTURE_2D, 0);
    return texture;
}

int InitTextures(void){
    TMP = Init2DTexture(GL_RGBA8, 512, 512, GL_RGBA);
    DIR = Init2DTexture(GL_RGB8, 512, 512, GL_RGB);
    RES = Init2DTexture(GL_RGBA8, 512, 512, GL_RGBA);
    TEST[0] = Init2DTextureFromFile("floor0.tga");
    TEST[1] = Init2DTextureFromFile("floor1.tga");
    TEST[2] = Init2DTextureFromFile("floor2.tga");
	
    return TRUE;
}


Initializing FBO:

GLuint fb;

int InitFBOs(void){
    GLuint depthBuffer;
    GLenum status;

    glGenFramebuffersEXT(1, &fb);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

    glGenRenderbuffersEXT(1, &depthBuffer);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT16, 512, 512);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
    
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, TMP, 0);
    //status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    return TRUE;
}


Rendering the scene:

int RenderScene(void){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0, 0, 512, 512);
    
    //Rendering to TMP
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
    glUseProgram(programs[PASS1]);
    DrawCube();
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    glPopAttrib();

    glUseProgram(0);

    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    glViewport(0, 0, window_w, window_h);
    
    glEnable(GL_TEXTURE_2D);
    //glBindTexture(GL_TEXTURE_2D, TEST[current]);
    glBindTexture(GL_TEXTURE_2D, TMP);

    DrawQuad();

    glBindTexture(GL_TEXTURE_2D, 0);
    glDisable(GL_TEXTURE_2D);
    return TRUE;
}


Thanks in advance for any hint how to solve this problem.
Advertisement
You should attach your backbuffer-texture to the FBO right before rendering to it. When that's done, unattach it again.
Also, you should modify your projection matrix to project to 512x512 as well.

This is what I can think of:
int RenderScene(void){    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glLoadIdentity();    glPushAttrib(GL_VIEWPORT_BIT);    glViewport(0, 0, 512, 512);    // NEW: Modify projection matrix to 512x512        //Rendering to TMP    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);    // NEW: Attach backbuffer texture    // NEW: Clear backbuffer texture with glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    glUseProgram(programs[PASS1]);    DrawCube();    // NEW: Unattach backbuffer texture    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);    glPopAttrib();    glUseProgram(0);    //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);        glViewport(0, 0, window_w, window_h);        glEnable(GL_TEXTURE_2D);    //glBindTexture(GL_TEXTURE_2D, TEST[current]);    glBindTexture(GL_TEXTURE_2D, TMP);    DrawQuad();    glBindTexture(GL_TEXTURE_2D, 0);    glDisable(GL_TEXTURE_2D);    return TRUE;}
while (tired) DrinkCoffee();
Thanks. It works now.
I will have to render to several (3) textures and would like to do it right from the beginning. What will be better: having a FBO for each texture I would like to render to or rather have one FBO and change the attached textures?
Quote:
I will have to render to several (3) textures and would like to do it right from the beginning. What will be better: having a FBO for each texture I would like to render to or rather have one FBO and change the attached textures?

The latter.

Check the 29th slide of this presentation from GDC 2005.

Note that there's also a third option that outperforms both of these.
Thanks for the link. I'll do it with the multiple attachments and choose the output in my shaders.

This topic is closed to new replies.

Advertisement