Jump to content
  • Advertisement
Sign in to follow this  
CirdanValen

OpenGL Render to texture coordinate problems

This topic is 2533 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

I'm trying to get render to texture working, but am having problems with the coordinate system. When I render this quad to the screen, it gets drawn in the top right corner. However, if I try binding the render target, the quad gets drawn in the bottom right corner, and ends up not getting rendered to the texture.

The quad:


graphics->beginScene();

graphics->bindRenderTarget(target);


glBegin(GL_QUADS);

glColor4f(1.f, 0.f, 0.f, 1.f);
glVertex3f(0.f, 0.f, 0.f);

glColor4f(0.f, 1.f, 0.f, 1.f);
glVertex3f(16.f, 0.f, 0.f);

glColor4f(0.f, 0.f, 1.f, 1.f);
glVertex3f(0.f, 16.f, 0.f);

glColor4f(1.f, 1.f, 0.f, 1.f);
glVertex3f(16.f, 16.f, 0.f);

glEnd();


graphics->unbindRenderTarget();


graphics->drawRenderTarget(target);


graphics->endScene();



void GraphicsDevice::bindRenderTarget(RenderTarget *target) {
// Bind the frame buffer
glBindFramebuffer(GL_FRAMEBUFFER_EXT, target->getFramebuffer());
// store the glViewport and glEnable states
glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);
glViewport(0, 0, target->getWidth(), target->getHeight());
glClearColor(1.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.f, 0.f, 0.f);
glLoadIdentity();
}

void GraphicsDevice::unbindRenderTarget() {
// Restore glViewport and glEnable states
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}

void GraphicsDevice::drawRenderTarget(RenderTarget *target) {
glBindTexture(GL_TEXTURE_2D, target->getTexture());

glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f);
glVertex3f(0.f, 0.f, 0.f);

glTexCoord2f(1.f, 0.f);
glVertex3f(target->getWidth(), 0.f, 0.f);

glTexCoord2f(1.f, 1.f);
glVertex3f(target->getWidth(), target->getHeight(), 0.f);
glTexCoord2f(0.f, 1.f);
glVertex3f(0.f, target->getHeight(), 0.f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}


RenderTarget::RenderTarget(GraphicsDevice *graphics, GLuint width, GLuint height) {

mWidth = width;
mHeight = height;

// First create the depth buffer
glGenRenderbuffers(1, &mDepth);
glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepth);

// Tell OpenGL that this renderbuffer is going to be a depth buffer
glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);

glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

// Create the frame buffer texture
glGenTextures(1, &mTexture);
glBindTexture(GL_TEXTURE_2D, mTexture);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glBindTexture(GL_TEXTURE_2D, 0);

// Create the frame buffer
glGenFramebuffers(1, &mFbo);
glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);

// Attach the texture
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture, 0);

//Attach the depth buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);


}

Share this post


Link to post
Share on other sites
Advertisement


glColor4f(0.f, 0.f, 1.f, 1.f);
glVertex3f(0.f, 16.f, 0.f);

glColor4f(1.f, 1.f, 0.f, 1.f);
glVertex3f(16.f, 16.f, 0.f);



These last two vertices are reversed. The first one should be (16, 16, 0) and the second one should be (0, 16, 0).



// Tell OpenGL that this renderbuffer is going to be a depth buffer
glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);



You can't call glFramebufferRenderbuffer here because a frame buffer has not been bound yet. This call to glFramebufferRenderbuffer should actually be put in place of the other call to glFramebufferRenderbuffer. The other call attaches mFbo to itself as a depth attachment which doesn't make sense. The FBO creation would actually be incomplete as a result. Rendering to the incomplete FBO is probably the source of your issue.

Share this post


Link to post
Share on other sites
Thanks for the tip. I checked glCheckFramebufferStatus(GL_FRAMEBUFFER); and it came back complete.

I was able to solve my initial problem by setting the view matrix, which I kind of thought was the problem in the first place but wasn't sure how to fix it. My next question is, can I push the matrix settings to the stack so I don't have to keep setting it back and forth? I don't want this to become a performance problem in the future.

EDIT: looks like if I glPushAttrib/glPopAttrib with [color=#444444][font=Consolas, Menlo, Monaco,]GL_TRANSFORM_BIT it will save the matrix mode[/font]

void GraphicsDevice::setRenderTarget(RenderTarget *target) {
// store the glViewport and glEnable states
glPushAttrib(GL_VIEWPORT_BIT);

// Bind the frame buffer
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target->getFramebuffer());

// Setup the view matrix
glViewport(0, 0, target->getWidth(), target->getHeight());
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, target->getWidth(), 0, target->getHeight(), -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//glClearColor(1.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glClearColor(0.f, 0.f, 0.f, 1.f);
}

void GraphicsDevice::clearRenderTarget() {

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
// Restore glViewport and glEnable state
glPopAttrib();
setViewMatrix();
}

Share this post


Link to post
Share on other sites

Come to think of it, the FBO creation code you posted could still work but it would be hiding a bug. In the case where mDepth = mFbo, it would be alright and this is the case you've witnessed (probably mDepth and mFBO were both one since there are only one RBO and one FBO). If those two values are different (perhaps if there is a different number of RBOs than FBOs generated), then either the FBO would be incomplete or the wrong RBO would be attached.



Pushing/popping the GL_TRANSFORM_BIT saves not just the matrix mode, but the clipping planes' coefficients as well as some other flags. For efficiency reasons, you might want to steer clear of using that. As for the matrices themselves, you should use glPushMatrix and glPopMatrix.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!