Sign in to follow this  

Rendering To Texture and Frame Buffer Object problem

This topic is 3477 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 3477 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this