OpenGL 矩形

在前面的三角形的基礎(chǔ)上繪制矩形就簡(jiǎn)單很多了,改下頂點(diǎn)坐標(biāo)就可以繪制出來,這里有兩種繪制方式。

第一種繪制方式

class RectangleRender : GLSurfaceView.Renderer {

    private val vao = IntArray(1)
    private val vbo = IntArray(1)
    private val ebo = IntArray(1)
    private var esShader = Shader()

    private var vertices = floatArrayOf(
        0.5f, 0.5f, 0.0f,   // 右上角
        0.5f, -0.5f, 0.0f,  // 右下角
        -0.5f, -0.5f, 0.0f, // 左下角
        -0.5f, 0.5f, 0.0f   // 左上角
    )

    private var indices = shortArrayOf(
        0, 1, 3, // 第一個(gè)三角形
        1, 2, 3  // 第二個(gè)三角形
    )

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(0.2f, 0.3f, 0.3f, 1.0f)

        //vao
        GLES30.glGenVertexArrays(1, vao, 0)
        GLES30.glBindVertexArray(vao[0])
        //vbo
        GLES30.glGenBuffers(1, vbo, 0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0])
        val vertexBuffer = DataUtil.createByteBuffer(vertices)
        //復(fù)制數(shù)據(jù)到opengl
        GLES30.glBufferData(
            //頂點(diǎn)緩沖對(duì)象當(dāng)前綁定到GL_ARRAY_BUFFER目標(biāo)上
            GLES30.GL_ARRAY_BUFFER,
            //指定傳輸數(shù)據(jù)的大小(以字節(jié)為單位)
            vertices.size * DataUtil.sizeof(GLES30.GL_FLOAT),
            //發(fā)送的實(shí)際數(shù)據(jù)
            vertexBuffer,
            //GL_STATIC_DRAW :數(shù)據(jù)不會(huì)或幾乎不會(huì)改變。
            //GL_DYNAMIC_DRAW:數(shù)據(jù)會(huì)被改變很多。
            //GL_STREAM_DRAW :數(shù)據(jù)每次繪制時(shí)都會(huì)改變
            GLES30.GL_STATIC_DRAW
        )
        //設(shè)置頂點(diǎn)數(shù)組指針
        GLES30.glVertexAttribPointer(
            //shader中 layout(location = 0)的值
            0,
            //頂點(diǎn)屬性的大小。頂點(diǎn)屬性是一個(gè)vec3,它由3個(gè)值組成,所以大小是3
            3,
            //數(shù)據(jù)的類型
            GLES30.GL_FLOAT,
            //GL_TRUE,數(shù)據(jù)被標(biāo)準(zhǔn)化,所有數(shù)據(jù)都會(huì)被映射到0(對(duì)于有符號(hào)型signed數(shù)據(jù)是-1)到1之間。我們把它設(shè)置為GL_FALSE
            false,
            //步長(zhǎng),它告訴我們?cè)谶B續(xù)的頂點(diǎn)屬性組之間的間隔 字節(jié)單位
            3 * DataUtil.sizeof(GLES30.GL_FLOAT),
            //數(shù)據(jù)偏移量 這里只有頂點(diǎn) 位置數(shù)據(jù)在數(shù)組的開頭,所以這里是0
            0
        )
        GLES30.glEnableVertexAttribArray(0)
        //vbo end
        //vao end

        //ebo start
        GLES30.glGenBuffers(1, ebo, 0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, ebo[0])
        val indexBuffer = DataUtil.createByteBuffer(indices)
        //復(fù)制數(shù)據(jù)到opengl
        GLES30.glBufferData(
            //頂點(diǎn)緩沖對(duì)象當(dāng)前綁定到GL_ELEMENT_ARRAY_BUFFER目標(biāo)上
            GLES30.GL_ELEMENT_ARRAY_BUFFER,
            //指定傳輸數(shù)據(jù)的大小(以字節(jié)為單位)
            indices.size * DataUtil.sizeof(GLES30.GL_SHORT),
            //發(fā)送的實(shí)際數(shù)據(jù)
            indexBuffer,
            //GL_STATIC_DRAW :數(shù)據(jù)不會(huì)或幾乎不會(huì)改變。
            //GL_DYNAMIC_DRAW:數(shù)據(jù)會(huì)被改變很多。
            //GL_STREAM_DRAW :數(shù)據(jù)每次繪制時(shí)都會(huì)改變
            GLES30.GL_STATIC_DRAW
        )
        //ebo end

        //shader
        esShader.loadProgramFromAsset(MyApp.context, "triangle_vert.glsl", "triangle_frag.glsl")
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES30.glViewport(0, 0, width, height)
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        esShader.use()
        GLES30.glBindVertexArray(vao[0])

        GLES30.glDrawElements(
            //圖元的類型
            GLES30.GL_TRIANGLES,
            //定點(diǎn)個(gè)數(shù)
            6,
            //定點(diǎn)數(shù)據(jù)類型
            GLES30.GL_UNSIGNED_SHORT,
            //頂點(diǎn)偏移量
            0
        )

    }
}

這里跟繪制三角形有區(qū)別的地方是使用了索引來繪制,創(chuàng)建索引跟創(chuàng)建vbo是一樣的??创a里面的注釋。
繪制時(shí)使用

GLES30.glDrawElements(
            //圖元的類型
            GLES30.GL_TRIANGLES,
            //定點(diǎn)個(gè)數(shù)
            6,
            //定點(diǎn)數(shù)據(jù)類型
            GLES30.GL_UNSIGNED_SHORT,
            //頂點(diǎn)偏移量
            0
        )

這樣可以節(jié)省頂點(diǎn)數(shù)據(jù)。

第二種繪制方式

這種就是定義6個(gè)頂點(diǎn),繪制兩個(gè)三角形

class RectangleRender2 : GLSurfaceView.Renderer {

    private val vao = IntArray(1)
    private val vbo = IntArray(1)
    private var esShader = Shader()

    private var vertices = floatArrayOf(
        -0.5f, 0.5f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f,
        // second triangle
        -0.5f, 0.5f, 0.0f,
        0.5f, 0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    )

    override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
        GLES30.glClearColor(0.2f, 0.3f, 0.3f, 1.0f)

        //vao
        GLES30.glGenVertexArrays(1, vao, 0)
        GLES30.glBindVertexArray(vao[0])
        //vbo
        GLES30.glGenBuffers(1, vbo, 0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbo[0])
        val vertexBuffer = DataUtil.createByteBuffer(vertices)
        //復(fù)制數(shù)據(jù)到opengl
        GLES30.glBufferData(
            //頂點(diǎn)緩沖對(duì)象當(dāng)前綁定到GL_ARRAY_BUFFER目標(biāo)上
            GLES30.GL_ARRAY_BUFFER,
            //指定傳輸數(shù)據(jù)的大小(以字節(jié)為單位)
            vertices.size * DataUtil.sizeof(GLES30.GL_FLOAT),
            //發(fā)送的實(shí)際數(shù)據(jù)
            vertexBuffer,
            //GL_STATIC_DRAW :數(shù)據(jù)不會(huì)或幾乎不會(huì)改變。
            //GL_DYNAMIC_DRAW:數(shù)據(jù)會(huì)被改變很多。
            //GL_STREAM_DRAW :數(shù)據(jù)每次繪制時(shí)都會(huì)改變
            GLES30.GL_STATIC_DRAW
        )
        //設(shè)置頂點(diǎn)數(shù)組指針
        GLES30.glVertexAttribPointer(
            //shader中 layout(location = 0)的值
            0,
            //頂點(diǎn)屬性的大小。頂點(diǎn)屬性是一個(gè)vec3,它由3個(gè)值組成,所以大小是3
            3,
            //數(shù)據(jù)的類型
            GLES30.GL_FLOAT,
            //GL_TRUE,數(shù)據(jù)被標(biāo)準(zhǔn)化,所有數(shù)據(jù)都會(huì)被映射到0(對(duì)于有符號(hào)型signed數(shù)據(jù)是-1)到1之間。我們把它設(shè)置為GL_FALSE
            false,
            //步長(zhǎng),它告訴我們?cè)谶B續(xù)的頂點(diǎn)屬性組之間的間隔 字節(jié)單位
            3 * DataUtil.sizeof(GLES30.GL_FLOAT),
            //數(shù)據(jù)偏移量 這里只有頂點(diǎn) 位置數(shù)據(jù)在數(shù)組的開頭,所以這里是0
            0
        )
        GLES30.glEnableVertexAttribArray(0)
        //vbo end
        //vao end
        //shader
        esShader.loadProgramFromAsset(MyApp.context, "triangle_vert.glsl", "triangle_frag.glsl")
    }

    override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
        GLES30.glViewport(0, 0, width, height)
    }

    override fun onDrawFrame(gl: GL10?) {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        esShader.use()
        GLES30.glBindVertexArray(vao[0])

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 6)

    }
}

代碼比較簡(jiǎn)單、也有注釋,就這樣了。

代碼

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 1 著色器和程序(Shaders and Programs) 1.1 著色器語言(Language Overvie...
    RichardJieChen閱讀 9,975評(píng)論 3 12
  • 你好,三角形 圖形渲染管線(Pipeline) 3D坐標(biāo)轉(zhuǎn)為2D坐標(biāo)的處理過程是由OpenGL的圖形渲染管線(Pi...
    IceMJ閱讀 7,643評(píng)論 2 13
  • 簡(jiǎn)介 本文記錄了我初學(xué)Opengl 繪制彩色矩形的過程,可能我對(duì)內(nèi)容的描述不夠準(zhǔn)確,還請(qǐng)多多指正 實(shí)現(xiàn) 配置圖層 ...
    miku醬啦閱讀 1,246評(píng)論 0 2
  • 關(guān)于OpenGL: OpenGL是一個(gè)跨平臺(tái)的庫,可用于與GPU進(jìn)行接口編程,以呈現(xiàn)實(shí)時(shí)3D圖形。其在CAD、內(nèi)容...
    HoFie閱讀 13,670評(píng)論 5 29
  • 2018年下半年時(shí)間軸 9月2號(hào)去湘君老師那取指關(guān)節(jié) 9月2號(hào)跟阿丁碰面 9月雪汩鳥文創(chuàng)衍生品推廣合作 9月14-...
    西方月閱讀 147評(píng)論 0 0

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