I am trying to implement a simple multipass rendering scheme. I first blit the multisampled version of the scene to a FBO beforeEffectsContext.fbo. If I then blit this to the application provided FB it works fine. But I want to do another pass on the scene to blur it. I therefore bind the texture in the COLOR_ATTACHMENT0 in the beforeEffectsContext.fbo, sample it, drawing a quad with a blur effect added to another framebuffer blurContext.fbo.
If I know display the content of blurContext.fbo's color attachment to the screen using the same approach with a quad and a texture sampling, it works and I get a blurred scene.
But if I try to use glBlitFramebuffer() instead in this step, I get a black screeen. The problem seems to be in my misunderstanding of the blitting process and FBOs.
Initialization code for the blurContext.fbo:
// BeforeEffects Framebuffer
glGenFramebuffers(1, &renderContext->beforeEffectsContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);
glGenTextures(1, &renderContext->beforeEffectsContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->beforeEffectsContext.colorAttachment, 0);
// Blur Framebuffer
glGenFramebuffers(1, &renderContext->blurContext.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);
glGenTextures(1, &renderContext->blurContext.colorAttachment);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderContext->blurContext.colorAttachment);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderContext->blurContext.colorAttachment, 0);
Rendering:
// Draw to the MSampled scene to the BeforeEffects framebuffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->multiSamplingContext.fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, renderContext->beforeEffectsContext.fbo);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
// Sample the texture attached to the beforeEffects FBO and draw to the blur FBO
glBindTexture(GL_TEXTURE_2D, renderContext->beforeEffectsContext.colorAttachment);
glBindFramebuffer(GL_FRAMEBUFFER, renderContext->blurContext.fbo);
glViewport(0, 0, 800, 600);
glUseProgram(renderContext->blurProgramContext.program);
glBindVertexArray(renderContext->vaoBlur);
glDrawArrays(GL_QUADS, 0, 4);
glUseProgram(0);
glBindVertexArray(0);
// Blit the content of the blur FBO to the app-provided Framebuffer (doesn't work, black screen)
glBindFramebuffer(GL_READ_FRAMEBUFFER, renderContext->blurContext.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_BUFFER, 0);
glViewport(0, 0, 800, 600);
glBlitFramebuffer(0, 0, 800, 600, 0, 0, 800, 600, GL_COLOR_BUFFER_BIT,
GL_NEAREST);
In the line where you are binding the default framebuffer (0) for drawing you have the target as GL_DRAW_BUFFER. According to https://www.opengl.org/sdk/docs/man/html/glBindFramebuffer.xhtml the correct enum for setting the draw framebuffer is GL_DRAW_FRAMEBUFFER. If you add a call to glGetError you will probably see a GL_INVALID_ENUM error.
Related
Initially, I wanted to have 2 texture attachments to one FBO but I see in OpenGL ES 2.0 GL_COLOR_ATTACHMENTi is not supported (only GL_COLOR_ATTACHMENT0 is supported). But just to see what happens with 2 texture attachment with the same GL_COLOR_ATTACHMENT0, I could see only the second texture's content visible.
Then I thought to have multiple FBOs with respective textures. But I still only see the 2nd texture (attached to 2nd FBO).
GLuint fbo;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
glBindTexture(GL_TEXTURE_2D, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("Problem with OpenGL framebuffer : %x\n", status);
}
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This is needed
DrawRect();
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderTexture("-- Hello texture 1");
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint fbo2;
glGenFramebuffers(1, &fbo2);
glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
GLuint texture2;
glGenTextures(1, &texture2);
glBindTexture(GL_TEXTURE_2D, texture2);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
glBindTexture(GL_TEXTURE_2D, 0);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("Problem with OpenGL framebuffer2 : %x\n", status);
}
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This is needed
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderTexture(" & texture 2 -- ");
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texture);
render_fboTexture();
glBindTexture(GL_TEXTURE_2D, texture2);
render_fboTexture();
glBindTexture(GL_TEXTURE_2D, 0);
eglSwapBuffers(egldisplay, eglsurface);
Full code can be seen at - Font rendering onto off-screen FBO not working. (Note: fonts are loaded by creating textures using Freetype lib with glTexImage2D)
So as a final step in my deferred shader I've been trying to get a skybox to work. Essentially I go through all the regular deferred shader steps and then use some post processing stuff like HDR and bloom, this final step is rendered to a full screen quad using a forward shader. Now if I just render the skybox separately or the deferred shading results everything looks fine and normal. It's when I try to render the skybox last that it doesn't end up on the screen.
So basically after I render the quad with the results I want to render the skybox using the depth values from the geometry pass. I've tried blitting the depth buffer as Deferred Rendering Skybox OpenGL suggests but it doesn't have any effect and I think the issue is with how I set up my depth buffer for the FBO since it shares a stencil attachment.
My render call for the skybox:
//draw skybox
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, mWindowWidth, mWindowHeight, 0, 0, mWindowWidth, mWindowHeight, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Draw skybox as last
glDepthFunc(GL_LEQUAL); // Change depth function so depth test passes when values are equal to depth buffer's content
ShaderMan.bindShader(SKY_BOX_SHADER);
glm::mat4 view = glm::mat4(glm::mat3(CameraMan.getActiveCamera()->getViewMatrix())); // Remove any translation component of the view matrix
glm::mat4 projection = CameraMan.getActiveCamera()->getProjectionMatrix();
glUniformMatrix4fv(ShaderMan.getActiveShader().getUniformLocation("viewMatrix"), 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(ShaderMan.getActiveShader().getUniformLocation("projectionMatrix"), 1, GL_FALSE, glm::value_ptr(projection));
// skybox cube
glUniform1i(ShaderMan.getActiveShader().getUniformLocation("skybox"), 0);
mSkybox.render();
glDepthFunc(GL_LESS); // Set depth function back to default
ShaderMan.unbindShader();
and how I set up the deferred FBO
//POSIITON
glGenTextures(1, &mPositionTexture);
glBindTexture(GL_TEXTURE_2D, mPositionTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, mWindowWidth, mWindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
//Nearest min mag filters since we dont want interpolated values
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glFrameBuffer attaches a texture as a color attachment, depth attachment or stencil etc
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mPositionTexture, 0);
glGenTextures(1, &mNormalTexture);
glBindTexture(GL_TEXTURE_2D, mNormalTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, mWindowWidth, mWindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mNormalTexture, 0);
//Combined color and specular buffer
glGenTextures(1, &mSpecularAlbedoTexture);
glBindTexture(GL_TEXTURE_2D, mSpecularAlbedoTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, mWindowWidth, mWindowHeight, 0, GL_RGBA, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, mSpecularAlbedoTexture, 0);
//Depth & stencil texture for the FBO
glGenTextures(1, &mDepthTexture);
glBindTexture(GL_TEXTURE_2D, mDepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH32F_STENCIL8, mWindowWidth, mWindowHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, mDepthTexture, 0);
// final
glGenTextures(1, &mFinalTexture);
glBindTexture(GL_TEXTURE_2D, mFinalTexture);
///Used to be GL_RGBA only
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, mWindowWidth, mWindowHeight, 0, GL_RGB, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, mFinalTexture, 0);
I'm thinking the GL_DEPTH_STENCIL_ATTACHMENT is what messes something up, but I also can't see why you shouldnt be able to blit the depth attachment if you specify it in the blit function
An image of the result, no skybox: result
EDIT
I tried searching around a bit and changed the format to GL_DEPTH_24_STENCIL8 in case the main fbo had a different float format, but that did not help either.
You shouldn't attempt to blit an FBO depth buffer to the default depth buffer. To blit from one depth buffer to another the internal formats of both must be exactly the same. Whilst you can define the format of an FBO, the default depth buffer is implementation defined. You might be able to deduce its format by trial and error but the solution will not be portable.
One solution would be to write out your depths to an R32F texture colour attachment during the geometry pass. Later when you're drawing your skybox to the default framebuffer you can bind the R32F texture to a sampler and read the depth for that pixel in the fragment shader. Only output the skybox to fragments where the depth is 0.0f.
I want to copy the opengl main framebuffer to a fbo, which attach two texture object. then I want transfer the color buffer and depth buffer to the two texture object. I use glbiltframebuffer,but the texure is black, what is right way? my code :
// Create the FBO
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
// Create textures
glGenTextures(1, &m_colorTexture);
glGenTextures(1, &m_depthTexture);
// color texture
glBindTexture(GL_TEXTURE_2D, m_colorTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_RGB, GL_FLOAT, NULL);
glFramebufferTexture2(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTexture, 0);
// depth texture
glBindTexture(GL_TEXTURE_2D, m_depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, Width, Height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTexture, 0);
GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (Status != GL_FRAMEBUFFER_COMPLETE) {
printf("error, status: 0x%x\n", Status);
return false;
}
// restore default FBO
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//copy the main framebuffer to FBO
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
glBlitFramebuffer(0, 0, Width, Height, 0, 0, Width, Height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
GLenum error = glGetError();
`
I solved it, the code is right. Error occurred in other place, I am sorry.
But I has been nagged by the bilt speed. I copy the main framebuffer to the fbo every frame. but it seems that the frame rate down a lot. can every one give some suggestion.
I am using Derelict3 which uses the specific openGL3 standard and I am having an issue with the screen freezing (not updating) if glEnable(GL_DEPTH_TEST) is called, and the depth buffers not working if it is not. I have noticed that calls to set the clear color and enable depth testing are ignored if they are made prior to setting up the SDL_GL context and reloading Derelict3. I had to make them in the following order:
win=SDL_CreateWindow("3Doodle", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w, h, flags);
if(!win){
writefln("Error creating SDL window");
SDL_Quit();
}
context=SDL_GL_CreateContext(win);
SDL_GL_SetSwapInterval(1);
glVersion=DerelictGL3.reload();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClearDepth(1.0);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
While this sorted out depth culling while writing to the standard double buffer, when I implement a framebuffer object with a renderBuffer as the new depth buffer I get a freeze... the program compiles and runs without warnings, but the rendered image to the screen aligned quad remains fixed. If I comment out glEnable(GL_DEPTH_TEST); the camera moves freely but the the rendered image pays no mind to depth testing and simply draws objects in order.
The framebuffer initialization code is:
//fbo
glEnable (GL_FRAMEBUFFER_SRGB);
glGenFramebuffers(1, &fbo);
assert(fbo > 0);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glGenRenderbuffers(1, &rbo);
assert(rbo > 0);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, projMat.w, projMat.h);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenTextures(1, &fbon);
assert(fbon > 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, fbon);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbon, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fboc);
assert(fboc > 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fboc);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fboc, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &fbop);
assert(fbop > 0);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, fbop);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, projMat.w, projMat.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, fbop, 0);
glBindTexture(GL_TEXTURE_2D, 0);
int status=glCheckFramebufferStatus(GL_FRAMEBUFFER);
assert(status == GL_FRAMEBUFFER_COMPLETE);
buffs=[GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2];
glDrawBuffers(3, buffs.ptr);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
The code calling the fbo in draw() is:
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shad);
glUniformMatrix4fv(viewLoc, 1, GL_TRUE, player.mat.ptr);
current.draw();
glUseProgram(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
rend.draw();
I am at a loss as the same codes is working in c# as it ought.
My stupidity. Forgot to specify glDepthFunc
In my program it is necessary for me to do off-screen rendering. For that purpose I use a FBO. In order to see if the image I draw is the correct for testing purposes I copy it from the FBO to a texture then render the texture to a quad. The problem is that when I copy from the FBO into the texture and render it the image appears dark/get a black color but the shapes are correct. I have tried using a texture as attachment in the FBO and rendering it directly (without copying it into another texture) and the colors are correct.
Below is the code for texture creation
//initial texture which works when rendered to a quad
glGenTexturesEXT(3, &textureID[0]);
glBindTextureEXT(GL_TEXTURE_2D, textureID[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
//second one which should be a copy of the above but has tha dark color mentioned
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); // automatic mipmap
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 600, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTextureEXT(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D,textureID[0],0);
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
st1=glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
Now in the rendering function
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb); //biding FBO
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//render code
unsigned char *pixels= new unsigned char [600*512*4];
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0); //unbiding
glBindTextureEXT(GL_TEXTURE_2D,textureID[1]); //if I change to textureID[0] result is fine
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,600,512,0,GL_RGBA,GL_UNSIGNED_BYTE,pixels);
glBindTextureEXT(GL_TEXTURE_2D,0);
glViewport(0, 0, 600, 512);
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glBindTextureEXT(GL_TEXTURE_2D, textureID[1]);
//setting the correct matrixes + render a quad
//before rendering a quad I set the color with
glColor3f(1.0, 1.0, 1.0);
delete[] pixels;
glutSwapBuffers();
I'm using glut for the setup. I have tried other functions such as glGetTexImage2D after unbiding the FBO and biding the texture as an alternative to glReadPixels(...) but with no success.
I don't understand this call to glTexImage2D in your second code snippet. pixels will contain just garbage. What do you expect it to do?
Textures have been core OpenGL for a very, very long time. It's just glGenTextures and glBindTexture not ...EXT. Also I recommend to either use ...ARB versions of the FBO functionality, or just using OpenGL core framebuffer support (of later OpenGL versions).