OpenGlES这东西真TM蛋疼,研究了几天了,终于能把这东西画出来,新手学开发就是不容易阿
其实两种方法都是画12个三角形画出来的,在OpenGL ES中,只支持三角形,所以任何复杂多边形都是由三角形画出来的。
第一种:顶点法
:
把一个四边形当成一个面,而一个面由两个三角形组成。一个三角形是不是有3个顶点?,所以一个面就有了3+3个顶点,一个立方体有6个面,6*6个顶点
此立方体的颜色也是根据顶点所渲染,正如定义这个立方体的顶点一样,不过它的参数可不是和定义顶点的一样哦,它的参数类型是:R,G,B,A,代表的是颜色值
public class OpenGlEsDemoActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GLSurfaceView glview = new GLSurfaceView(this);
glview.setRenderer(new OpenGlRender());
setContentView(glview);
}
}
public class OpenGlRender implements GLSurfaceView.Renderer{
//每一个面画两个三角形,立方体有6个面
private float[] vertices={
-1.0f,1.0f,1f, // top left
-1.0f,-1.0f,1f, // bottom left
1.0f,-1.0f,1f, //top right
-1.0f,1.0f,1f, //bottom left
1.0f,-1.0f,1f, //bottom right
1.0f,1.0f,1f, //top right //前面
1.0f,1.0f,1f,
1.0f,-1.0f,1f,
1.0f,-1.0f,-1f,
1.0f,1.0f,1f,
1.0f,-1.0f,-1.0f,
1.0f,1.0f,-1f, //右面
-1.0f,1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,1.0f,1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
-1.0f,1.0f,1.0f, //左面
1.0f,1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,1.0f,-1.0f, //后面
-1.0f,1.0f,-1.0f, // top left
-1.0f,1.0f,1.0f, //bottom left
1.0f,1.0f,-1.0f, //top right
-1.0f,1.0f,1.0f, //bottom left
1.0f,1.0f,1.0f, //top right
1.0f,1.0f,-1.0f, // -top right上面
-1.0f,-1.0f,1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,1.0f,
1.0f,-1.0f,-1.0f,
1.0f,-1.0f,1.0f, //下面
};
//立方体的顶点颜色
private float[] colors={
1f,0f,0f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f,
1f,0f,0f,1f,
1f,0f,1f,1f,
1f,0f,1f,1f,
1f,0f,1f,1f,
1f,0f,1f,1f,
1f,0f,1f,1f,
1f,0f,1f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0.5f,0f,1f,1f,
0.5f,0f,1f,1f,
0.5f,0f,1f,1f,
0.5f,0f,1f,1f,
0.5f,0f,1f,1f,
0.5f,0f,1f,1f,
1f,0f,0.5f,1f,
1f,0f,0.5f,1f,
1f,0f,0.5f,1f,
1f,0f,0.5f,1f,
1f,0f,0.5f,1f,
1f,0f,0.5f,1f,
};
FloatBuffer vertBuffer; //顶点缓冲
FloatBuffer colorBuffer; //颜色缓冲
float rx=-70f; //旋转角度
public OpenGlRender(){
ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
vertBuffer=vbb.asFloatBuffer();
vertBuffer.put(vertices);
vertBuffer.position(0);
ByteBuffer cbb= ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所做深度测试的类型
gl.glDepthFunc(GL10.GL_DITHER);
//黑色背景
gl.glClearColor(0f, 0f, 0f, 0.5f);
//启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//清除深度缓存
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_TEXTURE_2D);
//告诉系统对透视进行修正
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
}
public void draw(GL10 gl){
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
//开启顶点和纹理缓冲
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuffer);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -5);
gl.glRotatef(45f, 0f, 1f, 0f); //往右边(y轴)倾斜45度C
gl.glRotatef(rx,1f, 0f, 0f); //往上面倾斜(x轴)倾斜,根据每次得到的角度
gl.glDrawArrays(GL10.GL_TRIANGLES, 0,vertices.length);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
rx--; //旋转角度减1
}
public void onDrawFrame(GL10 gl) {
// 清除深度和颜色缓存
gl.glClearColor(0f, 0f, 0f, 0.5f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW); //设置矩阵模式
draw(gl);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
第二种:索引法
画出来的效果与 上面是一样的,不过它是通过索引所画出来的
还是分成6个面来画,一个面画2个三角形。
-1f,1f,1f, //0
-1f,-1f,1f, //1
1f,-1f,1f, //2
1f,1f,1f, //3
这里画出来的是这个立方体的最前面,对应的还是x,y,z轴。
private short[] indices={
0,1,2,
0,2,3,}
只不过的是在这个indices中指定了它的索引位置,所以它才会乖乖听话把四边形画出来
0是左上角的坐标,1是左下角,2是右下角,3是右上角
public class Demo extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
GLSurfaceView v = new GLSurfaceView(this);
v.setRenderer(new OpenGlRender2(null));
setContentView(v);
}
}
public class OpenGlRender2 implements Renderer{
//顶点坐标x,y,z
private float[] vertices=
{
-1f,1f,1f,
-1f,-1f,1f,
1f,-1f,1f,
1f,1f,1f, //前面
1f,1f,1f,
1f,-1f,1f,
1f,-1f,-1f,
1f,1f,-1f, //右面
1f,1f,-1f,
1f,-1f,-1f,
-1f,-1f,-1f,
-1f,1f,-1f, //后面
-1f,1f,-1f,
-1f,-1f,-1f,
-1f,-1f,1f,
-1f,1f,1f, //左面
-1f,1f,-1f,
-1f,1f,1f,
1f,1f,1f,
1f,1f,-1f, //上面
-1f,-1f,1f,
-1f,-1f,-1f,
1f,-1f,-1f,
1f,-1f,1f, //下面
};
//顶点颜色,R,G,B,A
private float[] colors={
0.2f,0f,0.7f,1f,
0f,0.4f,0.3f,1f,
0.8f,0.1f,0.1f,1f,
1f,1f,1f,1f, //前面
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f,
0f,1f,0f,1f, //后面
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f,
0f,0f,1f,1f, //左面
0.3f,0.5f,1f,1f,
0.3f,0.5f,1f,1f,
0.3f,0.5f,1f,1f,
0.3f,0.5f,1f,1f, //上面
0f,0.2f,0.3f,1f,
0f,0.4f,0.3f,1f,
0f,0.3f,0.3f,1f,
0f,0.4f,0.3f,1f, //下面
};
private short[] indices={
0,1,2,
0,2,3,
4,5,6,
4,6,7,
8,9,10,
8,10,11,
12,13,14,
12,14,15,
16,17,18,
16,18,19,
20,21,22,
20,22,23,
};
private FloatBuffer mVertexBuffer,mColorBuffer;
private ShortBuffer mIndixBuffer;
private float rx=45.0f;
public OpenGlRender2(Bitmap bitmap){
ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
mVertexBuffer=vbb.asFloatBuffer();
mVertexBuffer.put(vertices);
mVertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length*2);
ibb.order(ByteOrder.nativeOrder());
mIndixBuffer=ibb.asShortBuffer();
mIndixBuffer.put(indices);
mIndixBuffer.position(0);
ByteBuffer cbb=ByteBuffer.allocateDirect(colors.length*4);
cbb.order(ByteOrder.nativeOrder());
mColorBuffer=cbb.asFloatBuffer();
mColorBuffer.put(colors);
mColorBuffer.position(0);
}
public void onDrawFrame(GL10 gl) {
gl.glClearColor(0f, 0f, 0f, 0.5f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3,GL10.GL_FLOAT, 0, mVertexBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
gl.glLoadIdentity();
// gl.glColor4f(1f, 0f, 0f, 1f);
gl.glTranslatef(0f, 0f, -5f);
gl.glRotatef(-45f, 0f, 1f, 0f);
gl.glRotatef(rx, 1f, 0f, 0f);
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, mIndixBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
rx++;
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width/(float)height, 0.1f, 100.f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//启用深度测试
gl.glEnable(GL10.GL_DEPTH_TEST);
// 所做深度测试的类型
gl.glDepthFunc(GL10.GL_DITHER);
//黑色背景
gl.glClearColor(1f, 0f, 0f, 1f);
//启用阴影平滑
gl.glShadeModel(GL10.GL_SMOOTH);
//清除深度缓存
gl.glClearDepthf(1.0f);
}