OpenGL ES:基本形状的绘制(三角形、正方形、正方体)

三角形的绘制

  1. 编写顶点着色器和片段着色器代码

    输入和输出:基于OpenGL的渲染流程,从而每个着色器都有输入和输出,这样才能进行数据交流和传递。GLSL定义了in和out关键字专门来达成这个目的。只要一个输出变量与下一个着色器阶段的输入匹配,它就会传递下去。

    Uniform关键字:Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。

    1. uniform是全局的(Global)
    2. 无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新
//顶点着色器

//声明OpenGL es版本
#version 300 es
//in 代表输入属性
//顶点坐标属性
layout(location = 0) in vec3 aPos;
//颜色属性
layout(location = 1) in vec3 aColor;
//out 代表传递给片段着色器的属性
out vec3 color;

void main(){
	//gl_Position是内置的属性
    gl_Position= vec4(aPos.x,aPos.y,aPos.z,1.0f);
    color= aColor;
}

//片段着色器

#version 300 es
//定义浮点精度
precision mediump float;
//颜色采样输出
out vec4 fragColor;
//链接顶点着色器的同名输出
in vec3 color;

void main(){
    fragColor=vec4(color,1.0f);
}
  1. 编写渲染类,实现GLSurfaceView.Renderer接口中的三个方法:

    onSurfaceCreated: 做一些初始化操作

    1. 创建OpenGL ES执行程序
    2. 加载顶点着色器和片段着色器并将它们依附到执行程序上
    3. 链接程序
 public static int createGlProgram(String vertexSourcePath, String fragmentSourcePath, Resources resources){
 		//创建OpenGL ES执行程序
        int program = GLES30.glCreateProgram();
        if (vertexSourcePath != null && fragmentSourcePath != null) {
        
            //加载着色器
            int vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, getSource(vertexSourcePath,resources));
            int fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, getSource(fragmentSourcePath,resources));

            //把着色器依附到program上
            GLES30.glAttachShader(program,vertexShader);
            GLES30.glAttachShader(program,fragmentShader);
        }
        //链接program
        GLES30.glLinkProgram(program);
        
		//检查是否链接成功
        int[] linked = new int[1];
        GLES30.glGetProgramiv(program, GLES30.GL_LINK_STATUS, linked, 0);
        if (linked[0] == 0) {
            Log.d("error", GLES30.glGetProgramInfoLog(program));
            GLES30.glDeleteProgram(program);
        }
        return program;
    }

onSurfaceChanged: surface尺寸改变回调,可在其中进行相应的OpenGL的视图尺寸设置。

public void onSurfaceChanged(GL10 gl, int width, int height) {
       GLES30.glViewport(0,0,width,width);
    }

onDrawFrame: 在此回调中绘制图形

 //使用顶点数组对象和顶点缓存对象 推荐使用此方法
    private void drawByVaoAndVbo(){
    	//清除颜色和深度信息
        GLES30.glClearColor(1f,1f,1f,0.0f);
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
        //设置执行程序
        //使用此program 添加此program到OpenGL ES环境中去
        GLES30.glUseProgram(program);
		//生成VBO并绑定
        int[] VBOs = new int[1];
        GLES30.glGenBuffers(1, VBOs, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, VBOs[0]);
        //赋予数据
        //size 指的是 数组的总字节数
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vertices.length*4, OpenGlUtils.array2Buffer(vertices), GLES30.GL_STATIC_DRAW);
        //激活顶点位置属性并赋值
        GLES30.glEnableVertexAttribArray(0);
        GLES30.glVertexAttribPointer(0, 3, GLES20.GL_FLOAT, false, 6 * 4, 0);
       //激活颜色属性并赋值
        GLES30.glEnableVertexAttribArray(1);
        GLES30.glVertexAttribPointer(1,3,GLES20.GL_FLOAT,false,6*4,3*4);
		//绘制三角形
        GLES30.glDrawArrays(GLES30.GL_TRIANGLE_FAN,0,3);
        //删除缓存
        GLES30.glDeleteBuffers(1,VBOs,0);
    }

  //以顶点数组的方式绘制
    private void draw(){
        //设置背景颜色
        GLES30.glClearColor(1f,1f,1f,0.0f);
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
        //使用此program 添加此program到OpenGL ES环境中去
        GLES30.glUseProgram(program);
        GLES30.glEnableVertexAttribArray(0);
        GLES30.glEnableVertexAttribArray(1);
        //index 代表属性位置值 size 代表这个顶点属性的分量数  stride 代表一个顶点到下一个顶点到跨距(单位:字节) offset 代表偏移
        GLES30.glVertexAttribPointer(0,3, GLES20.GL_FLOAT,false,3*4,OpenGlUtils.array2Buffer(points));
        GLES30.glVertexAttribPointer(1,3,GLES20.GL_FLOAT,false,12,OpenGlUtils.array2Buffer(colors));
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES,0,3);
    }
  1. 交给GLSurfaceView渲染
		//设置OpenGL ES的版本
 		glSurfaceView.setEGLContextClientVersion(3);
 		//设置渲染对象
        glSurfaceView.setRenderer(renderer);
        //设置渲染模式 1.持续渲染(默认) 2.单次渲染
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

学习了三角形的绘制,大概可以了解到OpenGL 图元的绘制流程,其他图形的绘制流程也一样,无非是绘制的代码有所变动。

正方形的绘制

正方体的绘制

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务