OpenGl ES 3.0基本流程

OpenGl 基本流程

初始化數(shù)據(jù)和著色器渲染程序

  • 初始化頂點數(shù)據(jù),注意設(shè)置字節(jié)順序為本地操作系統(tǒng)順序

    /**
       * 初始化頂點坐標(biāo)
       */
      private fun initVertexLocation() {
          var vertices = floatArrayOf(
              -0.8f, 0f, 0f,
              0f, -0.8f,
              0f, 0.8f, 0f, 0f
          )
    
          var vbb = ByteBuffer.allocateDirect(vertices.size * 4)
          vbb.order(ByteOrder.nativeOrder())  //設(shè)置字節(jié)順序為本地操作系統(tǒng)順序
          mVertexBuffer = vbb.asFloatBuffer() //轉(zhuǎn)換為浮點型緩沖
          mVertexBuffer.put(vertices)
          mVertexBuffer.position(0)
    
      }
    
      /**
       * 初始化頂點顏色
       */
      private fun initVertexColor() {
          var colors = floatArrayOf(
              1F, 1F, 1F, 0F, //白色
              0F, 0F, 1F, 0F, //藍(lán)色
              0F, 1F, 0F, 0F //綠色
          )
    
          var cbb = ByteBuffer.allocateDirect(colors.size * 4)
          cbb.order(ByteOrder.nativeOrder())
          mColorBuffer = cbb.asFloatBuffer()
          mColorBuffer.put(colors)
          mColorBuffer.position(0)//設(shè)置緩沖區(qū)起始位置
      }
    
  • 初始化著色器:包括加載 頂點和片元著色器、創(chuàng)建片元著色器程序、獲取程序中的屬性引用

     //初始化著色器
      private fun initShader(mv: View) {
          //加載頂點著色器的腳本內(nèi)容
          mVertexShader = ShaderUtil.loadFromAssetsFile("vertex", mv.getResources())
          //加載片元著色器的腳本內(nèi)容
          mFragmentShader = ShaderUtil.loadFromAssetsFile("colorfrag", mv.getResources())
          //基于頂點著色器與片元著色器創(chuàng)建程序
          mProgram = ShaderUtil.createShaderProgram(mVertexShader!!, mFragmentShader!!)
          //獲取程序中頂點位置屬性引用
          maPositionHandle = GLES30.glGetAttribLocation(mProgram, "aPos")
          //獲取程序中頂點顏色屬性引用
          maColorHandle = GLES30.glGetAttribLocation(mProgram, "aColor")
          //獲取程序中總變換矩陣引用
          muMVPMatrixHandle = GLES30.glGetUniformLocation(mProgram, "mMVPMatrix")
      }
    

注意:mProgram為自定義渲染管線程序id

  • 基于著色器創(chuàng)建渲染管線程序:包括加載頂點和片元著色器、創(chuàng)建程序、向程序中加入頂點和片元著色器、鏈接程序

        //創(chuàng)建著色器程序
      fun createShaderProgram(vertexSource:String, fragmentSource:String): Int {
          var vertexShader = loadShader(GLES30.GL_VERTEX_SHADER, vertexSource)
          if (vertexShader == 0) return 0
    
          var fragmentShader = loadShader(GLES30.GL_FRAGMENT_SHADER, fragmentSource)
          if (fragmentShader == 0) return 0
    
          //創(chuàng)建渲染程序
          var program = GLES30.glCreateProgram()
    
          //若程序創(chuàng)建成功向程序中加入頂點何片元著色器
          if (program != 0) {
              //向程序中加入頂點著色器
              GLES30.glAttachShader(program, vertexShader)
              checkGlError("glAttachShader")
              //向程序中加入片元著色器
              GLES30.glAttachShader(program, fragmentShader)
              checkGlError("glAttachShader")
    
              //鏈接程序
              GLES30.glLinkProgram(program)
              //存放鏈接成功program數(shù)量的數(shù)組
              var linkStatus = IntArray(1)
              GLES30.glGetProgramiv(program, GLES30.GL_LINK_STATUS, linkStatus, 0)
              //若鏈接失敗則報錯并刪除程序
              if (linkStatus != null && linkStatus[0] != GLES30.GL_TRUE) {
                  Log.e("ES20_ERROR", "Could not link program: ")
                  Log.e("ES20_ERROR", GLES30.glGetProgramInfoLog(program))
                  GLES30.glDeleteProgram(program)
                  program = 0
              }
          }
          return program
      }
    
  • 加載著色器:包括 創(chuàng)建、加載著色器源代碼、編譯著色器

     //加載著色器 //shader的類型  GLES30.GL_VERTEX_SHADER(頂點)   GLES30.GL_FRAGMENT_SHADER(片元)
      fun loadShader(shaderType:Int, source:String):Int {
          //創(chuàng)建新的著色器
          var shader = GLES30.glCreateShader(shaderType)
          //若創(chuàng)建成功則加載shader
          if (shader != 0) {
              //加載shader的源代碼
              GLES30.glShaderSource(shader, source)
              //編譯shader
              GLES30.glCompileShader(shader)
    
              var compiled = IntArray(1)
              //獲取shader的編譯情況
              GLES30.glGetShaderiv(shader, GLES30.GL_COMPILE_STATUS, compiled, 0);
              if (compiled != null && compiled[0] == 0) {//若編譯失敗則顯示錯誤日志并刪除此shader
                  Log.e("ES20_ERROR", "Could not compile shader $shaderType:")
                  Log.e("ES20_ERROR", GLES30.glGetShaderInfoLog(shader))
                  GLES30.glDeleteShader(shader);
                  shader = 0;
              }
          }
          return shader
      }
    

繪制圖形

  • 指定使用的著色器、將需要渲染的數(shù)據(jù)傳入渲染、啟用頂點和片元數(shù)據(jù)、繪制
    fun drawSelf() {
          //指定使用某套shader程序
          GLES30.glUseProgram(mProgram)
          //初始化變換矩陣
          Matrix.setRotateM(mMMatrix, 0, 0f, 1f, 0f, 0f)
          //設(shè)置沿Z軸正向位移1
          Matrix.translateM(mMMatrix, 0, 0f, 0f, 1f)
          //設(shè)置繞x軸旋轉(zhuǎn)
          Matrix.rotateM(mMMatrix, 0, xAngle, 1f, 0f, 0f)
          //將變換矩陣傳入渲染管線
          GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, getFianlMatrix(mMMatrix), 0)
          //將頂點位置數(shù)據(jù)傳送進渲染管線
          GLES30.glVertexAttribPointer(
              maPositionHandle,
              3,
              GLES30.GL_FLOAT,
              false,
              3 * 4,
              mVertexBuffer
          )
          //將頂點顏色數(shù)據(jù)傳送進渲染管線
          GLES30.glVertexAttribPointer(
              maColorHandle,
              4,
              GLES30.GL_FLOAT,
              false,
              4 * 4,
              mColorBuffer
          )
          GLES30.glEnableVertexAttribArray(maPositionHandle)//啟用頂點位置數(shù)據(jù)
          GLES30.glEnableVertexAttribArray(maColorHandle)//啟用頂點著色數(shù)據(jù)
          //繪制三角形
          GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vCount)
    
      }
    

注意:傳入管線的渲染矩陣 需要多次變化,可以總結(jié)為MVP,最重要的幾個分別是模型(Model)、觀察(View)、投影(Projection)三 個矩陣,需要按順序左乘

  • 管線矩陣變換: 左乘觀察矩陣,左乘投影矩陣
    fun getFianlMatrix\(spec: FloatArray\): FloatArray {
    var mMVPMatrix = FloatArray(16)
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, spec, 0)
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0)
    return mMVPMatrix
    }
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容