第二課 介紹了著色器,這節(jié)課介紹繪制。
我個人認(rèn)為 OpenGL 其實就是著色器, 數(shù)據(jù)繪制方式,繪制代碼
第一步:其實也不分步驟,只是準(zhǔn)備工作
加載著色器 就是第二課的 加載兩個著色器代碼
第二步:創(chuàng)建一個程序?qū)ο?,并合著色器綁?/h4>
這里的程序,就是當(dāng)前的繪制程序,個人覺得應(yīng)該可以擴展,可以有多個程序之類的
/**
* 將 著色器 對象 和 程序 對象 綁定
*/
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
// 1、創(chuàng)建 openGL 程序
int programObjectId = GLES20.glCreateProgram();
if (programObjectId == 0) {
System.out.println("majie " + TAG + " could not create new program");
return 0;
}
// 2、把 著色器 附著 到 程序?qū)ο笊? GLES20.glAttachShader(programObjectId, vertexShaderId);
GLES20.glAttachShader(programObjectId, fragmentShaderId);
// 3、第 2 步是附著,這一步是 把該程序下的 著色器 聯(lián)合起來
GLES20.glLinkProgram(programObjectId);
// 4、檢查狀態(tài),并把狀態(tài)的結(jié)果放到 數(shù)組里面
int linkStatus[] = new int[1];
GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);
System.out.println("majie " + TAG + " Results of linking program: " + linkStatus[0]
+ " \n:" + GLES20.glGetProgramInfoLog(programObjectId));
if (linkStatus[0] == 0) {
GLES20.glDeleteProgram(programObjectId);
return 0;
}
return programObjectId;
}
program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
第三步:使用程序,獲取著色器代碼中的屬性,并告訴著色器,從哪里讀取屬性對應(yīng)的數(shù)據(jù)
glGetAttribLocation 獲取 著色器代碼中屬性對應(yīng)的 內(nèi)存地址(算不上是不是內(nèi)存地址,在C++中指針指向的都是內(nèi)存地址)
glVertexAttribPointer 這個方法是 往 著色器代碼中的屬性設(shè)置數(shù)據(jù)
if (ShaderHelper.validataProgram(program)) {
// 告訴 openGL 繪制任何東西的時候,都要使用 program 的程序
glUseProgram(program);
//TODO 不太理解 ----> 在 openGL 中把 uniform 和 attribute 修飾的 變量 賦予 了一個 位置編號
// ** ** ** openGL 把 頂點和片元著色器的代碼連城一個程序的時候,這些定義的變量有一個地址,也就是編號
// 獲取 片元著色器 中 uniform 標(biāo)記的 屬性
uColorLocation = glGetUniformLocation(program, U_COLOR);
// 獲取 頂點著色器 中 attribute 修飾的 屬性
aPositionLocation = glGetAttribLocation(program, A_POSITION);
/**
* TODO 告訴 openGL 從 vertexData 中 讀取數(shù)據(jù)
* 1、position(0) 從緩存區(qū) 的 第一個位置開始
*/
vertexData.position(0);
/**
* 2、往 屬性位置 讀取數(shù)據(jù) 每次讀取 POSITION_COMPONENT_COUNT 個
* aPositionLocation: 我們要讀取的數(shù)據(jù)放在 哪里
* POSITION_COMPONENT_COUNT: 該屬性數(shù)據(jù) 有多少個數(shù)
* GL_FLOAT: 屬性的類型
* vertexData: 從 哪里 讀取數(shù)據(jù)
*/
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);
/**
* 使能 頂點數(shù)組
*/
glEnableVertexAttribArray(aPositionLocation);
}
第四步:繪制了,也就是 onDrawFrame 方法了
glDrawArrays 繪制什么,從哪個點到哪個點
public void onDrawFrame(GL10 gl) {
System.out.println("niubi onDrawFrame");
glClear(GLES20.GL_COLOR_BUFFER_BIT);
/**
* onSurfaceCreated 中告訴 openGL 位置, 這里告訴 openGL 顏色
*/
// 1、更新 著色器 中 u_Color 的值 因為 u_Color 是 vec4 的類型,所以提供 4個分量的值
glUniform4f(uColorLocation, 1f,1f,1f,1f);
// 2、告訴 openGL 畫什么形狀,從哪里開始畫,有幾個頂點
/**
* GL_TRIANGLES 繪制三角形
* 0:從 頂點數(shù)組 開頭畫
* 6: 一共 6個頂點
*/
glDrawArrays(GL_TRIANGLES, 0, 6);
// 到這里為止,繪制了2個三角形
// 開始繪制線,1、線改變顏色
glUniform4f(uColorLocation, 1f,0f,0f,1f);
// 繪制 分割線
glDrawArrays(GL_LINES, 6, 2);
// 開始繪制 點
glUniform4f(uColorLocation, 0f, 1f,0f,1f);
glDrawArrays(GL_POINTS, 8, 1);
glUniform4f(uColorLocation, 0f, 0f,1f,1f);
glDrawArrays(GL_POINTS, 9, 1);
}
這里的程序,就是當(dāng)前的繪制程序,個人覺得應(yīng)該可以擴展,可以有多個程序之類的
/**
* 將 著色器 對象 和 程序 對象 綁定
*/
public static int linkProgram(int vertexShaderId, int fragmentShaderId) {
// 1、創(chuàng)建 openGL 程序
int programObjectId = GLES20.glCreateProgram();
if (programObjectId == 0) {
System.out.println("majie " + TAG + " could not create new program");
return 0;
}
// 2、把 著色器 附著 到 程序?qū)ο笊? GLES20.glAttachShader(programObjectId, vertexShaderId);
GLES20.glAttachShader(programObjectId, fragmentShaderId);
// 3、第 2 步是附著,這一步是 把該程序下的 著色器 聯(lián)合起來
GLES20.glLinkProgram(programObjectId);
// 4、檢查狀態(tài),并把狀態(tài)的結(jié)果放到 數(shù)組里面
int linkStatus[] = new int[1];
GLES20.glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0);
System.out.println("majie " + TAG + " Results of linking program: " + linkStatus[0]
+ " \n:" + GLES20.glGetProgramInfoLog(programObjectId));
if (linkStatus[0] == 0) {
GLES20.glDeleteProgram(programObjectId);
return 0;
}
return programObjectId;
}
program = ShaderHelper.linkProgram(vertexShader, fragmentShader);
glGetAttribLocation 獲取 著色器代碼中屬性對應(yīng)的 內(nèi)存地址(算不上是不是內(nèi)存地址,在C++中指針指向的都是內(nèi)存地址)
glVertexAttribPointer 這個方法是 往 著色器代碼中的屬性設(shè)置數(shù)據(jù)
if (ShaderHelper.validataProgram(program)) {
// 告訴 openGL 繪制任何東西的時候,都要使用 program 的程序
glUseProgram(program);
//TODO 不太理解 ----> 在 openGL 中把 uniform 和 attribute 修飾的 變量 賦予 了一個 位置編號
// ** ** ** openGL 把 頂點和片元著色器的代碼連城一個程序的時候,這些定義的變量有一個地址,也就是編號
// 獲取 片元著色器 中 uniform 標(biāo)記的 屬性
uColorLocation = glGetUniformLocation(program, U_COLOR);
// 獲取 頂點著色器 中 attribute 修飾的 屬性
aPositionLocation = glGetAttribLocation(program, A_POSITION);
/**
* TODO 告訴 openGL 從 vertexData 中 讀取數(shù)據(jù)
* 1、position(0) 從緩存區(qū) 的 第一個位置開始
*/
vertexData.position(0);
/**
* 2、往 屬性位置 讀取數(shù)據(jù) 每次讀取 POSITION_COMPONENT_COUNT 個
* aPositionLocation: 我們要讀取的數(shù)據(jù)放在 哪里
* POSITION_COMPONENT_COUNT: 該屬性數(shù)據(jù) 有多少個數(shù)
* GL_FLOAT: 屬性的類型
* vertexData: 從 哪里 讀取數(shù)據(jù)
*/
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexData);
/**
* 使能 頂點數(shù)組
*/
glEnableVertexAttribArray(aPositionLocation);
}
glDrawArrays 繪制什么,從哪個點到哪個點
public void onDrawFrame(GL10 gl) {
System.out.println("niubi onDrawFrame");
glClear(GLES20.GL_COLOR_BUFFER_BIT);
/**
* onSurfaceCreated 中告訴 openGL 位置, 這里告訴 openGL 顏色
*/
// 1、更新 著色器 中 u_Color 的值 因為 u_Color 是 vec4 的類型,所以提供 4個分量的值
glUniform4f(uColorLocation, 1f,1f,1f,1f);
// 2、告訴 openGL 畫什么形狀,從哪里開始畫,有幾個頂點
/**
* GL_TRIANGLES 繪制三角形
* 0:從 頂點數(shù)組 開頭畫
* 6: 一共 6個頂點
*/
glDrawArrays(GL_TRIANGLES, 0, 6);
// 到這里為止,繪制了2個三角形
// 開始繪制線,1、線改變顏色
glUniform4f(uColorLocation, 1f,0f,0f,1f);
// 繪制 分割線
glDrawArrays(GL_LINES, 6, 2);
// 開始繪制 點
glUniform4f(uColorLocation, 0f, 1f,0f,1f);
glDrawArrays(GL_POINTS, 8, 1);
glUniform4f(uColorLocation, 0f, 0f,1f,1f);
glDrawArrays(GL_POINTS, 9, 1);
}