Updated to be Android 2.0.1 compatible.
The first part of this series will give you a short introduction to the OpenGL terminology and the first step in your 3D programming.
The series itself will be about a 3D game called Vortex.
The tutorial will focus on 3D programming, stuff like menu or life cycle may be part of the code but will not be introduced.
Lets start with the terminology of OpenGL.
Vertex
A vertex is a point in 3D space and is the building block for many objects. In OpenGL you can specify as few as two coordinates (X,Y) and as many as four (X,Y,Z,W). The w-axis is optional, the default value is set to 1.0. The z-axis is also optional, the default value is set to 0. In this series, we will use the three main coordinates X, Y, and Z, since the W is generally used as a placeholder. The plural of vertex is vertices (mainly important for non native speakers, because it may create confusion). All objects are drawn using vertices as their points, so a point will refer to a vertex.
Triangle
A triangle requires three points to be created. So in OpenGL, we use three vertices to create one.
Polygon
A polygon is an object which has at least three connected points. Therefor a triangle is also a polygon.
Primitives
A primitive is a simple shape, like a line, point, or polygon (including a triangle, obviously). A model with 50,000 vertices is just a model, whether it’s a primitive or not depends on whether it’s a single polygon or is composed of many polygons. (Thanks to nil for clarification)
Now we can start with the programming.
We create a new project called Vortex, our activity will be named so, too.
Our activity will look familiar:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package com.droidnova.android.games.vortex; import android.app.Activity; import android.os.Bundle; public class Vortex extends Activity { private static final String LOG_TAG = Vortex.class.getSimpleName(); private VortexView _vortexView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); _vortexView = new VortexView(this); setContentView(_vortexView); } } |
As you see, we already added our own view. Lets take a look right on our VortexView class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package com.droidnova.android.games.vortex; import android.content.Context; import android.opengl.GLSurfaceView; public class VortexView extends GLSurfaceView { private static final String LOG_TAG = VortexView.class.getSimpleName(); private VortexRenderer _renderer; public VortexView(Context context) { super(context); _renderer = new VortexRenderer(); setRenderer(_renderer); } } |
As you see, we inherit GLSurfaceView because it will help us manage the drawing. The next thing you should see is our VortexRenderer class.
A renderer has the task to perform anything thats needed to draw a frame. Quote from references:
The renderer is responsible for making OpenGL calls to render a frame.
So lets take a look at this class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package com.droidnova.android.games.vortex; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView; public class VortexRenderer implements GLSurfaceView.Renderer { private static final String LOG_TAG = VortexRenderer.class.getSimpleName(); private float _red = 0.9f; private float _green = 0.2f; private float _blue = 0.2f; @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // Do nothing special. } @Override public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } @Override public void onDrawFrame(GL10 gl) { // define the color we want to be displayed as the "clipping wall" gl.glClearColor(_red, _green, _blue, 1.0f); // clear the color buffer to show the ClearColor we called above... gl.glClear(GL10.GL_COLOR_BUFFER_BIT); } } |
Ok what do we have here?
First we implemented the interface GLSurfaceView.Renderer which forces us to implement 3 methods calles onSurfaceCreated(), onSurfaceChanged() and onDrawFrame().
These methods are easily to understand, the first one is called after the surface was created, the second if the surface changed, e.g. you switch from portrait to landscape and the last one anytime a drawing is requested.
From line 11 to 13 we have floats defining each color of the RGB color system.
On line 28 we define the the color of our “clipping wall” with the method glClearColor(). The “clipping wall” covers everything that is behind the distance we can see, so every object behind this “wall” is invisible. Imagine the wall as something like fog. Later we will set the distance to show how it works. At the moment it is absolutely sufficient that you know it exists.
To make our color changes visible, we have to call glClear() with the mask for the color buffer to clear the buffer and use the new color for our “clipping wall”.
To see that it is working, we will create a response to a MotionEvent which changes the color we set.
First lets create a set for the color in our VortexRenderer class:
1 2 3 4 5 | public void setColor(float r, float g, float b) { _red = r; _green = g; _blue = b; } |
Now the method in our VortexView class to handle the MotionEvent:
1 2 3 4 5 6 7 8 | public boolean onTouchEvent(final MotionEvent event) { queueEvent(new Runnable() { public void run() { _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); } }); return true; } |
We create a new anonymous object of Runnable where the run() method call the setColor() method of the renderer with a bit of calculation depending on the MotionEvent coordinates.
We now have a little app which uses OpenGL to change the background color ![]()
In Germany we say in this case “Mit Kanonen auf Spatzen schießen”, you would say “He breaks a fly on the wheel.”. Thats absolute correct but it is the minimalistic example of working with OpenGL and you are now prepared for more!
The last hint in this part is a documentation for OpenGL. The usability is nonexistent but at least it is a documentation.
Sources as Eclipse project: Vortex Part I



Comments
Leave a comment Trackback