androidspritebuildercocos2d-iphone-3cocos2d-swift

CCClippingNode on Android not working


I started a new iOS project recently. I'd like to support also Android so I choose SpriteBuilder with newest cocos2d-iphone (cocos2d-swift).

I use CCClippingNode for clipping contents. It needs 24bit depth buffer and 8 bit stencil buffer, so I needed to add the following line to AppDelegate.m to application:didFinishLaunchingWithOptions:

[cocos2dSetup setObject:@GL_DEPTH24_STENCIL8_OES forKey:CCSetupDepthFormat];

naturally this is only for iOS. According to logs it should work for Android without any additional code, as it logs the following lines on startup:

EGL_DEPTH_SIZE = 24
EGL_STENCIL_SIZE = 8

Later when I create CCClippingNode in code, it logs:

[CCClippingNode initWithStencil:]_block_invoke : Stencil buffer is not enabled; enable it by passing GL_DEPTH24_STENCIL8_OES into the depthFormat parrameter when initializing CCGLView. Until then, everything will be drawn without stencil.

It happens because the following line in CCClippingNode.m returns 0:

glGetIntegerv(GL_STENCIL_BITS, &_stencilBits);

On iOS GL_STENCIL_BITS is 8 (after setting CCSetupDepthFormat to GL_DEPTH24_STENCIL8_OES). On Android it's 0.

What should I do to make it work also on Android?

I use SpriteBuilder 1.4.0-beta.3 and Cocos2D-Swift version 3.4.1-develop


Solution

  • I found out where was the problem, so I'll answer my own question :)

    The whole problem was in misleading logs. We need to modify function setupView: in Platforms/Android/CCGLView.m. CCGLView is logging EGL values before calling eglChooseConfig which sets depth and stencil size to 0.

    Moving line

    logConfig(_eglDisplay, _eglConfiguration);
    

    after

    eglChooseConfig(_eglDisplay, configAttribs, &_eglConfiguration, 1, &numConfigs)
    

    will show the real values. With this modification the following lines will appear in logs:

    EGL_DEPTH_SIZE = 0
    EGL_STENCIL_SIZE = 0
    

    So we have the real values in the log, all wee need is to set them. This can be done by adding the following two lines to structure configAttribs[] (at the very beginning of function setupView:)

    EGL_DEPTH_SIZE, 24,
    EGL_STENCIL_SIZE, 8,
    

    And CCClippingNode suddenly starts to clip contents on Android too

    NOTE: Only configAttribs[] structure needs to be enhanced by the mentioned two lines. The other changes are needed only when you need the real EGL values in the log for some other reason.