opengl es3.0学习篇七:使用opengl绘制一个立方体

这里简单运用之前所学的知识来实现一个对应的立方体:

public class MainActivity extends AppCompatActivity {
    RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        intGL();
    }

    private GLSurfaceView mSurfaceView;

    @Override
    protected void onPause() {
        super.onPause();
        if (mSurfaceView != null) {
            mSurfaceView.onPause();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mSurfaceView != null) {
            mSurfaceView.onResume();
        }
    }


    private void intGL() {
        mSurfaceView = findViewById(R.id.gl);
        boolean isSupport=detectOpenGLES30();
        mSurfaceView.setEGLContextClientVersion(3);
        mSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
        mSurfaceView.setRenderer(new MyRenderer());
        //RenderMode 有两种,RENDERMODE_WHEN_DIRTY 和 RENDERMODE_CONTINUOUSLY,
        // 前者是懒惰渲染,需要手动调用 glSurfaceView.requestRender() 才会进行更新,而后者则是不停渲染。
        mSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    private boolean detectOpenGLES30() {
        ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
        ConfigurationInfo info = am.getDeviceConfigurationInfo();
        String resulr=Integer.toString(info.reqGlEsVersion, 16);
        return (info.reqGlEsVersion >= 0x30000);
    }
    private static class MyRenderer implements GLSurfaceView.Renderer {
        private Triangle mSquare;

        @Override
        public void onSurfaceCreated(GL10 unused, EGLConfig config) {
            mSquare = new Triangle();
        }

        @Override
        public void onSurfaceChanged(GL10 unused, int width, int height) {
            //设置 Screen space 的大小
            mSquare.onSurfaceChange(width,height);
        }

        //绘制的过程其实就是为 shader 代码变量赋值,并调用绘制命令的过程
        @Override
        public void onDrawFrame(GL10 unused) {
            GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_DEPTH_BUFFER_BIT);
			GLES30.glEnable(GLES20.GL_DEPTH_TEST);
            mSquare.onDraw();
        }
    }

}

Triangle方法:

public class Triangle {
    private FloatBuffer vertexBuffer;
    private FloatBuffer colorBuffer;
    private ByteBuffer indicateBuffer;
    private final float[] projectionMatrix = new float[16];
    private final String vertexShaderCode =
            "#version 300 es  \n" +
                    "layout(location = 0) in vec4 vPosition;\n" +
                    "layout(location = 1) in vec4 aColor;\n" +
                    "uniform mat4 aMatrix;\n" +
                    "out vec4 vColor;" +
                    "void main() {\n" +
                    "gl_Position = aMatrix*vPosition;\n" +
                    "vColor=aColor;\n" +
                    "}";

    private final String fragmentShaderCode =
            "#version 300 es  \n" +
                    "precision mediump float;\n" +
                    "out vec4 fragColor;\n" +
                    "in vec4 vColor;" +
                    "void main() {\n" +
                    "fragColor = vColor;\n" +
                    "}";
    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {
            0.5f, 0.5f, 0.5f,
            0.5f, 0.5f, -0.5f,
            -0.5f, 0.5f, 0.5f,
            -0.5f, 0.5f, -0.5f,

            0.5f, -0.5f, 0.5f,
            0.5f, -0.5f, -0.5f,
            -0.5f, -0.5f, 0.5f,
            -0.5f, -0.5f, -0.5f,

    };
    private final int mProgram;
    // Set color with red, green, blue and alpha (opacity) values
    float color[] = {
            0.0f, 1.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            1.0f, 0.5f, 0.0f,
            1.0f, 0.5f, 0.0f,
            1.0f, 0.0f, 0.0f,
            1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 1.0f
    };
    byte indicates[] = {
            //上
            0, 1, 2,
            1, 2, 3,
            //下
            4, 5, 6,
            5, 6, 7,
            //左
            2, 3, 6,
            3, 6, 7,
            //右
            0, 1, 4,
            1, 4, 5,
            //前
            0, 2, 4,
            2, 4, 6,
            //后
            1, 3, 7,
            1, 7, 5


    };

    public static int loadShader(int type, String shaderCode) {

        // create a vertex shader type (GLES30.GL_VERTEX_SHADER)
        // or a fragment shader type (GLES30.GL_FRAGMENT_SHADER)
        int shader = GLES30.glCreateShader(type);

        // add the source code to the shader and compile it
        GLES30.glShaderSource(shader, shaderCode);
        GLES30.glCompileShader(shader);

        return shader;
    }

    public Triangle() {
        indicateBuffer = ByteBuffer.allocate(indicates.length);
        indicateBuffer.put(indicates);
        indicateBuffer.position(0);
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
                // (number of coordinate values * 4 bytes per float)
                triangleCoords.length * 4);
        // use the device hardware's native byte order
        bb.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        vertexBuffer = bb.asFloatBuffer();
        // add the coordinates to the FloatBuffer
        vertexBuffer.put(triangleCoords);
        // set the buffer to read the first coordinate
        vertexBuffer.position(0);
        ByteBuffer bb1 = ByteBuffer.allocateDirect(
                // (number of coordinate values * 4 bytes per float)
                color.length * 4);
        // use the device hardware's native byte order
        bb1.order(ByteOrder.nativeOrder());

        // create a floating point buffer from the ByteBuffer
        colorBuffer = bb1.asFloatBuffer();
        // add the coordinates to the FloatBuffer
        colorBuffer.put(color);
        // set the buffer to read the first coordinate
        colorBuffer.position(0);
        int vertexShader = loadShader(GLES30.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER,
                fragmentShaderCode);

        // create empty OpenGL ES Program
        mProgram = GLES30.glCreateProgram();

        // add the vertex shader to program
        GLES30.glAttachShader(mProgram, vertexShader);

        // add the fragment shader to program
        GLES30.glAttachShader(mProgram, fragmentShader);

        // creates OpenGL ES program executables
        GLES30.glLinkProgram(mProgram);
    }

    private int mPositionHandle;
    private int mColorHandle;

    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
    private final int colorStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex

    public void onDraw() {
        // Add program to OpenGL ES environment

//        Matrix.translateM(projectionMatrix,0,-0.5f,0f,0f);
        float[] rotateF = new float[16];
        Matrix.setIdentityM(rotateF, 0);
        Matrix.setRotateM(rotateF,0,rotateAgree,0.5f,0.5f,0f);

        Matrix.multiplyMM(projectionMatrix,0,orthMatrix,0,rotateF,0);
        rotateAgree+=1;
        if (rotateAgree >=360) {
            rotateAgree=0;
        }
        GLES30.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES30.glGetAttribLocation(mProgram, "vPosition");
//        createVertextBuffer();
        // Enable a handle to th、e triangle vertices
        GLES30.glEnableVertexAttribArray(mPositionHandle);
        // Prepare the triangle coordinate data
        GLES30.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES30.GL_FLOAT, false,
                0, vertexBuffer);
        // get handle to fragment shader's vColor member
        mColorHandle = GLES30.glGetAttribLocation(mProgram, "aColor");
        int aMatrixPos = GLES30.glGetUniformLocation(mProgram, "aMatrix");
        GLES30.glUniformMatrix4fv(aMatrixPos,1,false,projectionMatrix,0);

        // Set color for drawing the triangle
//        GLES30.glVertexAttrib4fv(mColorHandle,  color, 0);

        GLES30.glEnableVertexAttribArray(mColorHandle);
        GLES30.glVertexAttribPointer(mColorHandle, 3,
                GLES30.GL_FLOAT, false,
                0, colorBuffer);
        // Draw the triangle
        GLES30.glDrawElements(GLES30.GL_TRIANGLES, indicates.length,
                GLES30.GL_UNSIGNED_BYTE, indicateBuffer);

        // Disable vertex array
        GLES30.glDisableVertexAttribArray(mPositionHandle);
    }
    int rotateAgree=0;
    float[] orthMatrix = new float[16];
    public void onSurfaceChange(int width, int height) {
        GLES30.glViewport(0, 0, width, height);
        final float aspectRatio = width > height ?
                ((float) width / (float) height)
                : ((float) height / (float) width);
		//正交投影
        Matrix.setIdentityM(orthMatrix, 0);
        if (width > height) {
            Matrix.orthoM(orthMatrix,0,-aspectRatio,aspectRatio,
                    -1f,1f,-1f,1f);
        }else {
            Matrix.orthoM(orthMatrix, 0, -1f, 1f,
                    -aspectRatio, aspectRatio, -1f, 1f);
        }
    }

    private void createVertextBuffer() {
        int[] value = new int[1];
        GLES30.glGenBuffers(1, value, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, value[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES30.GL_STATIC_DRAW);
    }
}

代码效果如下所示:

gif图效果不好,手机上看还是很酷炫的,哈哈哈

代码地址:

https://github.com/JerryChan123/LearnOEL/tree/gl30 (opengl for cube v2为提交信息)

转载于:https://my.oschina.net/u/3863980/blog/1838532

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值