OpenGL – C++ Bài 3: Phép Quay và Phép Dịch Trong OpenGL
Hi. Chào mừng các bạn đến chủ đề Học Lập Trình OpenGL tại blog: Phát Triển Phần Mềm 123-az
Trong bài viết số 3 này. Mình sẽ nói về phép quay và phép dịch trong opengl.
I. Lý Thuyết Cơ Bản.
1. Phép Dịch:
Để di chuyển một điểm từ vị trí A tới một vị trí B trong tọa độ không gian 3d.
Người ta có hai cách thực hiện.
+ Giữ nguyên hệ trục tọa độ và thay đổi giá trị của điểm.
+ Giữ nguyên giá trị của điểm nhưng thay đổi vị trí của hệ tọa độ. Gọi là dời hệ quy chiếu.
Thay đổi giá trị của điểm thì không có gì khó, chúng ta chỉ việc tính toán giá trị muốn thay đổi và vẽ bình thường.
Nhưng khi muốn thay đổi hệ trục tọa độ sang một vị trí khác thì làm thế nào.
Opengl hỗ trợ câu lệnh sau để thực hiện
glTranslatef(x, y, z);
Câu lệnh này cho phép bạn rời hệ quy chiếu sang một vị trí mới với giá trị x, y, z được truyền vào.
glTranslatef(2.0, 0.0, 0.0); glBegin(GL_LINES); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd();
Trong đoạn code trên, tôi vẽ line màu vàng từ 2 điểm A(0.0, 0.0, 0.0) và B(1.0, 0.0. 0.0).
Nếu bình thường, line màu vàng sẽ nằm trùng với line màu đỏ.
Nhưng vì tôi dùng lệnh glTranslatef, nên hệ tọa độ được dịch sang vị trí gốc tọa độ mới là : O'(2.0, 0.0, 0.0).
Nên line màu vàng được vẽ trong tọa độ mới và nó cách hệ quy chiếu cũ một vector ( 2.0, 0.0, 0.0)
Câu hỏi đặt ra:
Khi tôi đổi hệ trục tọa độ sang vị trí mới, vậy nếu tôi muốn đưa nó về lại vị trí cũ thì sao.
Sử dụng câu lệnh glLoadIdentity() để đưa hệ tọa độ trở về ban đầu.
Sử dụng thêm 2 câu lệnh: glPushMatrix để cất hệ trục hiện tại vào stack, sau đó dùng gltranslate để thay đổi hệ tọa độ mới.
Sau khi vẽ xong đối tượng, muốn lấy lại hệ tọa độ trước khi dùng glTranslate. thì dùng glPopMatrix.
Như vậy, sẽ xảy ra trường hợp, người ta liên tục dùng glTranslate lồng nhau.
=> sẽ có bấy nhiêu cặp glPushMatrix và glPopMatrix đi kèm nếu người ta thực sự muốn khôi phục.
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glBegin(GL_LINES); //OX glColor3f(1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); glBegin(GL_LINES); //OY glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glEnd(); glBegin(GL_LINES); //OZ glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glEnd(); glPushMatrix(); //Cất hệ tọa độ hiện tại vào stack glTranslatef(2.0, 0.0, 0.0); // Rời trục sang gốc mới để có hệ tọa độ mới glBegin(GL_LINES); glColor3f(1.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); glPopMatrix(); // Lấy lại hệ tọa độ glBegin(GL_LINES); glColor3f(0.0, 1.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd();
Kết quả:
2. Phép Quay trong Opengl
Phép quay trong opengl cho phép một đối tượng quay quanh một trục.
Về bản chất, cũng là cách thay đổi hệ trục tọa độ hiện hành, nhưng không phải là phép dời trục mà là phép xoay trục.
Xoay theo X => Mặt phẳng YOZ quay | Xoay theo Y => Mặt phẳng XOZ quay | Xoay theo Z => Mặt phẳng XOY quay.
Và câu lệnh dưới đây sẽ thực hiên việc quay.
glRotatef(angle, x, y, z);
Ví dụ quay theo trục Z một góc 450 thì sẽ là: glRotatef(45.0, 0.0, 0.0, 1.0);
Code:
#include <stdio.h> #include <GL/glut.h> void DrawCoodinate() { glColor3f(1.0,0.0,0.0); glBegin(GL_LINES); glVertex3f(100.0,0.0,0.0); glVertex3f(-100.0,0.0,0.0); glVertex3f(10.0,0.0,0.0); glEnd(); glColor3f(0.0,1.0,0.0); glBegin(GL_LINES); glVertex3f(0.0,100.0,0.0); glVertex3f(0.0,-100.0,0.0); glEnd(); glColor3f(0.0,0.0,1.0); glBegin(GL_LINES); glVertex3f(0.0,0.0,100.0); glVertex3f(0.0,0.0,-100.0); glVertex3f(0.0,0.0,10.0); glEnd(); } void RenderScene() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0.0,0.0,0.5, 0.0,0.0,0.0, 0.0,1.0,0.0); DrawCoodinate(); glPushMatrix(); glRotatef(45, 0.0, 0.0, 1.0); glColor3f(1.0, 0.5, 0.5); glutWireTeapot(0.1); glPopMatrix(); glutSwapBuffers(); glFlush(); } void ReShape(int width, int height) { if (height == 0) { height = 1; } float ratio = (float)width/(float)height; glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, ratio, 0.1, 100.0); glMatrixMode(GL_MODELVIEW); } void main() { glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutInitWindowSize(1200,600); glutInitWindowPosition(100,100); glutCreateWindow ("Phat Trien Phan Mem 123AZ"); glutReshapeFunc(ReShape); glutDisplayFunc(RenderScene); glutMainLoop(); }
ad em đang học môn thiết kế đồ họa mà bóc trúng đề tài robot đá bóng nhưng k bt bắt đầu làm như thế nào