GL_DEPTH_TEST not work in glsl shader - opengl

Recently, I am working with glsl and fbo in a OpenGL framwork. Here are the details:
Glfw and glew are used to build the OpenGL environment.
I render to a OpenGL window,and also to a fbo (Framebuffer object).
Several render buffers are bind to the fbo, for difference render data, pixels' color, pixels' triangle and vertex id, etc.
A sphere is assigned its texture by "Projected texture" method.
I set glEnable(GL_DEPTH_TEST); before the render loop.
Before each frame I run glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Create the FBO:
glGenRenderbuffers(1,&m_color_buffer);
glBindRenderbuffer(GL_RENDERBUFFER,m_color_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, WindowWidth, WindowHeight);
//////generate other render buffers////////////
glGenFramebuffers(1, &m_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,m_fbo);
glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_color_buffer);
//////bind other render buffers////////////
//set the render buffers
GLenum drawBuffers[] = { GL_NONE, GL_COLOR_ATTACHMENT0,
GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 };
glDrawBuffers(5, drawBuffers);
In the fragment shader:
layout( location = 1 ) out vec4 FragColor;
//////////other output variables ///////////////////
void main() {
vec4 projTexColor = vec4(0.0);
if( frag.ProjTexCoord.z > 0.0 )
{
projTexColor = textureProj( ProjectorTex, frag.ProjTexCoord );
}
FragColor = projTexColor;
/////////write other data/////////////
}
RenderBuffer to file:
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
GLubyte *m_data = (GLubyte*)malloc(4 * m_width * m_height);
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_data);
TGAIO::write(m_data,m_width,m_height,"e:/1.tga");
Here is result:
Render to OpenGL window:
When render to fbo:
It seems that the back part of the sphere appears. And also the front part become fragmented.
So, what's happened ? I do not declare the output for GL_NONE(OpenGL default render buffer) in fragment shader, how does it get the right data ? It seems that OpenGL is smarter than me, at least. LOL.

Related

OpenGL depth buffer or depth test does not work when rendering with a shared context

I have a very specific OpenGL setup where the 3D geometry in the scene does not render. There is some depth-related state in the OpenGL context that illudes me.
This is in a production engine at work where we added shared context support with multiple window contexts. We are doing the rendering to a framebuffer object owned by the shared context, then blitting the color attachment renderbuffer to a window using a different context.
The clear color is showing in the resulting blit to the window, but not the 3D scene geometry itself, so we know the framebuffer and renderbuffer objects are at least partially correct.
To illustrate, I refactored a sample from the LearnOpenGL website to illustrate my bug. It shows up there as well, so I am clear this is something I am missing.
Here is the GitHub project where I made three commits to a working framebuffer sample so that it rendered to the framebuffer using a shared context and then blits the result: Framebuffer Shared Context Experiment
Here is most of the source code that produces the buggy result. I snipped a few sections that went unchanged.
// glfw dummy window creation
// --------------------
GLFWwindow* dummy = NULL;
#if USE_SHARED_CONTEXT
dummy = glfwCreateWindow(1, 1, "Dummy", NULL, NULL);
if (dummy == NULL)
{
std::cout << "Failed to create dummy GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(dummy);
#endif
// glfw window creation
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, dummy);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwShowWindow(window);
#if !USE_SHARED_CONTEXT
glfwMakeContextCurrent(window);
#endif
// <snip creation of shared resources>
// <snip creation of un-shared vertex array>
// framebuffer configuration
// -------------------------
unsigned int framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
#if 1
// create a color attachment render buffer
unsigned int Colorbuffer;
glGenRenderbuffers(1, &Colorbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, Colorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Colorbuffer); // now actually attach it
#else
// create a color attachment texture
unsigned int textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
#endif
// create a renderbuffer object for depth and stencil attachment (we won't be sampling these)
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, SCR_WIDTH, SCR_HEIGHT); // use a single renderbuffer object for both a depth AND stencil buffer.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo); // now actually attach it
// now that we actually created the framebuffer and added all attachments we want to check if it is actually complete now
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
// <snip timing and input>
#if USE_SHARED_CONTEXT
// use shared context because that is what is holding our framebuffer and vao.
// -----
glfwMakeContextCurrent(dummy);
#endif
// render
// ------
// bind to framebuffer and draw scene as we normally would to color texture
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glEnable(GL_DEPTH_TEST); // enable depth testing (is disabled for rendering screen-space quad)
// make sure we clear the framebuffer's content
glClearColor(1.0f, 0.1f, 0.1f, 1.0f);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// following render is unchanged
shader.use();
glm::mat4 model;
glm::mat4 view = camera.GetViewMatrix();
glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
// cubes
glBindVertexArray(cubeVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
model = glm::mat4();
model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f));
shader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
// floor
glBindVertexArray(planeVAO);
glBindTexture(GL_TEXTURE_2D, floorTexture);
shader.setMat4("model", glm::mat4());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
#if 1
#if USE_SHARED_CONTEXT
// use window context for presentation via blit.
// -----
glfwMakeContextCurrent(window);
// temorary framebuffer for visible window since framebuffers are not shared
// -------------------------
unsigned int readFramebuffer;
glGenFramebuffers(1, &readFramebuffer);
glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
glBindRenderbuffer(GL_RENDERBUFFER, Colorbuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, SCR_WIDTH, SCR_HEIGHT);
glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, Colorbuffer);
#endif
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBlitFramebuffer(0, 0, SCR_WIDTH, SCR_HEIGHT, 0, 0, SCR_WIDTH, SCR_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST);
#if USE_SHARED_CONTEXT
glDeleteFramebuffers(1, &readFramebuffer);
#endif
#else
// now bind back to default framebuffer and draw a quad plane with the attached framebuffer color texture
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST); // disable depth test so screen-space quad isn't discarded due to depth test.
// clear all relevant buffers
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // set clear color to white (not really necessery actually, since we won't be able to see behind the quad anyways)
glClear(GL_COLOR_BUFFER_BIT);
screenShader.use();
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // use the color attachment texture as the texture of the quad plane
glDrawArrays(GL_TRIANGLES, 0, 6);
#endif
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
// <snip epilog>
You can toggle the USE_SHARED_CONTEXT compile-time switch to remove the little bit of code that renders using a shared context.
I was missing a call to glViewport for the shared render context.
The value of the Viewport was defaulted to (0, 0) -> (width, height) for the context used by the visible window. The shared render context had been defaulted to (0, 0) -> (1, 1) because I used a width and height of 1 for the non-visible GLFW window.

OpenGL multiple Framebuffer chaining and post processing

I have three different framebuffer objects for three different steps:
GLuint fbo1; // Step1: draw initial scene
GLuint fbo2; // Step2: apply lens effect shader
GLuint fbo3; // Step3: final smoothing
I want to draw my initial scene as a texture attached to fbo1.
Then apply a lens-shader on that and save it as a texture in fbo2.
Then apply a smoothing-shader on fbo2 and save it to fbo3.
The code in my main render function, uses a few helper functions, and is as follows:
// Step1
useFrameBuffer(fbo1, fbo1); // src , dest
DrawInitialScene();
// Step2
LensShader.use(); // a glsl shader program class
useFrameBuffer(fbo1, fbo2); // src , dest
drawQuadOnFbo(fbo2Texture);
// Step3
SmoothingShader.use(); // a glsl shader program class
useFrameBuffer(fbo2, fbo3); // src , dest
drawQuadOnFbo(fbo3Texture);
// Final Copy Step to OpenGL default FBO
int width = self.frame.size.width;
int height = self.frame.size.height;
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo3);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //destination
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
The helper function useFrameBuffer(src, dest), simply sets the source framebuffer to read from and destination write framebuffer:
void useFrameBuffer (GLuint fboSrc , GLuint fboDest)
{
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSrc);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboDest);
GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, drawbufs);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glViewport(0, 0, width, height); // width, height are private to class
}
To apply the shader on the output of fbo1 and fbo2, I am drawing a quad with a texture associated to the respective frame-buffers:
void drawQuadOnFbo(GLuint fboTexture) {
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We're not using stencil buffer now
glBlendFunc(GL_ONE, GL_ONE);
glBindVertexArray(quadVAO);
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_2D, fboTexture);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
The Problem:
The problem is that output appears to be a combination of Step1 and Step3 only. Looks like the Step2 is completely missed out. You can see in the final copy step, I am copying the contents of fbo3 to the final OpenGL default fbo using:
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo3);
If I change this to fbo2, then I do see the results of applying Step2 (but then I don't have Step3).
So it looks like that both fbo2 and fbo3 are connected directly to the output of fbo1, but not connected to each other.
How can I fix that ??
Other Helper Functions:
I initialised my Framebuffers at the start of the application, outside the main render function using the method below:
GLuint initFrameBuffer( int width, int height, GLenum textureTarget) {
// 1. Create FBO
GLuint fbo;
glGenFramebuffers(1, &fbo);
// 2. Bind it
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
// FrameBuffer Requirements
// (i). atleast 1 buffer (color, depth, stencil)
// (ii). atleast 1 color-attachment
// (iii). all attachments should be complete
// (iv). same no. of samples for each buffer
// 3. Texture Attachment
GLuint quadTex; // texture to be associated to this FBO
glActiveTexture(textureTarget);
glGenTextures(1, &quadTex);
glBindTexture(GL_TEXTURE_2D, quadTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// attach it as COLOR-ATTACHMENT 0
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, quadTex, 0);
// 4. RenderBuffer attachement
GLuint rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// attach it
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
// 5. Set Targets for fragment shader output
GLenum drawbufs[] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, drawbufs);
// 6. Check that the FrameBuffer is complete
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
NSLog(#"ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
return fboObj;
}
// 7. revert to Default
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return fbo;
}

OpenGL: Depth Attachment breaks Framebuffer

I need a fresh pair of eyes. While working on rewriting my engine, I stumbled upon this issue while writing the Deferred Rendering path. The framebuffer displays only if I don't use a depth attachment, which means that the rendering is faulty, but if I do, all the outputs are blank. I wrote a lot of graphics handling classes but I broke down the code here:
Initialization:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE);
glClearColor(0, 0, 0, 1);
glViewport(0, 0, 1024, 768);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderPreparation();
numBuffer = 3;
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
numBuffers = numBuffer;
targetBuffer = 0;
textures = new unsigned int[numBuffers];
glGenTextures(numBuffers, textures);
This is done three times:
glBindTexture(GL_TEXTURE_2D, textures[targetBuffer]);
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, colorType, width, height, 0, colorFormat, colorDataType, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + targetBuffer, GL_TEXTURE_2D, textures[targetBuffer], 0);
targetBuffer++;
Then I create the Depth Attachment:
glGenTextures(1, &renderBuffer);
glBindTexture(GL_TEXTURE_2D, renderBuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderBuffer, 0);
EDIT 2: Forgot the last bit of the FBO:
GLenum *DrawBuffers = new GLenum[numBuffers];
for (size_t i = 0; i < numBuffers; i++)
DrawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
glDrawBuffers(numBuffers, DrawBuffers);
// Report errors
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
fprintf(stderr, "Framebuffer Error. Status 0x%x\n", status);
}
// Unbind
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
Finally, my drawing (all calculations for geometry shader happens before this):
geometryShader->Use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
graphicsWrapper->render(Geometry);
int val[3] = { 0,1,2 };
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
deferredShader->Use();
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glActiveTexture(GL_TEXTURE0 + 1);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glActiveTexture(GL_TEXTURE0 + 2);
glBindTexture(GL_TEXTURE_2D, textures[2]);
// I use this system so it's compatible with Uniform Buffer
// Objects and the rendering code of other graphics languages
deferredShader->PassData(&val);
deferredShader->SetInteger();
deferredShader->SetInteger();
deferredShader->SetInteger();
glClear(GL_COLOR_BUFFER_BIT);
vaoQuad->Bind();
graphicsWrapper->DrawVertexArray(4);
vaoQuad->Unbind();
Note that my code is much more object oriented than this, and I had to take a lot of this code out of context. My question is, why does attaching the depth attachment to the framebuffer cause the framebuffer to blank, while removing it works, and how do I fix it?
EDIT: I know that it's not a renderbuffer, I just called the depth texture that because it USED to be a renderbuffer, and I forgot to change the name.
When you don't have a depth buffer, every fragment will automatically pass the depth test. Now after you add a depth buffer, the depth test will be effective (assuming you enabled it). However, yo forgot to clear your depth buffer:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
You clear the default framebuffer's color and depth buffer (or another FBO, it that is bound at that time), but not the depth buffer of fbo here...
There is a high chance that you depth texture is initially all zeros. With default depth conventions, that means it is already the nearest value, so the depth test will likely fail for anything you draw.

OpenGL - Unable to write to frame buffer (or read it properly)

So I've been trying to get shadow mapping to work, but I was unsuccessful, and I am now trying to simply write anything to the frame buffer and then render it to a quad as a texture. I've been looking at this small piece of code for 10 hours, so I thought it might finally be time to ask for some help. Do let me know if you need any more information or if something is unclear.
I started by following this tutorial. After completing it two times, and straight copy pasting a third time I gave up, and started to look elsewhere for information. My current code is a bit of a mess, but I have tried to extract what is crucial
Here is how I set up my FBO with a TEXTURE2D (_shadowMap and _shadowMapFBO are private variables in the class acting as the main program):
glGenTextures(1, &_shadowMap);
glBindTexture(GL_TEXTURE_2D, _shadowMap);
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_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glGenFramebuffers(1, &_shadowMapFBO);
glBindFramebuffer(GL_FRAMEBUFFER, _shadowMapFBO);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowMap, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "Frame buffer failed" << std::endl;
system("pause");
exit(1);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
I then do the first render pass in the main loop:
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glBindFramebuffer(GL_FRAMEBUFFER, _shadowMapFBO);
glClear(GL_DEPTH_BUFFER_BIT);
_shadowShader.bind();
glBindVertexArray(_cubeVAO);
glDrawElements(GL_TRIANGLES, _numberOfIndicesCube, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(_planeVAO);
glDrawElements(GL_TRIANGLES, _numberOfIndicesPlane, GL_UNSIGNED_SHORT, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
Initially I wanted to create a shadow map, but at this point I'm simply trying to write an explicit value to the entire texture attached to the frame buffer using the following shader pair (the one used by _shadowShader)
Vertex
#version 450
in layout(location=0) vec3 position;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * vec4(position, 1.0f);
}
Fragment
#version 450
out float depth;
void main()
{
depth = 0.0f;
}
I then finish up by trying to display the texture on a quad:
glViewport(0, 0, _screenWidth, _screenHeight);
glClearColor(0.7f, 0.5f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_testShader.bind();
glBindTexture(GL_TEXTURE_2D, _shadowMap);
glBindVertexArray(_quadVAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
Here is the fragment shader for the quad:
#version 450
in vec2 textureCoordinates;
uniform sampler2D _shadowMap;
out vec4 color;
void main()
{
float depth = texture2D(_shadowMap, textureCoordinates).r;
color = texture2D(_shadowMap, textureCoordinates);
}
But to my continuous frustration, the quad appears white although I output 0.0f (black) from the fragment shader...I know the quad is able to display a texture, as I've been able to render a normal texture displaying a .jpg onto it. So, this is where I'm at now; any ideas, pointers, thoughts, motivational words etc?
EDIT I: So after some more time I have at least figured out that the texture is loaded correctly and that I'm able to read from it. I did this by actually loading a image onto it during initialization and then not writing to it. The quad then displays the texture correctly. So there must be something wrong with how I'm writing to it.
EDIT II: So I got it working; I sat down with a TA and copy pasted the code (yeah, I know...doesn't get much better than that) and it now works. Thanks Bart :)
Your shadow pass fragment shader is just wrong:
#version 450
out float depth;
void main()
{
depth = 0.0f;
}
This does just declare a single channel color output, which will be written to the color attachment (which you don't have). Since you want to write to the depth attachment of your FBO, you have to use the builtin gl_FragDepth output variable. If you don't do it, the GL will write the lineariliy interpolated window space depth value to the depth buffer.
Note that typically, you clear the depth buffer to 1.0, and when using a typical perspective projection, your objects would appear very close to 1.0, say at 0.99something, as the depth value, so it is very likely that converting the result to just 8 bit grayscale will look all white.

Rendering to OpenGL framebuffer object doesn't work correctly on some ATI GPUs

I'm using framebuffer objects to speed up rendering - everything is rendered to framebuffer object attached to a texture, the texture is rendered to the window. Everytime a part of the scene is changed, it is updated in the framebuffer object, so that it is not necessary to render everything all the time.
This works, but on some ATI cards it looks like the framebuffer size is not correct - it looks like there is some kind of 512x512 limit or something. All functions seem to work correctly, so the program doesn't see any difference, but just part of the texture is rendered.
The only difference I see is that these GPUs have a very low maximum texture size limit - 2048.
Any ideas how to fix this or at least detect that the framebuffer object doesn't work properly?
This is the code (simplified):
glGenFramebuffers(1, &FrameBuffer);
if (error != GL_NO_ERROR)
{
...
}
else
{
glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer);
glGenTextures(1, &FrameBufferTexture);
if (glGetError() != GL_NO_ERROR)
{
...
}
else
{
glBindTexture(GL_TEXTURE_2D, FrameBufferTexture);
glBindFramebuffer(GL_FRAMEBUFFER, FrameBuffer);
glBindTexture( GL_TEXTURE_2D, FrameBufferTexture );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, sz.X, sz.Y, 0,GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture( GL_TEXTURE_2D, NULL );
// Attach the texture to the framebuffer.
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, FrameBufferTexture, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers);
// Done!
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)