I have code which is the equivalent of the following:
init code:
glCullFace(GL_FRONT_AND_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
//clear to pink
glClearColor(1.0f, 0.0f, 1.0f, 0.0f);
GLuint textureObject;
glGenTextures(1, &textureObject);
glBindTexture(GL_TEXTURE_2D, textureObject);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA,
GL_UNSIGNED_BTYE, NULL);
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
textureObject, 0);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
assert(glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
== GL_FRAMEBUFFER_COMPLETE);
Object obj = CreateAFullscreenQuad(textureObject);
draw code:
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
glViewport(0, 0, 512, 512);
//clear to cyan
GLfloat clear[] = {0, 1, 1, 1};
glClearBufferfv(GL_COLOR, 0, clear);
SetUpPerspectiveAndCameraMatrix();
DrawSomeStuff();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glViewport(0, 0, window.width, window.height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
SetUpPerspectiveAndCameraMatrix();
obj.Draw();
SwapBuffers();
glxinfo excerpt:
OpenGL vendor string: VMware, Inc.
OpenGL renderer string: Gallium 0.4 on llvmpipe (LLVM 3.4, 128 bits)
OpenGL version string: 2.1 Mesa 10.1.3
The problem is that the call to glClearBufferfv doesn't seem to clear the whole buffer. As you can see, it clears the triangular shape, but it doesn't touch the other areas. They are also not the glClearColor color (pink). If I use the regular glClear call, it does the same thing, but pink instead of cyan.
Turns out I created a feedback loop by drawing the fullscreen quad while the FBO was bound, drawing the contents of the buffer to itself. Apparently the effects of this end up being interspersed with the effects of glClear.
Related
I am trying to render from a multisampled framebuffer to a default frame buffer.
first i enable multisampling with these commands.
glfwWindowHint(GLFW_SAMPLES, 4);
glEnable(GL_MULTISAMPLE);
Than i create a multisampled buffer
unsigned int fboMsaaId, rboDepthId;
unsigned int MsaaTexture;
// Generate texture
glGenTextures(1, &MsaaTexture);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, 800, 600, false);
// create a multisample buffer
glGenFramebuffers(1, &fboMsaaId);
glGenRenderbuffers(1, &rboDepthId);
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 800, 600);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, MsaaTexture, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,rboDepthId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
In the render loop.
while (!glfwWindowShouldClose(window))
{
// input
// -----
processInput(window);
// render
// ------
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMsaaId);
glDrawBuffer(GL_BACK);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glfwSwapBuffers(window);
glfwPollEvents();
}
If i render into the default framebuffer i am able to see the drawn object but when i blit from multisampled frame buffer to default frame buffer nothing is drawn on the screen.
What you want to do is make it so that the default framebuffer is not multisampled. That is, you want to blit from a multisampled framebuffer to a non-multisampled framebuffer.
Yes, it is legal to blit between two multisampled framebuffers, but this is only legal if they have the same sample count. And while you did request a 4-sampled default framebuffer, the default framebuffer is not entirely under your control. Implementations get to play fast-and-loose as to how many samples a default framebuffer gets.
So it's best to avoid this possibility altogether and use a non-multisampled default framebuffer.
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 currently trying to test out rendering to a framebuffer for various uses, but whenever I have an object(say a square) at a certain y-value, it appears "stretched", and then past a certain y-value or a certain x-value it seems to "thin out" and disappears. I have determined the x and y-values that it disappears at, but the coordinates seem to not have any rhyme or reason.
When I remove the framebuffer binding and render directly to the screen it draws the square perfectly fine, no matter the x or y-value.
Drawing a basic square(using immediate mode to remove possible errors) with a wide x-value looks like this:
Code here:
Window window("Framebuffer Testing", 1600, 900); //1600x900 right now
int fbowidth = 800, fboheight = 600;
mat4 ortho = mat4::orthographic(0, width, 0, height, -1.0f, 1.0f);
//trimmed out some code from shader creation that is bugless and unneccessary to include
Shader shader("basic"); shader.setUniform("pr_matrix", ortho);
Shader drawFromFBO("fbotest"); shader.setUniform("pr_matrix", ortho);
GLfloat screenVertices[] = {
0, 0, 0, 0, height, 0,
width, height, 0, width, 0, 0};
GLushort indices[] = {
0, 1, 2,
2, 3, 0 };
GLfloat texcoords[] = { //texcoords sent to the drawFromFBO shader
0, 0, 0, 1, 1, 1,
1, 1, 1, 0, 0, 0 };
IndexBuffer ibo(indices, 6);
VertexArray vao;
vao.addBuffer(new Buffer(screenVertices, 4 * 3, 3), 0);
vao.addBuffer(new Buffer(texcoords, 2 * 6, 2), 1);
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, fbowidth, fboheight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "false" << std::endl;
glEnable(GL_TEXTURE_2D);
//the x-values mess up at ~783 thru 800 and the y-values at 0 thru ~313
while(!window.closed()) {
glClearColor(0.2f, 0.2f, 0.2f, 1.0f); //grey
window.clear(); //calls glclear for depth and color buffer
//bind framebuffer and shader
shader.enable(); //literally just calls glUseProgram(id) with the compiled shader id
glViewport(0, 0, fbowidth, fboheight);
glBindFramebuffer(GL_FRAMEBUFFER, fbo); //bind the fbo
glClearColor(1.0f, 0.0f, 1.0f, 1.0f); //set clear color to pink
glClear(GL_COLOR_BUFFER_BIT);
//render a red square to the framebuffer texture
glBegin(GL_QUADS); {
glColor3f(1.0f, 0.0f, 0.0f); //set the color to red
glVertex3f(700, 400, 0);
glVertex3f(700, 450, 0);
glVertex3f(750, 450, 0);
glVertex3f(750, 400, 0);
} glEnd();
shader.disable();
glBindFramebuffer(GL_FRAMEBUFFER, 0); //set framebuffer to the default
//render from framebuffer to screen
glViewport(0, 0, width, height);
drawFromFBO.enable();
glActiveTexture(GL_TEXTURE0);
drawFromFBO.setUniform1i("texfbo0", 0);
glBindTexture(GL_TEXTURE_2D, texture);
vao.bind();
ibo.bind();
glDrawElements(GL_TRIANGLES, ibo.getCount(), GL_UNSIGNED_SHORT, NULL);
ibo.unbind();
vao.unbind();
drawFromFBO.disable();
window.update();
}
If you want to see any thing extra, the file is located at my Github: here
I ran the framebuffers example in this page -original code- (using glfw3 and glew in xcode 4.6 in osx 10.8), it worked fine, then I wanted to add multisampling (to avoid jagged edges on cube edges and on the floor, glfwWindowHint (GLFW_SAMPLES, 4) was enough when rendering directly to the back-buffer), found some answers directing to opengl.org, tried to use glTexImage2DMultisample but it displayed nothing (black screen). The framebuffer settings and rendering loop is:
// Create frame buffer
GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
// Create texture to hold color buffer
GLuint texColorBuffer;
glGenTextures(1, &texColorBuffer);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGB, width, height, GL_FALSE);
/*
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
*/
//glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texColorBuffer, 0);
// Create Renderbuffer Object to hold depth and stencil buffers
GLuint rboDepthStencil;
glGenRenderbuffers(1, &rboDepthStencil);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthStencil);
//glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboDepthStencil);
// ...
while (!window->shouldClose()) {
static int rot = 0;
// Bind our framebuffer and draw 3D scene (spinning cube)
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
auto err_res = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(err_res != GL_FRAMEBUFFER_COMPLETE) {
ERR("Incomplete frameBuffer:%X!", err_res);
goto end;
}
glBindVertexArray(vaoCube);
glEnable(GL_DEPTH_TEST);
glUseProgram(sceneShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texKitten);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texPuppy);
// Clear the screen to white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(proj));
// Draw cube
glEnable(GL_MULTISAMPLE);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_STENCIL_TEST);
// Draw floor
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilMask(0xFF);
glDepthMask(GL_FALSE);
glClear(GL_STENCIL_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 36, 6);
// Draw cube reflection
glStencilFunc(GL_EQUAL, 1, 0xFF);
glStencilMask(0x00);
glDepthMask(GL_TRUE);
model = glm::scale(glm::translate(model, glm::vec3(0, 0, -1)), glm::vec3(1, 1, -1));
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model));
glUniform3f(uniColor, 0.3f, 0.3f, 0.3f);
glDrawArrays(GL_TRIANGLES, 0, 36);
glUniform3f(uniColor, 1.0f, 1.0f, 1.0f);
glDisable(GL_STENCIL_TEST);
/*
// Bind default framebuffer and draw contents of our framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
glBindVertexArray(vaoQuad);
glDisable(GL_DEPTH_TEST);
glUseProgram(screenShaderProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);
*/
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Make sure no FBO is set as the draw framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, frameBuffer); // Make sure your multisampled FBO is the read framebuffer
glDrawBuffer(GL_BACK); // Set the back buffer as the draw buffer
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
// Swap buffers
glfwSwapBuffers(window->getHandle());
glfwPollEvents();
}
glVersion: 3.2 NVIDIA-8.10.44 304.10.65f03
glRenderer: NVIDIA GeForce 9400M OpenGL Engine
The 'EXT' additions are probably unnecessary but I also tried to run without them before and the result was the same. What am I doing wrong?
EDIT: Now binding GL_TEXTURE_2D_MULTISAMPLE and getting GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE error!
If you checked your framebuffer object for completeness, you would probably have caught this by now... your depth/stencil buffer needs to be multisampled as well.
A framebuffer is considered multisample incomplete by both core and the EXT FBO extension if one attachment has a different number of samples than any other attachment. In your case, you have a color buffer attachment with 4 samples and a depth/stencil attachment with 1 sample.
Name
glCheckFramebufferStatus — check the completeness status of a framebuffer
Description
glCheckFramebufferStatus queries the completeness status of the framebuffer object currently bound to target. target must be GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or GL_FRAMEBUFFER. GL_FRAMEBUFFER is equivalent to GL_DRAW_FRAMEBUFFER.
The return value is GL_FRAMEBUFFER_COMPLETE if the framebuffer bound to target is complete. Otherwise, the return value is determined as follows:
[...]
GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE is returned if the value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.
To fix this, you need to allocate a multisampled depth/stencil attachment with 4 samples:
glRenderbufferStorageMultisample (GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, width, height);
By the way, since your implementation is >= 3.0, you do not need the EXT suffix on anything. All of the constants defined by the EXT extension are identical to ARB / core FBOs, but some of the EXT functions (such as glCheckFramebufferStatusEXT) have more restrictive behavior (requiring each attachment to have the same image dimensions, for instance).
I have a test program that programmatically renders a texture and then renders a simple quad that is skinned with the previously drawn texture. The program is extremely simple and everything is done in 2D. This program works great under linux and everything looks like it should:
However when I run the program on my mac running 10.7 nothing shows up:
I'm at a complete loss as to why this program isn't working on my mac.
Here are the relevant bits of the program.
Creating the texture:
void createTextureObject(){
cout<<"Creating a new texture of size:"<<textureSize<<endl;
//glDeleteTextures(1, &textureId);
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureSize, textureSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
isTextureValid = true;
createFBObject();
}
Creating the Frame Buffer Object:
void createFBObject(){
cout<<"Creating a new frame buffer object"<<endl;
glDeleteFramebuffers(1, &fboId);
glGenFramebuffersEXT(1, &fboId);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
glGenRenderbuffersEXT(1, &rboId);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, textureSize, textureSize);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId, 0);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId);
bool status = checkFramebufferStatus();
if(!status){
cout<<"FrameBufferObject not created! Quitting!"<<endl;
exit(1);
fboUsed = false;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
Rendering to the texture:
void drawToTexture(){
if (!isTextureValid)
createTextureObject();
glViewport(0, 0, textureSize, textureSize);
glLoadIdentity();
// set the rendering destination to FBO
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId);
// clear buffer
glClearColor(0, 0, 0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw to the texture
glColor3f(0.0, 1.0, 0.0);
for (int i=1; i<=5; i++){
glBegin(GL_LINE_LOOP);
glVertex2f(-1 * i/5.0f, -1 * i/5.0f);
glVertex2f( 1 * i/5.0f, -1 * i/5.0f);
glVertex2f( 1 * i/5.0f, 1 * i/5.0f);
glVertex2f(-1 * i/5.0f, 1 * i/5.0f);
glEnd();
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
Rendering the textured quad:
void drawTexturedQuad(){
glViewport(50, 50, textureSize, textureSize);
glLoadIdentity();
glClearColor(0.2, 0.2, 0.2, 0.2);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, textureId);
int size = 1;
int texS = 1;
glBegin(GL_QUADS);
glColor4f(1, 1, 1, 1);
glTexCoord2f(texS, texS); glVertex3f(size, size,0);
glTexCoord2f(0, texS); glVertex3f(-1 * size , size,0);
glTexCoord2f(0, 0); glVertex3f(-1 * size, -1 * size,0);
glTexCoord2f(texS, 0); glVertex3f(size, -1 * size,0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}
I'm using GLUT and my display call back is simply:
void displayCB(){
drawToTexture();
drawTexturedQuad();
glutSwapBuffers();
}
Additionally I have other methods check to see if FrameBufferObjects are supported by OpenGL and if they are not the program quits. Additionally I have other logic that sets textureSize whenever the window is resized.
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap generation included in OpenGL v1.4
This might be a problem. The GL specification doesn't say exactly at what point mipmaps should be generated, and of course, this generates problems with render to texture. So the GL_EXT_framebuffer_object (and core versions too) introduced glGenerateMipmapEXT, which you call exactly in the point where you want mipmaps generated (usually after rendering to the texture).
So, remove the GL_GENERATE_MIPMAP stuff and use glGenerateMipmap manually when needed. You can read more about this problem in the GL_EXT_framebuffer_object specification.
Are you sure that your buffer id is 0 and not 1?
Maybe another FBO was already created before.
Also check texture dimensions try make them power of 2