Transformations


18 posts
by Hardcheese » Thu Dec 20, 2012 5:32 pm
Hi,

I was wondering how you would do this in OpenGL ES 2.0 because I can't seem to be able to get anything to move around on screen when I try to use the glTranslatef(.., .., ...). I read online that you would have to bind your custom matrices to the shaders uniform, I unfortunately don't know what this means or how to implement it.

Thanks.
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by fxmaker » Thu Dec 20, 2012 6:33 pm
Try glm bound to matrices in your shaders. The built in matrix stacks of legacy GL are all gone.

glm is a good choice because it exactly replicates the types found in glsl and has many helper functions such as perspective, ortho etc.

Note you will have to implement a normal matrix based upon the modelview if you are doing lighting. In legacy GL the normal matrix was hidden.
Posts: 43
Joined: Fri Dec 07, 2012 6:37 pm
by Hardcheese » Thu Dec 20, 2012 6:45 pm
Thanks for the reply. The problem is i am using plain C (as most of the tutorials seem to use it) and it seems glm is a C++ library. Is there a way you could do all this manually?
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Thu Dec 20, 2012 6:47 pm
Here is a simple Vertex shader that uses a uniform (called u_Translate) to move an object to the required position. The attribute a_position is passed the vertices of the object which are defined for the object positioned at the origin. The addition of a_position and u_Translate move the vertices to the required position before the viewing transformation is applied by multiplication with u_mvpMatrix.
Code: Select all
uniform vec4 u_Translate;
attribute vec4 a_position;

void main()
{
        vec4 posn;
        posn =  a_position + u_Translate;
        gl_Position = u_mvpMatrix * posn ;
}


To move the object, each time the scene is drawn the value set in u_Translate is changed.

HTH

PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by PeterO » Thu Dec 20, 2012 6:52 pm
Hardcheese wrote:Thanks for the reply. The problem is i am using plain C (as most of the tutorials seem to use it) and it seems glm is a C++ library. Is there a way you could do all this manually?


Have a look at the examples for the OpenGL ES 2.0 Programming guide. They are written in C.
https://github.com/benosteen/opengles-b ... ster/Raspi

PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Hardcheese » Thu Dec 20, 2012 6:59 pm
When I try to compile your shader code the compiler complains of the following line saying one of the variables is undefined:

Code: Select all
 gl_Position = u_mvpMatrix * posn ;


Also what would you have to put into your main C code to make this work?
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Thu Dec 20, 2012 7:09 pm
Hardcheese wrote:When I try to compile your shader code the compiler complains of the following line saying one of the variables is undefined:

Code: Select all
 gl_Position = u_mvpMatrix * posn ;


Also what would you have to put into your main C code to make this work?

OPSE ! Sorry about that, I took a much more complex shader and cut out all but the bits to make my point ! Add this at the top of the shader.....
Code: Select all
uniform mat4 u_mvpMatrix;


It is used in a loop to draw ~50 buttons on a control pannel....
Code: Select all
  glUseProgram ( userData->programWGbuttons );    // Use the simple Pick shader for now


    i = 0;
    while(WGButtons[i].objectIndex != 0)
    {
   
        // Load the vertex position
        glVertexAttribPointer ( userData->WGPositionLoc, 3, GL_FLOAT,
                                GL_FALSE, 3 * sizeof(GLfloat), WGButtons[i].object->vertices );

        glEnableVertexAttribArray ( userData->WGPositionLoc );

        glVertexAttribPointer ( userData->WGNormalsLoc, 3, GL_FLOAT,
                                GL_FALSE, 3 * sizeof(GLfloat), WGButtons[i].object->normals );

        glEnableVertexAttribArray ( userData->WGNormalsLoc );

        // Load the MVP matrix
        glUniformMatrix4fv( userData->WGmvpLoc, 1, GL_FALSE, (GLfloat*) &userData->mvpMatrix.m[0][0] );
        glUniform4fv(userData->WGColourLoc , 1,  (GLfloat *) WGButtons[i].colour); //&ButtonColours[0]);
        glUniform3fv(userData->WGLightPositionLoc , 1,  (GLfloat *) &WGLightPosition[0]);
        glUniform3fv(userData->WGCameraPositionLoc , 1,  (GLfloat *) &WGCameraPosition[0]);

 
        ButtonTranslate[0] = WGButtons[i].Translate[0];
        ButtonTranslate[1] = WGButtons[i].Translate[1];
        ButtonTranslate[2] = WGButtons[i].Translate[2];
        ButtonTranslate[3] = WGButtons[i].Translate[3];

        if(WGButtons[i].state == 1) ButtonTranslate[1] -= 0.4;
        glUniform4fv(userData->WGTranslateLoc , 1,  (GLfloat *) &ButtonTranslate[0]);
        glDrawElements ( GL_TRIANGLES, WGButtons[i].object->numIndices, GL_UNSIGNED_BYTE, WGButtons[i].object->indices );


        i += 1;
    }


User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Hardcheese » Thu Dec 20, 2012 7:22 pm
Although I haven't tried to implement the translations yet I am quite concerned that nothing is drawn on the screen now I have implemented the new shader code (although it compiles correctly). I am using the following code for drawing.

Code: Select all
void Draw(void)
{
update_keys(); //Start listening for keyboard events.

glViewport(0, 0, state->render_width, state->render_height);

glClear(GL_COLOR_BUFFER_BIT);

shader_select(shader); //Make the shaders program current.

glLineWidth(3.0f);

glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, ship );
glEnableVertexAttribArray( 0 );

glDrawArrays( GL_LINES, 0, 4 );
}


and the following shader code:

Code: Select all
uniform mat4 u_mvpMatrix;
uniform vec4 u_Translate;
attribute vec4 a_position;
void main()
{
vec4 posn;
posn = a_position + u_Translate;
gl_Position = u_mvpMatrix * posn;
}


and the fragment shader...

Code: Select all
precision mediump float;
void main()
{
gl_FragColor = vec4( 0.0, 1.0, 0.0, 1.0 );
}


I'm sorry but you might have to be a bit more specific to my code.

Thanks for all your help so far.
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Thu Dec 20, 2012 7:27 pm
If you can make a tarball of all your code I'll gladly take a look at it... I'll PM you my email address.
PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Hardcheese » Thu Dec 20, 2012 7:41 pm
Here is the code.
Attachments
code.tar.gz
Code
(18.09 KiB) Downloaded 78 times
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Thu Dec 20, 2012 8:13 pm
Looking at it now.....
PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by PeterO » Thu Dec 20, 2012 9:18 pm
Here is the "fixed code" :D

Problems were that you needed to set values for the uniforms used in the vertex shader.
See the modifications in the Draw function that define a view matrix (that does nothing) and a transform matrix. Note the code I've added to printout the values for the locations of the 2 uniforms and the position attribute. Your code should retrieve these locations and use them instead of "magic numbers"
when calling glUniformMatrix4fv and glUniform4fv (but I've left that for you to fix ;) )

If anything is unclear please ask.... :)
PeterO
Attachments
code.tgz
modified code
(18.6 KiB) Downloaded 79 times
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Hardcheese » Fri Dec 21, 2012 7:48 am
Thank you so much PeterO :D it all works.
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Fri Dec 21, 2012 10:49 am
No problem. 8-)
PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Hardcheese » Fri Dec 21, 2012 2:13 pm
Sorry but I have encountered trouble again! For my game I need rotations as well as translations but I don't know how to implement them (even though I now have the translations working well). What would I have to add to make a rotation?
Posts: 36
Joined: Sat Sep 01, 2012 12:25 pm
by PeterO » Fri Dec 21, 2012 2:28 pm
In the vertex shader you could multiply the position attribute by a uniform rotation matrix before adding the translation vector. You may be able to combine the rotation and translation with a single 4x4 matrix.

WIkipedia can help with rotation matrix: http://en.wikipedia.org/wiki/Rotation_matrix
This may help with 4x4 transform matrices: http://stackoverflow.com/questions/2465 ... 90#2465290
PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm
by Pickle » Wed Jan 16, 2013 1:56 pm
I would suggest taking a look at CML which can handle all of the matrix math you. I use it with all opengl versions and it has worked well.
http://cmldev.net/?p=423
Posts: 64
Joined: Tue Sep 20, 2011 5:09 pm
by PeterO » Thu Jan 17, 2013 10:25 am
Pickle wrote:I would suggest taking a look at CML which can handle all of the matrix math you. I use it with all opengl versions and it has worked well.
http://cmldev.net/?p=423


See 3rd post on this thread !

PeterO
User avatar
Posts: 1039
Joined: Sun Jul 22, 2012 4:14 pm