Thứ Sáu, 18 tháng 5, 2012

OpenGL Tiếng Việt Bài 4

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)

 

OpenGL Tiếng Việt Bài 3

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/adding_colour/13003/

Bài 3 - Adding Colour

Bài trước mình đã chỉ các bạn vẽ tam giác với lại tứ giác. Trong bài này tớ sẽ chỉ các bạn cách thêm 2 màu khác nhau vào hình tam giác với tứ giác. Flat coloring sẽ làm cho tứ giác có 1 màu. Smooth coloring sẽ blend 3 màu ở 3 đỉnh của tam giác, tạo ra sự hòa trộn màu nhìn rất là đẹp.

Dùng code của bài trước, chúng ta thêm mấy dòng vào hàm DrawGLScene. Tôi sẽ viết lại hàm này nên nếu muốn sửa code bài trước bạn chỉ cần copy đè hàm dưới đây vào là xong.

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 Current Modelview Matrix

glTranslatef(-1.5f,0.0f,-6.0f); // Left 1.5 Then Into Screen Six Units

glBegin(GL_TRIANGLES); // Begin Drawing Triangles

 

Nếu bạn còn nhớ bài trước thì ở đoạn code này ta vẽ tam giác ở nửa trái màn hình. Dòng code tiếp theo ta dùng lệnh glColor3f(r,g,b). 3 tham số trong ngoặc là đỏ, lục, lam. Giá trị từ 0.0f đến 1.0f.

Giờ ta cứ thiết lập màu là màu đỏ (đỏ sáng nhất, không lục, không lam). Dòng code sau đó là đỉnh đầu (đỉnh trên cùng của tam giác), và sẽ được vẽ bằng màu hiện tại (là màu đỏ). Bất cứ cái gì ta vẽ từ giờ sẽ có màu đỏ cho đến khi ta đổi màu.

glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red

glVertex3f( 0.0f, 1.0f, 0.0f); // Move Up One Unit From Center (Top Point)

Ta vừa vẽ đỉnh đầu ra màn hình với màu đỏ. Giờ trước khi vẽ đỉnh thứ 2 thì ta đổi màu thành màu lục. Như thế là đỉnh tría dưới sẽ có màu lục.

glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green

glVertex3f(-1.0f,-1.0f, 0.0f); // Left And Down One Unit (Bottom Left)

Giờ là đỉnh cuối. Trước khi vẽ ta đổi màu hiện tại thành màu lam. Ngay khi glEnd() được gọi, đa giác sẽ được tô màu. Nhưng mà vì màu ở 3 đỉnh là khác nhau nên thay vì đa giác có 1 màu thì đa giác sẽ được tô bằng màu chuyển, màu sắc thay đổi từ đỉnh này đến đỉnh kia. Cái này gọi là smooth coloring.

glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue

glVertex3f( 1.0f,-1.0f, 0.0f); // Right And Down One Unit (Bottom Right)

glEnd(); // Done Drawing A Triangle

glTranslatef(3.0f,0.0f,0.0f); // From Right Point Move 3 Units Right

Giờ ta vẽ hình vuông đặc màu lam. Phải nhớ rằng bất kỳ cái gì được vẽ đều có màu được thiết lập gần đây nhất. Tất cả các project bạn tạo sẽ sử dụng màu theo cách này hay cách kia. Even in scenes where everything is texture mapped, glColor3f can still be used to tint the color of textures, etc. More on that later.

Vậy để vẽ hình vuông với một màu, tất cả những gì ta phải làm là thiết lập màu về màu mà ta thích (màu lam trong ví dụ này), sau đó vẽ hình vuông. Màu lam sẽ được sử dụng cho mỗi đỉnh bởi vì ta không bảo OpenGL đổi màu ở mỗi đỉnh. Kết quả cuối cùng: hình vuông đặc màu lam. Lại nữa, hình vuông được vẽ theo chiều kim đồng hồ nên cái ta thấy là mặt sau của nó.

glColor3f(0.5f,0.5f,1.0f); // Set The Color To Blue One Time Only

glBegin(GL_QUADS); // Start Drawing Quads

glVertex3f(-1.0f, 1.0f, 0.0f); // Left And Up 1 Unit (Top Left)

glVertex3f( 1.0f, 1.0f, 0.0f); // Right And Up 1 Unit (Top Right)

glVertex3f( 1.0f,-1.0f, 0.0f); // Right And Down One Unit (Bottom Right)

glVertex3f(-1.0f,-1.0f, 0.0f); // Left And Down One Unit (Bottom Left)

glEnd(); // Done Drawing A Quad

return TRUE; // Keep Going

}

Cuối cùng đổi code để thay đổi chế độ cửa sổ/toàn màn hình để tiêu đề ở trên cửa sổ nó đúng.

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 Color 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, how to add flat and smooth coloring to your OpenGL polygons. Play around with the code, try changing the red, green and blue values to different numbers. See what colors you can come up with. 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.