定義圖形
創建高端圖形的第一步是在OpenGL ES視圖的上下文中定義被繪製的圖形,如果你不知道OpenGL ES如何定義繪製圖形的一些基礎知識,使用OpenGL ES繪製可能會有點棘手.
本課會講解與Android設備屏幕相關的OpenGL ES座標系統,圖形定義的基礎知識,圖形的表面,以及定義三角形和正方形.
定義三角形
OpenGL ES允許你在三維座標系中定義繪製物體.所以,在繪製三角形之前,你必須定義他的座標.在OpenGL中,通常的做法是爲座標定義浮點類型的頂點數組.爲了最大化的提升性能,將這些座標寫入ByteBuffer,傳遞給OpenGL ES的圖形管線處理.
public class Triangle {
private FloatBuffer vertexBuffer;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = { // in counterclockwise order:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
public Triangle() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
triangleCoords.length * 4);
// use the device hardware's native byte order
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate
vertexBuffer.position(0);
}
}
默認情況下,OpenGL ES假定[0,0,0](X,Y,Z)爲GLSurfaceView視圖的座標中心,[1,1,0]是視圖的右上角,[-1,-1,0]是視圖的左下角.座標系統的例圖說明見: OpenGL ES developer guide
注意圖形的座標是按照逆時針方向定義的.繪製的順序很重要,因爲它使用OpenGL ES 表面剔除特性,決定了圖形的哪一面是要繪製的圖形正面,哪一面是背面(不需要繪製的面),更多圖形表面和剔除的知識,請移步:OpenGL ES developer guide
定義正方形
在OpenGl中定義三角形非常的簡單,但是如果你想定義更復雜的圖形,比如:正方形,該怎麼做呢?有許多方法可以做到,但是在OpenGL ES中,通常的做法是,將兩個三角形組合起來:
再次重申,你應該按照逆時針方向定義代表正方形的兩個三角形的定點,然後把定義的定點放如ByteBuffer中.爲了避免定義的兩個座標被每個三角形共享兩次(這句我怎麼翻都不通順?),使用繪製列表告訴OpenGl ES圖形管線如何去繪製這些頂點.下面是這個圖形的代碼:
public class Square {
private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float squareCoords[] = {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
public Square() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(
// (# of coordinate values * 4 bytes per float)
squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(
// (# of coordinate values * 2 bytes per short)
drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
}
}