OpenGL ES 3.0學(xué)習(xí)實(shí)踐
- android平臺(tái)下OpenGL ES 3.0從零開(kāi)始
- android平臺(tái)下OpenGL ES 3.0繪制純色背景
- android平臺(tái)下OpenGL ES 3.0繪制圓點(diǎn)、直線和三角形
- android平臺(tái)下OpenGL ES 3.0繪制彩色三角形
- android平臺(tái)下OpenGL ES 3.0從矩形中看矩陣和正交投影
- android平臺(tái)下OpenGL ES 3.0著色語(yǔ)言基礎(chǔ)知識(shí)(上)
- android平臺(tái)下OpenGL ES 3.0著色語(yǔ)言基礎(chǔ)知識(shí)(下)
- android平臺(tái)下OpenGL ES 3.0實(shí)例詳解頂點(diǎn)屬性刻盐、頂點(diǎn)數(shù)組
- android平臺(tái)下OpenGL ES 3.0實(shí)例詳解頂點(diǎn)緩沖區(qū)對(duì)象(VBO)和頂點(diǎn)數(shù)組對(duì)象(VAO)
- android平臺(tái)下OpenGLES3.0繪制立方體的幾種方式
目錄
- 新建
SimpleRenderer
- 定義圓點(diǎn)坐標(biāo)
- 分配本地內(nèi)存
- 頂點(diǎn)著色器
- 片段著色器
- 編譯和加載著色器
- 設(shè)置視口
- 清除顏色緩沖區(qū)
- 繪制圓點(diǎn)
- 繪制直線
- 繪制三角形
新建SimpleRenderer
public class SimpleRenderer implements GLSurfaceView.Renderer
定義圓點(diǎn)坐標(biāo)
private float[] vertexPoints = new float[]{
0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
理想狀態(tài)下的屏幕坐標(biāo)系
躬翁,我們定義的就是下圖中的三角形的三個(gè)頂點(diǎn)。
image
分配本地內(nèi)存
因?yàn)?code>OpenGL作為本地系統(tǒng)庫(kù)運(yùn)行在系統(tǒng)中拾给,虛擬機(jī)需要分配本地內(nèi)存,供其存取兔沃。
public SimpleRenderer() {
//分配內(nèi)存空間,每個(gè)浮點(diǎn)型占4字節(jié)空間
vertexBuffer = ByteBuffer.allocateDirect(vertexPoints.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
//傳入指定的坐標(biāo)數(shù)據(jù)
vertexBuffer.put(vertexPoints);
vertexBuffer.position(0);
}
頂點(diǎn)著色器
#version 300 es
layout (location = 0) in vec4 vPosition;
void main() {
gl_Position = vPosition;
gl_PointSize = 10.0;
}
上述頂點(diǎn)著色器的描述:
- 第一行表示:著色器的版本蒋得,OpenGL ES 2.0版本可以不寫(xiě)。
- 第二行表示:
輸入屬性的數(shù)組
(一個(gè)名為vPosition
的4分量向量)乒疏,layout (location = 0)
表示這個(gè)變量的位置是頂點(diǎn)屬性0额衙。 - 第三行表示:聲明一個(gè)
main
函數(shù)。 - 第四行表示:它將
vPosition
輸入屬性拷貝到名為gl_Position
的特殊輸出變量怕吴。 - 第五行表示:它將浮點(diǎn)數(shù)據(jù)
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版本可以不寫(xiě)转绷。
- 第二行表示:聲明著色器中浮點(diǎn)變量的默認(rèn)精度伟件。
- 第三行表示:著色器聲明一個(gè)
輸出變量fragColor
,這個(gè)是一個(gè)4分量的向量议经。 - 第五行表示:表示將顏色值
(1.0,1.0,1.0,1.0)
斧账,輸出到顏色緩沖區(qū)。
編譯和加載著色器
/**
* 編譯
*
* @param type 頂點(diǎn)著色器:GLES30.GL_VERTEX_SHADER
* 片段著色器:GLES30.GL_FRAGMENT_SHADER
* @param shaderCode
* @return
*/
private static int compileShader(int type, String shaderCode) {
//創(chuàng)建一個(gè)著色器
final int shaderId = GLES30.glCreateShader(type);
if (shaderId != 0) {
//加載到著色器
GLES30.glShaderSource(shaderId, shaderCode);
//編譯著色器
GLES30.glCompileShader(shaderId);
//檢測(cè)狀態(tài)
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);
//創(chuàng)建失敗
GLES30.glDeleteShader(shaderId);
return 0;
}
return shaderId;
} else {
//創(chuàng)建失敗
return 0;
}
}
鏈接到著色器
/**
* 鏈接小程序
*
* @param vertexShaderId 頂點(diǎn)著色器
* @param fragmentShaderId 片段著色器
* @return
*/
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
final int programId = GLES30.glCreateProgram();
if (programId != 0) {
//將頂點(diǎn)著色器加入到程序
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 {
//創(chuàng)建失敗
return 0;
}
}
設(shè)置視口
這一步通常在onSurfaceChanged
中完成
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES30.glViewport(0, 0, width, height);
}
清除顏色緩沖區(qū)
GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
緩沖區(qū)將會(huì)用GLES30.glClearColor
指定的顏色清除煞肾,清除的顏色被設(shè)置為(0.5f, 0.5f, 0.5f, 0.5f)
咧织,所以屏幕顯示為灰色。
繪制圓點(diǎn)
在public void onDrawFrame(GL10 gl)
回調(diào)方法中:
//準(zhǔn)備坐標(biāo)數(shù)據(jù)
GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, vertexBuffer);
//啟用頂點(diǎn)的句柄
GLES30.glEnableVertexAttribArray(0);
//繪制三個(gè)點(diǎn)
GLES30.glDrawArrays(GLES30.GL_POINTS, 0, 3);
//禁止頂點(diǎn)數(shù)組的句柄
GLES30.glDisableVertexAttribArray(0);
剛才的頂點(diǎn)著色器已經(jīng)將vPosition
變量與輸入屬性位置0
綁定了籍救,頂點(diǎn)著色器中每個(gè)屬性都由一個(gè)無(wú)符號(hào)整數(shù)值唯一標(biāo)識(shí)的位置
习绢。
image
繪制直線
//繪制直線
GLES30.glDrawArrays(GLES30.GL_LINE_STRIP, 0, 2);
GLES30.glLineWidth(10);
繪制如圖所示:
image
繪制三角形
//繪制三角形
GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 2);
image
常用圖元類型
圖元類型 | 描述 |
---|---|
GL_POINTS | 點(diǎn)精靈圖元,對(duì)指定的每個(gè)頂點(diǎn)進(jìn)行繪制钧忽。 |
GL_LINES | 繪制一系列不相連的線段毯炮。 |
GL_LINE_STRIP | 繪制一系列相連的線段逼肯。 |
GL_LINE_LOOP | 繪制一系列相連的線段,首尾相連桃煎。 |
GL_TRIANGLES | 繪制一系列單獨(dú)的三角形篮幢。 |
GL_TRIANGLE_STRIP | 繪制一系列相互連接的三角形。 |
GL_TRIANGLE_FAN | 繪制一系列相互連接的三角形为迈。 |
直線圖元類型:
image
三角形圖元類型
image
項(xiàng)目地址:
https://github.com/byhook/opengles4android
原文地址:
http://blog.csdn.net/byhook/article/details/83719500
參考:
《OpenGL ES 3.0 編程指南第2版》
《OpenGL ES應(yīng)用開(kāi)發(fā)實(shí)踐指南Android卷》