Sign in to follow this  

NVIDIA : "depth only" fbo

This topic is 4339 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi out there ! After successfully setting up a "depth only" fbo for shadow mapping on an ATI card ,I've been running into a little problem setting up the same on NVIDIA. It complains about being "frame buffer incomplete", which (after a little research round the net) makes me wonder if anybody ever managed to get fbos running on NVIDIA with only a depth texture attached to a fbo. I know about setting glDrawBuffer and glReadBuffer to GL_NONE and changing the GL_DEPTH_COMPONENT to GL_DEPTH_COMPONENT24. Is there anything else I need to do ? Thanks in advance for any sugesstions, this is just killing me... Christian

Share this post


Link to post
Share on other sites
Right or wrong, the NVIDIA implementation seems to be picky about "completeness" of the texture attachments. Try setting the MIN and MAG filter modes on your depth texture to NEAREST or LINEAR - if its the default LINEAR_MIPMAP_NEAREST and you don't supply all the mipmap levels, the texture is considered "incomplete" and FBO validation fails.

I'm trying to decide whether this is a bug. In any case, this should work around it.

Share this post


Link to post
Share on other sites
Quote:
makes me wonder if anybody ever managed to get fbos running on NVIDIA with only a depth texture attached to a fbo.
yeah im doing it

glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, the_textureID, 0 );
glDrawBuffer( GL_NONE );
glReadBuffer( GL_NONE );

Share this post


Link to post
Share on other sites
NVIDIA introduced a new FBO extension featuring a format packing depth and stencil information at once.
You need to use that new format to setup your FBO.
Here's some code that I quickly put together:

bool FrameBufferObject::initialize(Texture &texture,
Texture &depthStencilPacked)
{
if(!GLEE_EXT_packed_depth_stencil)
return Logger::writeErrorLog("GL_EXT_packed_depth_stencil not supported!");

if(frameBufferID)
return Logger::writeErrorLog("FrameBufferObject already initialized!");

if(texture.getWidth() <= 0 || texture.getHeight() <= 0)
return Logger::writeErrorLog("Width and Height of FBO must be positive, non-zero");

if(texture.getTarget() != GL_TEXTURE_2D &&
texture.getTarget() != GL_TEXTURE_CUBE_MAP_ARB &&
texture.getTarget() != GL_TEXTURE_RECTANGLE_ARB)
return Logger::writeErrorLog("Current FBO implementation only supports 2D/RECT/CUBE textures");

if(!texture.getID())
return Logger::writeErrorLog("FBO need a valid Texture ID");

height = texture.getHeight();
width = texture.getWidth();

if(!depthStencilPacked.getID())
{
if(!depthStencilPacked.create2DShell(String("Packed Depth 24 Stencil 8 ") + int(height) + "x" + int(width) + ".",
height, width, GL_DEPTH24_STENCIL8_EXT, GL_DEPTH_STENCIL_EXT,
GL_CLAMP, GL_CLAMP, GL_NEAREST, GL_NEAREST, GL_UNSIGNED_INT_24_8_EXT))
return Logger::writeErrorLog("Failed to create depth stencil texture");
}

glGenFramebuffersEXT(1, &frameBufferID);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frameBufferID);

if((texture.getTarget() == GL_TEXTURE_RECTANGLE_ARB) ||
(texture.getTarget() == GL_TEXTURE_2D))
{
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, texture.getTarget(), texture.getID(), 0);
}
else
{
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texture.getID(), 0);
}

glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthStencilPacked.getID(), 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, depthStencilPacked.getID(), 0);

bool result = FrameBufferObject::checkStatus();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
return result;
}




Here's the definition of the create2DShell function:

bool Texture::create2DShell(const char* name,
GLuint width , GLuint height,
GLuint inFormat , GLuint format,
GLuint clampS , GLuint clampT,
GLuint magFilter, GLuint minFilter,
GLuint type)
{
if(!name)
return Logger::writeErrorLog("2D Texture Shell must have a valid name");

if(checkForRepeat(name))
return true;

destroy();
target = GL_TEXTURE_2D;

Logger::writeInfoLog(String("Loading new 2D Shell: width = ") + int(width)
+ ", height = " + int(height));

glGenTextures(1, &id);
glBindTexture(GL_TEXTURE_2D, id);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, getValidMagFilter(magFilter));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, getValidMinFilter(minFilter));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, getValidWrapMode(clampS));
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, getValidWrapMode(clampT));
glTexImage2D(GL_TEXTURE_2D, 0, inFormat, width, height, 0, format, type, NULL);

this->height = height;
this->width = width;
depth = 1;

return finalizeLoading(name);
}


Share this post


Link to post
Share on other sites

This topic is 4339 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this