OpenGL Tiếng Việt
Đọc bài gốc
+ download code minh họa bằng nhiều ngôn ngữ tại
trang của tác giả. Đây chỉ là bản dịch do
mình tự dịch.
http://nehe.gamedev.net/tutorial/rotation/14001/
Bài 4 - Rotation - Quay
Bài trước tôi đã
chỉ cho các bạn cách thêm màu vào tam giác và hình vuông. Trong bài
này tôi sẽ chỉ cho các bạn cách xoay các cái hình này quanh một
trục tọa độ.
Dùng code bài trước,
ta chỉ thêm vài dòng vào thôi. Tôi sẽ viết lại các đoạn
code để cho bạn tiện xem các dòng được
thêm vào và dòng nào thì bị thay thế.
Chúng ta bắt đầu
bằng việc thêm 2 biến vào đầu chương
trình để lưu độ xoay của mỗi đối
tượng. Nếu bạn để ý thì sẽ thấy
là ta có thêm dòng mới sau 'bool fullscreen=TRUE;'.
Hai dòng này khai báo 2 biến float mà ta dùng. Bạn cứ để
ý thì thấy OpenGL chủ yếu dùng số float. Biến
rtri lưu độ xoay của tam giác, rquad lưu độ
xoay của hình vuông.
#include <windows.h> // Header File For Windows
#include <gl\gl.h> // Header File For The OpenGL32
Library
#include <gl\glu.h> // Header File For The GLu32
Library
#include <gl\glaux.h> // Header File For The GLaux
Library
HDC hDC=NULL; //
Private GDI Device Context
HGLRC hRC=NULL; //
Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; //
Holds The Instance Of The Application
bool keys[256]; //
Array Used For The Keyboard Routine
bool active=TRUE; //
Window Active Flag
bool fullscreen=TRUE; //
Fullscreen Flag Set To TRUE By Default
GLfloat rtri; //
Angle For The Triangle ( NEW )
GLfloat rquad; // Angle For The Quad ( NEW )
Giờ sửa code
trong hàm DrawGLScene(). Tôi sẽ viết lại cả cái hàm
này. Tôi sẽ trình bày rõ tại sao lại sửa dòng nào, và
code mới thì nó làm công việc gì. Đoạn code tiếp đây
giống hệt đoạn code bài trước.
int DrawGLScene(GLvoid) //
Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT); // Clear The Screen And The
Depth Buffer
glLoadIdentity(); //
Reset The View
glTranslatef(-1.5f,0.0f,-6.0f); //
Move Into The Screen And Left
Dòng code tiếp theo là
dòng mới thêm vào. glRotate(Angle,Xvector,Yvector,Zvector) thực hiện
công việc xoay đối tượng quanh một tọa độ.
Bạn sẽ phải dùng cái hàm này nhiều. Angle là một
số chỉ độ xoay. Tham số Xvector, Yvector, Zvector
chỉ ra vector xoay. Nếu bạn dùng giá trị (1,0,0) thì là
đang dùng một vector chuyển hướng 1 đơn vị
tọa độ x về bên phải. Giá trị (-1,0,0) là
vector chuyển hướng một đơn vị về
bên trái.
D. Michael Traub: has
supplied the above explanation of the Xvector, Yvector and Zvector parameters.
Để hiểu
thêm về sự xoay X, Y và Z tôi sẽ giải thích bằng
ví dụ.
X Axis - You're working on a
table saw. The bar going through the center of the blade runs left to right
(just like the x axis in OpenGL). The sharp teeth spin around the x axis (bar
running through the center of the blade), and appear to be cutting towards or
away from you depending on which way the blade is being spun. When we spin
something on the x axis in OpenGL it will spin the same way.
Y Axis - Imagine that you
are standing in the middle of a field. There is a huge tornado coming straight
at you. The center of a tornado runs from the sky to the ground (up and down,
just like the y axis in OpenGL). The dirt and debris in the tornado spins
around the y axis (center of the tornado) from left to right or right to left.
When you spin something on the y axis in OpenGL it will spin the same way.
Z Axis - You are looking at
the front of a fan. The center of the fan points towards you and away from you
(just like the z axis in OpenGL). The blades of the fan spin around the z axis
(center of the fan) in a clockwise or counterclockwise direction. When You spin
something on the z axis in OpenGL it will spin the same way.
Vậy ở dòng code
sau, nếu rtri = 7, ta sẽ xoay 7 đơn vị quanh trục
Y (trái sang phải). Bạn có thể thử với code để
hiểu thêm.
Một điểm phải
nhớ đó là độ xoay tính bằng đơn vị độ
(chứ không phải radian hay gì đâu). Nếu rtri = 10, ta sẽ
quay 10 độ trên trục y.
Theo mình hiểu
thì tham số đầu là độ xoay - xoay 1800
thì đặt Angle=180. Còn 3 cái còn lại là vector trục xoay
với gốc vector là điểm hiện hành.
glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The
Triangle On The Y axis ( NEW )
Đoạn code tiếp
theo thì không có gì thay đổi tất. Vẽ tam giác màu với
chế độ hòa trộn là smooth. Tam giác sẽ được
vẽ ở phía trái màn hình, và sẽ bị xoay trên trục
Y theo chiều trái sang phải.
glBegin(GL_TRIANGLES); //
Start Drawing A Triangle
glColor3f(1.0f,0.0f,0.0f); // Set
Top Point Of Triangle To Red
glVertex3f( 0.0f, 1.0f, 0.0f); // First
Point Of The Triangle
glColor3f(0.0f,1.0f,0.0f); // Set
Left Point Of Triangle To Green
glVertex3f(-1.0f,-1.0f, 0.0f); // Second
Point Of The Triangle
glColor3f(0.0f,0.0f,1.0f); // Set
Right Point Of Triangle To Blue
glVertex3f( 1.0f,-1.0f, 0.0f); // Third
Point Of The Triangle
glEnd(); // Done Drawing The Triangle
Để ý đoạn
code dưới đây tôi thêm lệnh glLoadIdentity() mới.
Ta gọi nó để reset cái view. Nếu ta không reset nó. Nếu
ta translate sau khi đối tượng được xoay,
bạn sẽ gặp kết quả không mong muốn. Bởi
vì tọa độ đã bị xoay, nó có thể không phải
như bạn đã nghĩ. Vì thế nếu ta translate trái
trên trục X, ta có thể bị dịch lên hay xuống thay
vì như ta muốn. Thử lệnh glLoadIdentity() để
kiểm chứng những gì tôi vừa nói.
Một khi scene bị
reset, X là từ trái sang phải, Y là trên và dưới, Z là
vào và ra, ta dịch chuyển. Bạn sẽ thấy là ta chỉ
dịch 1.5 sang phải thay vì 3.0 như bài trước ta
làm. Khi ta reset cái màn hình, focus sẽ được dịch
về giữa màn hình. Nghĩa là ta không còn ở vị trí
1.5 đơn vị về phía trái nữa mà đã về vị
trí 0.0. Vì vậy dịch 1.5 đơn vị sang phải là đúng
rồi.
Sau khi dịch sang vị
trí mới ở bên phải màn hình, ta xoay hình vuông theo trục
X. Điều này làm hình vuông bị xoay lên và xuống.
glLoadIdentity(); //
Reset The Current Modelview Matrix
glTranslatef(1.5f,0.0f,-6.0f); //
Move Right 1.5 Units And Into The Screen 6.0
glRotatef(rquad,1.0f,0.0f,0.0f); //
Rotate The Quad On The X axis ( NEW )
Đoạn code này thì
cũng không thay đổi gì. Vẽ hình vuông xanh.
glColor3f(0.5f,0.5f,1.0f); //
Set The Color To A Nice Blue Shade
glBegin(GL_QUADS); //
Start Drawing A Quad
glVertex3f(-1.0f, 1.0f, 0.0f); // Top
Left Of The Quad
glVertex3f( 1.0f, 1.0f, 0.0f); // Top
Right Of The Quad
glVertex3f( 1.0f,-1.0f, 0.0f); // Bottom
Right Of The Quad
glVertex3f(-1.0f,-1.0f, 0.0f); // Bottom
Left Of The Quad
glEnd(); // Done Drawing The Quad
Hai dòng tiếp đây
là mới. Ta coi như rtri và rquad như là các cái thùng chứa
(containers ???). Ở đoạn đầu chương trình
ta tạo ra các thùng chứa (GLfloat rtri, và GLfloat rquad). Khi ta
xây dựng thùng chứa thì chúng chưa có gì. Dòng đầu
sau đây thêm 0.2 vào thùng. Vì thế mỗi lần ta kiểm
tra giá trị trong thùng chứa trong đoạn code này, nó sẽ
tăng thêm 0.2 đơn vị. rquad thì giảm 0.15 đơn
vị. Nói tóm lại thì độ
xoay của tam giác nó tăng dần mỗi lần chạy đoạn
code này 0.2 độ, của hình vuông thì giảm mỗi lần
0.15 độ.
Các bạn cứ thử
thay + bằng - , rồi thì 0.2 lên 1.0 để xem nó hoạt
động thế nào. Số càng to thì nhìn nó quay càng nhanh.
rtri+=0.2f; //
Increase The Rotation Variable For The Triangle ( NEW )
rquad-=0.15f; //
Decrease The Rotation Variable For The Quad
( NEW )
return TRUE; // Keep Going
}
Finally change the code to
toggle window / fullscreen mode so that the title at the top of the window is
proper.
if (keys[VK_F1]) // Is
F1 Being Pressed?
{
keys[VK_F1]=FALSE; // If So Make
Key FALSE
KillGLWindow(); // Kill
Our Current Window
fullscreen=!fullscreen; // Toggle
Fullscreen / Windowed Mode
// Recreate Our OpenGL Window ( Modified )
if (!CreateGLWindow("NeHe's Rotation
Tutorial",640,480,16,fullscreen))
{
return 0; // Quit If
Window Was Not Created
}
}
In this tutorial I have
tried to explain in as much detail as possible, how to rotate objects around an
axis. Play around with the code, try spinning the objects, on the Z axis, the X
& Y, or all three :) If you have comments or questions please email me. If
you feel I have incorrectly commented something or that the code could be done
better in some sections, please let me know. I want to make the best OpenGL
tutorials I can. I'm interested in hearing your feedback.
Jeff Molofee (NeHe)