I'm trying to render to a texture, then copy that texture and run it through post processing, then combine the filtered image with the original. I've got it so I can render to a a texture, then process it and display it, but I can only process it once. I'm really not sure what's going wrong.
Here is my FBO setup code:
for (int i = 0; i < 3; i++) {
glGenFramebuffers(1, &postfboId[i]);
glGenTextures(1, &postTextureId[i]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, postTextureId[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
//float color[4] = {0.0, 0.0, 0.0, 1.0};
//glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, screenSize.x, screenSize.y, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
// create a framebuffer object
glBindFramebuffer(GL_FRAMEBUFFER, postfboId[i]);
glGenRenderbuffers(1, &depthrenderbuffer[i]);
glBindRenderbuffer(GL_RENDERBUFFER, depthrenderbuffer[i]);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, screenSize.x, screenSize.y);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthrenderbuffer[i]);
// attach the texture to FBO depth attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D, postTextureId[i], 0);
}
GLenum DrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
glDrawBuffers(1, DrawBuffers);
// check FBO status
FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(FBOstatus != GL_FRAMEBUFFER_COMPLETE)
printf("hey man, you might want to sit down a minute, i didn't want to have to say this to you, but the FBO failed.\n");
I thought maybe I need glDrawBuffers to make 3 instead of 1, but this just causes the FBO to be incomplete.
Here is my render code:
glBindFramebuffer(GL_FRAMEBUFFER,postfboId[0]);
sf::Vector2u size = screenSize;
changeSize(size.x, size.y);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
//clear viewport
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(prog);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
setLookat();
glCullFace(GL_BACK);
setLights();
drawObjs();
glPopMatrix();
//first round post process
glClearColor(0, 0, 0, 1);
glUseProgram(postProg);
glBindFramebuffer(GL_FRAMEBUFFER,postfboId[1]);
glUniform1i(postProcessMode, 1);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
glOrtho(0,screenSize.x,0,screenSize.y,-1,20);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
glColor4f(1,1,1,1);
glUniform1i(texUniform3, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,postTextureId[0]);
glEnable(GL_TEXTURE_2D);
glTranslated(0,0,-19.5);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3f(0,0,0);
glTexCoord2d(1,0);glVertex3f(screenSize.x,0,0);
glTexCoord2d(1,1);glVertex3f(screenSize.x,screenSize.y,0);
glTexCoord2d(0,1);glVertex3f(0,screenSize.y,0);
glEnd();
// round 2 post
glUniform1i(postProcessMode, 2);
glBindFramebuffer(GL_FRAMEBUFFER,0);
glUniform1i(texUniform3, 3);
glActiveTexture(GL_TEXTURE3);
// bind postTextureId[0] to draw real screen.
glBindTexture(GL_TEXTURE_2D,postTextureId[1]);
glEnable(GL_TEXTURE_2D);
glTranslated(0,0,0.5);
glBegin(GL_QUADS);
glTexCoord2d(0,0);glVertex3f(0,0,0);
glTexCoord2d(1,0);glVertex3f(screenSize.x,0,0);
glTexCoord2d(1,1);glVertex3f(screenSize.x,screenSize.y,0);
glTexCoord2d(0,1);glVertex3f(0,screenSize.y,0);
glEnd();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
For whatever reason, drawing an FBOs texture to another FBO results in nonsense, but drawing that FBO texture to the screen is fine. Also, all 3 FBOs work, just not at the same time, which is odd since I have another FBO with just a depth buffer for shadowmapping which displays correctly.
One immediately apparent problem is that you're missing glClear() calls for all but the first render target. You call it once after binding fbo 0:
glBindFramebuffer(GL_FRAMEBUFFER,postfboId[0]);
...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
But you'll also need to clear after binding fbo 1:
glBindFramebuffer(GL_FRAMEBUFFER,postfboId[1]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
and after binding the default framebuffer:
glBindFramebuffer(GL_FRAMEBUFFER,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Some of your glPushMatrix() and glPopMatrix() calls also look somewhat suspicious. But it's hard to tell if they are incorrect without seeing the whole code. You may want to double check that they all balance, and that you're in the right matrix mode when calling them. For example in this sequence:
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPushMatrix();
glLoadIdentity();
the glPopMatrix() and glPushMatrix() calls are redundant. If anything, they could be harmful because there would be an error if you did not previously call glPushMatrix(). Otherwise, it will first copy the previous matrix to the top entry, but then immediately overwrite it with the identity matrix. Which is the same as just calling glLoadIdentity() by itself.
Related
So, i have this assignment about double pass rendering to compute shadows and I am trying to store the depth value of each of the objects of a scene and rendering them as a texture in another object.
I am using OpenGL, I don't really know where the error could be, but when analyzing a capture with RenderDoc, it says that the FBO (FrameBufferObject) is unused and also interprets what should be my 1st pass, a depth only pass, as a color pass.
/*-This is how I create the FBO and the texture to render the depth-*/
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Create texture for Depth image (first pass)
glGenTextures(1, &depthTexture);
glBindTexture(GL_TEXTURE_2D, depthTexture);
// Give pixel data to opengl
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, nullptr);
// WITH PCF for anti-aliasing shadow edges
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
depthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/*---------------------------END------------------------------------*/
/*---This is how I render all the objects (1st and second pass)-----*/
glViewport(0, 0, 1024, 1024);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cube.FirstPass(light.getPos());
plane.FirstPass(light.getPos());
cone1.FirstPass(light.getPos());
cone2.FirstPass(light.getPos());
glFlush();
glFinish();
glViewport(0, 0, WIDTH, HEIGHT);
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
cube.display(&cam, light.getPos());
plane.display(&cam, light.getPos());
viewport.display(&cam, light.getPos());
cone1.display(&cam, light.getPos());
cone2.display(&cam, light.getPos());
/*---------------------------END------------------------------------*/
/*---------This is how I do First Pass---------*/
//Here goes first pass
glBindFramebuffer(GL_FRAMEBUFFER, sceneManager.getFBO());
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(DepthPass.shader);
glm::mat4 mtx = glm::perspective(glm::radians(60.0f), 1024.0f / 1024.0f, 5.0f, 40.0f);
DepthPass.setMat("M", mtx * glm::lookAt(glm::vec3(lightPos.x, lightPos.y, lightPos.z), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0)) *
getModelToWorld());
glBindVertexArray(vao);
// Draw
glDrawArrays(GL_TRIANGLES, 0, ModelVertices.size());
glBindFramebuffer(GL_FRAMEBUFFER, 0);
/*---------------------------END------------------------------------*/
/*--This is what I pass to the shader that shows the depth texture--*/
DepthPass.setFloat("near", 5.0f);
DepthPass.setFloat("far", 40.0);
DepthPass.setInt("IsViewport", 1);
glActiveTexture(GL_TEXTURE0);
//GetDepthTexture() returns a handle of the texture created before
glBindTexture(GL_TEXTURE_2D, sceneManager.GetDepthTexture());
std::string textureName = "depthTexture";
DepthPass.setInt(textureName.c_str(), sceneManager.GetDepthTexture());
/*---------------------------END------------------------------------*/
I am trying to render a texture to a surface from a FBO but I am getting a repeat image effect like this: Repeating Image effect
I am not sure what is doing this. I am adapting the code from this tutorial: https://www.youtube.com/watch?v=21UsMuFTN0k which is in java to c++.
This is my code i use to setup to FBO:
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
//generate name for frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//create the framebuffer
glDrawBuffer(GL_COLOR_ATTACHMENT0);
//indicate that we will always render to color attachment 0
//texture setup
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 320, 180, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,texture, 0);
//depth buffer setup
GLuint depthBuffer;
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 320, 180);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
This section is used to render:
//water is two triangle joined together
Water test(texture);
render->addWater(&test);
while (!glfwWindowShouldClose(window))
{
// Set frame time
GLfloat currentFrame = (float)glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gameController->update(deltaTime);
glBindTexture(GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glViewport(0, 0, 320, 180);
render->renderScene();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
render->renderScene();
render->renderWater();
glfwSwapBuffers(window);
}
If there is any other code that is needed, let me know.
The "repeat image" effect is caused, because you don't clear the framebuffer (color attachment texture and render buffer for the depth).
It is not sufficient to clear the drawing buffer. You have to clar the color plane and the depth buffer of the framebuffer too.
Bind the framebuffer, set the clear color (background of the texture) and clear the frame buffer. This causes that the each texel of the texture object is set to the color which you specify by glClearColor right before and the render buffer object (depthBuffer) is cleared (set to 1.0 - default value see glClearDepth).
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
After rendering to the texture, set the default framebuffer for rendering, set the background color and clear the buffer:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I'm using opengl to draw the graphics for simple game like space invaders. So far I have it rendering moving meteorites and a gif file quite nicely. I get the basics. But I just cant get the framebuffer working properly which I indent to render bitmap font to.
The first function will be called inside the render function only when the score changes, This will produce a texture containing the score characters. The second function will draw the texture containing the bitmap font characters to the screen every time the render function is called. I thought this would be a more efficient way to draw the score. Right now I'm just trying to get it drawing a square using the frameBuffer, but it seems that the coordinates range from -1 to 0. I thought the coordinates for a texture went from 0 to 1? I commented which vertex effects which corner of the square and it seems to be wrong.
void Score::UpdateScoreTexture(int* success)
{
int length = 8;
char* chars = LongToNumberDigits(count, &length, 0);
glDeleteTextures(1, &textureScore);//last texture containing previous score deleted to make room for new score
glGenTextures(1, &textureScore);
GLuint frameBufferScore;
glGenTextures(1, &textureScore);
glBindTexture(GL_TEXTURE_2D, textureScore);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
glGenFramebuffers(1, &frameBufferScore);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferScore);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureScore, 0);
GLenum status;
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
std::cout << "status is: ";
std::cout << "\n";
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
std::cout << "good";
break;
default:
PrintGLStatus(status);
while (1 == 1);
}
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferScore);
glBegin(GL_POLYGON);
glVertex3f(-1, -1, 0.0);//appears to be the bottom left,
glVertex3f(0, -1, 0.0);//appears to be the bottom right
glVertex3f(0, 0, 0.0);//appears to be the top right
glVertex3f(-1, 0, 0.0);//appears to be the top left
glEnd();
glDisable(GL_TEXTURE_2D);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D,0);
glDeleteFramebuffers(1, &frameBufferScore);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, chars2);
}
void Score::DrawScore(void)
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glBindTexture(GL_TEXTURE_2D, textureScore);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(0.7, 0.925, 0.0);
glTexCoord2f(0.0, 1.0); glVertex3f(0.7, 0.975, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(0.975, 0.975, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(0.975, 0.925, 0.0);
glEnd();
glFlush();
glDisable(GL_TEXTURE_2D);
}
Any ideas where I'm going wrong?
You have not set the glViewport, this may give you problems.
Another possibility is that you have the matrix set to something other than identity.
Ensure that you have reset the model-view and projection matrices to identity (or what you want them to be) before glBegin(GL_POLYGON) in UpdateScoreTexture() (You may wish to push the matrices to the stack before you make changes):
glViewport(0,0, framebufferWidth, framebufferHeight)
glMatrixMode(GL_PROJECTION)
glPushMatrix()
glLoadIdentity()
glMatrixMode(GL_MODELVIEW)
glPushMatrix()
glLoadIdentity()
Then put them back at the end of the function:
glViewport(0,0, width, height)
glMatrixMode(GL_PROJECTION)
glPopMatrix()
glMatrixMode(GL_MODELVIEW)
glPopMatrix()
My problem is that after having set up a frame buffer object with a single colour texture attached to the GL_COLOR_ATTACHMENT0 point and rendering a number of objects to this texture when I then go to draw this to the screen I get a completely white texture.
Now I know the drawing code is correct as I can draw to the back buffer just fine, it's simply when the frame buffer becomes involved that the problem occurs. The drawing code uses a very basic shader that textures a quad.
My code is below:
// Create the FBO
glGenFramebuffers(1, &m_gbufferFBO);
glBindFramebuffer(GL_FRAMEBUFFER, m_gbufferFBO);
// Create a colour texture for use in the fbo
glGenTextures(1, &m_colourBuffer);
glBindTexture(GL_TEXTURE_2D, m_colourBuffer);
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_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colourBuffer, 0);
// check if the frame buffer was successfully created
CheckFrameBufferErrors();
CheckGLErrors();
// Begin rendering with the frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, m_gbufferFBO);
glPushAttrib(GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT);
// Set the viewport to match the width and height of our FBO
glViewport(0, 0, m_width, m_height);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
// Clear buffer to whatever the clear colour is set to
glClearColor(m_clearColour.GetR(), m_clearColour.GetG(), m_clearColour.GetB(), m_clearColour.GetA());
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
Game::GetInstance().GetCamera()->ApplyViewTransform();
// RENDERING OF OBJECTS
glPopAttrib();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Then the buffer's colour texture is rendered to the screen using the fixed function pipeline.
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
// Render the colour buffer to screen
glBindTexture(GL_TEXTURE_2D, m_colourBuffer);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2f(0.f, 0.f); glVertex3f(0.f, 0.f, 0.f);
glTexCoord2f(1.f, 0.f); glVertex3f(m_width, 0.f, 0.f);
glTexCoord2f(1.f, 1.f); glVertex3f(m_width, m_height, 0.f);
glTexCoord2f(0.f, 1.f); glVertex3f(0.f, m_height, 0.f);
glEnd();
Any ideas on what I could be doing wrong here?
The FBO attached texture must not be bound, when the FBO is bound. A texture can never be a data source and sink at the same time.
For all texturing units and targets to which the texture has been bound you must bind another or no texture before binding the FBO as render destination.
I'm trying to perform hidden line removal using polygon offset fill. The code works perfectly if I render directly to the window buffer but fails to draw the lines when passed through a FBO as shown below
The code I use to draw the objects
void drawCubes (GLboolean removeHiddenLines)
{
glLineWidth(2.0);
glPushMatrix();
camera.ApplyCameraTransform();
for(int i = 0; i < 50; i ++){
glPushMatrix();
cube[i].updatePerspective();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(1.0,1.0,1.0);
cube[i].draw();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if(removeHiddenLines){
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
glColor3f(1.0, 0.0, 0.0); //fill polygons for hidden line removal
cube[i].draw();
glDisable(GL_POLYGON_OFFSET_FILL);
}
glPopMatrix();
}
glPopMatrix();
}
For this example, the first pass involves rendering to both the window buffer and a FBO.
void firstPass()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, fboWidth, fboHeight);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
drawParticleView(GL_TRUE);
glDisable(GL_DEPTH_TEST);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[1]);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, fboWidth, fboHeight);
glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
drawParticleView(GL_TRUE);
glDisable(GL_DEPTH_TEST);
}
Second pass renders FBO back to window buffer.
void secondPass()
{
glEnable(GL_TEXTURE_2D);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glBindTexture(GL_TEXTURE_2D, renderTextureID[0]);
glViewport(fboWidth, 0, fboWidth, fboHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2i(0, 0);
glVertex2f(-1.0f, -1.0f);
glTexCoord2i(1, 0);
glVertex2f(1.0f, -1.0f);
glTexCoord2i(1, 1);
glVertex2f(1.0f, 1.0f);
glTexCoord2i(0, 1);
glVertex2f(-1.0f, 1.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
}
Setup FBO's
void setupRC()
{
setupTextures();
glGenFramebuffersEXT(2, framebufferID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[0]);
glGenRenderbuffersEXT(1, &renderbufferID);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbufferID);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, fboWidth, fboHeight);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderbufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTextureID[0], 0);
GLenum fboStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT){
fprintf(stderr, "FBO #1 Error!");
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebufferID[1]);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTextureID[1], 0);
fboStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if(fboStatus != GL_FRAMEBUFFER_COMPLETE_EXT){
fprintf(stderr, "FBO #2 Error!");
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
Setup textures
void setupTextures(void)
{
glGenTextures(2, renderTextureID);
for (GLint i = 0; i < 2; i++){
glBindTexture(GL_TEXTURE_2D, renderTextureID[i]);
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_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// this may change with window size changes
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, fboWidth, fboHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
}
glBindTexture(GL_TEXTURE_2D, 0);
}
I don't understand why the two views wouldn't be the same? Am I missing something (obviously I am)?
Thanks
The problem is that I was rendering to a FBO without a depth attachment. Setting up the second FBO the same as the first gave the correct results.
Your code seems ok to me. The weird stuff is that you still have the red cube drawn, but not the lines... What is your OpenGL implementation, driver version?
Can you test without enabling GL_POLYGON_OFFSET_FILL and/or glLineWidth to see if you see the lines (albeit hidden parts visible)?