Explorar o código

Fixes compile errors and non-OpenGL ES compliant code in FrameBuffer, RenderTarget and DepthStencilTarget classes.
Completes support for rendering to custom frame buffers.
Fixes #18
Fixes #9

Steve Grenier %!s(int64=14) %!d(string=hai) anos
pai
achega
4ff5917c89

+ 66 - 22
gameplay/src/DepthStencilTarget.cpp

@@ -1,3 +1,8 @@
+/**
+ * DepthStencilTarget.cpp
+ */
+
+#include "Base.h"
 #include "DepthStencilTarget.h"
 
 namespace gameplay
@@ -5,12 +10,62 @@ namespace gameplay
 
 static std::vector<DepthStencilTarget*> __depthStencilTargets;
 
-DepthStencilTarget* DepthStencilTarget::create(const char* id, unsigned int width, unsigned int height)
+DepthStencilTarget::DepthStencilTarget(const char* id, Format format)
+    : _id(id), _format(format), _depthTexture(NULL), _stencilBuffer(0)
+{
+}
+
+DepthStencilTarget::~DepthStencilTarget()
 {
-    DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, width, height);
+    SAFE_RELEASE(_depthTexture);
+
+    // Destroy GL resources.
+    if (_stencilBuffer)
+    {
+        GL_ASSERT( glDeleteTextures(1, &_stencilBuffer) );
+    }
 
+    // Remove from vector.
+    std::vector<DepthStencilTarget*>::iterator it = std::find(__depthStencilTargets.begin(), __depthStencilTargets.end(), this);
+    if (it != __depthStencilTargets.end())
+    {
+        __depthStencilTargets.erase(it);
+    }
+}
+
+DepthStencilTarget* DepthStencilTarget::create(const char* id, Format format, unsigned int width, unsigned int height)
+{
+    // Create a backing texture buffer.
+    Texture* depthTexture = Texture::create(Texture::DEPTH, width, height, NULL, false);
+    if (depthTexture == NULL)
+    {
+        return NULL;
+    }
+
+    // Create stencil renderbuffer if format is DEPTH24_STENCIL8
+    RenderBufferHandle stencilBuffer = 0;
+    if (format == DEPTH24_STENCIL8)
+    {
+        // Backup the existing render buffer
+        GLint currentRbo = 0;
+        GL_ASSERT( glGetIntegerv(GL_RENDERBUFFER_BINDING, &currentRbo) );
+
+        // Create the new render buffer
+        GL_ASSERT( glGenRenderbuffers(1, &stencilBuffer) );
+        GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer) );
+        GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height) );
+
+        // Restore the old render buffer
+        GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, currentRbo) );
+    }
+
+    // Create the depth stencil target
+    DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, format);
+    depthStencilTarget->_depthTexture = depthTexture;
+    depthStencilTarget->_stencilBuffer = stencilBuffer;
+
+    // Add it to the cache
     __depthStencilTargets.push_back(depthStencilTarget);
-    depthStencilTarget->_index = __depthStencilTargets.size() - 1;
 
     return depthStencilTarget;
 }
@@ -19,7 +74,7 @@ DepthStencilTarget* DepthStencilTarget::getDepthStencilTarget(const char* id)
 {
     // Search the vector for a matching ID.
     std::vector<DepthStencilTarget*>::const_iterator it;
-    for (it = __depthStencilTargets.begin(); it < __depthStencilTargets.end(); ++it)
+    for (it = __depthStencilTargets.begin(); it < __depthStencilTargets.end(); it++)
     {
         DepthStencilTarget* dst = *it;
         if (strcmp(id, dst->getID()) == 0)
@@ -31,30 +86,19 @@ DepthStencilTarget* DepthStencilTarget::getDepthStencilTarget(const char* id)
     return NULL;
 }
 
-DepthStencilTarget::~DepthStencilTarget()
+const char* DepthStencilTarget::getID() const
 {
-    // Destroy GL resources.
-    glDeleteTextures(1, &_handle);
-
-    // Remove from vector.
-    std::vector<DepthStencilTarget*>::const_iterator it = __depthStencilTargets.begin() + _index;
-    __depthStencilTargets.erase(it);
+    return _id.c_str();
 }
 
-const char* DepthStencilTarget::getID() const
+DepthStencilTarget::Format DepthStencilTarget::getFormat() const
 {
-    return _id.c_str();
+    return _format;
 }
 
-DepthStencilTarget::DepthStencilTarget(const char* id, unsigned int width, unsigned int height)
+Texture* DepthStencilTarget::getTexture() const
 {
-    // Create a backing texture / renderbuffer.
-    // Need to experiment to determine whether GL_DEPTH_STENCIL textures are supported.
-    // If not, need to use dual renderbuffers instead.
-    glGenTextures(1, &_handle);
-    glBindTexture(GL_TEXTURE_2D, _handle);
-    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);
+    return _depthTexture;
 }
 
-}
+}

+ 62 - 14
gameplay/src/DepthStencilTarget.h

@@ -2,23 +2,53 @@
 #define DEPTHSTENCILTARGET_H_
 
 #include "Base.h"
-#include "Ref.h"
+#include "Texture.h"
 
 namespace gameplay
 {
 
+/**
+ * Defines a contain for depth and stencil targets in a frame buffer object.
+ *
+ * This class assumes that the target hardware supports depth textures, since
+ * creation of a DepthStencilTarget always attempts to create an underlying
+ * depth texture.
+ */
 class DepthStencilTarget : public Ref
 {
+    friend class FrameBuffer;
+
 public:
- 
+
+    /**
+     * Defines the accepted formats for DepthStencilTargets.
+     */
+    enum Format
+    {
+        /**
+         * A target with 24-bits of depth data.
+         *
+         * This format may be internally stored as a 32-bit buffer with 8 bits of unused data.
+         */
+        DEPTH24,
+
+        /**
+         * A target with 24 bits of depth data and 8 bits stencil data.
+         */
+        DEPTH24_STENCIL8
+    };
+
     /**
      * Create a DepthStencilTarget and add it to the list of available DepthStencilTargets.
      *
      * @param id The ID of the new DepthStencilTarget.  Uniqueness is recommended but not enforced.
+     * @param format The format of the new DepthStencilTarget.
+     * @param width Width of the new DepthStencilTarget.
+     * @param height Height of the new DepthStencilTarget.
      *
      * @return A newly created DepthStencilTarget.
      */
-    static DepthStencilTarget* create(const char* id, unsigned int width, unsigned int height);
+    static DepthStencilTarget* create(const char* id, Format format, unsigned int width, unsigned int height);
 
     /**
      * Get a named DepthStencilTarget from its ID.
@@ -29,27 +59,45 @@ public:
      */
     static DepthStencilTarget* getDepthStencilTarget(const char* id);
 
-    /**
-     * Destructor.  Removes this DepthStencilTarget from the list of available DepthStencilTargets.
-     */
-    ~DepthStencilTarget();
-
     /**
      * Get the ID of this DepthStencilTarget.
      *
      * @return The ID of this DepthStencilTarget.
      */
     const char* getID() const;
- 
+
+    /**
+     * Returns the format of the DepthStencilTarget.
+     *
+     * @return The format.
+     */
+    Format getFormat() const;
+
+    /**
+     * Returns the depth texture for this DepthStencilTarget.
+     *
+     * @return The depth texture for this DepthStencilTarget.
+     */
+    Texture* getTexture() const;
+
 private:
- 
-    DepthStencilTarget(const char* id, unsigned int width, unsigned int height);
+
+    /**
+     * Constructor.
+     */
+    DepthStencilTarget(const char* id, Format format);
+
+    /**
+     * Destructor.
+     */
+    ~DepthStencilTarget();
 
     std::string _id;
-    RenderBufferHandle _handle;
-    unsigned int _index;
+    Format _format;
+    Texture* _depthTexture;
+    RenderBufferHandle _stencilBuffer;
 };
 
 }
 
-#endif
+#endif

+ 124 - 139
gameplay/src/FrameBuffer.cpp

@@ -1,8 +1,9 @@
+/**
+ * FrameBuffer.cpp
+ */
+
 #include "Base.h"
 #include "FrameBuffer.h"
-#include "RenderTarget.h"
-#include "DepthStencilTarget.h"
-#include "Texture.h"
 
 namespace gameplay
 {
@@ -10,28 +11,80 @@ namespace gameplay
 static unsigned int __maxRenderTargets = 0;
 static std::vector<FrameBuffer*> __frameBuffers;
 
+FrameBuffer::FrameBuffer(const char* id) :
+    _id(id ? id : ""), _handle(0), _renderTargets(NULL), _depthStencilTarget(NULL)
+{
+}
+
+FrameBuffer::~FrameBuffer()
+{
+    if (_renderTargets)
+    {
+        for (unsigned int i = 0; i < __maxRenderTargets; ++i)
+        {
+            SAFE_RELEASE(_renderTargets[i]);
+        }
+        SAFE_DELETE_ARRAY(_renderTargets);
+    }
+
+    // Release GL resource.
+    if (_handle)
+    {
+        GL_ASSERT( glDeleteFramebuffers(1, &_handle) );
+    }
+
+    // Remove self from vector.
+    std::vector<FrameBuffer*>::iterator it = std::find(__frameBuffers.begin(), __frameBuffers.end(), this);
+    if (it != __frameBuffers.end())
+    {
+        __frameBuffers.erase(it);
+    }
+}
+
 FrameBuffer* FrameBuffer::create(const char* id)
 {
-    FrameBuffer* frameBuffer = new FrameBuffer(id);
+    // Create GL FBO resource.
+    GLuint handle = 0;
+    GL_ASSERT( glGenFramebuffers(1, &handle) );
+
+    // Call getMaxRenderTargets() to force __maxRenderTargets to be set
+    getMaxRenderTargets();
+
+    // Create the render target array for the new frame buffer
+    RenderTarget** renderTargets = new RenderTarget*[__maxRenderTargets];
+    memset(renderTargets, 0, sizeof(RenderTarget*) * __maxRenderTargets);
+
+    // Create the new frame buffer
+    FrameBuffer* frameBuffer = new FrameBuffer(id ? id : "");
+    frameBuffer->_handle = handle;
+    frameBuffer->_renderTargets = renderTargets;
 
+    // Add to the global list of managed frame buffers
     __frameBuffers.push_back(frameBuffer);
-    frameBuffer->_index = __frameBuffers.size() - 1;
 
     return frameBuffer;
 }
 
 FrameBuffer* FrameBuffer::create(const char* id, unsigned int width, unsigned int height)
 {
-    FrameBuffer* frameBuffer = new FrameBuffer(id);
-
-    // Create RenderTarget with same ID and set as first color attachment.
+    // Create RenderTarget with same ID
     RenderTarget* renderTarget = RenderTarget::create(id, width, height);
+    if (renderTarget == NULL)
+    {
+        return NULL;
+    }
+
+    // Create the frame buffer
+    FrameBuffer* frameBuffer = create(id);
+    if (frameBuffer == NULL)
+    {
+        return NULL;
+    }
+
+    // Add the render target as the first color attachment
     frameBuffer->setRenderTarget(renderTarget);
     SAFE_RELEASE(renderTarget);
 
-    __frameBuffers.push_back(frameBuffer);
-    frameBuffer->_index = __frameBuffers.size() - 1;
-
     return frameBuffer;
 }
 
@@ -39,7 +92,7 @@ FrameBuffer* FrameBuffer::getFrameBuffer(const char* id)
 {
     // Search the vector for a matching ID.
     std::vector<FrameBuffer*>::const_iterator it;
-    for (it = __frameBuffers.begin(); it < __frameBuffers.end(); ++it)
+    for (it = __frameBuffers.begin(); it < __frameBuffers.end(); it++)
     {
         FrameBuffer* fb = *it;
         if (strcmp(id, fb->getID()) == 0)
@@ -51,25 +104,6 @@ FrameBuffer* FrameBuffer::getFrameBuffer(const char* id)
     return NULL;
 }
 
-FrameBuffer::~FrameBuffer()
-{
-    if (__renderTargets)
-    {
-        for (unsigned int i = 0; i < __maxRenderTargets; ++i)
-        {
-            SAFE_RELEASE(__renderTargets[i]);
-        }
-        SAFE_DELETE_ARRAY(__renderTargets);
-    }
-
-    // Release GL resource.
-    glDeleteFramebuffers(1, &_handle);
-
-    // Remove self from vector.
-    std::vector<FrameBuffer*>::const_iterator it = __frameBuffers.begin() + _index;
-    __frameBuffers.erase(it);
-}
-
 const char* FrameBuffer::getID() const
 {
     return _id.c_str();
@@ -79,9 +113,13 @@ unsigned int FrameBuffer::getMaxRenderTargets()
 {
     if (__maxRenderTargets == 0)
     {
+#ifdef GL_MAX_COLOR_ATTACHMENTS
         GLint val;
-        glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &val);
+        GL_ASSERT( glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &val) );
         __maxRenderTargets = (unsigned int) val;
+#else
+        __maxRenderTargets = 1;
+#endif
     }
 
     return __maxRenderTargets;
@@ -91,82 +129,41 @@ void FrameBuffer::setRenderTarget(RenderTarget* target, unsigned int index)
 {
     assert(index < __maxRenderTargets);
 
-    if (__renderTargets[index] == target)
+    if (_renderTargets[index] == target)
     {
+        // No change
         return;
     }
 
     // Release our reference to the current RenderTarget at this index.
-    SAFE_RELEASE(__renderTargets[index]);
+    SAFE_RELEASE(_renderTargets[index]);
 
-    __renderTargets[index] = target;
-        
-    // This FrameBuffer now references the RenderTarget.
-    target->addRef();
+    _renderTargets[index] = target;
 
-    // Now set this target as the color attachment corresponding to index.
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _handle);
-    GLenum attachment;
-    switch (index)
+    if (target)
     {
-        case 0:
-            attachment = GL_COLOR_ATTACHMENT0;
-            break;
-        case 1:
-            attachment = GL_COLOR_ATTACHMENT1;
-            break;
-        case 2:
-            attachment = GL_COLOR_ATTACHMENT2;
-            break;
-        case 3:
-            attachment = GL_COLOR_ATTACHMENT3;
-            break;
-        case 4:
-            attachment = GL_COLOR_ATTACHMENT4;
-            break;
-        case 5:
-            attachment = GL_COLOR_ATTACHMENT5;
-            break;
-        case 6:
-            attachment = GL_COLOR_ATTACHMENT6;
-            break;
-        case 7:
-            attachment = GL_COLOR_ATTACHMENT7;
-            break;
-        case 8:
-            attachment = GL_COLOR_ATTACHMENT8;
-            break;
-        case 9:
-            attachment = GL_COLOR_ATTACHMENT9;
-            break;
-        case 10:
-            attachment = GL_COLOR_ATTACHMENT10;
-            break;
-        case 11:
-            attachment = GL_COLOR_ATTACHMENT11;
-            break;
-        case 12:
-            attachment = GL_COLOR_ATTACHMENT12;
-            break;
-        case 13:
-            attachment = GL_COLOR_ATTACHMENT13;
-            break;
-        case 14:
-            attachment = GL_COLOR_ATTACHMENT14;
-            break;
-        case 15:
-            attachment = GL_COLOR_ATTACHMENT15;
-            break;
+        // This FrameBuffer now references the RenderTarget.
+        target->addRef();
+
+        // Store the current FBO binding so we can restore it
+        GLint currentFbo;
+        GL_ASSERT( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFbo) );
+
+        // Now set this target as the color attachment corresponding to index.
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
+        GLenum attachment = GL_COLOR_ATTACHMENT0 + index;
+        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, _renderTargets[index]->getTexture()->getHandle(), 0) );
+
+        // Restore the FBO binding
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, currentFbo) );
     }
-    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, attachment, GL_TEXTURE_2D, __renderTargets[index]->getTexture()->getHandle(), 0);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
 }
 
 RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
 {
     if (index < __maxRenderTargets)
     {
-        return __renderTargets[index];
+        return _renderTargets[index];
     }
 
     return NULL;
@@ -174,9 +171,40 @@ RenderTarget* FrameBuffer::getRenderTarget(unsigned int index) const
 
 void FrameBuffer::setDepthStencilTarget(DepthStencilTarget* target)
 {
+    if (_depthStencilTarget == target)
+    {
+        return; // No change
+    }
+
+    // Release our existing depth stencil target
     SAFE_RELEASE(_depthStencilTarget);
+
     _depthStencilTarget = target;
-    target->addRef();
+
+    if (target)
+    {
+        // The FrameBuffer now owns this DepthStencilTarget
+        target->addRef();
+
+        // Store the current FBO binding so we can restore it
+        GLint currentFbo;
+        GL_ASSERT( glGetIntegerv(GL_FRAMEBUFFER_BINDING, &currentFbo) );
+
+        // Now set this target as the color attachment corresponding to index.
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
+
+        // Bind the depth texture
+        GL_ASSERT( glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _depthStencilTarget->getTexture()->getHandle(), 0) );
+
+        // If the taget has a stencil buffer, bind that as well
+        if (target->getFormat() == DepthStencilTarget::DEPTH24_STENCIL8)
+        {
+            GL_ASSERT( glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthStencilTarget->_stencilBuffer) );
+        }
+
+        // Restore the FBO binding
+        GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, currentFbo) );
+    }
 }
 
 DepthStencilTarget* FrameBuffer::getDepthStencilTarget() const
@@ -186,56 +214,13 @@ DepthStencilTarget* FrameBuffer::getDepthStencilTarget() const
 
 void FrameBuffer::bind()
 {
-    // Check framebuffer completeness.
-    GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
-    switch(status)
-    {
-        case GL_FRAMEBUFFER_COMPLETE:
-            // Success.
-            break;
-
-        case GL_FRAMEBUFFER_UNSUPPORTED:
-            // Configuration error.
-            LOG_ERROR("FrameBuffer unsupported.");
-            return;
-
-        default:
-            // Programming error; will fail on all hardware.
-            LOG_ERROR("Unknown error checking FrameBuffer status.");
-            return;
-    }
-
     // Bind this FrameBuffer for rendering.
-    glBindTexture(GL_TEXTURE_2D, 0);
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _handle);
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, _handle) );
 }
 
 void FrameBuffer::bindDefault()
 {
-    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    GL_ASSERT( glBindFramebuffer(GL_FRAMEBUFFER, 0) );
 }
 
-FrameBuffer::FrameBuffer(const char* id) :
-    _handle(0), _depthStencilTarget(NULL), _index(0)
-{
-    if (id)
-    {
-        _id = id;
-    }
-
-    // Create GL FBO resource.
-    glGenFramebuffers(1, &_handle);
-
-    // Query MAX_COLOR_ATTACHMENTS the first time a FrameBuffer is created.
-    if (__maxRenderTargets == 0)
-    {
-        GLint val;
-        glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &val);
-        __maxRenderTargets = (unsigned int) val;
-    }
-
-    __renderTargets = new RenderTarget*[__maxRenderTargets];
-    memset(__renderTargets, 0, sizeof(RenderTarget*) * __maxRenderTargets);
 }
-
-}

+ 12 - 15
gameplay/src/FrameBuffer.h

@@ -2,20 +2,18 @@
 #define FRAMEBUFFER_H_
 
 #include "Base.h"
-#include "Ref.h"
+#include "RenderTarget.h"
+#include "DepthStencilTarget.h"
 
 namespace gameplay
 {
 
-class RenderTarget;
-class DepthStencilTarget;
-
 class FrameBuffer : public Ref
 {
 public:
 
     /**
-     * Create an empty FrameBuffer and add it to the list of available FrameBuffers.
+     * Creates an empty FrameBuffer and adds it to the list of available FrameBuffers.
      *
      * @param id The ID of the new FrameBuffer.  Uniqueness is recommended but not enforced.
      *
@@ -24,8 +22,8 @@ public:
     static FrameBuffer* create(const char* id);
 
     /**
-     * Create an empty FrameBuffer with a RenderTarget of the specified width and height,
-     * and add the FrameBuffer to the list of available FrameBuffers.
+     * Creates a new FrameBuffer with a RenderTarget of the specified width and height,
+     * and adds the FrameBuffer to the list of available FrameBuffers.
      *
      * @param id The ID of the new FrameBuffer.  Uniqueness is recommended but not enforced.
      * @param width The width of the RenderTarget to be created and attached.
@@ -43,11 +41,6 @@ public:
      * @return The FrameBuffer with the specified ID, or NULL if one was not found.
      */
     static FrameBuffer* getFrameBuffer(const char* id);
-     
-    /**
-     * Destructor.  Removes this FrameBuffer from the list of available FrameBuffers.
-     */
-    ~FrameBuffer();
 
     /**
      * Get the ID of this FrameBuffer.
@@ -108,13 +101,17 @@ private:
  
     FrameBuffer(const char* id);
 
+    /**
+     * Destructor.  Removes this FrameBuffer from the list of available FrameBuffers.
+     */
+    ~FrameBuffer();
+
     std::string _id;
     FrameBufferHandle _handle;
-    RenderTarget** __renderTargets;
+    RenderTarget** _renderTargets;
     DepthStencilTarget* _depthStencilTarget;
-    unsigned int _index;
 };
 
 }
 
-#endif
+#endif

+ 2 - 2
gameplay/src/Properties.cpp

@@ -600,7 +600,7 @@ bool Properties::getColor(const char* name, Vector3* out) const
 
         // Read the string into an int as hex.
         unsigned int color;
-        sscanf_s(valueString+1, "%x", &color);
+        sscanf(valueString+1, "%x", &color);
 
         out->set(Vector3::fromColor(color));
         return true;
@@ -628,7 +628,7 @@ bool Properties::getColor(const char* name, Vector4* out) const
 
         // Read the string into an int as hex.
         unsigned int color;
-        sscanf_s(valueString+1, "%x", &color);
+        sscanf(valueString+1, "%x", &color);
 
         out->set(Vector4::fromColor(color));
         return true;

+ 34 - 26
gameplay/src/RenderTarget.cpp

@@ -1,18 +1,45 @@
+/**
+ * RenderTarget.cpp
+ */
+
 #include "Base.h"
 #include "RenderTarget.h"
-#include "Texture.h"
 
 namespace gameplay
 {
 
 static std::vector<RenderTarget*> __renderTargets;
 
+RenderTarget::RenderTarget(const char* id)
+    : _id(id), _texture(NULL)
+{
+}
+
+RenderTarget::~RenderTarget()
+{
+    SAFE_RELEASE(_texture);
+
+    // Remove ourself from the cache
+    std::vector<RenderTarget*>::iterator it = std::find(__renderTargets.begin(), __renderTargets.end(), this);
+    if (it != __renderTargets.end())
+    {
+        __renderTargets.erase(it);
+    }
+}
+
 RenderTarget* RenderTarget::create(const char* id, unsigned int width, unsigned int height)
 {
-    RenderTarget* renderTarget = new RenderTarget(id, width, height);
+    // Create a new texture with the given width
+    Texture* texture = Texture::create(Texture::RGBA8888, width, height, NULL, false);
+    if (texture == NULL)
+    {
+        return NULL;
+    }
+
+    RenderTarget* renderTarget = new RenderTarget(id);
+    renderTarget->_texture = texture;
 
     __renderTargets.push_back(renderTarget);
-    renderTarget->_index = __renderTargets.size() - 1;
 
     return renderTarget;
 }
@@ -21,26 +48,17 @@ RenderTarget* RenderTarget::getRenderTarget(const char* id)
 {
     // Search the vector for a matching ID.
     std::vector<RenderTarget*>::const_iterator it;
-    for (it = __renderTargets.begin(); it < __renderTargets.end(); ++it)
+    for (it = __renderTargets.begin(); it < __renderTargets.end(); it++)
     {
-        RenderTarget* rt = *it;
-        if (strcmp(id, rt->getID()) == 0)
+        RenderTarget* dst = *it;
+        if (strcmp(id, dst->getID()) == 0)
         {
-            return rt;
+            return dst;
         }
     }
 
     return NULL;
 }
- 
-RenderTarget::~RenderTarget()
-{
-    SAFE_RELEASE(_texture);
-
-    // Erase this RenderTarget from the vector.
-    std::vector<RenderTarget*>::const_iterator it = __renderTargets.begin() + _index;
-    __renderTargets.erase(it);
-}
 
 const char* RenderTarget::getID() const
 {
@@ -51,15 +69,5 @@ Texture* RenderTarget::getTexture() const
 {
     return _texture;
 }
- 
-RenderTarget::RenderTarget(const char* id, unsigned int width, unsigned int height)
-{
-    if (id)
-    {
-        _id = id;
-    }
 
-    _texture = Texture::create(Texture::RGBA8888, width, height, NULL, true);
 }
-
-}

+ 15 - 14
gameplay/src/RenderTarget.h

@@ -2,13 +2,11 @@
 #define RENDERTARGET_H_
 
 #include "Base.h"
-#include "Ref.h"
+#include "Texture.h"
 
 namespace gameplay
 {
 
-class Texture;
-
 class RenderTarget : public Ref
 {
 public:
@@ -16,7 +14,9 @@ public:
     /**
      * Create a RenderTarget and add it to the list of available RenderTargets.
      *
-     * @param id The ID of the new RenderTarget.  Uniqueness is recommended but not enforced.
+     * The created RenderTarget contains a 32-bit texture with a single/base mipmap level only.
+     *
+     * @param id The ID of the new RenderTarget.
      * @param width The width of the new RenderTarget.
      * @param height The height of the new RenderTarget.
      *
@@ -32,11 +32,6 @@ public:
      * @return The RenderTarget with the specified ID, or NULL if one was not found.
      */
     static RenderTarget* getRenderTarget(const char* id);
- 
-    /**
-     * Destructor.  Removes this RenderTarget from the list of available RenderTargets.
-     */
-    ~RenderTarget();
 
     /**
      * Get the ID of this RenderTarget.
@@ -53,15 +48,21 @@ public:
     Texture* getTexture() const;
  
 private:
- 
-    RenderTarget(const char* id, unsigned int width, unsigned int height);
-    RenderTarget();
+
+    /**
+     * Constructor.
+     */
+    RenderTarget(const char* id);
+
+    /**
+     * Destructor.
+     */
+    ~RenderTarget();
 
     std::string _id;
     Texture* _texture;
-    unsigned int _index; // Index into vector.
 };
 
 }
 
-#endif
+#endif

+ 2 - 1
gameplay/src/Texture.h

@@ -28,7 +28,8 @@ public:
         RGB888 = GL_RGB,
         RGBA8888 = GL_RGBA,
         LUMINANCE = GL_LUMINANCE,
-        LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA
+        LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA,
+        DEPTH = GL_DEPTH_COMPONENT
     };
 
     /**