Integrating LiquidFun with Cocos2d-x: Part II

In Part I I described to how integrated LiquidFun with Cocos2d-x. In this part (part II) I’ll describe how to render the particles using a basic water effect. Part I uses just one glDrawArrays(GL_POINTS, 0, total); to draw the particles. And although that works to draw “particles”, it is not enough to draw “water”. Drawing “water” requires a more complex rendering algorithm, like the one used in this example. And implementing an algorithm similar that one is what this article describes. The algorithm works more or less like this: Choose a white circle and blur it. You can blur the circle at runtime Or you can blur it off-line. Create an a new frame-buffer (think of a clean off-screen buffer where you can render whatever you want) Render the particles into the newly created frame-buffer using the blurred circle Now render the frame-buffer into the main color-buffer using a threshold. The threshold could be something like this: If pixel.r < 0.1, discard the pixel (the pixel won’t be drawn) If pixel.r < 0.2, draw a blue pixel (for the border, although this is optional) else draw a white pixel (the inner part of the water) How to do it using Cocos2d-x and LiquidFun Let’s take the LFParticleSystemNode from Part I, and “evolve” it: The first thing to do is to add the “off-screen” frame-buffer into the LFParticleSystemNode class. In Cocos2d-x, the “off-screen” buffers are created with the RenderTexture class. Example: [code language=“cpp”] bool LFParticleSystemNode::init(b2ParticleSystem* particleSystem, float ratio) { … // create an off-screen frame-buffer with the size of the screen auto s = Director::getInstance()->getWinSize(); _renderTexture = cocos2d::RenderTexture::create(s.width, s.height, Texture2D::PixelFormat::RGBA8888); this->addChild(_renderTexture); _renderTexture->setAnchorPoint(Point::ANCHOR_MIDDLE); _renderTexture->setPosition(Point(s.width/2, s.height/2)); // Change the default shader. Use a the threshold shader auto program = GLProgram::createWithByteArrays(_renderTextureShaderVert, _renderTextureShaderFrag); auto programState = GLProgramState::getOrCreateWithGLProgram(program); programState->setUniformFloat(“u_threshold_discard”, 0.15); programState->setUniformFloat(“u_threshold_border”, 0.3); … } [/code] And, as mentioned earlier, the RenderTexture (the off-screen frame-buffer) needs a shader with a threshold. The threshold shader should look like the following: [code language=“cpp”] varying vec4 v_fragmentColor; varying vec2 v_texCoord; uniform float u_threshold_discard; uniform float u_threshold_border; void main() { vec4 color = v_fragmentColor * texture2D(CC_Texture0, v_texCoord); if( color.r < u_threshold_discard) // black or discard color = vec4(0,0,0,0); else if( color.r < u_threshold_border) // blue for the border color = vec4(0.2,0.2,0.9,1); else // white for the center color = vec4(1,1,1,1); gl_FragColor = color; } [/code] The values u_threshold_discard, and u_threshold_border are defined at runtime. In the example, they are set at 0.15 and 0.3 respectively. The next thing to do is, to render the particles in the RenderTexture. [code language=“cpp”]void LFParticleSystemNode::draw(Renderer *renderer, const Mat4 &transform, uint32_t transformFlags) { // tell RenderTexture to “capture” the particles _renderTexture->beginWithClear(0,0,0,0); _customCommand.init(_globalZOrder); _customCommand.func = CC_CALLBACK_0(LFParticleSystemNode::onDraw, this, transform, transformFlags); renderer->addCommand(&_customCommand); // tell RenderTexture to stop “capturing” the particles _renderTexture->end(); } [/code] The result is the following

July 30, 2014 · 4 min · ricardoquesada

Integrating LiquidFun with Cocos2d-x: Part I

[caption id="" align=“alignnone” width=“400”] LiquidFun Testbed + Cocos2d-x[/caption] From LiquidFun’s site: Based on Box2d, LiquidFun features particle-based fluid simulation. Game developers can use it for new game mechanics and add realistic physics to game play. Designers can use the library to create beautiful fluid interactive experiences. Basically LiquidFun is Box2d plus an extension to simulate fluids using a particle system. To test it, download and install the official LiquidFun - Testbed, and LiquidFun - EyeCandy for Android. Cocos2d-x already has Box2d integration, so in order to integrate Cocos2d-x with LiquidFun, we only need to integrate this new class: b2ParticleSystem. LiquidFun’s b2ParticleSystem I’m not going to describe how to use LiquidFun (for that, read its programmers guide). Instead, I’m going to describe how to integrate b2ParticleSystem in Cocos2d-x (also applicable to any other game engine). For the integration, what we need is a Cocos2d-x node that knows how to render a b2ParticleSystem. And b2ParticleSystem has these 4 useful methods: [code language=“cpp”] class b2ParticleSystem { … // Get the number of particles. int32 GetParticleCount() const; // Get the particle radius. float32 GetRadius() const; // Get the position of each particle in Box2d’s coordinate system // Array is length GetParticleCount() b2Vec2* GetPositionBuffer(); // Get the color of each particle in RGBA Uint8 format. // Array is length GetParticleCount() b2ParticleColor* GetColorBuffer(); }; [/code] Ideally we should be able to reuse cocos2d::ParticleSystemQuad for the rendering, but we can’t because: cocos2d::ParticleSystemQuad doesn’t support changing the attractor (this is a design bug, we need to fix it). A nil attractor would be needed for this case. ParticleSystemQuad works with Quads, and not Points. And even if Points were supported (like in Cocos2d-x v1), it wouldn’t work because the points and colors should be in an interleaved array. The other issue is the conversion between Box2d and Cocos2d-x coordinate system, but it would be easy to fix.

April 23, 2014 · 5 min · ricardoquesada

Vistual Studio: First steps

Goals Compile and run cocos2d-x tests on the emulator Set a breakpoint in Visual Studio. Running cpp-test on the Emulator 1. Download cocos2d-x v3.0 2. Unzip it and then go to cocos2d-x/build directory $ cd cocos2d-x/build 3. Open cocos2d-wp8.vc2012.sln with Visual Studio $ start cocos2d-wp8.vc2012.sln 4. Set cpp-tests (Windows Phone Silverlight 8) as the default project: Go to the Solution Explorer Right click on cpp-tests (Windows Phone Silverlight 8) Click on Set as StartUp Project 5. Run cpp-tests on the Emulator Press the Emulator 8.1 WVGA 4 inch button If an Hyper-V error appears, then you have to enable Hyper-V: Enable Hyper-V on the BIOS And then enable Hyper-V on Windows 8.1 Pro (it won’t work on the ‘Regular’ edition). 6. If the following Dialog pops-up, just press Retry: And that’s all. You should see the cpp-tests running on the Emulator:

April 11, 2014 · 2 min · ricardoquesada