Getting started w/ OpenGL ES 2.0 Android NDK

Alex Egg,

Vertices

First you need to think in vertices. Each vertex consists of 3 cords in 3D space - x,y,z

Next, you need to think in triangles. Opengl es (OGLES) draws everything in triangles, i.e. if you wanna draw a triangle you need to draw 3 vertices and if you want to draw a square you need to draw 2 right triangles or 6 vertices.

Example: you want to draw a flat (2D) equilateral triangle:
You must define 3 vertices (omitting z in this example): (1,0) (0,1) (-1,0)
Note: they must be defined in counter-clockwise order (for this example - will explain later)

Example: square: (1,0) (0,1) (-1,0) (-1, 0) (0, -1) (1, 0)

In OGLES vertices are used to make more complex objects. Polygons are build out of these points, and objects are built out of multiple polygons. The only polygons OGLES supports are triangles.

Triangles & Lines

OGLES can draw only basic shapes: triangles or lines.

A triangle is 3 vertices and a line is 2 vertices.

OGL draws triangles in a counter-clockwise direction - this is called winding. It just means the order the vertices are drawn matters. If you draw in a clockwise manner it will be considered not facing the viewer.

Next we will learn about how OGLES takes these vertices and draws them to the screen. Then we’ll talk about 3D space and how OGLES handles objects in the virtual world.

Simple Drawing

Every OGLES instance implements a draw function which is called as fast as the computer can run - or the frame rate. Now we must understand a few OGLES functions to continue:

Consider this example pseudo code:

const GLfloat triangle_vertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f };

void renderFrame() 
{
    glClearColor(grey, grey, grey, 1.0f);
    glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glUseProgram(gProgram);

    glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangle_vertices);
    glEnableVertexAttribArray(gvPositionHandle);

    glDrawArrays(GL_TRIANGLES, 0, 3);
}

First we define 3 vertices (9 points) in 3D space.
Then we call glLoadIdentity which resets 3D space orientation
gluseProgram setup up our shader program (will explain later)
Then glVertexAttribPointer has to dwith shaders (will explain later)
Then glClearColor which sets the background to light grey.
glClear erases anything that was drawn last frame
glVertexPointer function tells OGL how many points define a vertex (e.g. 2 or 3)

3D Space

Now that we are more acquainted w/ flatland let’s learn to manipulate objects in 3D. At this point you should understand the basics of drawing shapes in OGLES, such as vertices and how polygons are made of vertices and how any object is made of polygons. You should also be able to draw a simple triangle on the handset.

Consider the triangle from the previous examples. We want to be able to view this triangle from different angles, move it, scale it and rotate it. We need a way to translate the 3D world onto the 2D screen. This is accomplished though matrix transformations.

Matrix Transformations

Consider a normalized vector for the X axis 1,0,0, Y axis: 0,1,0 and Z axis: 0,0,1. Now if you put these matrices together:

1,0,0
0,1,0
0,0,1

Volvia! An identity matrix. Consider this the initial view of the camera in 3D space.

Now to lets do some matrix math to rotate the object around the z axis a degrees. To do this the X value of the X-axis vector and the Y value of the Y-axis vector need to be adjusted by the cosine of the rotation angle:

cos(a),  sin(a),  0
-sin(a), cos(-a), 0
0,       0,       1

Now, if you take every vertex in every object in your world and multiply them by this matrix, you get the new location of the vertex in the rotated world. Once you’ve applied this matrix to every vertex in your object, you have an object that has been rotated along the Z-axis by a degrees.

OpenGL ES maintains two separate matrices, both are 4x4 matrices of GLfloats. One of these matrices, called the modelview matrix is the one you’ll be interacting with most of the time. This is the one that you use to apply transformations to the virtual world. To rotate, translate, or scale objects in your virtual world, you do it by making changes to the model view matrix.

The other matrix is used in creating the two-dimensional representation of the world based on the viewport you set up. This second matrix is called the projection matrix. The vast majority of the time, you won’t touch the projection matrix.

Only one of these two matrices is active at a time, and all matrix-related calls, including those to glLoadIdentity(), glRotatef(), glTranslatef(), and glScalef() affect the active matrix. When you call glLoadIdentity, you set the active matrix to the identity matrix. When you call the other three, OpenGL ES creates an appropriate translate, scale, or rotate matrix and multiplies the active matrix by that matrix, replacing the results of the active matrix with the result of the matrix multiplication operation.

Shaders

At this point all our transforms are done and we have a model view projection matrix (mvp). We have not yet applied this to out model. To move/scale/rotate our model we must use a shader. This is a little program written in shader language (similar to C) which is executed on the graphics card. A vertex shader will take our mvp matrix and apply it to every vertex in our model and thus effectively moving it. See example:

attribute vec4 vertexPosition;
uniform mat4 modelViewProjectionMatrix;

void main()
{
   gl_Position = modelViewProjectionMatrix * vertexPosition;
}

Summary

So, in summary. You have a model view matrix which represents the orientation of the camera. You have the model matrix which is your 3D model. You have 3 transforms: translate (move x,y, z), rotate and scale. After you multiply the model view matrix by the transforms you choose you have the model view projection matrix. You pass the mvp matrix to the vertex shader, which multiples the mvp matrix by every vertex in the model. This is passed to the display.

Where do I go from here?

Permalink: getting-started-w-opengl-es-android

Tags: android, programming, opengl

Last edited by Alex Egg, 2016-10-05 19:09:15
View Revision History