前面介绍了OpenGL ES所有能够绘制的基本图形,点,线段和三角形。其它所有复杂的2D或3D图形都是由这些基本图形构成。

本例介绍如何使用三角形构造一个正20面体。一个正20面体,有12个顶点,20个面,30条边构成:

创建一个DrawIcosahedron Activity, 定义20面体的12个顶点,和20个面如下:

static final float X=.525731112119133606f;
static final float Z=.850650808352039932f; static float vertices[] = new float[]{
-X, 0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z,
0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z, -X,
Z, X, 0.0f, -Z, X, 0.0f, Z, -X, 0.0f, -Z, -X, 0.0f
}; static short indices[] = new short[]{
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,, };

OpenGL ES缺省使用同一种颜色来绘制图形,为了能够更好的显示3D效果,我们为每个顶点随机定义一些颜色如下:

float[] colors = {
0f, 0f, 0f, 1f,
0f, 0f, 1f, 1f,
0f, 1f, 0f, 1f,
0f, 1f, 1f, 1f,
1f, 0f, 0f, 1f,
1f, 0f, 1f, 1f,
1f, 1f, 0f, 1f,
1f, 1f, 1f, 1f,
1f, 0f, 0f, 1f,
0f, 1f, 0f, 1f,
0f, 0f, 1f, 1f,
1f, 0f, 1f, 1f };

将顶点,面,颜色存放到Buffer中以提高性能:

private FloatBuffer vertexBuffer;

private FloatBuffer colorBuffer;

private ShortBuffer indexBuffer;

ByteBuffer vbb
= ByteBuffer.allocateDirect(vertices.length * );
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(); ByteBuffer cbb
= ByteBuffer.allocateDirect(colors.length * );
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(); ByteBuffer ibb
= ByteBuffer.allocateDirect(indices.length * );
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position();

看一看DrawScene代码:

public void DrawScene(GL10 gl) {
super.DrawScene(gl); gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glLoadIdentity();
gl.glTranslatef(, , -);
gl.glRotatef(angle, , , ); gl.glFrontFace(GL10.GL_CCW); gl.glEnable(GL10.GL_CULL_FACE); gl.glCullFace(GL10.GL_BACK); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(, GL10.GL_FLOAT, , vertexBuffer); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(, GL10.GL_FLOAT, , colorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
GL10.GL_UNSIGNED_SHORT, indexBuffer); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisable(GL10.GL_CULL_FACE);
angle++; }

用来绘制20面体使用了gl.glDrawElements:

public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定义顶点的顺序,顶点的顺序由indices Buffer 指定。

本例会显示一个绕Y轴不断旋转的20面体,如何旋转模型将在后面的坐标系统和坐标变换中介绍.

完整代码:

MainActiviy.java

package com.example.gltest;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.Window;
import android.view.WindowManager; public class MainActivity extends Activity
implements IOpenGLDemo{
private FloatBuffer vertexBuffer; private FloatBuffer colorBuffer; private ShortBuffer indexBuffer; private GLSurfaceView mGLSurfaceView; static final float X=.525731112119133606f;
static final float Z=.850650808352039932f; static float vertices[] = new float[]{
-X, 0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z,
0.0f, Z, X, 0.0f, Z, -X, 0.0f, -Z, X, 0.0f, -Z, -X,
Z, X, 0.0f, -Z, X, 0.0f, Z, -X, 0.0f, -Z, -X, 0.0f
}; static short indices[] = new short[]{
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,,,
,,, ,,, ,,, ,,, ,, };
float[] colors = {
0f, 0f, 0f, 1f,
0f, 0f, 1f, 1f,
0f, 1f, 0f, 1f,
0f, 1f, 1f, 1f,
1f, 0f, 0f, 1f,
1f, 0f, 1f, 1f,
1f, 1f, 0f, 1f,
1f, 1f, 1f, 1f,
1f, 0f, 0f, 1f,
0f, 1f, 0f, 1f,
0f, 0f, 1f, 1f,
1f, 0f, 1f, 1f }; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ByteBuffer vbb
= ByteBuffer.allocateDirect(vertices.length * );
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(); ByteBuffer cbb
= ByteBuffer.allocateDirect(colors.length * );
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(); ByteBuffer ibb
= ByteBuffer.allocateDirect(indices.length * );
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(); this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow()
.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN); mGLSurfaceView = new GLSurfaceView(this);
mGLSurfaceView.setRenderer(new OpenGLRenderer(this));
setContentView(mGLSurfaceView);
} // public void DrawScene(GL10 gl) {
// gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
// // Clears the screen and depth buffer.
// gl.glClear(GL10.GL_COLOR_BUFFER_BIT
// | GL10.GL_DEPTH_BUFFER_BIT);
//
// }
public void DrawScene(GL10 gl) {
// super.DrawScene(gl); gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
gl.glLoadIdentity();
gl.glTranslatef(, , -); float angle=;
gl.glRotatef(angle, , , ); gl.glFrontFace(GL10.GL_CCW); gl.glEnable(GL10.GL_CULL_FACE); gl.glCullFace(GL10.GL_BACK); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glVertexPointer(, GL10.GL_FLOAT, , vertexBuffer); gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(, GL10.GL_FLOAT, , colorBuffer); gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,
GL10.GL_UNSIGNED_SHORT, indexBuffer); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisable(GL10.GL_CULL_FACE);
angle++; }
@Override
protected void onResume() {
// Ideally a game should implement
// onResume() and onPause()
// to take appropriate action when the
//activity looses focus
super.onResume();
mGLSurfaceView.onResume();
} @Override
protected void onPause() {
// Ideally a game should implement onResume()
//and onPause()
// to take appropriate action when the
//activity looses focus
super.onPause();
mGLSurfaceView.onPause();
} }

其他类似。

Android OpenGL ES(十一)绘制一个20面体 .的更多相关文章

  1. Android OpenGL ES 开发教程 从入门到精通

    感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...

  2. Android OpenGL ES(七)基本几何图形定义 .

    在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...

  3. Android OpenGL ES(八)绘制点Point ..

    上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...

  4. [置顶] 使用Android OpenGL ES 2.0绘图之五:添加运动

    传送门 ☞ 系统架构设计 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 传送门 ☞ GoF23种设计模式 ☞ 转载请注明 ☞ http://blog.csd ...

  5. Android OpenGL ES(十二):三维坐标系及坐标变换初步 .

    OpenGL ES图形库最终的结果是在二维平面上显示3D物体(常称作模型Model)这是因为目前的打部分显示器还只能显示二维图形.但我们在构造3D模型时必须要有空间现象能力,所有对模型的描述还是使用三 ...

  6. Android OpenGL ES(五)GLSurfaceView .

    Android OpenGL ES 相关的包主要定义在 javax.microedition.khronos.opengles    GL 绘图指令 javax.microedition.khrono ...

  7. Android OpenGL ES(十三)通用的矩阵变换指令 .

    Android OpenGL ES 对于不同坐标系下坐标变换,大都使用矩阵运算的方法来定义和实现的.这里介绍对应指定的坐标系(比如viewmodel, projection或是viewport) An ...

  8. Android OpenGL ES .介绍

    引自:http://blog.csdn.net/hgl868/article/details/6971624 1.    OpenGL ES 简介 Android 3D引擎采用的是OpenGL ES. ...

  9. Android OpenGL ES(六)创建实例应用OpenGLDemos程序框架 .

    有了前面关于Android OpenGL ES的介绍,可以开始创建示例程序OpenGLDemos. 使用Eclipse 创建一个Android项目 Project Name: OpenGLDemos ...

随机推荐

  1. Xcode-App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

    在xcode中上报数据时候,logserver一直没有数据,后来发现控制台有一个提示: 找了半天是因为Xcode7禁止明码的HTTP请求,而自己使用的是Xcode7.2.1 解决办法:修改info.p ...

  2. Testing a Redux & React web application

    Part 1 - https://www.youtube.com/watch?v=iVKPbH3qyW0 Part 2 - https://www.youtube.com/watch?v=M5lwOs ...

  3. 配置nginx为HTTPS服务器

    默认情况下ssl模块并未被安装,如果要使用该模块则需要在编译时指定–with-http_ssl_module参数,安装模块依赖于OpenSSL库和一些引用文件,通常这些文件并不在同一个软件包中.通常这 ...

  4. php字符操作

    //一:定义字符串的方法 //1.双引号 //2.单引号 //3.heredoc语法结构 //heredoc语法定义字符串 $str=<<<TAG 我的武功终成武林盟主TAG;//注 ...

  5. 2.3 DHC REST

    DHC REST也是Chrome浏览器的插件,可以在Chrome应用商店安装下载,主要用来模拟HTTP客户端发送测试数据到服务器.HTTP Get请求在开发中比较常用.

  6. 肢体语言心理学+FBI阅人术(行为心理学) 用最短的时间了解一个人

    肢体语言心理学      如何从站姿判断人 每个人都有自己习惯的站立姿势.美国夏威夷大学心理学家指出,不同的站姿可以显示出一个人的性格特征. 站立时习惯把双手插入裤袋的人:城府较深,不轻易向人表露内心 ...

  7. 模型驱动 ModelDriven

    ModelDriven:模型驱动,对所有action的模型对象进行批处理. 我们在开发中, 在action中一般是用实体对象,然后给实体对象get,set方法. RegAction{ User use ...

  8. 错误: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: PC

    su - root mkdir temp mv /local/ldconfig  apt-get update

  9. 多工段查询存放到DataTable到List<DataTable>集合在C#里面做汇总

    private void btnQuery_Click(object sender, EventArgs e) { if (cboxFactory.Text=="") { Mess ...

  10. forEach用法介绍

    array.forEach(callback[, thisArg]) forEach() 方法让数组的每一项都执行一次给定的函数. callback在数组每一项上执行的函数,接收三个参数: curre ...