To use my custom shader with CCRenderTexture, I was doing:
glUseProgram(myProgramHandle);
//other code to update program variables
//..
myCCRenderTexture->beginWithClear(1,1,1,1);
glBindTexture(GL_TEXTURE_2D, texName);
glUniform1fv(paramHandle, 12, paramValue);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
myCCRenderTexture->end();
But my use of glUseProgram confuses cocos2d later. I could fix it by adding these lines to first manually save GL_CURRENT_PROGRAM and GL_ARRAY_BUFFER_BINDING values and then restore them later:
GLint savedPreviousProgram, savedPreviousArrayBuffer; //temp variables to save gl state
glGetIntegerv(GL_CURRENT_PROGRAM,&savedPreviousProgram); //save current program
glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&savedPreviousArrayBuffer); //save array buffer binding
glUseProgram(myProgramHandle);
//other code to update program variables
//..
myCCRenderTexture->beginWithClear(1,1,1,1);
glBindTexture(GL_TEXTURE_2D, texName);
glUniform1fv(paramHandle, 12, paramValue);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
myCCRenderTexture->end();
glUseProgram(savedPreviousProgram); //restore previous gl program
glBindBuffer(GL_ARRAY_BUFFER, savedPreviousArrayBuffer); //restore previous array buffer binding
Why do I need to manually save and restore GL program and array buffer value? Is there any other way to do this with cocos2d without using direct openGL functions?
CCSprite::draw sets the shader for you. You only need to call CCNode::setShaderProgram with your shader program in the initialization function or elsewhere.
If you need to set uniforms you can try the following code:
it make your shader program active and sets builtin uniform parameters;
it sets various attribute pointers, binds the main texture etc-etc.
But you have to set your uniform between these two things somehow, which is imposimple since a single call to CCSprite::draw. Thus, you have to call CC_NODE_DRAW_SETUP by yourself. Note that there is a minimal overhead of invocation of this function is CCSprite::draw since Cocos2d won’t set the shader program again if it’s alread set.