I’m trying to create an EXT_framebuffer_object with a 1024x1024 depth texture and no color texture, to use for shadow mapping.
I have verified that GL 2.1 is available, as is ARB_shadow and ARB_depth_texture and EXT_framebuffer_object. However, whatever I do (including adding a color framebuffer render target for good luck) I can’t get past the framebuffer consistency/validation check. What am I doing wrong?
Here’s my code:
#include "stdafx.h"
#include "base.h"
RenderTarget::RenderTarget(Context &ctx, int width, int height, bool useColor, bool depthTexture)
: ctx_(ctx)
{
UseContext uc(ctx_);
if (!GLEW_EXT_framebuffer_object)
throw std::exception("EXT_framebuffer_object is not available");
glGenFramebuffersEXT(1, &fb_);
CHECKGL();
SaveFBO sfb;
SaveTex2D stx;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_);
CHECKGL();
// if (useColor)
{
glGenTextures(1, &color_);
glBindTexture(GL_TEXTURE_2D, color_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_, 0);
glGenerateMipmapEXT(GL_TEXTURE_2D);
CHECKGL();
}
// else
// {
// color_ = 0;
// }
depthTexture_ = depthTexture;
if (depthTexture)
{
if (!GLEW_ARB_depth_texture)
throw std::exception("Depth textures are not supported by the graphics hardware.");
if (!GLEW_ARB_shadow)
throw std::exception("Depth texture comparisons are not supported by the graphics hardware.");
glGenTextures(1, &depth_);
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_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE_ARB);
glBindTexture(GL_TEXTURE_2D, depth_);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depth_, 0);
CHECKGL();
}
else
{
glGenRenderbuffersEXT(1, &depth_);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_);
CHECKGL();
}
GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
throw std::exception("Render targets of the requested type are not supported.");
default:
throw std::exception("Render targets are not properly supported by the driver.");
}
}
RenderTarget::~RenderTarget()
{
UseContext uc(ctx_);
SaveFBO sfb;
glDeleteFramebuffersEXT(1, &fb_);
if (color_ != 0)
glDeleteTextures(1, &color_);
if (depthTexture_)
glDeleteTextures(1, &depth_);
else
glDeleteRenderbuffersEXT(1, &depth_);
CHECKGL();
}
void RenderTarget::Activate()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_);
CHECKGL();
}
class SaveFBO
{
public:
SaveFBO()
{
glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &fb_);
CHECKGL();
}
~SaveFBO()
{
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb_);
CHECKGL();
}
GLint fb_;
};
class SaveTex2D
{
public:
SaveTex2D()
{
glGetIntegerv(GL_TEXTURE_2D_BINDING_EXT, &tx_);
CHECKGL();
}
~SaveTex2D()
{
glBindTexture(GL_TEXTURE_2D, tx_);
CHECKGL();
}
GLint tx_;
};
The specific failure is that I get GL_FRAMEBUFFER_UNSUPPORTED_EXT as a result from checking the framebuffer set-up.
I’m using a Sony Vaio VGN-SZ140P, running Windows XP SP2, Visual Studio 2008, and ForceWare version 163.71. (Note: the latest driver available from SONY is in the 80s, so I installed a generic driver with an INF hack half a year back or so)
Other OpenGL functionality, including GLSL, works just fine for me on this machine.