OpenGL – C++ Bài 5: Thiết Lập Chiếu Sáng trong OpenGL
Hi. Chào mừng các bạn đến với chủ đề Học Lập Trình OpenGL tại blog: Phát Triển Phần Mềm 123-az
Bài viết ngày hôm nay, mình sẽ chia sẻ với các bạn về kỹ thuật chiếu sáng trong OpenGL.
Một kỹ thuật không thể thiếu khi thực hiện mô phỏng đồ họa.
1. Nguyên Lý Cơ Bản.
Chiếu sáng hay còn gọi là Lighting trong OpenGL là một kỹ thuật không thể thiếu,
và nó vô cùng đa dạng, sử dụng phổ biến trong mô phỏng đồ họa.
Giả sử không có lighting khi tôi vẽ một đối tượng thì nó có dạng như sau:
Khi có lighting vào thì kết quả sẽ khác biệt như sau:
+ Trong Hàm Init. Bật chế độ lighting
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
+ Chọn vị trí ánh sáng chiếu vào:
GLfloat light_pos [] = {0.0, 0.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
Như thế này nghĩa là: ánh sáng chiếu theo chiều ngược với trục Z của OpenGL. Z đâm ra ngoài màn hình thì ánh sáng chiếu từ ngoài màn hình vào.
Tương tự nếu đổi sang thành trục X và Y.
+ Kết hợp với glMaterial tạo tính chất vật liệu cho đối tượng khi được chiếu sáng.
4 Tham số chính như sau:
GL_AMBIENT: Chiếu sáng toàn phần cho đối tượng của vật
GL_DIFFUSE: Tạo ánh sáng khuếch tán cho đối tượng
GL_SPECULAR: Tạo ánh sáng phản xạ trong đối tượng.
GL_SHININESS: Điều chỉnh cường độ điểm chiếu sáng phản xạ.
Khi thiết lập đầy đủ các thông số như dưới đây:
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); GLfloat light_pos [] = {0.0, 0.0, 1.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); GLfloat ambient [] = {1.0, 0.0, 0.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); GLfloat diff_use [] = {0.0, 0.5, 0.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff_use); GLfloat specular[] = {1.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); GLfloat shininess = 50.0f; glMateriali(GL_FRONT, GL_SHININESS, shininess);
Thì ta có được 1 kết quả như sau:
Shininess sẽ là tham số điều chỉnh độ lớn hay nhỏ của specular
Full Code:
#include <gl\glut.h> void DrawCoordinate() { glDisable(GL_LIGHTING); glBegin(GL_LINES); glColor3f(1.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(10.0, 0.0, 0.0); glEnd(); glBegin(GL_LINES); glColor3f(0.0, 1.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 10.0, 0.0); glEnd(); glBegin(GL_LINES); glColor3f(0.0, 0.0, 1.0); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, 10.0); glEnd(); glEnable(GL_LIGHTING); } void RendenScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(5.0, 5.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glPushMatrix(); DrawCoordinate(); glutSolidTeapot(3.0); glPopMatrix(); glFlush(); } void ReShape(int width, int height) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float ratio = (float)width/(float)height; gluPerspective(45.0, ratio, 1, 100.0); glMatrixMode(GL_MODELVIEW); } void Init() { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); GLfloat light_pos [] = {0.0, 0.0, 1.0, 0.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_pos); GLfloat ambient [] = {1.0, 0.0, 0.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); GLfloat diff_use [] = {0.0, 0.5, 0.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diff_use); GLfloat specular[] = {1.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular); GLfloat shininess = 50.0f; glMateriali(GL_FRONT, GL_SHININESS, shininess); } void main() { glutInitDisplayMode(GLUT_SINGLE |GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("Opengl Study"); Init(); glutReshapeFunc(ReShape); glutDisplayFunc(RendenScene); glutMainLoop(); }
Liệu có thể chiếu sáng mà phát ra nhiều màu trong cùng 1 vật thể không ạ? Ví dụ, chiếu sáng ô tô thay vì chiếu sáng 1 màu ta có thể chiếu sáng nhiều màu trên ô tô đó
Có thể làm được bạn ạ, nhưng kiến thức nâng cao và phức tạp hơn, cần nhiều thời gian nghiên cứu
sao em cứ bật glEnable(GL_DEPTH_TEST); là chạy bị đen màn hình nhỉ?
post code va hien tuong vao group di