diff --git a/doomsday/sdk/libgui/include/de/graphics/glinfo.h b/doomsday/sdk/libgui/include/de/graphics/glinfo.h index 7d84044884..ab22f21e11 100644 --- a/doomsday/sdk/libgui/include/de/graphics/glinfo.h +++ b/doomsday/sdk/libgui/include/de/graphics/glinfo.h @@ -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 + * http://www.gnu.org/licenses */ #ifndef LIBGUI_GLINFO_H @@ -32,7 +32,6 @@ 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; @@ -40,6 +39,7 @@ class LIBGUI_PUBLIC GLInfo 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; diff --git a/doomsday/sdk/libgui/include/de/graphics/gltarget.h b/doomsday/sdk/libgui/include/de/graphics/gltarget.h index 200c69e98e..07cace9b11 100644 --- a/doomsday/sdk/libgui/include/de/graphics/gltarget.h +++ b/doomsday/sdk/libgui/include/de/graphics/gltarget.h @@ -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 + * http://www.gnu.org/licenses */ #ifndef LIBGUI_GLTARGET_H @@ -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 }; diff --git a/doomsday/sdk/libgui/src/graphics/glframebuffer.cpp b/doomsday/sdk/libgui/src/graphics/glframebuffer.cpp index 1a6ece71ec..a4fc9d6d66 100644 --- a/doomsday/sdk/libgui/src/graphics/glframebuffer.cpp +++ b/doomsday/sdk/libgui/src/graphics/glframebuffer.cpp @@ -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 + * http://www.gnu.org/licenses */ #include "de/GLFramebuffer" @@ -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); @@ -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) { @@ -398,7 +421,7 @@ void GLFramebuffer::drawBuffer(float opacity) } bool GLFramebuffer::setDefaultMultisampling(int sampleCount) -{ +{ LOG_AS("GLFramebuffer"); int const newCount = max(1, sampleCount); diff --git a/doomsday/sdk/libgui/src/graphics/glinfo.cpp b/doomsday/sdk/libgui/src/graphics/glinfo.cpp index 4c5860d88d..4e6c7b02f1 100644 --- a/doomsday/sdk/libgui/src/graphics/glinfo.cpp +++ b/doomsday/sdk/libgui/src/graphics/glinfo.cpp @@ -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 + * http://www.gnu.org/licenses */ #include "de/GLInfo" @@ -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 @@ -119,7 +119,6 @@ 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"); @@ -127,6 +126,7 @@ DENG2_PIMPL_NOREF(GLInfo) 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"); diff --git a/doomsday/sdk/libgui/src/graphics/gltarget.cpp b/doomsday/sdk/libgui/src/graphics/gltarget.cpp index 7262b9e7cf..b73a26fc0c 100644 --- a/doomsday/sdk/libgui/src/graphics/gltarget.cpp +++ b/doomsday/sdk/libgui/src/graphics/gltarget.cpp @@ -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 + * http://www.gnu.org/licenses */ #include "de/GLTarget" @@ -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. @@ -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(); @@ -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); } } @@ -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); } @@ -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"; }