一、一些基本概念
世界座標系
世界座標系就是3D繪圖中像素的座標。在3D繪圖中,座標軸遵循右手法則,讓你右手手心正對自己,大拇指指向X軸正方向,拇指指向Y軸正方向,中指指向Z軸正方向。如下圖所示
點的表示
空間中一個點具有(x,y,z)座標。在Android系統中,可以用一個float數組、int數組等來表示一個點,比如
private float[] mArray = { 0f, 0f, 0f };
而在OpenGl ES中,爲了提高性能,會把點、顏色等數組放在java.nio 包中定義的Buffer類中。類似於IO流中的緩衝。
創建一個工具類Utils,把獲取Buffer數據的代碼封裝下
public class Utils {
/**
* @param vertexs float 數組
* @return 獲取浮點形緩衝數據
*/
public static FloatBuffer getFloatBuffer(float[] vertexs) {
FloatBuffer buffer;
ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 4);
qbb.order(ByteOrder.nativeOrder());
buffer = qbb.asFloatBuffer();
//寫入數組
buffer.put(vertexs);
//設置默認的讀取位置
buffer.position(0);
return buffer;
}
}
二、繪製一個點
這裏只貼上MyRenderer類的代碼,其餘代碼和之前搭建的基礎框架一樣。
我會逐一講解
public class MyRenderer implements GLSurfaceView.Renderer {
//頂點數組
private float[] mArray = { 0f, 0f, 0f };
// 緩衝區
private FloatBuffer mBuffer;
public MyRenderer() {
//獲取浮點形緩衝數據
mBuffer = Utils.getFloatBuffer(mArray);
}
// Surface創建的時候調用
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 設置清屏顏色爲黑色
gl.glClearColor(0f, 0f, 0f, 0f);
}
// Surface改變的的時候調用
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 設置窗口大小
gl.glViewport(width / 4, width / 2, width / 2, height / 2);
}
// 在Surface上繪製的時候調用
@Override
public void onDrawFrame(GL10 gl) {
// 清除屏幕
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// 允許設置頂點 // GL10.GL_VERTEX_ARRAY頂點數組
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// 設置頂點
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mBuffer);
//設置點的顏色爲綠色
gl.glColor4f(0f, 1f, 0f, 0f);
//設置點的大小
gl.glPointSize(80f);
// 繪製點
gl.glDrawArrays(GL10.GL_POINTS, 0, 1);
// 禁止頂點設置
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
1、定義頂點數組
我取了一個點的數組,定義x,y,z座標爲(0f,0f,0f)
2、獲取浮點形緩衝數據
傳入數組,獲取浮點形緩衝數據,這一段代碼是放在了構造函數裏
3、設置清屏顏色
onSurfaceCreated裏設置了清屏顏色爲黑色,這樣便於觀看。
glClearColor是設置清屏顏色,類似的還有
- glClearDepthf——指明深度緩衝區的清理值
- glClearStencil——指明模板緩衝區的清理值
通過調用步驟4裏的glClear方法清理。
glClearDepthf(float depth )指明的區間是0~1,初始值爲1
glClearStencil(int s)指明模板緩衝區的清理值
4、清除屏幕
glClear(int mask) 方法是用來清理緩衝區,並設置爲預設值。
mask的值有以下三種:
- GL_COLOR_BUFFER_BIT——表明顏色緩衝區
- GL_DEPTH_BUFFER_BIT——表明深度緩衝
- GL_STENCIL_BUFFER_BIT——表明模型緩衝區
關於清除屏幕的這三種類型的用法,我會在後續單獨用一篇文章來講解。
5、允許設置頂點
glEnableClientState(int array) 調用這個方法來啓用客戶端的某項功能。對應的是glDisableClientState(int array) 禁用客戶端的某項功能。
默認情況下,所有功能是被禁止的。
根據傳遞進入的int參數選擇某項功能。
array 可以是下列符號常量:
- GL_VERTEX_ARRAY ——如果啓用,頂點矩陣可以用來寫入
- GL_COLOR_ARRAY————如果啓用,顏色矩陣可以用來寫入
- GL_NORMAL_ARRAY—— 如果啓用, 法線矩陣可以用來寫入
- GL_TEXTURE_COORD_ARRAY——如果啓用,紋理座標矩陣可以用來寫入
- GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)——如果啓用,點大小矩陣控制大小以渲染點和點sprites。這時由glPointSize 定義的點大小將被忽略,由點大小矩陣提供的大小將被用來渲染點和點sprites。
以上幾種參數按順序對應的專業名詞是
- 頂點
- 顏色
- 法線(用於光照處理)
- 材質
PS:最後一個參數GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension)我在GL10這個類裏沒找到,不知道爲什
後續會講到這些的用法。
6、設置頂點
glVertexPointer(int size, int type, int stride, Buffer pointer)是定義一個頂點座標矩陣。傳入四個參數
- size——每個頂點的座標維數,必須是2, 3 或者4,初始值是4。
- type——指明每個頂點座標的數據類型,允許的符號常量GL_BYTE, GL_SHORT,GL_FIXED 和GL_FLOAT,初始值爲GL_FLOAT。
- stride——指明連續頂點間的位偏移,如果爲0,頂點被認爲是緊密壓入矩陣,初始值爲0。
- pointer——指明頂點座標的緩衝區,如果爲null,則沒有設置緩衝區。
7、設置頂點的顏色爲綠色
這個就是設置頂點的顏色
8、設置點的大小
這個就是設置頂點的大小
9、繪製頂點
glDrawArrays(int mode, int first, int count)傳入三個參數,分別代表模式、繪製的起點、頂點數量
官方API解釋如下:
- mode——指明渲染哪一種圖元。允許的符號常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN 和GL_TRIANGLES。
- first——指明在允許訪問的矩陣中的起始索引。
- count——指明要渲染的索引的數量。
OpenGL ES提供了兩類方法來繪製一個空間幾何圖形:
- public abstract void glDrawArrays(int mode, int first, int count) 使用VetexBuffer 來繪製,頂點的順序由vertexBuffer中的順序指定。
- public abstract void glDrawElements(int mode, int count, int type, Buffer indices) ,可以重新定義頂點的順序,頂點的順序由indices Buffer 指定。
10、禁止頂點設置
繪製完成後,就關閉對應的功能。
三、效果
附上Demo鏈接:打開鏈接
密碼:yvd5