Professional Documents
Culture Documents
Baithuchanhso6 3D
Baithuchanhso6 3D
Trong bài thực hành này, chúng ta tạo một hình cầu bán kính 2 đơn vị có tâm trùng với gốc tọa
độ, camera nằm trên phía dương trục z. Ngoài ra, chúng ta tạo hai nguồn sáng nằm trên trục x, một
nguồn sáng nằm ở phía dương trục x, một nguồn sáng nằm ở phía âm của trục x. Vị trí và màu của hai
nguồn sáng này được định nghĩa như sau:
1
GLfloat shiness = 100;
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, shiness);
Như chúng ta thấy,
- Đối với thành phần ánh sáng khuyếch tán, hình cầu này phản xạ 100% ánh sáng màu lục và
hấp thụ hoàn tòan thành phần ánh sáng màu đỏ và màu xanh của nguồn sáng. Vì thế hai nửa
của hình cầu đều có ánh sáng khuyếch tán màu lục.
- Đối với thành phần ánh sáng phản chiếu, hình cầu này cũng phản xạ 100% ánh sáng màu lục
và hấp thụ hoàn tòan thành phần ánh sáng màu đỏ và màu xanh của nguồn sáng. Vì thế hai nửa
của hình cầu đều có ánh sáng phản chiếu màu lục.
- Tham số shiness phản ánh độ tập trung của phần sáng phản chiếu và có giá trị từ 0 đến 128.
Trong đoạn chương trình trên, shiness có giá trị là 100 và vùng sáng phản chiếu cũng khá tập
trung.
#include "Canvas.h"
#define PI 3.1415926
void myInit()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
2
glLightfv(GL_LIGHT0, GL_SPECULAR, rightLightSpecColor);
glEnable(GL_LIGHT0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutSwapBuffers();
glFlush();
}
3
}
myInit();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
b) Bây giờ thay đổi hệ số phản chiếu của vật liệu để cho nó phản xạ 100% cả ba thành phần ánh
sáng của nguồn sáng:
GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0f };
Khi đó phần ánh sáng phản chiếu của nửa tay trái của hình cầu có màu trắng, giống như màu
sắc của nguồn sáng.
Hãy dịch và chạy chương trình.
c) Tiến hành sửa đổi nguồn sáng và hệ số phản xạ của vật liệu để cảm nhận được sự ảnh hưởng
của các tham số đến màu sắc của vật thể.
#include "Canvas.h"
#define PI 3.1415926
4
const GLfloat leftLightColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat leftLightAmbColor[] = { 0.1f, 0.1f, 0.1f, 1.0f};
const GLfloat leftLightPos[] = { 5.0, 0.0, 0.0, 0.0 };
void myInit()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
}
void myDisplay()
{
int i;
float size;
size = 1.0;
5
cvs.clearScreen();
glLoadIdentity();
gluLookAt(6.0, 4.0, 6.0, 0.0, 0.0, 2.0*size, 0.0, 1.0, 0.0);
glPushMatrix();
glutSolidSphere(size, 100, 100);
glPopMatrix();
//draw nose
ambient[0] = 1.0; ambient[1] = 0.0;ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0;diffuse[2] = 0.0;
specular[0] = 1.0; specular[1] = 0.0;specular[2] = 0.0;
shiness = 100.8;
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, shiness);
glPushMatrix();
glTranslated(0.0, 1.4*size, 0.0);
glTranslated(0.0, 0.0, 0.8*size);
glutSolidSphere(0.3*size, 20, 20);
6
glPopMatrix();
glPushMatrix();
glTranslated(0.0, 2.9*size, 0.0);
glRotated(90, 1.0, 0.0, 0.0);
obj = gluNewQuadric();
gluQuadricDrawStyle(obj, GLU_LINE);
gluCylinder(obj, 0.7*size, 0.7*size, size, 30, 10);
glPopMatrix();
7
glPushMatrix();
glTranslated(0.0, 0.5*size, 0.0);
glRotated(-90, 0.0, 1.0, 0.0);
obj = gluNewQuadric();
gluQuadricDrawStyle(obj, GLU_FILL);
gluCylinder(obj, 0.4*size, 0.4*size, 3*size, 30, 10);
glPopMatrix();
glPushMatrix();
glTranslated(0.0, 0.0, 5.0*size);
glTranslated(0.0, -1.0*size, 0.0);
glRotated(-90, 1.0, 0.0, 0.0);
glutSolidCone(0.8*size, 2.5*size, 30, 20);
glPopMatrix();
glPushMatrix();
glTranslated(0.0, 0.0, 5.0*size);
glTranslated(0.0, 1.0*size, 0.0);
glRotated(-90, 1.0, 0.0, 0.0);
glutSolidCone(0.8*size, 2.5*size, 30, 20);
glPopMatrix();
glPushMatrix();
glTranslated(0.0, 0.0, 5.0*size);
glTranslated(0.0, -3.0*size, 0.0);
glRotated(-90, 1.0, 0.0, 0.0);
obj = gluNewQuadric();
gluQuadricDrawStyle(obj, GLU_FILL);
gluCylinder(obj, 0.4*size, 0.4*size, 3*size, 30, 10);
glPopMatrix();
//left light
if(m_leftlightOn)
{
glPushMatrix();
glLightfv(GL_LIGHT1, GL_POSITION, leftLightPos);
glTranslatef(leftLightPos[0], leftLightPos[1], leftLightPos[2]);
glEnable(GL_LIGHT1);
glPopMatrix();
}
else
glDisable(GL_LIGHT1);
8
//right light
if(m_rightlightOn)
{
glPushMatrix();
glLightfv(GL_LIGHT0, GL_POSITION, rightLightPos);
glTranslatef(rightLightPos[0], rightLightPos[1], rightLightPos[2]);
glEnable(GL_LIGHT0);
glPopMatrix();
}
else
glDisable(GL_LIGHT0);
if(m_wireframeOn)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
if(m_smoothshadeModeOn)
glShadeModel(GL_SMOOTH);
else
glShadeModel(GL_FLAT);
glutSwapBuffers();
glFlush();
}
float dt = 0.5;
m_angle = m_angle + dt;
if(m_angle >= 360)
m_angle = 0;
myDisplay();
}
void myKeyboard(unsigned char theKey, int mouseX, int mouseY)
{
switch(theKey)
{
case 'r':
m_rightlightOn = !m_rightlightOn;
break;
case 'l':
9
m_leftlightOn = !m_leftlightOn;
break;
case 'w':
m_wireframeOn = !m_wireframeOn;
break;
case 's':
m_smoothshadeModeOn = !m_smoothshadeModeOn;
break;
default:
break;
}
}
int main(int argc, char* argv[])
{
cvs.setBackgroundColor(0.0, 0.0, 0.0);
cvs.setColor(0.0, 0.0, 0.0);
myInit();
glutReshapeFunc(myReshape);
glutDisplayFunc(myDisplay);
glutIdleFunc(myIdle);
glutKeyboardFunc(myKeyboard);
glutMainLoop();
return 0;
}
10
0.025 0.0828 0.086014
Vàng 0.24725 0.75164 0.628281 51.2
0.1995 0.60648 0.555802
0.0745 0.22648 0.366065
Hợp kim 0.10588 0.427451 0.3333 9.84615
thiếc 0.058824 0.470588 0.3333
0.113725 0.541176 0.521569
Bạc 0.19225 0.50754 0.508273 51.2
0.19225 0.50754 0.508273
0.19225 0.50754 0.508273
Bạc đánh 0.23125 0.2775 0.773911 89.6
bóng 0.23125 0.2775 0.773911
0.23125 0.2775 0.773911
Để có thể tô màu cho đối tượng, cần phải thực hiện các công việc sau:
- Thiết lập nguồn sáng ở vị trí (0, 10, 0), nguồn sáng có màu sắc là màu trắng.
- Thiết lập đặc tính của vật liệu.
- Cần phải gửi pháp tuyến xuống đường ống đồ họa. Thêm vào hàm Draw(…) của lớp Mesh
đoạn mã cho phép tô màu cho đối tượng. Khi tô màu, ngoài việc gửi tọa độ đỉnh xuống đường
ống đồ họa, còn phải gửi thêm vector pháp tuyến của đỉnh đó. Ở đây, chúng ta sử dụng hai
phương pháp tô màu là tô màu phẳng và tô màu trơn.
o Đối với phương pháp tô màu phẳng: vector pháp tuyến của đỉnh chính là vector pháp
tuyến của mặt chứa đỉnh đó. Nhược điểm của phương pháp này là nhìn thấy đường biên
giữa các mặt của lưới đa giác.
Dùng phương pháp tô màu phẳng, có thể nhìn thấy rõ ranh giới
11
giữa các mặt tam giác của lưới đa giác
o Đối với phương pháp tô màu trơn: vector pháp tuyến của đỉnh được tính là trung bình
cộng của các vector pháp tuyến của các mặt xung quanh đỉnh đó. Chính vì thế ranh giới
giữa các mặt của lưới đa giác sẽ biến mất.
12