Android opengl es创建动画详解
OpenGL(全写Open Graphics Library)是一个跨语言、跨平台的三维图象编程接口,同样他也可以用来创建二维图像。OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。android 平台上同样集成了opengl es的开发包,opengl es在android平台上的运用,既有利于充分利用android平台不断进步的硬件配置,也能为用户提供更加多姿多彩的视觉体验。android平台创建三维动画有二种方式,一种是使用matrix三维变形实现伪3D,一种就是使用opengl创建真3D。使用matrix三维变形,方法简单,速度快,效率高,但因为其是伪3D,所以抛开视觉感受不谈,其缺陷也非常明显,他没有真正的3D建模,只是对二维的VIEW做3D移动,大小变换和旋转等操作,当你需要创建一个旋转的六面体时,你需要创建六个VIEW,并让他们实现绕一个虚拟的轴做同步旋转,当这个3D模型有足够多的面时,其复杂度大大增加了,因为在初始化时需要提前计算每个面的初始位置信息,旋转,大小,位移的同步信息,这对于非矩形的view来说,这种计算相当繁琐而且易于出错并且不容易精确,而且目前来看,使用伪3D技术构建规则曲面似乎是难以实现。这时opengl es的优势相当明显。你可以创建任意形状的多面体,只要把VIEW转为BITMAP为多面体贴图就行了。
android使用opengl ES创建立方体,需要用到下面一些函数。
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
void glFrontFace(GLenum mode);
作用是控制多面形的正面是如何决定的。在默认情况下,mode是GL_CCW。一个多边形有两个面,每个面使用不同的介质贴图,旋转时是可以看到
mode的值为:
GL_CCW 表示窗口坐标上投影多边形的顶点顺序为逆时针方向的表面为正面。
GL_CW 表示顶点顺序为顺时针方向的表面为正面。
void glVertexPointer(GLint size,
GLenum type,
GLsizei stride,
const GLvoid * pointer)
作用是指定多面体每个顶点的坐标, size:指定了每个顶点对应的坐标个数,只能是2,3,4中的一个,默认值是4
type:指定了数组中每个顶点坐标的数据类型,可取常量:GL_BYTE, GL_SHORT,GL_FIXED,GL_FLOAT;
stride:指定了连续顶点间的字节排列方式,如果为0,数组中的顶点就会被认为是按照紧凑方式排列的,默认值为0
pointer:制订了数组中第一个顶点的首地址,默认值为0,对于我们的android,大家可以不用去管什么地址的,一般给一个IntBuffer就可以了。
需要说明的是第二个参数,一般在android中,会使用 GL10.GL_FIXED和GL10. FLOAT, 整型和浮点型相互对应, 0x10000=1.0f,整型的低八位表示浮点的小数,高八位表示浮点小数部分。而且第四个参数必须是 nativeOrder,如果是直接赋值的数组,需要使用下面代码转化
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
gl.glColorPointer
这个是颜色了,和上一个函数一样,是指定每个顶点的颜色值,参数结构也类似
gl.glDrawElements
这个是用来显示的,六面体六个面,有12个三角形,每个三角形三个顶点,共36个
这样就可以得到下面的四面体的类:
package com.example.openglactivity;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
public class Cube {
private IntBuffer mVertexBuffer;
private IntBuffer mColorBuffer;
private ByteBuffer mIndexBuffer;
// 定义本程序所使用的纹理
private int texture;
public Cube()
{
int one = 0x10000; //int 10000=1.0f
int vertices[] = {
-one, -one, -2000,//-one, //第三象限
one, -one, -2000,//-one, //第四象限
one, one, -2000,//-one, //第一象限
-one, one, -2000,//-one, //第二象限
-one, -one, 0, //one, //第三象限
one, -one, 0, //one, //第四象限
one, one, 0, //one, //第一象限
-one, one, 0, //one, //第二象限
};
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,
};
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
};
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer = vbb.asIntBuffer();
补充:移动开发 , Android ,