OpenGL ES 立方體 還有球體的代碼

立方體實現的代碼
import android.opengl.GLSurfaceView;
import android.opengl.GLU;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class OpenGLRender implements GLSurfaceView.Renderer {
    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, //top lest
            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, -1.0f, //bottom right
            1.0f, 1.0f, -1f,  //top right //右面

            -1.0f, 1.0f, -1.0f, //top lest
            -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, //bottom right
            -1.0f, 1.0f, 1.0f,  //top right //左面

            1.0f, 1.0f, -1.0f, //top lest
            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, //bottom right
            -1.0f, 1.0f, -1.0f,  //top right //後面

            -1.0f, 1.0f, -1.0f, //top lest
            -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, //bottom right
            1.0f, 1.0f, -1.0f,  //-top right //上面

            -1.0f, -1.0f, 1.0f, //top lest
            -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, //bottom right
            1.0f, -1.0f, 1.0f,  //top right //下面
    };
    //立方體的顏色
    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 verBuffer;//頂點緩衝
    FloatBuffer colorBuffer;//顏色緩衝
    float rx = -70f;
    public OpenGLRender(){
        ByteBuffer vbb =ByteBuffer.allocateDirect(vertices.length*4);
        vbb.order(ByteOrder.nativeOrder());
        verBuffer =vbb.asFloatBuffer();
        verBuffer.put(vertices);
        verBuffer.position(0);
        ByteBuffer cbb =ByteBuffer.allocateDirect(colors.length*4);
        cbb.order(ByteOrder.nativeOrder());
        colorBuffer =cbb.asFloatBuffer();
        colorBuffer.put(colors);
        colorBuffer.position(0);
    }
    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
        //啓用深度測試
        gl10.glEnable(GL10.GL_DEPTH_TEST);
        //所做深度測試的類型
        gl10.glDepthFunc(GL10.GL_DITHER);
        //透明背景
        gl10.glClearColor(1.0f,1.0f,1.0f,0.0f);
        //啓用陰影平滑
        gl10.glShadeModel(GL10.GL_SMOOTH);
        //清除深度緩存
        gl10.glClearDepthf(1.0f);

        gl10.glEnable(GL10.GL_TEXTURE_2D);
        //告訴系統對透視進行修正
        gl10.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        gl10.glViewport(0,0,width,height);
        gl10.glMatrixMode(GL10.GL_PROJECTION);
        gl10.glLoadIdentity();
        GLU.gluPerspective(gl10,45.0f,(float)width/(float)height,0.1f,100.f);
        gl10.glMatrixMode(GL10.GL_MODELVIEW);
        gl10.glLoadIdentity();
    }

    @Override
    public void onDrawFrame(GL10 gl10) {
        //清除深度和顏色緩存
        gl10.glClearColor(1.0f,1.0f,1.0f,0.0f);
        gl10.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
        gl10.glMatrixMode(GL10.GL_MODELVIEW);//設置矩陣模式
        draw(gl10);
    }
    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,verBuffer);
        gl.glColorPointer(4,GL10.GL_FLOAT,0,colorBuffer);
        gl.glLoadIdentity();
        gl.glTranslatef(0,0,-5);
        gl.glRotatef(45f,0f,1f,0f);//往右邊(Y軸)傾斜45度
        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
    }
}

球體實現的代碼

import android.opengl.GLSurfaceView;
import android.opengl.GLU;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class OpenGLRender2 implements GLSurfaceView.Renderer {

    // 環境光
    private final float[] mat_ambient = { 0.2f, 0.3f, 0.4f, 1.0f };
    private FloatBuffer mat_ambient_buf;
    // 平行入射光
    private final float[] mat_diffuse = { 0.4f, 0.6f, 0.8f, 1.0f };
    private FloatBuffer mat_diffuse_buf;
    // 高亮區域
    private final float[] mat_specular = { 0.2f * 0.4f, 0.2f * 0.6f, 0.2f * 0.8f, 1.0f };
    private FloatBuffer mat_specular_buf;

    private Sphere mSphere = new Sphere();

    public volatile float mLightX = 10f;
    public volatile float mLightY = 10f;
    public volatile float mLightZ = 10f;

    @Override
    public void onDrawFrame(GL10 gl) {
        // 清晰屏幕和深度緩存
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
        // 重置當前的模型觀察矩陣
        gl.glLoadIdentity();

        gl.glEnable(GL10.GL_LIGHTING);
        gl.glEnable(GL10.GL_LIGHT0);

        // 材質
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, mat_ambient_buf);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, mat_diffuse_buf);
        gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_SPECULAR, mat_specular_buf);
        // 鏡面指數 0~128 越小越粗糙
        gl.glMaterialf(GL10.GL_FRONT_AND_BACK, GL10.GL_SHININESS, 96.0f);

        //光源位置
        float[] light_position = {mLightX, mLightY, mLightZ, 0.0f};
        ByteBuffer mpbb = ByteBuffer.allocateDirect(light_position.length*4);
        mpbb.order(ByteOrder.nativeOrder());
        FloatBuffer mat_posiBuf = mpbb.asFloatBuffer();
        mat_posiBuf.put(light_position);
        mat_posiBuf.position(0);
        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, mat_posiBuf);

        gl.glTranslatef(0.0f, 0.0f, -3.0f);
        mSphere.draw(gl);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        // 設置輸出屏幕大小
        gl.glViewport(0, 0, width, height);

        // 設置投影矩陣
        gl.glMatrixMode(GL10.GL_PROJECTION);
        // 重置投影矩陣
        gl.glLoadIdentity();
        // 設置視口大小
        // gl.glFrustumf(0, width, 0, height, 0.1f, 100.0f);

        GLU.gluPerspective(gl, 90.0f, (float) width / height, 0.1f, 50.0f);

        // 選擇模型觀察矩陣
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        // 重置模型觀察矩陣
        gl.glLoadIdentity();

    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
        // 對透視進行修正
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        // 背景:黑色
        gl.glClearColor(0, 0.0f, 0.0f, 0.0f);
        // 啓動陰影平滑
        gl.glShadeModel(GL10.GL_SMOOTH);

        // 復位深度緩存
        gl.glClearDepthf(1.0f);
        // 啓動深度測試
        gl.glEnable(GL10.GL_DEPTH_TEST);
        // 所做深度測試的類型
        gl.glDepthFunc(GL10.GL_LEQUAL);

        initBuffers();
    }

    private void initBuffers() {
        ByteBuffer bufTemp = ByteBuffer.allocateDirect(mat_ambient.length * 4);
        bufTemp.order(ByteOrder.nativeOrder());
        mat_ambient_buf = bufTemp.asFloatBuffer();
        mat_ambient_buf.put(mat_ambient);
        mat_ambient_buf.position(0);

        bufTemp = ByteBuffer.allocateDirect(mat_diffuse.length * 4);
        bufTemp.order(ByteOrder.nativeOrder());
        mat_diffuse_buf = bufTemp.asFloatBuffer();
        mat_diffuse_buf.put(mat_diffuse);
        mat_diffuse_buf.position(0);

        bufTemp = ByteBuffer.allocateDirect(mat_specular.length * 4);
        bufTemp.order(ByteOrder.nativeOrder());
        mat_specular_buf = bufTemp.asFloatBuffer();
        mat_specular_buf.put(mat_specular);
        mat_specular_buf.position(0);
    }
}

 

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

// 計算球面頂點
public class Sphere {

    public void draw(GL10 gl) {

        float  angleA, angleB;
        float  cos, sin;
        float  r1, r2;
        float  h1, h2;
        float  step = 2.0f;
        float[][] v = new float[32][3];
        ByteBuffer vbb;
        FloatBuffer vBuf;

        vbb = ByteBuffer.allocateDirect(v.length * v[0].length * 4);
        vbb.order(ByteOrder.nativeOrder());
        vBuf = vbb.asFloatBuffer();

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

        for (angleA = -90.0f; angleA < 90.0f; angleA += step) {
            int    n = 0;

            r1 = (float)Math.cos(angleA * Math.PI / 180.0);
            r2 = (float)Math.cos((angleA + step) * Math.PI / 180.0);
            h1 = (float)Math.sin(angleA * Math.PI / 180.0);
            h2 = (float)Math.sin((angleA + step) * Math.PI / 180.0);

            // 固定緯度, 360 度旋轉遍歷一條緯線
            for (angleB = 0.0f; angleB <= 360.0f; angleB += step) {

                cos = (float)Math.cos(angleB * Math.PI / 180.0);
                sin = -(float)Math.sin(angleB * Math.PI / 180.0);

                v[n][0] = (r2 * cos);
                v[n][1] = (h2);
                v[n][2] = (r2 * sin);
                v[n + 1][0] = (r1 * cos);
                v[n + 1][1] = (h1);
                v[n + 1][2] = (r1 * sin);

                vBuf.put(v[n]);
                vBuf.put(v[n + 1]);

                n += 2;

                if(n>31){
                    vBuf.position(0);

                    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuf);
                    gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);
                    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);

                    n = 0;
                    angleB -= step;
                }

            }
            vBuf.position(0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuf);
            gl.glNormalPointer(GL10.GL_FLOAT, 0, vBuf);
            gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, n);
        }

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
    }
}

頁面顯示

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GLSurfaceView glSurfaceView = (GLSurfaceView)findViewById(R.id.glsurfaceview);
        glSurfaceView.setRenderer(new OpenGLRender());
        mRenderer = new OpenGLRender2();
        GLSurfaceView glsurfaceview2 = (GLSurfaceView)findViewById(R.id.glsurfaceview2);
        glsurfaceview2.setRenderer(mRenderer);
        glsurfaceview2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                int action = event.getActionMasked();
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                        mDownX = event.getX();
                        mDownY = event.getY();
                        return true;
                    case MotionEvent.ACTION_UP:
                        return true;
                    case MotionEvent.ACTION_MOVE:
                        float mX = event.getX();
                        float mY = event.getY();
                        mRenderer.mLightX += (mX - mDownX) / 10;
                        mRenderer.mLightY -= (mY - mDownY) / 10;
                        mDownX = mX;
                        mDownY = mY;
                        return true;
                        default:
                            return false;
                }
            }
        });
    }

頁面佈局xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    tools:context=".MainActivity">

    <android.opengl.GLSurfaceView
        android:id="@+id/glsurfaceview"
        android:layout_width="100px"
        android:layout_height="100px"
        android:layout_centerInParent="true"/>

    <android.opengl.GLSurfaceView
        android:id="@+id/glsurfaceview2"
        android:layout_width="500px"
        android:layout_height="200px"
        android:layout_marginTop="20px"
        android:layout_below="@+id/glsurfaceview"
        android:layout_centerInParent="true"/>

</RelativeLayout>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章