实现功能:点击屏幕背景颜色变化的同时三角形旋转。
package org.jun.opengl01; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.ShortBuffer; 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; public void onSurfaceCreated(GL10 gl, EGLConfig config) { // preparation gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); initTriangle(); } public void onSurfaceChanged(GL10 gl, int w, int h) { gl.glViewport(0, 0, w, h); } 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); // set rotation gl.glRotatef(_angle, 0f, 1f, 0f); // set the color of our element gl.glColor4f(0.5f, 0f, 0f, 0.5f);//设置三角形为暗红色 // define the vertices we want to draw //第一个参数是大小,也是顶点的维数。我们使用的是x,y,z三维坐标。 //第二个参数,GL_FLOAT定义buffer中使用的数据类型。 //第三个变量是0,是因为我们的坐标是在数组中紧凑的排列的,没有使用offset。 //第四个参数顶点缓冲 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer); // finally draw the vertices //将所有这些元素画出来 //第一个参数定义了什么样的图元将被画出来。 //第二个参数定义有多少个元素, //第三个是indices使用的数据类型。 //最后一个是绘制顶点使用的索引缓冲。 //当最后测试这个应用的使用,你会看到一个在屏幕中间静止的三角形。 //当你点击屏幕的时候,屏幕的背景颜色还是会改变。 gl.glDrawElements(GL10.GL_TRIANGLES, _nrOfVertices, GL10.GL_UNSIGNED_SHORT, _indexBuffer); } public void setColor(float r, float g, float b) { _red = r; _green = g; _blue = b; } /* * 初始化需要显示的三角形 */ // new object variables we need // a raw buffer to hold indices private ShortBuffer _indexBuffer; // a raw buffer to hold the vertices private FloatBuffer _vertexBuffer; private short[] _indicesArray = { 0, 1, 2 }; private int _nrOfVertices = 3; /* * 让我们从新的对象变量开始. _ * vertexBuffer为我们的三角形保存坐标. * _indexBuffer保存索引. * _nrOfVertices变量定义需要多少个顶点.对于一个三角形来说,一共需要三个顶点. * 这个方法首先为这里两个buffer分配必须的内存. * 接下来我们定义一些坐标 后面的注释对用途给予了说明. * 我们将coords数组填充给_vertexBuffer * 同样将indices数组填充给_indexBuffer * 最后将两个buffer都设置position为0 * 为了防止每次都对三角形进行初始化,我们仅仅在onDrawFrame()之前的行数调用它一次。 * 一个比较好的选择就是在onSurfaceCreated()函数中 */ // code snipped private void initTriangle() { // float has 4 bytes ByteBuffer vbb = ByteBuffer.allocateDirect(_nrOfVertices * 3 * 4); vbb.order(ByteOrder.nativeOrder()); _vertexBuffer = vbb.asFloatBuffer(); // short has 2 bytes ByteBuffer ibb = ByteBuffer.allocateDirect(_nrOfVertices * 2); ibb.order(ByteOrder.nativeOrder()); _indexBuffer = ibb.asShortBuffer(); float[] coords = { -0.5f, -0.5f, 0f, // (x1, y1, z1) 0.5f, -0.5f, 0f, // (x2, y2, z2) 0f, 0.5f, 0f // (x3, y3, z3) }; _vertexBuffer.put(coords); _indexBuffer.put(_indicesArray); _vertexBuffer.position(0); _indexBuffer.position(0); } private float _angle; public void setAngle(float angle) { _angle = angle; } }
package org.jun.opengl01; import android.content.Context; import android.opengl.GLSurfaceView; import android.view.MotionEvent; 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); } public boolean onTouchEvent(final MotionEvent event) { queueEvent(new Runnable() { public void run() { _renderer.setColor(event.getX() / getWidth(), event.getY() / getHeight(), 1.0f); _renderer.setAngle(event.getX() / 10); } }); return true; } }
package org.jun.opengl01; import android.app.Activity; import android.os.Bundle; public class Vortex extends Activity { /** Called when the activity is first created. */ 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); } }
运行效果