Trong bài trước Học android 3d với opengles (bài 3) chúng ta đã biết vẽ hình và một số thao tác xoay hình…. Trong phần này sẽ hướng dẫn bạn vẽ hình chóp (Pyramid), hình hộp (cuboid).

- Trước tiên chúng ta cần xác định một số công việc cần thiết để thực hiện vẽ
+ Tọa độ các đỉnh
+ Màu vẽ các đỉnh để phân biệt khi xoay hình
+ Chỉ số các đỉnh
+ Góc xoay // ta khai báo trong lớp GLRenderer.java

B1: Ta cần thiết khai báo 3 buffer để lưu trữ đỉnh, màu, và chỉ số đỉnh. Ta sẽ khai báo chúng trong lớp Triangle như sau:

private FloatBuffer vertices_Buffer;// ta thay floatbuffer = vertices_Buffer cho dễ hiểu;
private ShortBuffer indices_Buffer;
private FloatBuffer colors_buffer;


- Và khai báo trong method Initialize() như sau:

float vertices[] = { //Đây là tọa độ 4 đỉnh của hình chóp
-0.5f, -0.5f, 0.5f, // 0
0.5f, -0.5f, 0.5f, // 1
0f, -0.5f, -0.5f, // 2
0f, 0.5f, 0f, // 3
};

short indices[] = new short[]{//Là id của các Triangle
0, 1, 3, // Triangle1
0, 2, 1, // Triangle1
0, 3, 2, // Triangle1
1, 2, 3, // Triangle1
};

float[] colors = {//Màu các đỉnh tương ứng
1f, 0f, 0f, 1f, // point 0 red
0f, 1f, 0f, 1f, // point 1 green
0f, 0f, 1f, 1f, // point 2 blue
1f, 1f, 1f, 1f, // point 3 white

};

ByteBuffer vbb = ByteBuffer.allocateDirect(coords.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertices_Buffer= vbb.asFloatBuffer();


ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
indices_Buffer= ibb.asShortBuffer();

ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colors_buffer= cbb.asFloatBuffer();

vertices_Buffer.put(vertices);
indices_Buffer.put(indices);
colors_buffer.put(colors);

vertices_Buffer.position(0);
indices_Buffer.position(0);
colors_buffer.position(0);
}
OK: Bây giờ đã xong bước khởi tạo các tham số cần thiết cho lớp Triangle.java thực ra đây là lớp (Hình chóp).
Trong bước này rất dễ hiểu và nội dung giải thích đầy đủ ở bài 2 nên tôi không nói thêm.

B2: Trong method onDrawGL(GL10 gl) ta khai báo như sau:

public void onDrawGL(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, floatBuffer);

gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);

gl.glDrawElements(GL10.GL_TRIANGLES, 12,GL10.GL_UNSIGNED_SHORT ,shortBuffer);

gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

}
- Các lệnh cũng dễ hiểu, ở đây chỉ khác là tôi thay lệnh gl.glDrawArrays bằng lệnh gl.glDrawElements(GL10.GL_TRIANGLES, 12,GL10.GL_UNSIGNED_SHORT ,shortBuffer); Với mục đích dễ vẽ hơn. Tham số thứ nhất là kiểu vẽ primitive là các hình tam giác (Bài 1), và tham số thứ 2 là số đỉnh cần vẽ, tham số thứ 4 kiểu, tham số thứ 4 là indices.

- Trong lớp GLRenderer ta bỏ đi Triangle1 ở bài trước và bổ sung trong phương thức onSurfaceCreated như sau: (Phân biệt mặt trước, mặt sau (Trong, ngoài) theo chiều kim đồng hồ).
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// TODO Auto-generated method stub
//bật chức năng phân biệt mặt trước, mặt sau của hình tam giác
gl.glEnable(GL10.GL_CULL_FACE);
//Mặt trước được vẽ theo chiều kim đồng hồ
gl.glFrontFace(GL10.GL_CCW);
//Mặt khác thì không được vẽ
gl.glCullFace(GL10.GL_BACK);

triangle=new Triangle();
//triangle1 =new Triangle1();
}

Bây giờ Launching sẽ được hình như sau:



B3: Để cảm nhận sự thay đổi và nhận biết rõ hình chóp ta sẽ thay đổi trong lớp GLRenderer.java

- Ta thêm 2 biến xAngle, yAngle và tạo get, set cho nó với mục đính là xoay hình chóp theo cả 2 trục tọa độ X, Y:

private float xAngle;

private float yAngle;

public float getxAngle() {
return xAngle;
}

public void setxAngle(float xAngle) {
this.xAngle = xAngle;
}

public float getyAngle() {
return yAngle;
}

public void setyAngle(float yAngle) {
this.yAngle = yAngle;
}

à Và bổ xung 2 lệnh trong onDrawFrame như sau:

public void onDrawFrame(GL10 gl) {
// TODO Auto-generated method stub

// xóa màu nền bởi màu đen ta không thay đổi màu nền nữa

gl.glClearColor(0f, 0f, 0f, 1.0f);

//reset matrix
gl.glLoadIdentity();

// xóa buffer dept
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

// triangle1.onDrawGL(gl);
// set rotation
gl.glRotatef(xAngle, 1f, 0f, 0f);
gl.glRotatef(yAngle, 0f, 1f, 0f);

triangle.onDrawGL(gl);

}

  • Trong lớp Android3Dview ta thay đổi trong onTouchEvent với mục đích để xoay hình chóp.


private float _x = 0;
private float _y = 0;



public boolean onTouchEvent(final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
_x = event.getX();
_y = event.getY();
}
if (event.getAction() == MotionEvent.ACTION_MOVE) {
final float xdiff = (_x - event.getX());
final float ydiff = (_y - event.getY());
queueEvent(new Runnable() {
public void run() {
glRenderer.setxAngle(glRenderer.getxAngle() + ydiff);
glRenderer.setyAngle(glRenderer.getyAngle() + xdiff);
}
});
_x = event.getX();
_y = event.getY();
}
return true;
}
Bây giờ ta Launching và kiểm tra xem hình được vẽ như thế nào nhé


B4: Tương tự như trên để vẽ hình chóp ta chỉ cần thay đổi kích thước của Đỉnh, Màu, Chỉ số các đỉnh là OK:


=> Trong public void initialize() Ta thay 3 biến như sau

private float width=0.3f,height=0.3f,depth=0.3f;
float[] vertices = {

-width, -height, -depth, // 0
width, -height, -depth, // 1
width, height, -depth, // 2
-width, height, -depth, // 3
-width, -height, depth, // 4
width, -height, depth, // 5
width, height, depth, // 6
-width, height, depth // 7


};
float colors[] = // 2
{
1f, 0f, 0f, 1f, // point 0 red
0f, 1f, 0f, 1f, // point 1 green
0f, 0f, 1f, 1f, // point 2 blue
1f, 1f, 1f, 1f, // point 3 white
1f, 1f, 0f, 0f,
0f,1f,1f,0f,
1f,1f,0f,0f,
1f,0f,0f,0f,
};

short[] indices = new short[] {
0, 2, 1,
0, 3, 2,

1,2,6,
6,5,1,

4,5,6,
6,7,4,

2,3,6,
6,3,7,

0,7,3,
0,4,7,

0,1,5,
0,5,4

};
Và trong onDrawGL() thay thay 12 đỉnh = 36 đỉnh: gl.glDrawElements(GL10.GL_TRIANGLES, 36,GL10.GL_UNSIGNED_SHORT , indices_Buffer);

Kết quả khi chạy:


Pyramid: Example Android3D.rar

Cuboid: Example Tutorial3D.rar

Chủ đề tương tự: