android平臺下OpenGL ES 3.0繪製圓點、直線和三角形
阿新 • • 發佈:2018-11-06
OpenGL ES 3.0學習實踐
- android平臺下OpenGL ES 3.0從零開始
- android平臺下OpenGL ES 3.0繪製純色背景
- android平臺下OpenGL ES 3.0繪製圓點、直線和三角形
- android平臺下OpenGL ES 3.0繪製彩色三角形
- android平臺下OpenGL ES 3.0從矩形中看矩陣和座標系
目錄
新建SimpleRenderer
public class SimpleRenderer implements GLSurfaceView.Renderer
定義圓點座標
private float[] vertexPoints = new float[]{
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
理想狀態下的螢幕座標系
,我們定義的就是下圖中的三角形的三個頂點。
分配本地記憶體
因為OpenGL
作為本地系統庫執行在系統中,虛擬機器需要分配本地記憶體,供其存取。
public SimpleRenderer() {
//分配記憶體空間,每個浮點型佔4位元組空間
vertexBuffer = ByteBuffer.allocateDirect(vertexPoints.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
//傳入指定的座標資料
vertexBuffer.put(vertexPoints);
vertexBuffer.position (0);
}
頂點著色器
#version 300 es
layout (location = 0) in vec4 vPosition;
void main() {
gl_Position = vPosition;
gl_PointSize = 10.0;
}
上述頂點著色器的描述:
- 第一行表示:著色器的版本,OpenGL ES 2.0版本可以不寫。
- 第二行表示:
輸入屬性的陣列
(一個名為vPosition
的4分量向量),layout (location = 0)
表示這個變數的位置是頂點屬性0。 - 第三行表示:宣告一個
main
函式。 - 第四行表示:它將
vPosition
輸入屬性拷貝到名為gl_Position
的特殊輸出變數。 - 第五行表示:它將浮點資料
10.0
拷貝到gl_PointSize
的變數中。
片段著色器
#version 300 es
precision mediump float;
out vec4 fragColor;
void main() {
fragColor = vec4(1.0,1.0,1.0,1.0);
}
上述片段著色器的描述:
- 第一行表示:著色器的版本,OpenGL ES 2.0版本可以不寫。
- 第二行表示:宣告著色器中浮點變數的預設精度。
- 第三行表示:著色器宣告一個
輸出變數fragColor
,這個是一個4分量的向量。 - 第五行表示:表示將顏色值
(1.0,1.0,1.0,1.0)
,輸出到顏色緩衝區。
編譯和載入著色器
/**
* 編譯
*
* @param type 頂點著色器:GLES30.GL_VERTEX_SHADER
* 片段著色器:GLES30.GL_FRAGMENT_SHADER
* @param shaderCode
* @return
*/
private static int compileShader(int type, String shaderCode) {
//建立一個著色器
final int shaderId = GLES30.glCreateShader(type);
if (shaderId != 0) {
//載入到著色器
GLES30.glShaderSource(shaderId, shaderCode);
//編譯著色器
GLES30.glCompileShader(shaderId);
//檢測狀態
final int[] compileStatus = new int[1];
GLES30.glGetShaderiv(shaderId, GLES30.GL_COMPILE_STATUS, compileStatus, 0);
if (compileStatus[0] == 0) {
String logInfo = GLES30.glGetShaderInfoLog(shaderId);
System.err.println(logInfo);
//建立失敗
GLES30.glDeleteShader(shaderId);
return 0;
}
return shaderId;
} else {
//建立失敗
return 0;
}
}
連結到著色器
/**
* 連結小程式
*
* @param vertexShaderId 頂點著色器
* @param fragmentShaderId 片段著色器
* @return
*/
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
final int programId = GLES30.glCreateProgram();
if (programId != 0) {
//將頂點著色器加入到程式
GLES30.glAttachShader(programId, vertexShaderId);
//將片元著色器加入到程式中
GLES30.glAttachShader(programId, fragmentShaderId);
//連結著色器程式
GLES30.glLinkProgram(programId);
final int[] linkStatus = new int[1];
GLES30.glGetProgramiv(programId, GLES30.GL_LINK_STATUS, linkStatus, 0);
if (linkStatus[0] == 0) {
String logInfo = GLES30.glGetProgramInfoLog(programId);
System.err.println(logInfo);
GLES30.glDeleteProgram(programId);
return 0;
}
return programId;
} else {
//建立失敗
return 0;
}
}
設定視口
這一步通常在onSurfaceChanged
中完成
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES30.glViewport(0, 0, width, height);
}
清除顏色緩衝區
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
緩衝區將會用GLES30.glClearColor
指定的顏色清除,清除的顏色被設定為(0.5f, 0.5f, 0.5f, 0.5f)
,所以螢幕顯示為灰色。
繪製圓點
在public void onDrawFrame(GL10 gl)
回撥方法中:
//準備座標資料
GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);
//啟用頂點的控制代碼
GLES30.glEnableVertexAttribArray(0);
//繪製三個點
GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 3);
//禁止頂點陣列的控制代碼
GLES30.glDisableVertexAttribArray(0);
剛才的頂點著色器已經將vPosition
變數與輸入屬性位置0
綁定了,頂點著色器中每個屬性都由一個無符號整數值唯一標識的位置
。
繪製直線
//繪製直線
GLES30.glDrawArrays(GLES30.GL_LINE_STRIP, 0, 2);
GLES30.glLineWidth(10);
繪製如圖所示:
繪製三角形
//繪製三角形
GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 2);
常用圖元型別
圖元型別 | 描述 |
---|---|
GL_POINTS | 點精靈圖元,對指定的每個頂點進行繪製。 |
GL_LINES | 繪製一系列不相連的線段。 |
GL_LINE_STRIP | 繪製一系列相連的線段。 |
GL_LINE_LOOP | 繪製一系列相連的線段,首尾相連。 |
GL_TRIANGLES | 繪製一系列單獨的三角形。 |
GL_TRIANGLE_STRIP | 繪製一系列相互連線的三角形。 |
GL_TRIANGLE_FAN | 繪製一系列相互連線的三角形。 |
直線圖元型別:
三角形圖元型別
專案地址:
https://github.com/byhook/opengles4android
參考:
《OpenGL ES 3.0 程式設計指南第2版》
《OpenGL ES應用開發實踐指南Android卷》