12/08/2018, 13:01

OpenGL part 2: Building a polygon

Trong bài viết này chúng ta sẽ tìm hiểu cách render 1 polygon. Mô hình 3D được xây dựng với các phần tử nhỏ hơn (đỉnh, cạnh, khuôn mặt, và đa giác) mà có thể được thao tác riêng lẻ. Một vertex (đỉnh trong số nhiều) là các khối xây dựng nhỏ nhất của mô hình 3D. Một đỉnh là một điểm nơi hai ...

Trong bài viết này chúng ta sẽ tìm hiểu cách render 1 polygon.

Mô hình 3D được xây dựng với các phần tử nhỏ hơn (đỉnh, cạnh, khuôn mặt, và đa giác) mà có thể được thao tác riêng lẻ.

Một vertex (đỉnh trong số nhiều) là các khối xây dựng nhỏ nhất của mô hình 3D. Một đỉnh là một điểm nơi hai hay nhiều cạnh đáp ứng. Trong một mô hình 3D một đỉnh có thể được chia sẻ giữa tất cả các kết nối cạnh, bước và đa giác. Một đỉnh cũng có thể là một đại diện cho vị trí của một máy ảnh hoặc một nguồn ánh sáng. Bạn có thể thấy một đỉnh trong hình dưới đây được đánh dấu bằng màu vàng.

vertex.png

Để định nghĩa các đỉnh trong android, chúng ta phải định nghĩa 1 mảng số thực đặt trong một bộ nhớ đệm byte để đạt được hiệu suất tốt hơn.

poly1.png

private float vertices[] = {
      -1.0f,  1.0f, 0.0f,  // 0, Top Left
      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
       1.0f,  1.0f, 0.0f,  // 3, Top Right
};

// a float is 4 bytes, therefore we multiply the number if vertices with 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);

private float vertices[] = {
      -1.0f,  1.0f, 0.0f,  // 0, Top Left
      -1.0f, -1.0f, 0.0f,  // 1, Bottom Left
       1.0f, -1.0f, 0.0f,  // 2, Bottom Right
       1.0f,  1.0f, 0.0f,  // 3, Top Right
};

// a float is 4 bytes, therefore we multiply the number if vertices with 4.
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);

Đừng quên rằng kiểu float là 4 byte và nhân nó với số lượng các đỉnh để có được kích thước trên bộ đệm. OpenGL ES có chuỗi các chức năng để áp dụng khi bạn muốn nó render. Hầu hết các chức năng này không được kích hoạt mặc định, do đó bạn cần phải nhớ để tạo ra những cái bạn muốn sử dụng. Bạn cũng cần phải khởi tạo những chức năng để chúng làm việc cùng. Vì vậy, trong trường hợp của đỉnh của chúng tôi, chúng tôi cần phải nói với OpenGL ES rằng nó không quan trọng để làm việc với các bộ đệm đỉnh, chúng tôi khởi tạo ra nó để biết rằng nó ở đâu.

// Enabled the vertex buffer for writing and to be used during rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

Khi bạn đang thực hiện với các bộ đệm không quên để vô hiệu hóa nó.

// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

Edge là một đường thẳng giữa hai đỉnh. Họ là những đường viền của khuôn mặt và đa giác. Trong một mô hình 3D một cạnh có thể được chia sẻ giữa hai mặt kề nhau hoặc đa giác. Chuyển một cạnh ảnh hưởng đến tất cả các đỉnh kết nối, khuôn mặt và đa giác. Trong OpenGL ES bạn không xác định các cạnh, bạn thay xác định khuôn mặt bằng cách cho họ các đỉnh đó sẽ xây dựng ba cạnh. Nếu bạn muốn thay đổi một cạnh bạn thay đổi hai đỉnh mà làm cho cạnh. Bạn có thể thấy một cạnh trong hình dưới đây được đánh dấu bằng màu vàng.

edge.png

Face là một hình tam giác. Face là một bề mặt giữa ba đỉnh góc và ba cạnh xung quanh. Chuyển một mặt ảnh hưởng đến tất cả các đỉnh kết nối, cạnh và đa giác.

faceopengl.png

Khi bạn muốn cuộn trên một mặt, nó cần hướng đúng bởi vì hướng được định nghĩa hướng xác định những gì bên sẽ có mặt trước và những gì bên sẽ có mặt trở lại. Tại sao điều đó lại quan trọng, bởi vì để đạt được hiệu suất, chúng ta không muốn vẽ cả hai bên vì vậy chúng tôi tắt mặt sau . Vậy đây là ý tưởng tốt nhất để sử dụng cuộn trên tất cả dự án của bạn.Nó có thể thay đổi hướng được định nghĩa mặt trước với glFrontFace.

 gl.glFrontFace(GL10.GL_CCW);

Để làm cho OpenGL ko bỏ qua tất cả mặt bị biến mất trên màn hình, bạn có thể sử dụng gọi lại mặt bị tiêu huỷ. Những gì đã được đinh trước một, hình đa giác của một đối tượng đồ họa có thể nhìn thấy bằng cách kiểm tra nếu mặt cuộn lên đúng thứ tự.

 gl.glEnable(GL10.GL_CULL_FACE);

Đó là tất nhiên có thể thay đổi những gì khuôn mặt bên phải được rút ra hay không.

gl.glCullFace(GL10.GL_BACK);

polygon.png

Thời gian để cuộn một mặt, chúng ta nhớ rằng chúng ta quyết định hướng cuộn ngược chiều kim đồng hồ. poly2.png

private short[] indices = { 0, 1, 2, 0, 2, 3 };

Để có lợi cho hiệu năng chúng ta cũng cần một bộ nhớ đệm kiểu byte.

// short is 2 bytes, therefore we multiply the number if vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);

// short is 2 bytes, therefore we multiply the number if vertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);

Đừng quên rằng kiểu short bằng 2 byte và nhân nó với số lượng các chỉ số để có được kích thước phù hợp để cấp cho bộ đệm trên.

0