美文网首页OpenGL ES
附录(三)绘制三角形

附录(三)绘制三角形

作者: 大旺旺的弟弟小旺旺 | 来源:发表于2021-06-22 07:50 被阅读0次

    在复习一次绘制流程。

    • 创建顶点和片段着色器
    • 加载编译
    • 创建程序
    • 附着,连接
    • 使用
    • 得到位置信息 (不太规范的叫法,就是属性等参数的位置)
    • 传值
    • 绘制

    创建着色器

     private final String vertexShaderCode =
          "attribute vec4 vPosition;" +
          "void main() {" +
          "  gl_Position = vPosition;" +
          "}";
    
    private final String fragmentShaderCode =
          "precision mediump float;" +
          "uniform vec4 vColor;" +
          "void main() {" +
          "  gl_FragColor = vColor;" +
          "}";
    

    这个很简单的,将传递进来的顶点属性直接给内置变量。片段着色器直接将传递的值给内置变量gl_FragColor,这个值会通过后续步骤之后显示在屏幕上的。

    加载和编译

    • 创建着色器
    //根据type创建顶点着色器或者片元着色器
    int shader = GLES20.glCreateShader(type);
    
    • 加载程序
    //将资源加入到着色器中,并编译
    GLES20.glShaderSource(shader, shaderCode);
    
    • 编译程序
    GLES20.glCompileShader(shader);
    
    • 检查异常
    int []arr = new int[1]        GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,arr,0);
           int i = arr[0];
           if (i == 0){
               //失败了
               int [] length = new int[1];
               GLES20.glGetShaderiv(shader,GLES20.GL_INFO_LOG_LENGTH,length,0);
               if (length[0]>0){
                   String s = GLES20.glGetShaderInfoLog(shader);
                   System.out.println(s);
               }
           }
           return shader;
       }
    

    创建程序

    • 创建程序
    mProgram = GLES20.glCreateProgram();
    
    • 附着着色器
    GLES20.glAttachShader(mProgram,vertexShader);
    GLES20.glAttachShader(mProgram,fragmentShader);
    
    • 连接
    GLES20.glLinkProgram(mProgram);
    
    • 检查
    int lin[] = new int[1];
    GLES20.glGetProgramiv(mProgram,GLES20.GL_LINK_STATUS,lin,0);
    if (lin[0] == 0){
        String s = GLES20.glGetProgramInfoLog(mProgram);
        System.out.println(s);
    }
    

    使用

    GLES20.glUseProgram(mProgram);
    

    得到位置

    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
    

    传值

    color使用的是uniform,可以直接的传值,传入数组就可以了。

    GLES20.glUniform4fv(mColorHandle, 1, color, 0);
    
    

    但是对于属性值就比较麻烦一点,需要使用到FloatBuffer.它 是一个特殊的区域,就是jvm和操作系统共享的区域。

    float triangleCoords[] = {
                0.5f,  0.5f, 0.0f, // top
                -0.5f, -0.5f, 0.0f, // bottom left
                0.5f, -0.5f, 0.0f  // bottom right
        };
    
    
    ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(triangleCoords);
    vertexBuffer.position(0);
    
    GLES20.glVertexAttribPointer(
            mPositionHandle,
            COORDS_PER_VERTEX,
            GLES20.GL_FLOAT,
            false,
            vertexStride,
            vertexBuffer);
    

    完整代码

    /**
     * 三角形
     */
    public class Triangle extends BaseGameScreen {
       
        static final int COORDS_PER_VERTEX = 3;
        private FloatBuffer vertexBuffer;
        static float triangleCoords[] = {
                0.5f,  0.5f, 0.0f, // top
                -0.5f, -0.5f, 0.0f, // bottom left
                0.5f, -0.5f, 0.0f  // bottom right
        };
    
        //顶点个数
        private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
        //顶点之间的偏移量
        private final int vertexStride = COORDS_PER_VERTEX * 4; // 每个顶点四个字节
        //设置颜色,依次为红绿蓝和透明通道
        float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
        private int mPositionHandle;
        private int mColorHandle;
        float d = 0.01F;
        public Triangle(){
    
        }
    
        public void create(){
            ByteBuffer bb = ByteBuffer.allocateDirect(
                    triangleCoords.length * 4);
            bb.order(ByteOrder.nativeOrder());
            vertexBuffer = bb.asFloatBuffer();
            vertexBuffer.put(triangleCoords);
            vertexBuffer.position(0);
    
            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
            int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
            mProgram = GLES20.glCreateProgram();
            GLES20.glAttachShader(mProgram,vertexShader);
            GLES20.glAttachShader(mProgram,fragmentShader);
            GLES20.glLinkProgram(mProgram);
            //程序加入到环境里面
            GLES20.glUseProgram(mProgram);
    //        检查是否有效
            GLES20.glValidateProgram(mProgram);
            //得到活跃的unifor
            int arr[] = new int[1];
            int arr1[] = new int[1];
            int arr2[] = new int[1];
            int arr3[] = new int[1];
            byte arr4[] = new byte[10];
            GLES20.glGetProgramiv(mProgram,GLES20.GL_ACTIVE_UNIFORMS,arr,0);
            GLES20.glGetActiveUniform(
                    mProgram,
                    1,
                    1,
                    arr1,
                    1,
                    arr2,
                    1,
                    arr3,
                    1,
                    arr4,
                    0
                    );
            mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
            mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        }
    
        @Override
        public void surfaceChange(int width, int height) {
            GLES20.glViewport(0,0,width,height);
        }
    
        @Override
        public void dispose() {
    
        }
    
    
        @Override
        public void render() {
            //获取位置句柄   属性句柄
    
            GLES20.glEnableVertexAttribArray(mPositionHandle);
            //准备三角形的坐标数据
            GLES20.glVertexAttribPointer(
                    mPositionHandle,
                    COORDS_PER_VERTEX,
                    GLES20.GL_FLOAT,
                    false,
                    vertexStride,
                    vertexBuffer);
            //获取片元着色器的vColor成员的句柄
    
            color[1] = color[1]-d;
            if (color[1]<=0||color[1]>=1){
                d=-d;
            }
            //设置绘制三角形的颜色
            GLES20.glUniform4fv(mColorHandle, 1, color, 0);
            //绘制三角形
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
            //禁止顶点数组的句柄
            GLES20.glDisableVertexAttribArray(mPositionHandle);
        }
    }
    

    相关文章

      网友评论

        本文标题:附录(三)绘制三角形

        本文链接:https://www.haomeiwen.com/subject/bqduyltx.html