PDA

View Full Version : FBO, MRT and NPOT



bobsyouruncle
12-10-2006, 09:02 AM
Hello, I've never had to post on here before, but this task is killing me. Essentially, I have a deferred shader engine that uses 4 color channels to accumulate the frame color and lighting information. I had previously used 4xFP16, but that was wasteful and broke the depth buffer, I have been trying to convert the code to handle 3xRGBA8 textures and save off the depth buffer and convert the depth to eye-space positions afterward. The problem I am running into is that any attempt to render to a depth texture using my existing FBO approach either does nothing to help the depth test or breaks everything. My current set up is as follows:

glGenFramebuffersEXT( 1, &m_GLFrameBufferObject );
glGenRenderbuffersEXT( 1, &m_GLFrameDepthBufferObject );

NumColourTargets = 3;
DrawBuffers[0] = GL_COLOR_ATTACHMENT0_EXT;
DrawBuffers[1] = GL_COLOR_ATTACHMENT1_EXT;
DrawBuffers[2] = GL_COLOR_ATTACHMENT2_EXT;
// DrawBuffers[3] = GL_DEPTH_ATTACHMENT_EXT;

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_GLFrameBufferObject );

// Color buffer 0
{
CDTexture *RT = m_RenderTargetObjects[ 0 ].m_Texture;
CDASSERTS( RT != NULL,
"Render target texture is NULL" );
CDGLTexture *GLTexture = (CDGLTexture*)RT->Implementation();
CDASSERTS( GLTexture != NULL,
"GL Render target texture is NULL" );

glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, GLTexture->GLTextureID(), 0);
}

// Color buffer 1
{
CDTexture *RT = m_RenderTargetObjects[ 1 ].m_Texture;
CDASSERTS( RT != NULL,
"Render target texture is NULL" );
CDGLTexture *GLTexture = (CDGLTexture*)RT->Implementation();
CDASSERTS( GLTexture != NULL,
"GL Render target texture is NULL" );

glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, GLTexture->GLTextureID(), 0);
}

// Color buffer 2
{
CDTexture *RT = m_RenderTargetObjects[ 2 ].m_Texture;
CDASSERTS( RT != NULL,
"Render target texture is NULL" );
CDGLTexture *GLTexture = (CDGLTexture*)RT->Implementation();
CDASSERTS( GLTexture != NULL,
"GL Render target texture is NULL" );

glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, GLTexture->GLTextureID(), 0);
}

// Depth buffer
{
CDTexture *RT = m_RenderTargetObjects[ 3 ].m_Texture;
CDASSERTS( RT != NULL,
"Render target texture is NULL" );
CDGLTexture *GLTexture = (CDGLTexture*)RT->Implementation();
CDASSERTS( GLTexture != NULL,
"GL Render target texture is NULL" );

GLuint TextureID;
glGenTextures(1, &TextureID);
glBindTexture(GL_TEXTURE_2D, TextureID);
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 );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, RT->Width(), RT->Height(), 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_GLFrameDepthBufferObject );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, RT->Width(), RT->Height());
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_GLFrameDepthBufferObject );

// glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, TextureID, 0);

GLTexture->GLTextureID( TextureID );
}


// Specify the colour buffers
glDrawBuffersARB( NumColourTargets, DrawBuffers );

// Make sure everything worked
GLenum Status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );

#ifdef _DEBUG
if( Status != GL_FRAMEBUFFER_COMPLETE_EXT )
{
switch( Status )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT :
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT" );
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT" );
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
CDASSERTS( Status == GL_FRAMEBUFFER_COMPLETE_EXT,
"GLFrameBuffer Error: GL_FRAMEBUFFER_UNSUPPORTED_EXT" );
};
}
#endif

I have code elsewhere that allows me to toggle the buffers in a shader to view the contents, and the first 3 color buffers are definately rendering exactly what I want. The rendered polys are just out of order (i.e. they are ordered based on primitive sumbission order)

I am definately creating a window with depth.
The creation of m_GLFrameBufferObject and m_GLFrameDepthBufferObject are definately getting generated.
It is definately binding these buffers before I render, and unbinding after.
The color buffer textures are all RGBA8 and I have attempted to create Depth16/24/32 textures.
I am doing a clear of color and depth after the bind point.
I have tried all combinations in glDepthFunc
I am setting glDepthMask and GL_DEPTH_TEST on before rendering.
I am running a P4D3.2 with a NV7300 that I just got last month and updated the drivers right after I got it.
My window size is 800x600 currently.

If I uncomment the // glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, TextureID, 0); line, all of the buffers end up rendering wrong. (i.e. When I toggle through them, they are all solid colors (white, black or red)

Does anybody know of a working demo that provides all the code necessary to set up these buffers in a similar manner.