老
孟
一個
有态度
的程式員

前面的文章介紹了如何 繪制三角形,在OpenGL ES中沒有直接繪制矩形的方式,通過繪制2個三角形的方式繪制矩形。
繪制矩形的頂點shader:
attribute vec4 vPosition;
void main() {
gl_Position = vPosition;
}
複制
繪制矩形的片段shader:
precision mediump float;
void main()
{
gl_FragColor = vec4(1,0,0,1);
}
複制
建立program:
private fun createProgram() {
var vertexCode =
AssetsUtils.readAssetsTxt(
context = context,
filePath = "glsl/triangle_vertex.glsl"
)
var fragmentCode =
AssetsUtils.readAssetsTxt(
context = context,
filePath = "glsl/triangle_fragment.glsl"
)
mProgramHandle = GLTools.createAndLinkProgram(vertexCode, fragmentCode)
}
複制
triangle_vertex.glsl和triangle_vertex.glsl分别表示頂點shader和片段shader的檔案,存放于assets/glsl目錄下,readAssetsTxt為讀取assets目錄下檔案的公用方法。
擷取參數句柄:
vPositionLoc = GLES20.glGetAttribLocation(mProgramHandle, "vPosition")
複制
初始化頂點資料,代碼如下:
var vertexBuffer = GLTools.array2Buffer(
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
)
)
複制
初始化索引資料,代碼如下:
var index = shortArrayOf(3,2,0,0, 1, 2)
val indexBuffer = GLTools.array2Buffer(index)
複制
繪制:
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT)
GLES20.glUseProgram(mProgramHandle)
vertexBuffer.position(0)
GLES20.glEnableVertexAttribArray(vPositionLoc)
GLES20.glVertexAttribPointer(vPositionLoc, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer)
GLES20.glDrawElements(GLES20.GL_TRIANGLES, index.size, GLES20.GL_UNSIGNED_SHORT,indexBuffer)
複制
效果圖如下:
上面設定的頂點雖然都是0.5,但不一定是正方形,0.5表示x軸或者y軸的一半,如果繪制的視窗本身是矩形,那麼繪制出來的也是矩形,如何繪制出正方形呢?
繪制正方形需要根據繪制視窗的寬高計算頂點資料,計算方式如下:
override fun onSurfaceChanged(p0: GL10?, width: Int, height: Int) {
GLES20.glViewport(0, 0, width, height)
var ratio = width / height.toFloat()
vertexBuffer = GLTools.array2Buffer(
floatArrayOf(
-0.5f, 0.5f * ratio, 0.0f,
-0.5f, -0.5f * ratio, 0.0f,
0.5f, -0.5f * ratio, 0.0f,
0.5f, 0.5f * ratio, 0.0f
)
)
}
複制
onSurfaceChanged是Renderer實作的方法,這個方法有寬高參數,計算寬高比,保持x軸不變,計算y軸長度,效果如下: