I'm 99% sure you cannot mix because you cannot switch rendering contexts mid frame. And ES2 doesn't support many of the functions found in ES1, which means providing alternate ES2 versions of all drawing implementation and most of that would be going into shader programs.
Take for example rotating the current model matrix:
In ES1 you would simply do:
glPushMatrix();
glRotate3f(x, y, z);
..draw something..
glPopMatrix();
But in ES2 this is quite different:
1. Before drawing anything you'll need a fragment and vertex shader compiled into a program (at runtime using openGL, although I think you can precompile programs it's beyond the scope of this discussion ATM)
Here is an example for the fragment shader that lets you apply color:
uniform mediump vec4 Col;
void main(void)
{
gl_FragColor = Col;
}
Here is an example for the vertex shader that lets you set the position (this would encompass position,rotation,scale):
attribute highp vec4 myVertex;
uniform mediump mat4 myPMVMatrix;
void main(void)
{
gl_Position = myPMVMatrix * myVertex;
}
2. You'll need to get a handle for your program to use to modify the variables for the uniform properties above: Col and myPMVMatrix by doing:
PMVMatrixHandle = glGetUniformLocation(uiProgramObject, "myPMVMatrix");
ColHandle = glGetUniformLocation(uiProgramObject, "Col");
You are now ready to draw:
1. Calculate your model matrix by rotating,moving,scaling the identity matrix based on your nodes properties.
MATRIX theModelViewProjectionMatrix;
.. apply rotation, translation, scale ..
2. Tell openGl to use the program above:
glUseProgram(uiProgramObject);
3. Set the uniform value of the color and matrix for your shaders:
glUniformMatrix4fv( PMVMatrixHandle, 1, GL_FALSE, theModelViewProjectionMatrix);
glUniform4fv( ColHandle, 1, GL_FALSE, theColor);
Anyway, I think you'll see that this just demonstrates how different ES1 and ES2 are.
I think this all boils down to the need to separate the drawing of nodes from the logical idea of nodes unless you want a duplicate set to support ES2.
I propose keeping CCNodes in a scene graph called CCSceneGraph, and having another graph for rendering called CCRenderGraph.
The idea would be to add/remove nodes from the scene graph in normal usage. But within each node it would add/remove itself from the render graph depending on visibility of itself and it's parent hierarchy.
In the director's main loop it would then do the following:
1. tick the scheduler
2. tick the scene graph (may update the render graph by modifying geometry/colors/vertices whatever)
3. draw the render graph
4. swap buffers.
I recommend taking a look at the Oolong 3D engine for iPhone, it is based on the Imagination Technologies MBX/SGX SDK, so the implemenation is pretty light and should offer a good reference for what will perform best on the hardware that we happen to have available in iPhone/3GS.
NOTE:
The example ES2 code was copied from the Oolong engine example project and is not intended as a reference for proper implementation of an ES2 shader. It is only here to provide a basis for discussion on the potentially great differences between ES1 and ES2.