There are three parts to this solution. One is the changes required to cocos2d, the second is the changes to SIO2 and the third is the design pattern of communication and control between cocos2d and SIO2. I tried to keep the changes required to a minimum, and used a simple function callback control mechanism between cocos2d and SIO2.
Riq made namespace changes in rc0.99 which helps to integrate cocos2d, but unfortunately this hasn't yet included the Support/EAGLView.m class. Of course SIO2 has it's own EAGLview class, and I chose to keep SIO2 EAGLview class for the app. You then need to refactor cocos2d Director class to accept a new EAGLview. Instead, I made the following changes:
- Rename cocos2d Support/EAGLView class to ccEAGLView (optionally change the .h/.m file names too)
- Patch Director.h to accept this new class:
- Patch Director.m to use the EAGLView class, plus make some edits to the following functions:
Update the initOpenGLViewWithView method to accept an SIO2 view, create an optional FPSLabel and return. You could create a new init method of course.
Update the mainLoop method to not clear or swap the gl buffers, let SIO2 do that.
Update the end method so that cocos2d doesn't detach the view because of course it was never attached.
Note: you may need to patch the convertCoordinats and winSize methods, but in my version of cocos2d they were already updated to use GL_VIEWPORT parameters and not the UIView; check the Google code svn for a patch.
Because we're using the SIO2 EAGLView with cocos2d, we just use the normal SIO2 gl buffer creation process and simply initialize cococ2d. Then within SIO2, within the 2d gl projection, make a call to mainLoop.
First, the patch to SIO2 EAGLView.mm
Within the EAGLview createFramebuffer method you simply add a call to attach cocos2d into the SIO2 view. Then you'll need to patch the touchesBegan/Ended methods to pass through touches to cocos2d:
And you'll have to repeat this for touchesMoved, touchesEnded.
Note: I also added a cocos2d teardown function to EAGLview, but you could do that explicitly elsewhere.
Next, you'll need to update your SIO2 render functions to call cocos2d. For example, in the SIO2 tutorial template.mm files, you can create a function like this:
This function does nothing more than call the gl matrix and model view, and sets up the SIO2 2D state.
With this function, you can then render your 3D scene with SIO2 as normal and then call this to render the 2D scene, blended, on top of it. You could change the render order if you choose.
Cocos2D Controlling SIO2
This is where it can get tricky: how do you control scene progression? What I chose to do was to have cocos2d control the SIO2 state from within the cocos2d scenes or layers. To do this, I just crated some callback helper functions to change the state. So, for example, when a user clicks on a cocos2d menu button, it triggers a new state within SIO2 causing, say, a new 3d model to load.