Skip to content

Commit e88a05e

Browse files
author
minggo
authored
Fix RenderTexture DepthAndStencil issue on Android (#18648)
* Fixing issue where Stencil and Depths buffers would not function for a render texture if you backgrounded an application, and then resumed. * Fixing typo: bufffer -> buffer
1 parent bd84264 commit e88a05e

File tree

2 files changed

+84
-57
lines changed

2 files changed

+84
-57
lines changed

cocos/2d/CCRenderTexture.cpp

Lines changed: 81 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ RenderTexture::RenderTexture()
6060
, _autoDraw(false)
6161
, _sprite(nullptr)
6262
, _saveFileCallback(nullptr)
63+
, _depthAndStencilFormat(0)
6364
{
6465
#if CC_ENABLE_CACHE_TEXTURE_DATA
6566
// Listen this event to save render texture before come to background.
@@ -118,6 +119,18 @@ void RenderTexture::listenToBackground(EventCustom* /*event*/)
118119

119120
glDeleteFramebuffers(1, &_FBO);
120121
_FBO = 0;
122+
123+
if (_depthRenderBuffer)
124+
{
125+
glDeleteRenderbuffers(1, &_depthRenderBuffer);
126+
_depthRenderBuffer = 0;
127+
}
128+
129+
if (_stencilRenderBuffer)
130+
{
131+
glDeleteRenderbuffers(1, &_stencilRenderBuffer);
132+
_stencilRenderBuffer = 0;
133+
}
121134
#endif
122135
}
123136

@@ -126,9 +139,18 @@ void RenderTexture::listenToForeground(EventCustom* /*event*/)
126139
#if CC_ENABLE_CACHE_TEXTURE_DATA
127140
// -- regenerate frame buffer object and attach the texture
128141
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
142+
143+
GLint oldRBO;
144+
glGetIntegerv(GL_RENDERBUFFER_BINDING, &oldRBO);
129145

130146
glGenFramebuffers(1, &_FBO);
131147
glBindFramebuffer(GL_FRAMEBUFFER, _FBO);
148+
149+
const Size& s = _texture->getContentSizeInPixels();
150+
if (_depthAndStencilFormat != 0)
151+
{
152+
setupDepthAndStencil(s.width, s.height);
153+
}
132154

133155
_texture->setAntiAliasTexParameters();
134156
if(_textureCopy)
@@ -137,6 +159,7 @@ void RenderTexture::listenToForeground(EventCustom* /*event*/)
137159
}
138160

139161
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
162+
glBindRenderbuffer(GL_RENDERBUFFER, oldRBO);
140163
glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);
141164
#endif
142165
}
@@ -258,69 +281,15 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
258281

259282
if (depthStencilFormat != 0)
260283
{
261-
262-
263-
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
264-
if(Configuration::getInstance()->supportsOESPackedDepthStencil())
265-
{
266-
//create and attach depth buffer
267-
glGenRenderbuffers(1, &_depthRenderBuffer);
268-
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
269-
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, (GLsizei)powW, (GLsizei)powH);
270-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
271-
272-
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
273-
if (depthStencilFormat == GL_DEPTH24_STENCIL8)
274-
{
275-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
276-
}
277-
}
278-
else
279-
{
280-
281-
glGenRenderbuffers(1, &_depthRenderBuffer);
282-
glGenRenderbuffers(1, &_stencilRenderBuffer);
283-
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
284-
285-
if(Configuration::getInstance()->supportsOESDepth24())
286-
{
287-
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, (GLsizei)powW, (GLsizei)powH);
288-
}
289-
else
290-
{
291-
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, (GLsizei)powW, (GLsizei)powH);
292-
}
293-
294-
glBindRenderbuffer(GL_RENDERBUFFER, _stencilRenderBuffer);
295-
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, (GLsizei)powW, (GLsizei)powH);
296-
297-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
298-
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
299-
GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _stencilRenderBuffer);
300-
}
301-
#else
302-
303-
//create and attach depth buffer
304-
glGenRenderbuffers(1, &_depthRenderBuffer);
305-
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
306-
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, (GLsizei)powW, (GLsizei)powH);
307-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
308-
309-
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
310-
if (depthStencilFormat == GL_DEPTH24_STENCIL8)
311-
{
312-
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
313-
}
314-
315-
#endif
316-
284+
_depthAndStencilFormat = depthStencilFormat;
285+
setupDepthAndStencil(powW, powH);
317286
}
318287

319288
// check if it worked (probably worth doing :) )
320289
CCASSERT(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Could not attach texture to framebuffer");
321290

322291
_texture->setAntiAliasTexParameters();
323-
if(_textureCopy)
292+
if (_textureCopy)
324293
{
325294
_textureCopy->setAntiAliasTexParameters();
326295
}
@@ -351,6 +320,61 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
351320
return ret;
352321
}
353322

323+
void RenderTexture::setupDepthAndStencil(int powW, int powH)
324+
{
325+
326+
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
327+
if(Configuration::getInstance()->supportsOESPackedDepthStencil())
328+
{
329+
//create and attach depth buffer
330+
glGenRenderbuffers(1, &_depthRenderBuffer);
331+
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
332+
glRenderbufferStorage(GL_RENDERBUFFER, _depthAndStencilFormat, (GLsizei)powW, (GLsizei)powH);
333+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
334+
335+
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
336+
if (_depthAndStencilFormat == GL_DEPTH24_STENCIL8)
337+
{
338+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
339+
}
340+
}
341+
else
342+
{
343+
glGenRenderbuffers(1, &_depthRenderBuffer);
344+
glGenRenderbuffers(1, &_stencilRenderBuffer);
345+
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
346+
347+
if(Configuration::getInstance()->supportsOESDepth24())
348+
{
349+
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, (GLsizei)powW, (GLsizei)powH);
350+
}
351+
else
352+
{
353+
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, (GLsizei)powW, (GLsizei)powH);
354+
}
355+
356+
glBindRenderbuffer(GL_RENDERBUFFER, _stencilRenderBuffer);
357+
glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, (GLsizei)powW, (GLsizei)powH);
358+
359+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
360+
glFramebufferRenderbuffer(GL_FRAMEBUFFER,
361+
GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _stencilRenderBuffer);
362+
}
363+
#else
364+
//create and attach depth buffer
365+
glGenRenderbuffers(1, &_depthRenderBuffer);
366+
glBindRenderbuffer(GL_RENDERBUFFER, _depthRenderBuffer);
367+
glRenderbufferStorage(GL_RENDERBUFFER, _depthAndStencilFormat, (GLsizei)powW, (GLsizei)powH);
368+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
369+
370+
// if depth format is the one with stencil part, bind same render buffer as stencil attachment
371+
if (_depthAndStencilFormat == GL_DEPTH24_STENCIL8)
372+
{
373+
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, _depthRenderBuffer);
374+
}
375+
#endif
376+
}
377+
354378
void RenderTexture::setSprite(Sprite* sprite)
355379
{
356380
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS

cocos/2d/CCRenderTexture.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,7 @@ class CC_DLL RenderTexture : public Node
327327
Texture2D* _textureCopy; // a copy of _texture
328328
Image* _UITextureImage;
329329
Texture2D::PixelFormat _pixelFormat;
330+
GLuint _depthAndStencilFormat;
330331

331332
// code for "auto" update
332333
GLbitfield _clearFlags;
@@ -363,6 +364,8 @@ class CC_DLL RenderTexture : public Node
363364
void onClearDepth();
364365

365366
void onSaveToFile(const std::string& fileName, bool isRGBA = true);
367+
368+
void setupDepthAndStencil(int powW, int powH);
366369

367370
Mat4 _oldTransMatrix, _oldProjMatrix;
368371
Mat4 _transformMatrix, _projectionMatrix;

0 commit comments

Comments
 (0)