Navigation Menu

Skip to content

Commit

Permalink
OpenGL|libgui: Check for EXT_framebuffer_object; more robust FBO setup
Browse files Browse the repository at this point in the history
Should check for EXT_framebuffer_object rather than the ARB extension,
because the ARB extension was added for OpenGL 3 and we are still
working with OpenGL 2.1.

If the render-to-texture FBO fails, and the 24+8 depth-stencil texture
fails, try separate render buffers for depth and stencil (using the
default bit depths). If that also fails, attempt to create a simple
FBO with render buffers only. This will break parts of the renderer,
but allow the engine to start.
  • Loading branch information
skyjake committed Sep 7, 2015
1 parent d49157c commit 77aa9e3
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 23 deletions.
4 changes: 2 additions & 2 deletions doomsday/sdk/libgui/include/de/graphics/glinfo.h
Expand Up @@ -13,7 +13,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBGUI_GLINFO_H
Expand All @@ -32,14 +32,14 @@ class LIBGUI_PUBLIC GLInfo
struct Extensions
{
duint32 ARB_draw_instanced : 1;
duint32 ARB_framebuffer_object : 1;
duint32 ARB_instanced_arrays : 1;
duint32 ARB_texture_env_combine : 1;
duint32 ARB_texture_non_power_of_two : 1;

duint32 EXT_blend_subtract : 1;
duint32 EXT_framebuffer_blit : 1;
duint32 EXT_framebuffer_multisample : 1;
duint32 EXT_framebuffer_object : 1;
duint32 EXT_packed_depth_stencil : 1;
duint32 EXT_texture_compression_s3tc : 1;
duint32 EXT_texture_filter_anisotropic : 1;
Expand Down
4 changes: 3 additions & 1 deletion doomsday/sdk/libgui/include/de/graphics/gltarget.h
Expand Up @@ -13,7 +13,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#ifndef LIBGUI_GLTARGET_H
Expand Down Expand Up @@ -58,6 +58,8 @@ class LIBGUI_PUBLIC GLTarget : public Asset
ColorStencil = Color | Stencil,
DepthStencil = Depth | Stencil,

SeparateDepthAndStencil = 0x10, ///< Depth and stencil should use separate buffers.

NoAttachments = 0,
DefaultFlags = ColorDepth
};
Expand Down
43 changes: 33 additions & 10 deletions doomsday/sdk/libgui/src/graphics/glframebuffer.cpp
Expand Up @@ -13,7 +13,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#include "de/GLFramebuffer"
Expand Down Expand Up @@ -162,17 +162,40 @@ DENG2_PIMPL(GLFramebuffer)
try
{
// We'd like to use texture attachments for both color and depth/stencil.
// If this fails, we'll try a couple of different alternate setups (which
// may mean that some renderer features are unavailable).
target.configure(&color, &depthStencil);
}
catch(GLTarget::ConfigError const &er)
{
// Alternatively try without depth/stencil texture (some renderer features
// will not be available!).
LOG_GL_WARNING("Texture-based framebuffer failed: %s\n"
"Trying fallback without depth/stencil texture")
<< er.asText();
try
{
LOG_GL_WARNING("Texture-based framebuffer failed: %s\n"
"Trying fallback without depth/stencil texture")
<< er.asText();

target.configure(GLTarget::Color, color, GLTarget::DepthStencil);
}
catch(GLTarget::ConfigError const &er)
{
try
{
LOG_GL_WARNING("Unified depth/stencil buffer failed: %s\n"
"Trying to allocate separately")
<< er.asText();

target.configure(GLTarget::Color, color, GLTarget::DepthStencil);
target.configure(GLTarget::Color, color,
GLTarget::DepthStencil | GLTarget::SeparateDepthAndStencil);
}
catch(GLTarget::ConfigError const &er)
{
LOG_GL_WARNING("Separate depth and stencil buffers failed: %s\n"
"Final fallback: disabling render-to-texture")
<< er.asText();

target.configure(size, GLTarget::ColorDepthStencil);
}
}
}

target.clear(GLTarget::ColorDepthStencil);
Expand Down Expand Up @@ -304,9 +327,9 @@ void GLFramebuffer::glInit()
LOG_AS("GLFramebuffer");

// Check for some integral OpenGL functionality.
if(!GLInfo::extensions().ARB_framebuffer_object)
if(!GLInfo::extensions().EXT_framebuffer_object)
{
LOG_GL_WARNING("Required GL_ARB_framebuffer_object is missing!");
LOG_GL_WARNING("Required GL_EXT_framebuffer_object is missing!");
}
if(!GLInfo::extensions().EXT_packed_depth_stencil)
{
Expand Down Expand Up @@ -398,7 +421,7 @@ void GLFramebuffer::drawBuffer(float opacity)
}

bool GLFramebuffer::setDefaultMultisampling(int sampleCount)
{
{
LOG_AS("GLFramebuffer");

int const newCount = max(1, sampleCount);
Expand Down
6 changes: 3 additions & 3 deletions doomsday/sdk/libgui/src/graphics/glinfo.cpp
Expand Up @@ -14,7 +14,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#include "de/GLInfo"
Expand Down Expand Up @@ -90,7 +90,7 @@ DENG2_PIMPL_NOREF(GLInfo)

#ifdef WIN32
// Prefer the wgl-specific extensions.
if(wglGetExtensionsStringARB != nullptr &&
if(wglGetExtensionsStringARB != nullptr &&
checkExtensionString(ext, (GLubyte const *)wglGetExtensionsStringARB(wglGetCurrentDC())))
return true;
#endif
Expand Down Expand Up @@ -119,14 +119,14 @@ DENG2_PIMPL_NOREF(GLInfo)

// Extensions.
ext.ARB_draw_instanced = query("GL_ARB_draw_instanced");
ext.ARB_framebuffer_object = query("GL_ARB_framebuffer_object");
ext.ARB_instanced_arrays = query("GL_ARB_instanced_arrays");
ext.ARB_texture_env_combine = query("GL_ARB_texture_env_combine") || query("GL_EXT_texture_env_combine");
ext.ARB_texture_non_power_of_two = query("GL_ARB_texture_non_power_of_two");

ext.EXT_blend_subtract = query("GL_EXT_blend_subtract");
ext.EXT_framebuffer_blit = query("GL_EXT_framebuffer_blit");
ext.EXT_framebuffer_multisample = query("GL_EXT_framebuffer_multisample");
ext.EXT_framebuffer_object = query("GL_EXT_framebuffer_object");
ext.EXT_packed_depth_stencil = query("GL_EXT_packed_depth_stencil");
ext.EXT_texture_compression_s3tc = query("GL_EXT_texture_compression_s3tc");
ext.EXT_texture_filter_anisotropic = query("GL_EXT_texture_filter_anisotropic");
Expand Down
16 changes: 9 additions & 7 deletions doomsday/sdk/libgui/src/graphics/gltarget.cpp
Expand Up @@ -16,7 +16,7 @@
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy of
* the GNU Lesser General Public License along with this program; if not, see:
* http://www.gnu.org/licenses</small>
* http://www.gnu.org/licenses</small>
*/

#include "de/GLTarget"
Expand Down Expand Up @@ -79,7 +79,7 @@ DENG2_OBSERVES(Asset, Deletion)
GLTexture *bufTextures[MAX_ATTACHMENTS];
Flags flags;
Flags textureAttachment; ///< Where to attach @a texture.
GLTexture *texture;
GLTexture *texture;
Vector2ui size;
Vector4f clearColor;
Rectangleui activeRect; ///< Initially null.
Expand Down Expand Up @@ -255,7 +255,9 @@ DENG2_OBSERVES(Asset, Deletion)
attachRenderbuffer(ColorBuffer, GL_RGBA8, GL_COLOR_ATTACHMENT0);
}

if(flags.testFlag(DepthStencil) && (!texture || textureAttachment == Color))
if( flags.testFlag(DepthStencil) &&
!flags.testFlag(SeparateDepthAndStencil) &&
(!texture || textureAttachment == Color))
{
// We can use a combined depth/stencil buffer.
LOG_GL_VERBOSE("FBO %i: depth+stencil renderbuffer %s") << fbo << size.asText();
Expand All @@ -267,12 +269,12 @@ DENG2_OBSERVES(Asset, Deletion)
if(flags.testFlag(Depth) && !textureAttachment.testFlag(Depth))
{
LOG_GL_VERBOSE("FBO %i: depth renderbuffer %s") << fbo << size.asText();
attachRenderbuffer(DepthBuffer, GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT);
attachRenderbuffer(DepthBuffer, GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT);
}
if(flags.testFlag(Stencil) && !textureAttachment.testFlag(Stencil))
{
LOG_GL_VERBOSE("FBO %i: stencil renderbuffer %s") << fbo << size.asText();
attachRenderbuffer(StencilBuffer, GL_STENCIL_INDEX8, GL_STENCIL_ATTACHMENT);
attachRenderbuffer(StencilBuffer, GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT);
}
}

Expand Down Expand Up @@ -354,7 +356,7 @@ DENG2_OBSERVES(Asset, Deletion)
status == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT? "Incomplete attachments" :
status == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS? "Mismatch with dimensions" :
status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT? "No images attached" :
"Unsupported");
QString("Unsupported (0x%1)").arg(status, 0, 16));
}
self.setState(Ready);
}
Expand Down Expand Up @@ -521,7 +523,7 @@ void GLTarget::glBind() const
//DENG2_ASSERT(!d->fbo || glIsFramebuffer(d->fbo));
if(d->fbo && !glIsFramebuffer(d->fbo))
{
qDebug() << "GLTarget: WARNING! Attempting to bind FBO" << d->fbo
qDebug() << "GLTarget: WARNING! Attempting to bind FBO" << d->fbo
<< "that is not a valid OpenGL FBO";
}

Expand Down

0 comments on commit 77aa9e3

Please sign in to comment.