OpenGL ES 2.0 - Life without push/pop

Hello,

I’m really struggling to grasp the thinking behind OpenGL ES 2.0, and the lack of immediate mode and push/pop matrix.

Usually, when rendering a scene in OpenGL I would do something like this:


GL.PushMatrix();
{

    //World Transformations
    GL.Translate...
    GL.Rotate...

    //Render first sub-component
    GL.PushMatrix();
    {
         //some transformations (e.g. position of person in world)
        GL.Translate...
        GL.Rotate...
        
        //actually render the first object (e.g. a person)
        GL.Begin(...);
        GL.End();

        //Render first sub-sub-component (e.g. hat on person's head)
        GL.PushMatrix();
        {
           //some transformations (e.g. position of hat relative to person)
           GL.Translate...
           GL.Rotate...
        
           //actually render the first sub-sub-object (e.g. a hat)
           GL.Begin(...);
           GL.End();        


        }
        GL.PopMatrix();

    }
    GL.PopMatrix();

    //render second sub-component
    GL.PushMatrix();
    {
        //some transformations (e.g. position of dog in world)
        GL.Translate...
        GL.Rotate...
        
        //actually render the second object (e.g. a dog)
        GL.Begin(...);
        GL.End();

    }
    GL.PopMatrix();


}
GL.PopMatrix();

From what I understand of OpenGL ES 2.0, I can’t push/pop matrix, and instead I have to :

  1. Define a shader (which appears to require me to define both a vertex AND fragment shader?!)
  2. At each level of nesting (i.e. each time I push above), I have to do all the matrix transformations <i>in software</i> and push the results into the shader?

Seriously?

Please tell me I’m missing something here. Apart from being unbelievably inconvenient, this feels like a horrible horrible hack.

It would seem that the very first thing I’m going to need to do before OpenGL ES 2.0 is usable for me is to build a little framework on top of it so that I can do the type of object composition that I’ve always considered to be fundamental to OpenGL.

I sincerely hope that I’m missing something fundamental here, so I look forward to being corrected.

Regards,

James L.

The matrix transformed always happened in software anyway (with the possible exception of some really really early SGI cards) so there’s nothing different about having to do them in software yourself, aside from the fact that you have to do them yourself.

The general workflow was something like: you make your glPushMatrix/glTranslate/glRotate/etc calls, the driver does these in software, a dirty flag is set, you issue a draw call, the driver checks the dirty flags and if set it uploads the final transformed MVP matrix to the GPU, the GPU then uses that to transform the verts (that’s assuming hardware T&L).

Doing it without the matrix stack is actually not that bad, and can be cleaner and more efficient (modelview is always identity? Fine - just send projection. Don’t need inverse transpose? Fine - don’t calculate it.) As to how you do it, the best thing to do is just grab a matrix library and use that.

If you are going to go the shader route, and GL ES 2 is that way, then there is no need to integrate matrix function in GL API. That’s how it is for Direct3D as well.
I’m not sure why GL ever had those matrix functions but perhaps mhagain is right about old SGI hardware having that capability.

Unfortunately, GLU hasn’t been updated to go along with GL and I’m assuming there is no GLU ES.
For GL, there are 3rd party math libraries Related toolkits and APIs - OpenGL Wiki
For GL ES, you should ask khronos. They have their own forum on GL ES.

If you absolutely need fixed function pipeline and are doing OpenGL ES, you have 2 choices:

[ul]
[li]Use OpenGL ES 1.x which has the fixed function pipeline. It has push/pop matrix[/li][/ul]
OR

[ul]
[li]Using OpenGL ES 2.x, write your own shaders and make your own matrix stack[/li][/ul]

For the 2nd option, there is Regal: https://github.com/p3/regal which AFAIK implements (most of) the fixed function pipeline on top of an OpenGL (in this case ES2) implementation.