PDA

View Full Version : FrameBuffer problem.



Sanctus
01-19-2010, 11:10 AM
Hey guys. I have an intresting problem.
I made a framebuffer object and it acts very strange. Never seen this before because in my debug way of having the scene I do some more steps (one of which make the problem go away).

So I have CBuffer class that handles all the buffers. I can get the texture id of a component and just draw it. So normally I use it for my deferred setup which works fine and for my shadow map. I always draw them textures on screen so I can always take a look at them in case there's something wrong. Problem is that when I don't draw the textures on screen then everything get's weird.
Here's the header of my CBuffer class


#define BUFFER_COLOR1 1
#define BUFFER_COLOR2 2
#define BUFFER_DEPTH 4
#define BUFFER_NORMAL 8
class CBuffer
{
private:
int width, height;
GLuint bufferID;
GLuint color1;
GLuint color2;
GLuint depth;
GLuint normal;
int type;
public:
CBuffer(int width,int height,int type);
void Resize(int width,int height);
void Set();
int GetTextureID(int type);
void CheckStatus();
int GetWidth();
int GetHeight();
};

TBuffer CreateBuffer(int width,int heght,int type);
void SetBuffer(TBuffer buffer);
void ResizeBuffer(TBuffer buffer,int width,int height);
int GetBufferTextureID(TBuffer buffer,int type);


And here is the cpp


#include "stdafx.h"
#include "CEngine.h"

CBuffer::CBuffer(int Width,int Height,int Type)
{
glGenFramebuffersEXT(1, &bufferID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
color1=color2=normal=depth=0;
width =Width;
height=Height;
type=Type;
if(type & BUFFER_COLOR1)
{
glGenTextures(1, &color1);
glBindTexture(GL_TEXTURE_2D, color1);
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_RGBA16, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, color1, 0);
glBindTexture(GL_TEXTURE_2D,0);
}
if(type & BUFFER_NORMAL)
{
glGenTextures(1, &normal);
glBindTexture(GL_TEXTURE_2D, normal);
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_RGBA16, Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,GL_TEXTURE_2D, normal, 0);
glBindTexture(GL_TEXTURE_2D,0);
}
if(type & BUFFER_DEPTH)
{

glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
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_TO_EDGE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, Width, Height, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,depth, 0);
glGenerateMipmapEXT(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);
}
CheckStatus();

}

void CBuffer::Resize(int Width,int Height)
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
width =Width;
height=Height;
if (type &BUFFER_COLOR1)
{
glGenTextures(1, &color1);
glBindTexture(GL_TEXTURE_2D, color1);
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, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, color1, 0);
glBindTexture(GL_TEXTURE_2D,0);
}
if (type &BUFFER_COLOR2)
{
glGenTextures(1, &color2);
glBindTexture(GL_TEXTURE_2D, color2);
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, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,GL_TEXTURE_2D, color2, 0);
glBindTexture(GL_TEXTURE_2D,0);
}
if(type & BUFFER_NORMAL)
{
glGenTextures(1, &normal);
glBindTexture(GL_TEXTURE_2D, normal);
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, Width, Height, 0,GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,GL_TEXTURE_2D, normal, 0);
glBindTexture(GL_TEXTURE_2D,0);
}
if(type & BUFFER_DEPTH)
{
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, Width, Height, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D,depth, 0);
glBindTexture(GL_TEXTURE_2D,0);
}


}

void CBuffer::Set()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
GLenum buffers[4];
int c=0;
if(color1)
{
buffers[c] = GL_COLOR_ATTACHMENT0_EXT;
c++;
}
if(normal)
{
buffers[c] = GL_COLOR_ATTACHMENT1_EXT;
c++;
}

glDrawBuffers(c,buffers);
}

int CBuffer::GetTextureID(int type)
{
switch (type)
{
case BUFFER_COLOR1:
return color1;
case BUFFER_COLOR2:
return color2;
case BUFFER_DEPTH:
return depth;
case BUFFER_NORMAL:
return normal;
}
return 0;
}


void CBuffer::CheckStatus()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufferID);
int status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
fprintf(GetCurrentEngine()->GetLogFile(), "Framebuffer complete.\n");
break;

case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: Attachment is NOT complete.\n" );
break;

case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: No image is attached to FBO.\n" );
break;

case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: Attached images have different dimensions.\n");
break;

case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: Color attached images have different internal formats.\n" );
break;

case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: Draw buffer.\n");
break;

case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Framebuffer incomplete: Read buffer.\n");
break;

case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Unsupported by FBO implementation.\n");
break;

default:
fprintf(GetCurrentEngine()->GetLogFile(),"[ERROR] Unknow error.\n");
break;
}
}
int CBuffer::GetWidth()
{
return width;
}
int CBuffer::GetHeight()
{
return height;
}
TBuffer CreateBuffer(int width,int height,int type)
{
return new CBuffer(width,height,type);
}
void ResizeBuffer(TBuffer buffer,int width,int height)
{
buffer->Resize(width,height);
}
void SetBuffer(TBuffer buffer)
{
GetCurrentEngine()->SetBuffer(buffer);
}
int GetBufferTextureID(TBuffer buffer,int type)
{
return buffer->GetTextureID(type);
}


Basically the code seams longer than it is... Anyway the log also gives me this:
[ERROR] Framebuffer incomplete: Draw buffer.
Framebuffer complete.

From the order in which i see this I take it the shadadow map buffer isn't created well.
Intresting fact is that if I do show them as textures then it works even tho I have that on the log.
Also I have another test where I don't show the textures on screen and I still get everything done right (fact is that in that example shadow map get's actually to be used).

Is there something wrong with my implementation?
How could I clear the data that the depth buffer has when I create it at start?
I think the problem lies there.
I'd be thankfull if anyone could help me a bit on this.

Dark Photon
01-19-2010, 04:50 PM
Anyway the log also gives me this:
[ERROR] Framebuffer incomplete: Draw buffer.


* The value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE must not be NONE for any color attachment point(s) named by DRAW_BUFFERi. { FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER }

So I'd put prints before every single glDrawBuffer and glDrawBuffers command in your application, and verify that none of the values you are passing is GL_NONE. Also make sure you are actually calling it before you check for framebuffer status.