OpenGlES,终于能把这东西画出来
其实两种方法都是画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); }