What is this: This tutorial shows how to create colored 3D Objects using the OpenGL® ES cross-platform API.
What you learn: You will learn how easy it is, to create a Colored 3D Cube, using OpenGL® ES.
Difficulty: 1.5 of 5

What it will look like:

Introduction:
Lets quote wikipedia first:
OpenGL ES (OpenGL for Embedded Systems) is a subset of the OpenGL 3D graphics API designed for embedded devices such as mobile phones, PDAs, and video game consoles. It is defined and promoted by the Khronos Group, a graphics hardware and software industry consortium interested in open APIs for graphics and multimedia.
Description:
What we will do is, create a custom view and using OpenGL ES in it to draw a colored cube.
The Main steps are:
- 1. Setup the view and create a cube
(1.1. Start/Stop the animation if we are (not) viewing it)
2. Do some trigonometry (rotation)
3. Make the Cube paint itself
Most interesting:
What the heck do those values in the Cube-Constructor mean...
Using java Syntax Highlighting
- int one = 0x10000;
- /* Every vertex got 3 values, for
- * x / y / z position in the kartesian space.
- */
- int vertices[] = {
- -one, -one, -one, // Vertex Zero
- one, -one, -one, // Vertex Two
- one, one, -one, // Vertex ...
- -one, one, -one,
- -one, -one, one,
- one, -one, one,
- one, one, one,
- -one, one, one, // Vertex Seven
- };
Parsed in 0.032 seconds, using GeSHi 1.0.8.4
That is pretty easy, each row stands for a single vertex, consisting of three values (x,y,z) which simply result in a point in the cartesian space.
So if you think of each codeline as one vertex you get something like this:
(Note: We only created the vertices, not the edges. I just added them, that the cube-structure becomes better visible.)
(Note2: You will see that the blue coordinate-system is located right in the middle of the cube)

Using java Syntax Highlighting
- /* Every vertex has got its own color, described by 4 values
- * R(ed)
- * G(green)
- * B(blue)
- * A(lpha) <-- Opticacy
- */
- int colors[] = {
- 0, 0, 0, one,
- one, 0, 0, one,
- one, one, 0, one,
- 0, one, 0, one,
- 0, 0, one, one,
- one, 0, one, one,
- one, one, one, one,
- 0, one, one, one,
- };
Parsed in 0.031 seconds, using GeSHi 1.0.8.4
In this code-block the color of all the 8 vertices are described, as '4' each: R(ed) G(reen) B(lue) A(lpha). (Alpha means Opticacy)
OpenGL SE will create the color-flows automatically!
Using java Syntax Highlighting
- /* The last thing is that we need to describe some Triangles.
- * A triangle got 3 vertices.
- * The confusing thing is, that it is important in which order
- * the vertices of each triangle are described.
- * So describing a triangle through the vertices: "0, 4, 5"
- * will not result in the same triangle as: "0, 5, 4"
- * You probably ask: Why the hell isn't that the same ???
- * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
- * which means, that we have to describe the "visible" side of the
- * triangles by naming its vertices in a ClockWise order!
- * From the other side, the triangle will be 100% lookthru!
- * You can create a kind of magic mirror with that <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" />.
- */
- byte indices[] = {
- 0, 4, 5,
- 0, 5, 1,
- 1, 5, 6,
- 1, 6, 2,
- 2, 6, 7,
- 2, 7, 3,
- 3, 7, 4,
- 3, 4, 0,
- 4, 7, 6,
- 4, 6, 5,
- 3, 0, 1,
- 3, 1, 2
- };
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
This is the tricky part. I think that I described it good enough in them comment.
Lets take a look at two example triangles:

The Code
Original Source:
code.google.com
Modified by: Nicolas 'plusminus' Gramlich
Using java Syntax Highlighting
- /*
- * Copyright (C) 2007 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.google.android.samples.graphics;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.OpenGLContext;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.os.SystemClock;
- import android.view.View;
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.IntBuffer;
- import javax.microedition.khronos.opengles.GL10;
- /**
- * Example of how to use OpenGL|ES in a custom view
- *
- */
- public class GLView1 extends Activity {
- @Override
- protected void onCreate(Bundle icicle)
- {
- super.onCreate(icicle);
- setContentView(new GLView( getApplication() ));
- }
- @Override
- protected void onResume()
- {
- super.onResume();
- //android.os.Debug.startMethodTracing("/tmp/trace/GLView1.dmtrace",
- // 8 * 1024 * 1024);
- }
- @Override
- protected void onStop()
- {
- super.onStop();
- //android.os.Debug.stopMethodTracing();
- }
- }
- class GLView extends View
- {
- /**
- * The View constructor is a good place to allocate our OpenGL context
- */
- public GLView(Context context)
- {
- super(context);
- /*
- * Create an OpenGL|ES context. This must be done only once, an
- * OpenGL contex is a somewhat heavy object.
- */
- mGLContext = new OpenGLContext(0);
- mCube = new Cube();
- mAnimate = false;
- }
- /*
- * Start the animation only once we're attached to a window
- * @see android.view.View#onAttachedToWindow()
- */
- @Override
- protected void onAttachedToWindow() {
- mAnimate = true;
- Message msg = mHandler.obtainMessage(INVALIDATE);
- mNextTime = SystemClock.uptimeMillis();
- mHandler.sendMessageAtTime(msg, mNextTime);
- super.onAttachedToWindow();
- }
- /*
- * Make sure to stop the animation when we're no longer on screen,
- * failing to do so will cause most of the view hierarchy to be
- * leaked until the current process dies.
- * @see android.view.View#onDetachedFromWindow()
- */
- @Override
- protected void onDetachedFromWindow() {
- mAnimate = false;
- super.onDetachedFromWindow();
- }
- /**
- * Draw the view content
- *
- * @see android.view.View#onDraw(android.graphics.Canvas)
- */
- @Override
- protected void onDraw(Canvas canvas) {
- if (true) {
- /*
- * First, we need to get to the appropriate GL interface.
- * This is simply done by casting the GL context to either
- * GL10 or GL11.
- */
- GL10 gl = (GL10)(mGLContext.getGL());
- /*
- * Before we can issue GL commands, we need to make sure all
- * native drawing commands are completed. Simply call
- * waitNative() to accomplish this. Once this is done, no native
- * calls should be issued.
- */
- mGLContext.waitNative(canvas, this);
- int w = getWidth();
- int h = getHeight();
- /*
- * Set the viewport. This doesn't have to be done each time
- * draw() is called. Typically this is called when the view
- * is resized.
- */
- gl.glViewport(0, 0, w, h);
- /*
- * Set our projection matrix. This doesn't have to be done
- * each time we draw, but usualy a new projection needs to be set
- * when the viewport is resized.
- */
- float ratio = (float)w / h;
- gl.glMatrixMode(gl.GL_PROJECTION);
- gl.glLoadIdentity();
- gl.glFrustumf(-ratio, ratio, -1, 1, 2, 12);
- /*
- * dithering is enabled by default in OpenGL, unfortunattely
- * it has a significant impact on performace in software
- * implementation. Often, it's better to just turn it off.
- */
- gl.glDisable(gl.GL_DITHER);
- /*
- * Usually, the first thing one might want to do is to clear
- * the screen. The most efficient way of doing this is to use
- * glClear(). However we must make sure to set the scissor
- * correctly first. The scissor is always specified in window
- * coordinates:
- */
- gl.glClearColor(1,1,1,1);
- gl.glEnable(gl.GL_SCISSOR_TEST);
- gl.glScissor(0, 0, w, h);
- gl.glClear(gl.GL_COLOR_BUFFER_BIT);
- /*
- * Now we're ready to draw some 3D object
- */
- gl.glMatrixMode(gl.GL_MODELVIEW);
- gl.glLoadIdentity();
- gl.glTranslatef(0, 0, -3.0f);
- gl.glScalef(0.5f, 0.5f, 0.5f);
- gl.glRotatef(mAngle, 0, 1, 0);
- gl.glRotatef(mAngle*0.25f, 1, 0, 0);
- gl.glColor4f(0.7f, 0.7f, 0.7f, 1.0f);
- gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
- gl.glEnableClientState(gl.GL_COLOR_ARRAY);
- gl.glEnable(gl.GL_CULL_FACE);
- mCube.draw(gl);
- mAngle += 1.2f;
- /*
- * Once we're done with GL, we need to flush all GL commands and
- * make sure they complete before we can issue more native
- * drawing commands. This is done by calling waitGL().
- */
- mGLContext.waitGL();
- }
- }
- // ------------------------------------------------------------------------
- private static final int INVALIDATE = 1;
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- if (mAnimate && msg.what == INVALIDATE) {
- invalidate();
- msg = obtainMessage(INVALIDATE);
- long current = SystemClock.uptimeMillis();
- if (mNextTime < current) {
- mNextTime = current + 20;
- }
- sendMessageAtTime(msg, mNextTime);
- mNextTime += 20;
- }
- }
- };
- private OpenGLContext mGLContext;
- private Cube mCube;
- private float mAngle;
- private long mNextTime;
- private boolean mAnimate;
- }
- class Cube
- {
- public Cube()
- {
- int one = 0x10000;
- /* Every vertex got 3 values, for
- * x / y / z position in the kartesian space.
- */
- int vertices[] = {
- -one, -one, -one,
- one, -one, -one,
- one, one, -one,
- -one, one, -one,
- -one, -one, one,
- one, -one, one,
- one, one, one,
- -one, one, one,
- };
- /* Every vertex has got its own color, described by 4 values
- * R(ed)
- * G(green)
- * B(blue)
- * A(lpha) <-- Opticacy
- */
- int colors[] = {
- 0, 0, 0, one,
- one, 0, 0, one,
- one, one, 0, one,
- 0, one, 0, one,
- 0, 0, one, one,
- one, 0, one, one,
- one, one, one, one,
- 0, one, one, one,
- };
- /* The last thing is that we need to describe some Triangles.
- * A triangle got 3 vertices.
- * The confusing thing is, that it is important in which order
- * the vertices of each triangle are described.
- * So describing a triangle through the vertices: "0, 4, 5"
- * will not result in the same triangle as: "0, 5, 4"
- * You probably ask: Why the hell isn't that the same ???
- * The reason for that is the call of: "gl.glFrontFace(gl.GL_CW);"
- * which means, that we have to describe the "visible" side of the
- * triangles by naming its vertices in a ClockWise order!
- * From the other side, the triangle will be 100% lookthru!
- * You can create a kind of magic mirror with that <img src="http://www.anddev.org/images/smilies/wink.png" alt=";)" title="Wink" />.
- */
- byte indices[] = {
- 0, 4, 5,
- 0, 5, 1,
- 1, 5, 6,
- 1, 6, 2,
- 2, 6, 7,
- 2, 7, 3,
- 3, 7, 4,
- 3, 4, 0,
- 4, 7, 6,
- 4, 6, 5,
- 3, 0, 1,
- 3, 1, 2
- };
- // Buffers to be passed to gl*Pointer() functions
- // must be direct, i.e., they must be placed on the
- // native heap where the garbage collector cannot
- // move them.
- //
- // Buffers with multi-byte datatypes (e.g., short, int, float)
- // must have their byte order set to native order
- ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
- vbb.order(ByteOrder.nativeOrder());
- mVertexBuffer = vbb.asIntBuffer();
- mVertexBuffer.put(vertices);
- mVertexBuffer.position(0);
- ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
- cbb.order(ByteOrder.nativeOrder());
- mColorBuffer = cbb.asIntBuffer();
- mColorBuffer.put(colors);
- mColorBuffer.position(0);
- mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
- mIndexBuffer.put(indices);
- mIndexBuffer.position(0);
- }
- public void draw(GL10 gl)
- {
- gl.glFrontFace(gl.GL_CW);
- gl.glVertexPointer(3, gl.GL_FIXED, 0, mVertexBuffer);
- gl.glColorPointer(4, gl.GL_FIXED, 0, mColorBuffer);
- gl.glDrawElements(gl.GL_TRIANGLES, 36, gl.GL_UNSIGNED_BYTE, mIndexBuffer);
- }
- private IntBuffer mVertexBuffer;
- private IntBuffer mColorBuffer;
- private ByteBuffer mIndexBuffer;
- }
Parsed in 0.063 seconds, using GeSHi 1.0.8.4
I hope you succeeded and understood this tutorial.
Please vote and/or leave a comment
.See you soon




even worse I assume.



