DepthStencilTarget.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "Base.h"
  2. #include "DepthStencilTarget.h"
  3. namespace gameplay
  4. {
  5. static std::vector<DepthStencilTarget*> __depthStencilTargets;
  6. DepthStencilTarget::DepthStencilTarget(const char* id, Format format)
  7. : _id(id), _format(format), _depthTexture(NULL), _stencilBuffer(0)
  8. {
  9. }
  10. DepthStencilTarget::~DepthStencilTarget()
  11. {
  12. SAFE_RELEASE(_depthTexture);
  13. // Destroy GL resources.
  14. if (_stencilBuffer)
  15. {
  16. GL_ASSERT( glDeleteTextures(1, &_stencilBuffer) );
  17. }
  18. // Remove from vector.
  19. std::vector<DepthStencilTarget*>::iterator it = std::find(__depthStencilTargets.begin(), __depthStencilTargets.end(), this);
  20. if (it != __depthStencilTargets.end())
  21. {
  22. __depthStencilTargets.erase(it);
  23. }
  24. }
  25. DepthStencilTarget* DepthStencilTarget::create(const char* id, Format format, unsigned int width, unsigned int height)
  26. {
  27. // Create a backing texture buffer.
  28. Texture* depthTexture = Texture::create(Texture::DEPTH, width, height, NULL, false);
  29. if (depthTexture == NULL)
  30. {
  31. return NULL;
  32. }
  33. // Create stencil renderbuffer if format is DEPTH24_STENCIL8
  34. RenderBufferHandle stencilBuffer = 0;
  35. if (format == DEPTH24_STENCIL8)
  36. {
  37. // Backup the existing render buffer
  38. GLint currentRbo = 0;
  39. GL_ASSERT( glGetIntegerv(GL_RENDERBUFFER_BINDING, &currentRbo) );
  40. // Create the new render buffer
  41. GL_ASSERT( glGenRenderbuffers(1, &stencilBuffer) );
  42. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer) );
  43. GL_ASSERT( glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, width, height) );
  44. // Restore the old render buffer
  45. GL_ASSERT( glBindRenderbuffer(GL_RENDERBUFFER, currentRbo) );
  46. }
  47. // Create the depth stencil target
  48. DepthStencilTarget* depthStencilTarget = new DepthStencilTarget(id, format);
  49. depthStencilTarget->_depthTexture = depthTexture;
  50. depthStencilTarget->_stencilBuffer = stencilBuffer;
  51. // Add it to the cache
  52. __depthStencilTargets.push_back(depthStencilTarget);
  53. return depthStencilTarget;
  54. }
  55. DepthStencilTarget* DepthStencilTarget::getDepthStencilTarget(const char* id)
  56. {
  57. // Search the vector for a matching ID.
  58. std::vector<DepthStencilTarget*>::const_iterator it;
  59. for (it = __depthStencilTargets.begin(); it < __depthStencilTargets.end(); it++)
  60. {
  61. DepthStencilTarget* dst = *it;
  62. if (strcmp(id, dst->getID()) == 0)
  63. {
  64. return dst;
  65. }
  66. }
  67. return NULL;
  68. }
  69. const char* DepthStencilTarget::getID() const
  70. {
  71. return _id.c_str();
  72. }
  73. DepthStencilTarget::Format DepthStencilTarget::getFormat() const
  74. {
  75. return _format;
  76. }
  77. Texture* DepthStencilTarget::getTexture() const
  78. {
  79. return _depthTexture;
  80. }
  81. }