美文网首页
OpenGLES2.0(二)实战绘制一个三角形

OpenGLES2.0(二)实战绘制一个三角形

作者: 张小潇 | 来源:发表于2020-03-10 01:02 被阅读0次

    这是我们绘制的第一个图形,选择三角形,点、线、三角形是OpenGL ES世界的图形基础。无论多么复杂的几何物体,在OpenGL ES的世界里都可以用三角形拼成。关于Android OpenGL ES 三角形的绘制,在Android官方文档中也是优先详细介绍三角形,这边也是根据官方文档来绘制。

    一、流程

    1. 在AndroidManifest.xml文件中设置使用的OpenGL ES的版本
    2. 创建显示三角形的Activity,利用GLSurfaceView作为显示三角形的View,图形的具体渲染工作都是在Render中完成的。
    3. 实现GLSurfaceView的Render,在Render中完成三角形的绘制,具体行为有:
      • 加载顶点和片元着色器。
      • 确定需要绘制图形的坐标和颜色数据。
      • 创建program对象(着色器程序),连接顶点和片元着色器,链接program对象。
      • 设置视图窗口(viewport)。
      • 将坐标数据传入OpenGL ES程序中。
      • 使颜色缓冲区的内容显示到屏幕上。

    二、实现

    1、在清单中声明 OpenGL ES 的使用:

    • OpenGL ES 1.0 和 1.1 - 此 API 规范受 Android 1.0 及更高版本的支持。
    • OpenGL ES 2.0 - 此 API 规范受 Android 2.2(API 级别 8)及更高版本的支持。
    • OpenGL ES 3.0 - 此 API 规范受 Android 4.3(API 级别 18)及更高版本的支持。
    • OpenGL ES 3.1 - 此 API 规范受 Android 5.0(API 级别 21)及更高版本的支持。
    //为了让您的应用使用 OpenGL ES 2.0 API,您必须将以下声明添加到清单中: 
    //假如:OpenGL ES 3.1配置 0x00030001
    <uses-feature android:glEsVersion="0x00020000" android:required="true" />
    

    2、 创建Activity,自定义GLSurfaceView 作为主要视图的 Activity 的最低实现:

    public class Mai nActivity extends Activity {
    
            private GLSurfaceView gLView;
    
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
    
                //创建一个自定义的GLSurfaceView
                gLView = new MyGLSurfaceView(this);
                setContentView(gLView);
            }
        }
    

    创建GLSurfaceView 是一种专用视图,您可以在其中绘制 OpenGL ES 图形。它本身并没有很大的作用。对象的实际绘制由您在此视图中设置的 GLSurfaceView.Renderer 控制

     import android.content.Context;
        import android.opengl.GLSurfaceView;
    
        class MyGLSurfaceView extends GLSurfaceView {
    
            private final MyGLRenderer renderer;
    
            public MyGLSurfaceView(Context context){
                super(context);
    
                //设置opengl版本
                setEGLContextClientVersion(2);
                            //创建自定义渲染器
                renderer = new MyGLRenderer();
                    
                // Set the Renderer for drawing on the GLSurfaceView
                setRenderer(renderer);
                //性能有关。安卓默认使用这个按需渲染
                    //该设置可防止系统在您调用 requestRender() 之前重新绘制 GLSurfaceView 帧,这对于此示例应用而言更为高效。
                        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
            }
        }
    

    3、具体Render渲染器的实现:

    • 基本着色器编写:

      顶点着色器:

      attribute vec4 vPosition;
       void main() {
           gl_Position = vPosition;
       }
    
    片元着色器:
    
     precision mediump float;
    
    //uniform vec4 vColor;
    void main() {
        //系统默认颜色字段:gl_FragColor
        gl_FragColor = vec4(0.9, 0.5, 0.7, 1.0);
    }
    
    • 定义三角形和创建program对象(着色器程序)
     private final int mProgram;
        private final FloatBuffer mVertexBuffer;
        private int vertexCount;
        private final int vertexStride = 3 * 4; // 4 bytes per vertex
    
        public Triangle(Context context) {
            String vertex = OpenGLUtils.readRawTextFile(context, R.raw.triangle_vert);
            String frag = OpenGLUtils.readRawTextFile(context, R.raw.triangle_frag);
            //顶点着色器id
            int vertexId = loadShader(GLES20.GL_VERTEX_SHADER, vertex);
            //片元着色器id
            int fragId = loadShader(GLES20.GL_FRAGMENT_SHADER, frag);
            //OpenGL ES渲染程序
            mProgram = GLES20.glCreateProgram();
            GLES20.glAttachShader(mProgram, vertexId);
            GLES20.glAttachShader(mProgram, fragId);
            //link一下。激活
            GLES20.glLinkProgram(mProgram);
            GLES20.glDeleteShader(vertexId);
            GLES20.glDeleteShader(fragId);
                    //世界坐标
            float squareCoords[] = {
                    -0.5f, -0.5f, 0f,
                    0.5f, -0.5f, 0f,
                    -0.5f, 0.5f, 0f,
                    0.5f, 0.5f, 0f};
            mVertexBuffer = ByteBuffer.allocateDirect(squareCoords.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
            mVertexBuffer.clear();
            mVertexBuffer.put(squareCoords);
            vertexCount = squareCoords.length / 3;
        }
    
        private int loadShader(int type, String shaderCode) {
            //获取着色器
            int shader = GLES20.glCreateShader(type);
            //添加对于代码
            GLES20.glShaderSource(shader, shaderCode);
            //编译着色器
            GLES20.glCompileShader(shader);
            return shader;
        }
    
        public void draw() {
                    //创建程序。链接到GPU
            GLES20.glUseProgram(mProgram);
            //获取顶点着色器坐标
            int vPosition = GLES20.glGetAttribLocation(mProgram, "vPosition");
            mVertexBuffer.position(0);
            //第二个参数是坐标个数:x,y,z
            GLES20.glVertexAttribPointer(vPosition, 3, GLES20.GL_FLOAT, false, vertexStride, mVertexBuffer);
            GLES20.glEnableVertexAttribArray(vPosition);
            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        }
    
    • 绘制渲染
    public class MyRenderer implements GLSurfaceView.Renderer {
    
        private MyGLSurfaceView myGLSurfaceView;
        private Triangle mTriangle;
    
        public MyRenderer(MyGLSurfaceView myGLSurfaceView) {
            this.myGLSurfaceView = myGLSurfaceView;
        }
    
        @Override
        public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
            //设置要清空窗体为指定的颜色
            GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            mTriangle = new Triangle(myGLSurfaceView.getContext());
        }
    
        @Override
        public void onSurfaceChanged(GL10 gl10, int i, int i1) {
            //设置窗口大小
            GLES20.glViewport(0,0,i,i1);
        }
    
        @Override
        public void onDrawFrame(GL10 gl10) {
            //执行清空窗体
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
            mTriangle.draw();
        }
    }
    

    三、效果

    image

    相关文章

      网友评论

          本文标题:OpenGLES2.0(二)实战绘制一个三角形

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