Android-- acquaintance OpenGL ES 2.0

concept

OpenGL (Open Graphics Library) is a cross-platform, high-performance 3D rendering API, OpenGL ES 2.0 (Open Graphics Library Embedded System 2.0) is its embedded platform version 2.0.

Simple implementation

Activity in the inside, creating a GLSurfaceView object, and then as the layout of the Activity and achieve a Renderer interface upon their GLSurfaceView, and make them simple configuration.

const val TAG = "HelloPoints"
class HelloPoints : Activity() {
    private lateinit var glSurfaceView: GLSurfaceView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        title = "Play with Points"
        glSurfaceView = GLSurfaceView(this)
       	//GLSurfaceView作为布局
        setContentView(glSurfaceView)
        glSurfaceView.setEGLContextClientVersion(2)//OpenGL 2.0版本
        //Renderer接口设置进入
        glSurfaceView.setRenderer(PointsRender)
        glSurfaceView.renderMode = GLSurfaceView.RENDERMODE_CONTINUOUSLY
    }

    override fun onResume() {
        super.onResume()
        glSurfaceView.onResume()
    }

    override fun onPause() {
        super.onPause()
        glSurfaceView.onPause()
    }
    companion object PointsRender : GLSurfaceView.Renderer {
    	/**
         * shader语言跟C语言很像,它有一个主函数,也叫void main(){}。
         * gl_Position是一个内置变量,用于指定顶点,它是一个点,三维空间的点,所以用一个四维向量来赋值。
         * vec4是四维向量的类型,vec4()是它的构造方法。等等,三维空间,不是(x, y, z)三个吗?为什么用
         * *vec4层呢?
         * 四维是叫做齐次坐标,它的几何意义仍是三维,对于2D的话,第四位永远传1.0就可以了。
         * 这里,是指定原点(0, 0, 0)作为顶点,就是说想在原点位置画一个点。gl_PointSize是另外一个内置变量,用于指定点的大小。
         *
         * 这个shader就是想在原点画一个尺寸为20的点。
         */
        private const val VERTEX_SHADER =
                "void main() {\n" +
                        "gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n" +
                        "gl_PointSize = 20.0;\n" +
                        "}\n"
        /**
         * gl_FragColor是fragment shader的内置变量,
         * 用于指定当前顶点的颜色,四个分量(r, g, b, a)。
         * 这里是想指定为红色,不透明。
         */                
        private const val FRAGMENT_SHADER =
                "void main() {\n" +
                        "gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" +
                        "}\n"
       private var mGLProgram: Int = -1
        /**
         * 所有的GL API的调用都要在GLSurfaceView.Renderer的三个方法里面来call,
         * 就是方法的调用栈必须从这几个方法开始
         */
        //初始化操作
        override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
            GLES20.glClearColor(1f, 0f, 0f, 1f)//把背景,或者叫作画布,画成黑色,不透明
			//编译和链接shader程序
            val vsh = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER)
            // 告诉OpenGL,这一坨字串里面是vertex shader的源码。
            GLES20.glShaderSource(vsh, VERTEX_SHADER) 
            GLES20.glCompileShader(vsh) // 编译vertex shader
            val fsh = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER)
            GLES20.glShaderSource(fsh, FRAGMENT_SHADER)
            GLES20.glCompileShader(fsh)

            mGLProgram = GLES20.glCreateProgram() // 创建shader program句柄
            GLES20.glAttachShader(mGLProgram, vsh) // 把vertex shader添加到program
            GLES20.glAttachShader(mGLProgram, fsh) // 把fragment shader添加到program
            // 做链接,可以理解为把两种shader进行融合,做好投入使用的最后准备工作
            GLES20.glLinkProgram(mGLProgram) 
			// 让OpenGL来验证一下我们的shader program,并获取验证的状态
            GLES20.glValidateProgram(mGLProgram) 
            val status = IntArray(1)
            GLES20.glGetProgramiv(mGLProgram, GLES20.GL_VALIDATE_STATUS, status, 0) // 获取验证的状态
            Log.d(TAG, "validate shader program: " + GLES20.glGetProgramInfoLog(mGLProgram))
        }

        //surface发生改变时调用,通常是size发生变化
        override fun onSurfaceChanged(p0: GL10?, p1: Int, p2: Int) {
            GLES20.glViewport(0, 0, p1, p2) // 参数是left, top, width, height
        }

        //而此方法是用来绘制每帧的,所以每次刷新都会被调一次,所有的绘制都发生在这里。
        override fun onDrawFrame(p0: GL10?) {
        	// 清除颜色缓冲区,因为我们要开始新一帧的绘制了,所以先清理,以免有脏数据。
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT) 
             // 告诉OpenGL,使用在onSurfaceCreated里面准备好了的shader program来渲染
            GLES20.glUseProgram(mGLProgram)
            //开始渲染,发送渲染点的指令, 第二个参数是offset,第三个参数是点的个数。
            //目前只有一个点,所以是1。
            GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1)
        }
    }
}

Some explanations:

Description 1
All the GL API calls should be in GLSurfaceView.Renderer inside three methods to call, is the call stack method must start from several methods. Call elsewhere is not effective:
onSurfaceCreated
onSurfaceChanged
onDrawFrame

DESCRIPTION 2
the OpenGL coordinate system is a so-called right-handed
Sit high
Description. 3: Shader
GL ES 2.0 put rendering operations associated with a specific called shading language programs expressed, full name as OpenGL ES Shading language, it is a programming language, C language is very similar **, matrix and vector operations can be direct, run on dedicated graphics rendering GPU **. It is divided into two, called vertex shader (vertex shader), the geometry of vertices specified location and size , the other is called the fragment shader (fragment shader), which specifies each vertex shader . Each GL program must have a vertex shader and a fragment shader, and they correspond to each other. (Correspond to each other, meaning that there must be a vertex shader fragment shader, and vice versa, but not necessarily one to one). Of course, also can be reused, such as the same vertex shader, a plurality of fragment shader may express different colored solution.

Description 4: the coordinate values and the color values of
the coordinates of the normal range of -1 to 1, and a float.
Color value is 0 to 1, is of type float, 0 is empty (no meaning, such as black or transparent), is 1 (full meaning, such as white, or opaque).

Description 5
Renderer instance, rendering mode (render mode) is divided into two, one is GLSurfaceView initiative to refresh (Continuously) , kept callback Renderer of onDrawFrame, another is called passive refresh (the when Dirty) , that is, when requested refresh tune once onDrawFrame.

Original Reference

Published 28 original articles · won praise 1 · views 425

Guess you like

Origin blog.csdn.net/qq_40575302/article/details/105107643