Việc có thể xác định hình dạng cần vẽ trong bối cảnh chế độ xem OpenGL ES là bước đầu tiên trong tạo đồ hoạ cao cấp cho ứng dụng của bạn. Vẽ bằng OpenGL ES có thể hơi phức tạp nếu không biết một số thông tin cơ bản về cách OpenGL ES muốn bạn xác định đối tượng đồ hoạ.
Bài học này giải thích về hệ toạ độ OpenGL ES liên quan đến màn hình thiết bị Android, kiến thức cơ bản về việc xác định hình dạng, mặt của hình dạng cũng như xác định tam giác và hình vuông.
Định nghĩa tam giác
OpenGL ES cho phép bạn xác định các đối tượng được vẽ bằng cách sử dụng toạ độ trong không gian ba chiều. Vì vậy,
trước khi vẽ một hình tam giác, bạn phải xác định toạ độ của nó. Trong OpenGL, cách làm thông thường
hàm này xác định một mảng đỉnh gồm các số có dấu phẩy động cho toạ độ. Tối đa
hiệu quả, bạn sẽ viết các toạ độ này vào ByteBuffer
, được chuyển vào
Quy trình đồ hoạ OpenGL ES để xử lý.
Kotlin
// number of coordinates per vertex in this array const val COORDS_PER_VERTEX = 3 var triangleCoords = floatArrayOf( // 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 ) class Triangle { // Set color with red, green, blue and alpha (opacity) values val color = floatArrayOf(0.63671875f, 0.76953125f, 0.22265625f, 1.0f) private var vertexBuffer: FloatBuffer = // (number of coordinate values * 4 bytes per float) ByteBuffer.allocateDirect(triangleCoords.size * 4).run { // use the device hardware's native byte order order(ByteOrder.nativeOrder()) // create a floating point buffer from the ByteBuffer asFloatBuffer().apply { // add the coordinates to the FloatBuffer put(triangleCoords) // set the buffer to read the first coordinate position(0) } } }
Java
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); } }
Theo mặc định, OpenGL ES giả định một hệ toạ độ trong đó [0,0,0] (X,Y,Z) xác định tâm của
khung GLSurfaceView
,
[1,1,0] là góc trên cùng bên phải của khung hình và
[-1,-1,0] là góc dưới cùng bên trái của khung hình. Để biết hình minh hoạ hệ toạ độ này, hãy xem
Nhà phát triển OpenGL ES
hướng dẫn.
Lưu ý rằng toạ độ của hình dạng này được xác định theo thứ tự ngược chiều kim đồng hồ. Bản vẽ rất quan trọng vì nó xác định mặt nào là mặt trước của hình dạng, mà bạn thường muốn vẽ và mặt sau (bạn có thể chọn không vẽ bằng cách sử dụng bộ chọn OpenGL ES khuôn mặt. Để biết thêm thông tin về các khuôn mặt và danh sách chọn khuôn mặt, hãy xem Hướng dẫn cho nhà phát triển OpenGL ES.
Xác định hình vuông
Xác định tam giác khá dễ dàng trong OpenGL, nhưng nếu bạn muốn nhận thêm một chút phức tạp không? Bạn có muốn chọn hình vuông không? Có một số cách để thực hiện điều này, nhưng cách thức thông thường để vẽ hình dạng trong OpenGL ES sử dụng hai hình tam giác được vẽ cùng nhau:
![](https://developer.android.com/static/images/opengl/ccw-square.png?authuser=9&hl=vi)
Hình 1. Vẽ hình vuông bằng hai hình tam giác.
Xin nhắc lại, bạn nên xác định các đỉnh theo thứ tự ngược chiều kim đồng hồ cho cả hai tam giác
biểu thị hình dạng này và đặt các giá trị vào ByteBuffer
. Để tránh
xác định hai toạ độ mà mỗi tam giác dùng chung hai lần, hãy sử dụng danh sách vẽ để cho
Quy trình đồ hoạ của OpenGL ES cách vẽ các đỉnh này. Đây là mã cho hình dạng này:
Kotlin
// number of coordinates per vertex in this array const val COORDS_PER_VERTEX = 3 var squareCoords = floatArrayOf( -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 ) class Square2 { private val drawOrder = shortArrayOf(0, 1, 2, 0, 2, 3) // order to draw vertices // initialize vertex byte buffer for shape coordinates private val vertexBuffer: FloatBuffer = // (# of coordinate values * 4 bytes per float) ByteBuffer.allocateDirect(squareCoords.size * 4).run { order(ByteOrder.nativeOrder()) asFloatBuffer().apply { put(squareCoords) position(0) } } // initialize byte buffer for the draw list private val drawListBuffer: ShortBuffer = // (# of coordinate values * 2 bytes per short) ByteBuffer.allocateDirect(drawOrder.size * 2).run { order(ByteOrder.nativeOrder()) asShortBuffer().apply { put(drawOrder) position(0) } } }
Java
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); } }
Ví dụ này cung cấp cho bạn thông tin sơ bộ về những việc cần làm để tạo hình dạng phức tạp hơn bằng OpenGL. Trong nói chung, bạn sẽ sử dụng các bộ sưu tập tam giác để vẽ các đối tượng. Trong bài học tiếp theo, bạn sẽ học cách vẽ các hình dạng này trên màn hình.