diff --git a/graphics/opengles2/framebuffer.cpp b/graphics/opengles2/framebuffer.cpp index 0c3065ce033..5c450db6e3d 100644 --- a/graphics/opengles2/framebuffer.cpp +++ b/graphics/opengles2/framebuffer.cpp @@ -33,6 +33,19 @@ namespace Graphics { +template +static T nextHigher2(T k) { + if (k == 0) + return 1; + --k; + + for (uint i = 1; i < sizeof(T) * 8; i <<= 1) + k = k | k >> i; + + return k + 1; +} + + static bool usePackedBuffer() { #ifdef USE_GLES2 return Graphics::isExtensionSupported("GL_OES_packed_depth_stencil"); @@ -40,26 +53,53 @@ static bool usePackedBuffer() { return true; } -FrameBuffer::FrameBuffer(GLuint texture_name, uint width, uint height, uint texture_width, uint texture_height) : _colorTexture(texture_name), _width(width), _height(height) { +FrameBuffer::FrameBuffer(uint width, uint height) + : _managedTexture(true), _width(width), _height(height), + _texWidth(nextHigher2(width)), _texHeight(nextHigher2(height)) { + glGenTextures(1, &_colorTexture); + glBindTexture(GL_TEXTURE_2D, _colorTexture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + + init(); +} + +FrameBuffer::FrameBuffer(GLuint texture_name, uint width, uint height, uint texture_width, uint texture_height) + : _managedTexture(false), _colorTexture(texture_name), _width(width), _height(height), + _texWidth(texture_width), _texHeight(texture_height) { + init(); +} + +FrameBuffer::~FrameBuffer() { + glDeleteRenderbuffers(2, &_renderBuffers[0]); + glDeleteFramebuffers(1, &_frameBuffer); + if (_managedTexture) + glDeleteTextures(1, &_colorTexture); +} + +void FrameBuffer::init() { glGenFramebuffers(1, &_frameBuffer); glGenRenderbuffers(2, &_renderBuffers[0]); glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_name, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _colorTexture, 0); if (usePackedBuffer()) { glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffers[0]); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, texture_width, texture_height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, _texWidth, _texHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderBuffers[0]); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _renderBuffers[0]); glBindRenderbuffer(GL_RENDERBUFFER, 0); } else { glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffers[0]); - glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, texture_width, texture_height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _texWidth, _texHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _renderBuffers[0]); glBindRenderbuffer(GL_RENDERBUFFER, _renderBuffers[1]); - glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, texture_width, texture_height); + glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, _texWidth, _texHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _renderBuffers[1]); glBindRenderbuffer(GL_RENDERBUFFER, 0); } @@ -73,11 +113,6 @@ FrameBuffer::FrameBuffer(GLuint texture_name, uint width, uint height, uint text glBindFramebuffer(GL_FRAMEBUFFER, 0); } -FrameBuffer::~FrameBuffer() { - glDeleteRenderbuffers(2, &_renderBuffers[0]); - glDeleteFramebuffers(1, &_frameBuffer); -} - void FrameBuffer::attach() { glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer); glViewport(0,0, _width, _height); diff --git a/graphics/opengles2/framebuffer.h b/graphics/opengles2/framebuffer.h index 965d65da3f5..e5631c6e85e 100644 --- a/graphics/opengles2/framebuffer.h +++ b/graphics/opengles2/framebuffer.h @@ -29,6 +29,7 @@ namespace Graphics { class FrameBuffer { public: + FrameBuffer(uint width, uint height); FrameBuffer(GLuint texture_name, uint width, uint height, uint texture_width, uint texture_height); ~FrameBuffer(); @@ -36,12 +37,19 @@ public: void detach(); GLuint getColorTextureName() const { return _colorTexture; } + uint getWidth() const { return _width; } + uint getHeight() const { return _height; } + uint getTexWidth() const { return _texWidth; } + uint getTexHeight() const { return _texHeight; } private: + void init(); + bool _managedTexture; GLuint _colorTexture; GLuint _renderBuffers[2]; GLuint _frameBuffer; uint _width, _height; + uint _texWidth, _texHeight; }; }