Преглед изворни кода

Adds support for GLES2 fallback mode for split depth and stencil attachments at D24_S8 and lower quality D16_S8 for TEGRA 3

setaylor пре 13 година
родитељ
комит
f2bd7aea4e
3 измењених фајлова са 50 додато и 10 уклоњено
  1. 46 7
      gameplay/src/DepthStencilTarget.cpp
  2. 2 1
      gameplay/src/DepthStencilTarget.h
  3. 2 2
      gameplay/src/FrameBuffer.cpp

+ 46 - 7
gameplay/src/DepthStencilTarget.cpp

@@ -1,21 +1,30 @@
 #include "Base.h"
 #include "DepthStencilTarget.h"
 
+#ifndef GL_DEPTH24_STENCIL8_OES
+#define GL_DEPTH24_STENCIL8_OES 0x88F0
+#endif
+#ifndef GL_DEPTH_COMPONENT24
+#define GL_DEPTH_COMPONENT24 GL_DEPTH_COMPONENT24_OES
+#endif
+
 namespace gameplay
 {
 
 static std::vector<DepthStencilTarget*> __depthStencilTargets;
 
 DepthStencilTarget::DepthStencilTarget(const char* id, Format format, unsigned int width, unsigned int height)
-    : _id(id ? id : ""), _format(format), _renderBuffer(0), _width(width), _height(height)
+    : _id(id ? id : ""), _format(format), _depthBuffer(0), _stencilBuffer(0), _width(width), _height(height)
 {
 }
 
 DepthStencilTarget::~DepthStencilTarget()
 {
     // Destroy GL resources.
-    if (_renderBuffer)
-        GL_ASSERT( glDeleteRenderbuffers(1, &_renderBuffer) );
+    if (_depthBuffer)
+        GL_ASSERT( glDeleteRenderbuffers(1, &_depthBuffer) );
+    if (_stencilBuffer)
+        GL_ASSERT( glDeleteRenderbuffers(1, &_stencilBuffer) );
 
     // Remove from vector.
     std::vector<DepthStencilTarget*>::iterator it = std::find(__depthStencilTargets.begin(), __depthStencilTargets.end(), this);
@@ -30,11 +39,41 @@ DepthStencilTarget* DepthStencilTarget::create(const char* id, Format format, un
     // Create the depth stencil target.
     DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, format, width, height);
 
-    // Create a render buffer for this new depth stencil target
-    GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_renderBuffer) );
-    GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_renderBuffer) );
-    GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height) );
+    // Create a render buffer for this new depth+stencil target
+    GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_depthBuffer) );
+    GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_depthBuffer) );
+
+    // First try to add storage for the most common standard GL_DEPTH24_STENCIL8 
+    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
 
+    // Fall back to less common GLES2 extension combination for seperate depth24 + stencil8 or depth16 + stencil8
+    __gl_error_code = glGetError();
+    if ( __gl_error_code != GL_NO_ERROR)
+    {
+        const char* extString = (const char*)glGetString(GL_EXTENSIONS);
+
+        if (strstr(extString, "GL_OES_packed_depth_stencil") != 0)
+        {
+            GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height) );
+        }
+        else
+        {
+            if (strstr(extString, "GL_OES_depth24") != 0)
+            {
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height) );
+            }
+            else
+            {
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height) );
+            }
+            if (format == DepthStencilTarget::DEPTH_STENCIL)
+            {
+                GL_ASSERT( glGenRenderbuffers(1, &depthStencilTarget->_stencilBuffer) );
+                GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, depthStencilTarget->_stencilBuffer) );
+                GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height) );
+            }
+        }
+    }
     // Add it to the cache.
     __depthStencilTargets.push_back(depthStencilTarget);
 

+ 2 - 1
gameplay/src/DepthStencilTarget.h

@@ -101,7 +101,8 @@ private:
 
     std::string _id;
     Format _format;
-    RenderBufferHandle _renderBuffer;
+    RenderBufferHandle _depthBuffer;
+    RenderBufferHandle _stencilBuffer;
     unsigned int _width;
     unsigned int _height;
 };

+ 2 - 2
gameplay/src/FrameBuffer.cpp

@@ -218,10 +218,10 @@ void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
         GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
 
         // Attach the render buffer to the framebuffer
-        GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_renderBuffer) );
+        GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_depthBuffer) );
         if (target->getFormat() == DepthStencilTarget::DEPTH_STENCIL)
         {
-            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_renderBuffer) );
+            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_stencilBuffer) );
         }
 
         // Check the framebuffer is good to go.