在前面的三角形的基礎(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)單、也有注釋,就這樣了。