Tài liệu tham khảo của trường đại học wakayama Nhật


/*filename connectlines.cpp*/



tải về 450.11 Kb.
trang2/2
Chuyển đổi dữ liệu08.06.2018
Kích450.11 Kb.
#39699
1   2

/*filename connectlines.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#include"stdio.h"

#endif
GLvoid CALLBACK draw(void){

}
GLvoid CALLBACK left(AUX_EVENTREC *event)

{

static int flag=0;



static GLint x,y;
if(flag){

glColor3d(0.0,0.0,0.0);

glBegin(GL_LINE_STRIP);

glVertex2i(x,y);

glVertex2i(event->data[AUX_MOUSEX],event->data[AUX_MOUSEY]);

glEnd();


glFlush();

}

x=event->data[AUX_MOUSEX];



y=event->data[AUX_MOUSEY];

flag=1;


}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glLoadIdentity();



glViewport(0,0,w,h);

glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0);/* đổi thông số*/

glClearColor(1.0,1.0,1.0,0.0); /*chuyển vị trí 2 hàm này*/

glClear(GL_COLOR_BUFFER_BIT);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,640,480);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left);

auxMainLoop(draw);

return 0;

}

Thực ra chương trình này rất dễ hiểu, có lẽ không phải trình bày gì nhiều.Nó lưu cá điểm lại và nối thành một đường gấp khúc.Nhược điểm của chương trình trên hẳn các bạn đã rõ khi biên dịch nó.Nó không vẽ lại cửa sổ của bạn khi cửa sổ của bạn bị che bởi một cửa sổ khác, hay bị minimize, tức là hình mà bạn muốn vẽ không được gửi tới hàm draw().Vì vậy bạn phải lưu những điểm đã chọn và vẽ lại chúng trong hàm draw().Dưới đây là mã nguồn:



/*filename connectlines1.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
#define MAXPOINTS 100 /*s điểm tối đa có th được chọn*/



GLint point[MAXPOINTS][2]; /*mảng lưu trữ các điểm đó*/

int num=0; /*s đim đã chọn đến thời điểm hiện tại*/
GLvoid CALLBACK draw(void)

{

int i;


if(num>=2){

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glColor3d(0.0,0.0,0.0);

glBegin(GL_LINE_STRIP); /*bạny nh cấu trúcy*/

for(i=0;i

{

glVertex2iv(point[i]);

}

glEnd();

glFlush();

}

}
GLvoid CALLBACK left(AUX_EVENTREC *event)



{

if(num>=MAXPOINTS) return; /*giới hạn s điểm bạn v */

point[num][0]=event->data[AUX_MOUSEX]; /*lưu trữ to đ x của chuột*/

point[num][1]=event->data[AUX_MOUSEY]; /*lưu tr to đ y của chuột*/

num++; /*tăng số điểm sau mỗi lần bấm*/

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glLoadIdentity();



glViewport(0,0,w,h);

glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,640,480);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left);

auxMainLoop(draw);

return 0;

}

Bây giờ bạn không phải lo đến việc cửa sổ không chịu vẽ lại khi nó bị che mất.Một điều cũng đáng chú ý trong chương trình trên là chúng ta đã sử dụng hàm glVertex2iv() hàm này có tham số là thành viên của mảng và thành viên của mảng có các giá trị x,y là số nguyên, chữ i trong phần hậu tố của hàm trên biểu hiện cho giá trị nguyên còn chữ v biểu hiện cho kiểu pointer.Dưới đây cung cấp cho bạn một chương trình có thể vẽ được cả những đường gấp khúc và các đa giác.Mã nguồn không có gì phức tạp và đáng bàn ở đây cả, nó chỉ là cách sắp xếp dữ liệu và có thêm một hàm right() mà thực ra tôi đã đề cập ở các phần trên.



/*filename connectlines2.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
#define MAXPOINTS 100

GLint point[MAXPOINTS][2];

int num=0;

int flag=0;
GLvoid CALLBACK draw(void)

{

int i;



if(num>=2){

if(flag){

flag=0;

i=num-2;


glColor3d(0.0,0.0,0.0);

glBegin(GL_LINE_STRIP);

}

else{


i=0;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glColor3d(0.0,0.0,0.0);

glBegin(GL_POLYGON);

}

for(;i

{

glVertex2iv(point[i]);

}

glEnd();


glFlush();

}

}


GLvoid CALLBACK left(AUX_EVENTREC *event)

{

if(num>=MAXPOINTS) return;



point[num][0]=event->data[AUX_MOUSEX];

point[num][1]=event->data[AUX_MOUSEY];

num++;

flag=1;


}
GLvoid CALLBACK right(AUX_EVENTREC *event)

{

draw();



}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glLoadIdentity();



glViewport(0,0,w,h);

glOrtho(0.0,(GLdouble)w,(GLdouble)h,0.0,0.0,1.0);

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,640,480);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxMouseFunc(AUX_LEFTBUTTON,AUX_MOUSEDOWN,left);

auxMouseFunc(AUX_RIGHTBUTTON,AUX_MOUSEDOWN,right);

auxMainLoop(draw);

return 0;

}

8-Th hiển to đ 3 chiều:

Đến giờ các bạn mới biết đến toạ độ 2 chiều trong opengl, nếu chỉ có vậy thì chẳng khác gì trong lập trình Window cả.Vì vậy trong phần này chúng ta sẽ cùng xem opengl vẽ các hình 3 chiều như thế nào.
/*filename : rotated45.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
GLvoid CALLBACK draw(void)

{

glClearColor(0.0,0.0,0.0,0.0);



glClear(GL_COLOR_BUFFER_BIT);

glRotated(45,0.0,1.0,0.0); /*quay quanh trục OY 45 đ*/

glBegin(GL_QUADS);

glColor3d(1.0,0.0,0.0);

glVertex2d(0.1,0.1);

glColor3d(0.0,1.0,0.0);

glVertex2d(0.9,0.1);

glColor3d(0.0,0.0,1.0);

glVertex2d(0.9,0.9);

glColor3d(1.0,0.0,1.0);

glVertex2d(0.1,0.9);

glEnd();


glFlush();

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glLoadIdentity();



glViewport(0,0,w,h);

glOrtho(-1.0,1.0,-1.0,1.0,0.0,1.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,640,480);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxMainLoop(draw);

return 0;

}

Chương trình này không có gì đặc biệt ngoài hàm glRotated() , hàm này cho phép chúng ta quay hình tứ giác của chúng ta quanh trục OY với góc quay 45 độ.Tham số đầu tiên của nó là góc sẽ được quay, 3 tham số sau là tham số của vector mà hình của chúng ta sẽ quay với góc quay trên.Bạn nhận thấy rằng các giá trị của vector chúng ta là : toạ độ x bằng 0, toạ độ y bằng 1, toạ độ z bằng 0. Tức là véctơ của chúng ta thẳng đứng theo trục OY, bạn có thể thay đổi các thông số của vector này để kiểm nghiệm hàm này xem !Các giá trị của các thông số này là kiểu double.(Chú ý nếu không thử các thông số khác thì bạn sẽ rất khó để quan sát hàm này hoạt động ra sao )


Tiếp theo tôi xin trình bày với các bạn cách vẽ một hình lập phương thật sự bằng opengl.

/*filename cube1.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
GLdouble vertex[][3]={ /*Khai báo dữ liệu cho tám đỉnh của hình lập phương*/

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int edge[][2]={ /*Khai báo các cạnh, mà chúng ta sẽ sư dụng dữ liệu*/

{0,1}, /*của các đỉnh bên trên*/

{1,2},

{2,3},


{0,3},

{4,5},


{5,6},

{6,7},


{7,4},

{0,4},


{1,5},

{2,6},


{3,7}

};
GLvoid CALLBACK draw(void)

{

int i;
glClearColor(0.0,0.0,0.0,0.0);



glClear(GL_COLOR_BUFFER_BIT);

glColor3d(1.0,1.0,1.0);

glBegin(GL_LINES);

for(i=0;i<12;i++){

glVertex3dv(vertex[edge[i][0]]); /*hàm mới*/

glVertex3dv(vertex[edge[i][1]]); /*hàm mới*/

}

glEnd();



glFlush();

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glLoadIdentity();



glViewport(0,0,w,h);

glOrtho(-2.0,2.0,-2.0,2.0,0.0,2.0);

//gluPerspective(30.0,1.0,1.0,10.0);

//gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxMainLoop(draw);

return 0;

}

Phần khai báo dữ liệu, đối với các bạn chắc thật dễ hiểu, điều đáng nói thứ nhất là chúng ta dùng hàm glVertex3dv() thay cho các hàm vẽ đỉnh 2 chiều trước đây, hàm này nhận tham số là thành viên của mảng, giá trị của các thành viên phải là double, và nó có toạ độ 3 chiều.



Trước hết biên dịch chương trình trên, bạn sẽ chưa thấy gì nếu không cho hai hàm mà tôi đã đánh dấu đỏ bên trên vào.Các bạn hãy nhớ lại cách quan sát bằng glOrtho() trước đây và dễ dàng nhận thấy chúng ta không thể nhìn thấy toàn bộ hình lập phương được mà chỉ là một hình vuông, vì cách nhìn bằng glOrtho() chỉ cho ta nhìn song song thôi.Chính vì vậy mà chúng ta phải chuyển qua cách quan sát bằng gluPerspective(), bốn tham số của nó được trình bày như sau:



void gluPerspective(GLdouble fovy, GLdouble aspect,
GLdouble
near, GLdouble far);

Tham số đầu tiên là góc quan sát trong mặt phẳng XOZ, trong ví dụ trên góc đó là 30độ, tham số thứ hai là tỉ lệ giữa w và h, nó bằng w/h, tham số thứ 3 và thứ 4 thì hẳn các bạn đã quen khi quan sát bằng glOrtho().Nếu chỉ có hàm này không thôi thì chúng ta vẫn chưa quan sát được hình lập phương mà chúng ta vẽ. Để quan sát được chúng ta phải dùng thêm hàmgluLookAt()

Hàm này có tới 9 tham số, nhưng thực ra nó nằm trong 3 tham số chính.Tham số đầu tiên là vị trí của mắt, cũng có thể coi đó là vị trí của camera(chú ý là trong toạ độ 3 chiều, nên vị trí của mắt chứa 3 toạ độ), tham số thứ 2 là điểm nhìn, và tham số thứ 3 gọi là upvector, từ này không biết dịch ra tiếng việt ra sao.Upvector , hãy tưởng tượng bạn đang theo dõi một vật, upvector chính là vector từ tim bạn lên đỉnh đầu, nếu thay đổi số liệu cũng tương tự như bạn nghiêng đầu sang phải sang trái.Vậy là 9 tham số đã rõ, bây giờ hãy bỏ lệnh glOrtho()đi và cho 2 lệnh đánh dấu đỏ vào, chúng ta sẽ quan sát được hình lập phương đó, mã nguồn nằm trong file cube2.cpp

9.Animation(Hoạt cảnh)

Phần này sẽ giới thiệu với các bạn về cách tạo hoạt cảnh trong opengl.Hoạt cảnh luôn luôn có sức thu hút người lập trình, nó là một phần quan trọng trong lập trình đồ hoạ.

Trước hết chúng ta sẽ xem xét hai hàm auxIdleFunc() và auxMainLoop().Hàm auxIdleFun() có nhiệm vụ gọi các hàm trong khi không nhận một sự kiện (event) của người dùng, trong chương trình dưới đây, cụ thể là nó sẽ vẽ lại window khi không có event nào.Còn hàm auxMainLoop() chỉ vẽ lại window khi có một sự kiện cụ thể như người dùng di chuyển cửa sổ, nút được bấm, bị cửa sổ khác đè lên.... Để quan sát được rõ ràng chúng ta cũng phải dùng đến hàm glMatrixMode().Khi thay đổi modeling và viewing thì phải thay đổi ma trận của nó, bằng cách dùng hai thông số GL_MODELVIEW và GL_PROJECTION, vì nếu chỉ thay đổi trong lúc khởi tạo window thì ta sẽ không thu được tác dụng của các hàm này khi cửa sổ bị thay đổi, chính vì thế mà chúng ta để nó trong hàm resize(), vì ma trận trên được lặp đi lặp lại nên chúng ta để hàm glMatrixMode(GL_MODELVIEW) sau cùng.Dưới đây là mã nguồn:

/*filename animation1.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int edge[][2]={

{0,1},


{1,2},

{2,3},


{0,3},

{4,5},


{5,6},

{6,7},


{7,4},

{0,4},


{1,5},

{2,6},


{3,7}

};
GLvoid CALLBACK none(void)

{

}
GLvoid CALLBACK draw(void)



{

int i;


static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glColor3d(1.0,1.0,1.0);

glBegin(GL_LINES);

for(i=0;i<12;i++){

glVertex3dv(vertex[edge[i][0]]);

glVertex3dv(vertex[edge[i][1]]);

}

glEnd();



glFlush();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

auxMainLoop(none);

return 0;

}

Trong chương trình trên, mỗi lần hàm draw()được gọi thì giá trị r được tăng lên một đơn vị nếu vượt quá 360 độ thì nó sẽ trở về 0.Chúng ta phải thành lập hàm none() mặc dù nó không thực hiện một chức năng gì, nhưng hàm auxMainLoop() cần một hàm để gọi đến nó nên ta đã tạo hàm none.Tuy vậy bạn cũng chỉ nhìn thấy nhấp nháy của hình lập phương, để có thể quan sát được hãy biên dịch mã nguồn của chương trình sau:



/*filename animation2.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int edge[][2]={

{0,1},

{1,2},


{2,3},

{0,3},


{4,5},

{5,6},


{6,7},

{7,4},


{0,4},

{1,5},


{2,6},

{3,7}


};
GLvoid CALLBACK none(void)

{

}


GLvoid CALLBACK draw(void)

{

int i;



static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glColor3d(1.0,1.0,1.0);

glBegin(GL_LINES);

for(i=0;i<12;i++){

glVertex3dv(vertex[edge[i][0]]);

glVertex3dv(vertex[edge[i][1]]);

}

glEnd();



auxSwapBuffers(); /*hàm mới*/

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE);/*thông s mới*/

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

auxMainLoop(none);

return 0;

}

Trong hàm draw() tôi đã bỏ đi hàm glFlush() và thay bằng hàm auxSwapBuffers(), sử dụng double buffer là một kỹ thuật để tránh hiện tượng nhấp nháy màn hình mà các bạn mới lập trình đồ hoạ thường mắc phải.Kỹ thuật này được mô tả như sau: dùng một offbuffer, rồi vẽ lên đó sau đó mới đưa lên màn hình, tưởng tượng nếu bạn cắt từng chữ rồi dán lên để người xem thấy thì họ sẽ nhìn thấy bạn dán từng chữ một, nhưng nếu bạn dán lên đằng sau tờ giấy rồi lật ngược lại thì họ không biết là nó được dán từng chữ một(tượng trưng thôi, chứ người ta biết thừa)Để dùng được double buffers bạn phải thêm thông số AUX_DOUBLE trong hàm auxInitDisplayMode().Bây giờ bạn đã có một hình lập phương chuyển động mịn màng quanh trục OY.


Thật ra hình lập phương mà chúng ta đã vẽ chỉ là một khung của hình lập phương thôi, còn các mặt thì chúng ta chưa vẽ, vì thế mà các nét khuất chúng ta vẫn nhìn thấy, bây giờ chúng ta sẽ dùng tham số GL_QUADS để vẽ hình lập phương với các mặt đầy đủ và phần bị khuất sẽ không nhìn thấy được.Mã nguồn:

/*filename : animation3.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLvoid CALLBACK none(void)

{

}


GLvoid CALLBACK draw(void)

{

int i,j;



static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glColor3d(1.0,1.0,1.0);

glBegin(GL_QUADS);

for(i=0;i<6;i++)

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

glEnd();



auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

auxMainLoop(none);

return 0;

}

Tiếp theo chúng ta sẽ thêm màu vào để hình của chúng ta được sinh động, bạn chú ý cách sắp xếp dữ liệu của tôi, rất nhiều nhà lập trình thích cách sắp xếp này.Mã nguồn:



/*filename animation4.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble color[][3]={

{1.0,0.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,1.0,0.0},

{1.0,0.0,1.0},

{0.0,1.0,1.0}

};
GLvoid CALLBACK none(void)

{

}


GLvoid CALLBACK draw(void)

{

int i,j;



static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glBegin(GL_QUADS);

for(i=0;i<6;i++){

glColor3dv(color[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

auxMainLoop(none);

return 0;

}

Tạm thời dừng phần animation ở đây chúng ta chuyển qua phần khác.



10-Sử dụng Depth buffer test:

Mới nghe tên thôi các bạn cũng có thể hình dung được công việc chúng ta sắp làm đó là tạo chiều sâu và độ xa từ khi quan sát vật từ điểm quan sát.Trong phần này chúng ta sử dụng thêm thư viện nữa vì thế hãy thêm vào tiêu đề file GL/glu.h(cái này cũng có sẵn trong VC bạn không phải download ở đâu cả).Dưới đây là mã nguồn



/*filename depth1.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
#include


GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble color[][3]={

{1.0,0.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,1.0,0.0},

{1.0,0.0,1.0},

{0.0,1.0,1.0}

};
GLvoid CALLBACK none(void)

{

}
GLvoid CALLBACK draw(void)



{

int i,j;


static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/*thông sô mới*/

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glEnable(GL_DEPTH_TEST); /*hàm mới*/
glBegin(GL_QUADS);

for(i=0;i<6;i++){

glColor3dv(color[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

glDisable(GL_DEPTH_TEST); /*hàm mới*/

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);/*thông số mới*/

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

auxMainLoop(none);

return 0;

}

Trong chương trình trên chúng ta đã sử dụng tham số GL_DEPTH_BUFFER_BIT, muốn xoá buffer z thì chúng ta phải dùng tham số này(mục đích là cài đặt z buffer), hai hàm glEnable() và glDisable() có tác dụng khởi động buffer z(chiều sâu) và tắt nó đi, được dùng với thông số GL_DEPTH_TEST.Trong hàm auxInitDisplayMode() chúng ta cũng phải thêm thông số AUX_DEPTH để có thể quan sát được chiều sâu của đồ vật.Tuy vậy chương trình trên có một số yếu điểm, đó là việc liên quan đến các mặt khuất.Thử biên dịch mã nguồn dưới đây và quan sát sự khác nhau:



/*filename depth2.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
#include


GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble color[][3]={

{1.0,0.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,1.0,0.0},

{1.0,0.0,1.0},

{0.0,1.0,1.0}

};
GLvoid CALLBACK none(void)

{

}
GLvoid CALLBACK draw(void)



{

int i,j;


static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glEnable(GL_DEPTH_TEST);

glEnable(GL_CULL_FACE);


glBegin(GL_QUADS);

for(i=0;i<6;i++){

glColor3dv(color[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

glDisable(GL_CULL_FACE);

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}

các bạn thấy rõ sự khác nhau rồi chứ?Chương trình trước, các cạnh dường như song song, trông không giống một vật 3 chiều chút nào, vì các mặt được chọn để thể hiện chưa được làm chính xác.Muốn hiểu rõ hơn xin xem tại trang opengl.org.



10-S dụng ánhng trong opengl.

Để xác định mặt nào được chiếu sáng và với cường độ sáng bao nhiêu, người ta dùng véc tơ pháp tuyến (normal vector).Trong chương trình dưới đây tôi sẽ giới thiệu cách dùng véc tơ này.Mã nguồn:



/*filename: light1.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
#include
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble normal[][3]={

{0.0,0.0,-1.0},

{1.0,0.0,0.0},

{0.0,0.0,1.0},

{-1.0,0.0,0.0},

{0.0,-1.0,0.0},

{0.0,1.0,0.0}

};
GLvoid CALLBACK none(void)

{

}
GLvoid CALLBACK draw(void)



{

int i,j;


static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING); /*tham số mới*/



glEnable(GL_LIGHT0); /*tham s mới*/
glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]); /*hàm mới*/

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();
glDisable(GL_LIGHT0); /*tham s mới*/

glDisable(GL_LIGHTING); /*tham s mới*/

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}

Các bạn đã thấy thông số mới trong hàm glEnable() và glDisable(), các thông số này cho phép chúng ta sử dụng ánh sáng trong khi tạo đồ vật.Opengl cung cấp cho chúng ta 8 nguồn sáng mà chương trình trên mới chỉ sử dụng một nguồn sáng LIGHT0, hàm glNormal3dv() thiết lập véc tơ pháp tuyến cho mỗi mặt chúng ta vẽ, vì thế khi vật thể quay quanh trục thì ta sẽ thấy độ sáng tối thay đổi.


Trong chương trình light0.cpp trên chúng ta không sử dụng màu nên màu sẽ được xác định là màu mặc định như các bạn đã thấy.Tiếp theo đây tôi xin giới thiệu cách sử dụng vật liệu để tạo vật với các màu sắc ấn tượng khác nhau.Chúng ta khai báo dữ liệu sau:
GLfloat ambient[]={ 0.2,0.2,0.2,1.0};

GLfloat diffuse[]={ 0.8,0.0,0.0,1.0};

GLfloat specular[]={0.5,0.5,0.5,1.0};

GLfloat shininess=40.0;


Trong đó các thông số trên đều được đặt theo hệ RGBA(như đã đề cập ở các phần trên), chính vì thế mà chúng có 4 giá trị.Thông số ambient biểu hiện cho độ sáng của môi trường bên ngoài, diffuse là độ khuếch tán, specular là độ phản xạ và shininess là độ bóng(độ bóng sáng). Các thông số trên được hàm glMaterial*() sử dụng để tạo vật thể của chúng ta.Hãy quan sát cách khai báo hàm trên:
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuse);

glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);

glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);

Chú ý là lệnh cuối cùng không phải là “fv” như bình thường, vì shininess chỉ là một số.

Đây là mã nguồn của chương trình.



/*filename light1.cpp*/

#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else


#include

#include

#include

#endif
#include


GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble normal[][3]={

{0.0,0.0,-1.0},

{1.0,0.0,0.0},

{0.0,0.0,1.0},

{-1.0,0.0,0.0},

{0.0,-1.0,0.0},

{0.0,1.0,0.0}

};
GLfloat ambient[]={ 0.2,0.2,0.2,1.0};

GLfloat diffuse[]={ 0.8,0.0,0.0,1.0};

GLfloat specular[]={0.5,0.5,0.5,1.0};

GLfloat shininess=40.0;
GLvoid CALLBACK none(void)

{

}


GLvoid CALLBACK draw(void)

{

int i,j;



static int r=0;
glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

glRotated((double)r,0.0,1.0,0.0);
glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambient);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,diffuse);

glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular);

glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess);


glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();
glDisable(GL_LIGHT0);

glDisable(GL_LIGHTING);

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}

11-V nhiều vật-Dùng Ma trân.

Trong phần này tôi sẽ giới thiều với các bạn cách vẽ có vẻ chuyên nghiệp hơn một chút, có thể từ đây bạn sẽ tạo được những điều mà mình mong muốn.

Trước hết hãy tạo một hàm vẽ hình lập phương:


void cube()

{

int i,j;



glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

}

Vì điểm nhìn không thay đôi nên khi cỡ của window thay đổi ta cũng phải thay đổi theo. Dưới đây là mã nguồn để thay đổi khung nhìn của chúng ta:


GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

}
Chú ý là hai hàm cuối trong hàm trên đã được chuyển từ hàm draw() sang.Nếu thiết đặt ma trân như trên thì khi hàm glRotated() làm thay đổi vị trí của vật sẽ làm cho window của chúng ta trở nên không bình thường.Vì vậy trước khi dùng hàm glRotated() thì chúng ta phải lưu ma trận vào đã rồi khì thực hiện xong hàm này ta lại trả lại ma trận thì sẽ bình thương. Để làm việc này chúng ta sử dụng 2 hàm glPushMatrix() và glPopMatrix().Mã nguồn được trình bày dưới đây.
/*filename matrix1.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
#include
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble normal[][3]={

{0.0,0.0,-1.0},

{1.0,0.0,0.0},

{0.0,0.0,1.0},

{-1.0,0.0,0.0},

{0.0,-1.0,0.0},

{0.0,1.0,0.0}

};
void cube()

{

int i,j;


glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

}

GLvoid CALLBACK none(void)



{

}
GLvoid CALLBACK draw(void)

{

static int r=0;


glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);
glPushMatrix();

glRotated((double)r,0.0,1.0,0.0);

cube();

glPopMatrix();
glDisable(GL_LIGHT0);

glDisable(GL_LIGHTING);

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}
Bây giờ ta sẽ tìm cách để vẽ hai hình lập phương mà không mất công vẽ lại từng mặt của hình lập phương mới nữa. Để làm được điều này bạn dùng hàm glTranslated(), hàm này có 3 thông số, nó có nhiệm vụ chuyển ta đến vị trí mới để vẽ(qua ba thông số của nó).Thực ra nó nhân ma trận hiện tại với một ma trận khác để chuyển toạ độ cho chúng ta, vì thế mà chúng ta sẽ phải dùng 2 lần các hàm glPushMatrix() và glPopMatrix().Hãy nhớ là bao nhiêu lần gọi hàm glPushMatrix() thì cũng phải từng đấy lần gọi hàm glPopmatrix().Dưới đây là mã nguồn:


/*filename matrix2.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
#include
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble normal[][3]={

{0.0,0.0,-1.0},

{1.0,0.0,0.0},

{0.0,0.0,1.0},

{-1.0,0.0,0.0},

{0.0,-1.0,0.0},

{0.0,1.0,0.0}

};
void cube()

{

int i,j;


glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

}

GLvoid CALLBACK none(void)



{

}
GLvoid CALLBACK draw(void)

{

static int r=0;


glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);
glPushMatrix();

glRotated((double)r,0.0,1.0,0.0);

cube();
glPushMatrix();

glTranslated(1.0,1.0,1.0);

cube();

glPopMatrix();


glPopMatrix();
glDisable(GL_LIGHT0);

glDisable(GL_LIGHTING);

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}
Tiếp theo chúng ta sẽ cho hình lập phương thứ hai quay với vận tốc khác, vận tốc mới của nó là 2*r, để làm được điều này bạn chỉ cần thêm hàm glRotated((double)(2*r),0.0,1.0,0.0); vào sau hàm glTranslated(1.0,1.0,1.0); v à trước hàm cube() thứ hai.Mã nguồn nằm trong file matrix3.cpp.

Bây giờ hãy cùng tô màu cho chúng.
/*filename matrix4.cpp*/
#ifdef unix

#include

#include "aux.h"

#define CALLBACK

#else

#include



#include

#include

#endif
#include
GLdouble vertex[][3]={

{0.0,0.0,0.0},

{1.0,0.0,0.0},

{1.0,1.0,0.0},

{0.0,1.0,0.0},

{0.0,0.0,1.0},

{1.0,0.0,1.0},

{1.0,1.0,1.0},

{0.0,1.0,1.0}

};
int face[][4]={

{0,1,2,3},

{1,5,6,2},

{5,4,7,6},

{4,0,3,7},

{4,5,1,0},

{3,2,6,7}

};
GLdouble normal[][3]={

{0.0,0.0,-1.0},

{1.0,0.0,0.0},

{0.0,0.0,1.0},

{-1.0,0.0,0.0},

{0.0,-1.0,0.0},

{0.0,1.0,0.0}

};
void cube()

{

int i,j;


glBegin(GL_QUADS);

for(i=0;i<6;i++){

glNormal3dv(normal[i]);

for(j=0;j<4;j++){

glVertex3dv(vertex[face[i][j]]);

}

}



glEnd();

}

GLvoid CALLBACK none(void)



{

}
GLvoid CALLBACK draw(void)

{

static int r=0;



static GLfloat red[]={ 1.0,0.0,0.0,1.0};

static GLfloat blue[]={ 0.0,0.0,1.0,1.0};


glClearColor(0.0,0.0,0.0,0.0);

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


glEnable(GL_DEPTH_TEST);

glEnable(GL_LIGHTING);

glEnable(GL_LIGHT0);
glPushMatrix();

glRotated((double)r,0.0,1.0,0.0);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,red);

cube();
glPushMatrix();

glTranslated(1.0,1.0,1.0);

glRotated((double)(2*r),0.0,1.0,0.0);

glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,blue);

cube();


glPopMatrix();
glPopMatrix();
glDisable(GL_LIGHT0);

glDisable(GL_LIGHTING);

glDisable(GL_DEPTH_TEST);

auxSwapBuffers();

if(++r>=360) r=0;

}
GLvoid CALLBACK resize(GLsizei w,GLsizei h)

{

glMatrixMode(GL_PROJECTION);



glLoadIdentity();

glViewport(0,0,w,h);

gluPerspective(30.0,1.0,1.0,10.0);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();

gluLookAt(3.0,4.0,5.0,0.0,0.0,0.0,0.0,1.0,0.0);

}

int main(int argc, char *argv[])



{

auxInitPosition(200,100,512,512);

auxInitDisplayMode(AUX_RGBA|AUX_DOUBLE|AUX_DEPTH);

auxInitWindow(argv[0]);

auxReshapeFunc(resize);

auxIdleFunc(draw);

glCullFace(GL_BACK);

auxMainLoop(none);

return 0;

}

Đến đây thì không cần giải thích gì các bạn cũng đã hiểu chương trình này. Đây là vài gợi ý cho những bạn thích tìm tòi, các bạn có thể dùng các hàm vừa đề cập để vẽ một hệ mặt trời với các hành tinh, hay vẽ một cánh tay robốt cử động chẳng hạnNếu có điều kiện tôi sẽ còn tiếp tục viết tiếp những bài khác về opengl , có thể là thư viên glut vì nó rất mạnh.Hi vọng một ngày nào đó gặp lại. Nếu bài viết của tôi có gì sai thì vui lòng gửi cho tôi lời nhắn, tôi sẽ sửa lại để nó thật đúng và thật hợp.Mời các bạn ghé qua trang web của tôi, trên đó có một số chương trình khá thú vị nếu bạn nào cần mã nguồn thì mail cho tôi, tôi sẽ sẵn lòng gửi cho.Thân ái.



http://www.diendantinhoc.net/tute/


tải về 450.11 Kb.

Chia sẻ với bạn bè của bạn:
1   2




Cơ sở dữ liệu được bảo vệ bởi bản quyền ©hocday.com 2024
được sử dụng cho việc quản lý

    Quê hương