zoukankan      html  css  js  c++  java
  • Android OpenGL ES(十一)绘制一个20面体 .

    前面介绍了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[]{
     0,4,1, 0,9,4, 9,5,4, 4,5,8, 4,8,1,
     8,10,1, 8,3,10, 5,3,8, 5,2,3, 2,7,3,
     7,10,3, 7,6,10, 7,11,6, 11,0,6, 0,1,6,
     6,1,10, 9,0,11, 9,11,2, 9,2,5, 7,2,11 };

     

    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 * 4);
    vbb.order(ByteOrder.nativeOrder());
    vertexBuffer = vbb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);
     
    ByteBuffer cbb
    = ByteBuffer.allocateDirect(colors.length * 4);
    cbb.order(ByteOrder.nativeOrder());
    colorBuffer = cbb.asFloatBuffer();
    colorBuffer.put(colors);
    colorBuffer.position(0);
     
    ByteBuffer ibb
    = ByteBuffer.allocateDirect(indices.length * 2);
    ibb.order(ByteOrder.nativeOrder());
    indexBuffer = ibb.asShortBuffer();
    indexBuffer.put(indices);
    indexBuffer.position(0);

    看一看DrawScene代码:

    public void DrawScene(GL10 gl) {
     super.DrawScene(gl);
     
     gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
     gl.glLoadIdentity();
     gl.glTranslatef(0, 0, -4);
     gl.glRotatef(angle, 0, 1, 0);
     
     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, vertexBuffer);
     
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
     
     gl.glColorPointer(4, GL10.GL_FLOAT, 0, 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[]{
         0,4,1, 0,9,4, 9,5,4, 4,5,8, 4,8,1,
         8,10,1, 8,3,10, 5,3,8, 5,2,3, 2,7,3,
         7,10,3, 7,6,10, 7,11,6, 11,0,6, 0,1,6,
         6,1,10, 9,0,11, 9,11,2, 9,2,5, 7,2,11 };
        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 * 4);
                vbb.order(ByteOrder.nativeOrder());
                vertexBuffer = vbb.asFloatBuffer();
                vertexBuffer.put(vertices);
                vertexBuffer.position(0);
                 
                ByteBuffer cbb
                = ByteBuffer.allocateDirect(colors.length * 4);
                cbb.order(ByteOrder.nativeOrder());
                colorBuffer = cbb.asFloatBuffer();
                colorBuffer.put(colors);
                colorBuffer.position(0);
                 
                ByteBuffer ibb
                = ByteBuffer.allocateDirect(indices.length * 2);
                ibb.order(ByteOrder.nativeOrder());
                indexBuffer = ibb.asShortBuffer();
                indexBuffer.put(indices);
                indexBuffer.position(0);
                
                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(0, 0, -4);
                 
                float angle=0;
                gl.glRotatef(angle, 0, 1, 0);
                 
                 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, vertexBuffer);
                 
                 gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
                 
                 gl.glColorPointer(4, GL10.GL_FLOAT, 0, 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();
            }
         
            
         
        }

    其他类似。

     

  • 相关阅读:
    java中split()特殊符号"." "|" "*" "" "]"
    AJAX传递数组
    d3.js+svg的树形图
    d3.js之树形折叠树
    echarts之bootstrap选项卡不能显示其他标签echarts图表
    mysql 将时间戳与日期时间的转换
    ztree使用
    EL表达式之sessionScope
    struts2配置文件中的method={1}详解
    XML创建与解析常用方法介绍
  • 原文地址:https://www.cnblogs.com/Anita9002/p/4452612.html
Copyright © 2011-2022 走看看