#include "Base.h" #include "DepthStencilTarget.h" namespace gameplay { static std::vector __depthStencilTargets; DepthStencilTarget::DepthStencilTarget(const char* id, Format format) : _id(id ? id : ""), _format(format), _depthTexture(NULL), _stencilBuffer(0) { } DepthStencilTarget::~DepthStencilTarget() { SAFE_RELEASE(_depthTexture); // Destroy GL resources. if (_stencilBuffer) { GL_ASSERT( glDeleteTextures(1, &_stencilBuffer) ); } // Remove from vector. std::vector::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, ¤tRbo) ); // 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); return depthStencilTarget; } DepthStencilTarget* DepthStencilTarget::getDepthStencilTarget(const char* id) { GP_ASSERT(id); // Search the vector for a matching ID. std::vector::const_iterator it; for (it = __depthStencilTargets.begin(); it < __depthStencilTargets.end(); it++) { DepthStencilTarget* dst = *it; GP_ASSERT(dst); if (strcmp(id, dst->getID()) == 0) { return dst; } } return NULL; } const char* DepthStencilTarget::getID() const { return _id.c_str(); } DepthStencilTarget::Format DepthStencilTarget::getFormat() const { return _format; } Texture* DepthStencilTarget::getTexture() const { return _depthTexture; } }