You are on page 1of 15

THỰC HÀNH ĐỒ HỌA MÁY TÍNH

CÁC PHÉP BIẾN ĐỔI ĐỒ HỌA 3D


(Model Transformation)

Nhóm học phần:


Mã Sinh viên, Họ và Tên: 102220048 Nguyễn Đức Hoài Vũ

MỤC LỤC
1. Chương trình lab02transform.cpp biến đổi các đối tượng...........................................1
2. Chương trình lab02rotation01.cpp xoay hình vuông một góc 20 o. Tâm xoay là gốc
tọa độ.................................................................................................................................3
3. Chương trình lab02rotation02.cpp xoay hình vuông một góc 20o. Tâm xoay là
điểm(x, y)..........................................................................................................................3
4. Chương trình lab02rotation03.cpp vẽ hình chữ nhật quay quanh tâm.......................4
5. Chương trình lab02affine.cpp: Xây dựng các hàm biến đổi affine.............................6
6. Chương trình lab02earth.cpp vẽ hình trái đất quay xung quanh mặt trời.................9
7. Bài tập.............................................................................................................................11

CHÚ Ý: Thay XYZ bằng Họ tên SV

1. Chương trình lab02transform.cpp biến đổi các đối tượng


#include <windows.h> // for MS Windows
#include <GL/glut.h> // GLUT, include glu.h and gl.h

/* Initialize OpenGL Graphics */


void init() {
// Set "clearing" or background color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black and opaque
}

void display() {
glClear(GL_COLOR_BUFFER_BIT); // Clear the color buffer
glMatrixMode(GL_MODELVIEW); // To operate on Model-View matrix
glLoadIdentity(); // Reset the model-view matrix

glTranslatef(-0.5f, 0.4f, 0.0f); // Translate left and up


glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(-0.3f, -0.3f); // Define vertices in counter-clockwise(CCW) order
glVertex2f( 0.3f, -0.3f); // so that the normal(front-face) is facing you
glVertex2f( 0.3f, 0.3f);
glVertex2f(-0.3f, 0.3f);
glEnd();

glTranslatef(0.1f, -0.7f, 0.0f); // Translate right and down


glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex2f(-0.3f, -0.3f);
glVertex2f( 0.3f, -0.3f);
glVertex2f( 0.3f, 0.3f);
glVertex2f(-0.3f, 0.3f);
glEnd();

KhoaCNTT – Trường ĐHBK Đà Nẵng 1


glTranslatef(-0.3f, -0.2f, 0.0f); // Translate left and down
glBegin(GL_QUADS); // Each set of 4 vertices form a quad
glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray
glVertex2f(-0.2f, -0.2f);
glColor3f(1.0f, 1.0f, 1.0f); // White
glVertex2f( 0.2f, -0.2f);
glColor3f(0.2f, 0.2f, 0.2f); // Dark Gray
glVertex2f( 0.2f, 0.2f);
glColor3f(1.0f, 1.0f, 1.0f); // White
glVertex2f(-0.2f, 0.2f);
glEnd();

glTranslatef(1.1f, 0.2f, 0.0f); // Translate right and up


glBegin(GL_TRIANGLES); // Each set of 3 vertices form a triangle
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex2f(-0.3f, -0.2f);
glVertex2f( 0.3f, -0.2f);
glVertex2f( 0.0f, 0.3f);
glEnd();

glTranslatef(0.2f, -0.3f, 0.0f); // Translate right and down


glRotatef(180.0f, 0.0f, 0.0f, 1.0f); // Rotate 180 degree
glBegin(GL_TRIANGLES); // Each set of 3 vertices form a triangle
glColor3f(1.0f, 0.0f, 0.0f); // Red
glVertex2f(-0.3f, -0.2f);
glColor3f(0.0f, 1.0f, 0.0f); // Green
glVertex2f( 0.3f, -0.2f);
glColor3f(0.0f, 0.0f, 1.0f); // Blue
glVertex2f( 0.0f, 0.3f);
glEnd();

glRotatef(-180.0f, 0.0f, 0.0f, 1.0f); // Undo previous rotate


glTranslatef(-0.1f, 1.0f, 0.0f); // Translate right and down
glBegin(GL_POLYGON); // The vertices form one closed polygon
glColor3f(1.0f, 1.0f, 0.0f); // Yellow
glVertex2f(-0.1f, -0.2f);
glVertex2f( 0.1f, -0.2f);
glVertex2f( 0.2f, 0.0f);
glVertex2f( 0.1f, 0.2f);
glVertex2f(-0.1f, 0.2f);
glVertex2f(-0.2f, 0.0f);
glEnd();

glFlush(); // Render now


}

/* Handler for window re-size event */


void reshape(GLsizei width, GLsizei height)
{
// Compute aspect ratio of the new window
if(height == 0) height = 1; // To prevent divide by 0
GLfloat aspect =(GLfloat)width /(GLfloat)height;

// Set the viewport to cover the new window


glViewport(0, 0, width, height);

// Set the aspect ratio of the clipping area to match the viewport
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(width >= height) {
// aspect >= 1, set the height from -1 to 1, with larger width
gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
} else {
// aspect < 1, set the width to -1 to 1, with larger height
gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
}
} reshape

int main(int argc, char** argv)


{
glutInit(&argc, argv); // Initialize GLUT

KhoaCNTT – Trường ĐHBK Đà Nẵng 2


glutInitWindowSize(640, 480); // Set the window's initial width & height - non-
square
glutInitWindowPosition(50, 50); // Position the window's initial top-left corner
glutCreateWindow("HO VA TEN - Modelview matrix");
glutDisplayFunc(display); // Register callback handler for window re-paint event
glutReshapeFunc(reshape); // Register callback handler for window re-size event
init(); // Our own OpenGL initialization
glutMainLoop(); // Enter the infinite event-processing loop
return 0;
}//main

KhoaCNTT – Trường ĐHBK Đà Nẵng 3


2. Chương trình lab02rotation01.cpp xoay hình vuông một góc 20o.
Tâm xoay là gốc tọa độ

3. Chương trình lab02rotation02.cpp xoay hình vuông một góc 20o.


Tâm xoay là điểm(x, y)
#include <GL/glut.h>
#include <GL/gl.h>

void myInit(void){
glClearColor(0.7f,0.7f,0.7f,0.7f); //To nen mau xam
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,640.0,0.0,480.0);
glMatrixMode(GL_MODELVIEW);
}

void myDisplay(void){
int x=50, y=40;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f,0.0f,0.0f);
glRectf(200,100,400,300);
glColor3f(1.0f,1.0f,0.0f);

glPushMatrix(); // Luu ma tran hien hanh


glTranslatef(x,y,0.); // Quay goc 20o CCW trong mat phang Oxy
glRotatef(30.,0.,0.,1.);
glRectf(200.,100.,400.,300.); // Ve hinh chu nhat

KhoaCNTT – Trường ĐHBK Đà Nẵng 4


glPopMatrix(); // Lay lai ma tran M ban dau

glPointSize(4.);
glColor3f(0.0f,0.0f,1.0f);
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd();
glFlush();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640,480);
glutInitWindowPosition(100,150);
glutCreateWindow("HO VA TEN - Modelview matrix");
glutDisplayFunc(myDisplay);
myInit();
glutMainLoop();
}

4. Chương trình lab02rotation03.cpp vẽ hình chữ nhật quay quanh


tâm
Để tránh trường hợp hình bị giật khi chuyển động, ta sẽ dùng kỹ thuật double buffer:
 Trong khi buffer 1 đang được dùng để trình diễn frame t trên screen thì chương trình
sẽ dùng buffer 2 để chuẩn bị cho frame t+1,
 Khi đến lượt trình diễn frame t+1 thì chương trình chỉ cần thể hiện buffer 2 và đưa
buffer 1 về đằng sau để chuẩn bị cho frame t+2.
Thời gian chuyển tiếp giữa 2 frame liên tiếp sẽ rất nhỏ và mắt người thường không phát
hiện ra được, dẫn đến việc hiển thị các frame liên tiếp sẽ rất mượt.

#include <GL/glut.h>
#include <GL/gl.h>

static GLfloat spin = 0.0; // Goc quay hien tai cua hinh chu nhat

void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin, 0.0, 0.0, 1.0); // Xoay mot goc spin quanh truc z
glColor3f(1.0, 1.0, 1.0); // Mau ve cho hcn(mau trang)
glRectf(-25.0, -25.0, 25.0, 25.0); // ve hcn
glPopMatrix();
glutSwapBuffers(); // Hoan doi 2 buffer
}
void spinDisplay(void)
{
spin = spin + 2.0; // Xoay them 2 deg cho moi lan lap
if(spin > 360.0) spin = spin - 360.0;
glutPostRedisplay(); // Thuc hien viec ve lai
}

void reshape(int w, int h)


{
glViewport(0, 0,(GLsizei) w,(GLsizei) h);

KhoaCNTT – Trường ĐHBK Đà Nẵng 5


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

// Thao tac xu ly chuot


void mouse(int button, int state, int x, int y)
{
switch(button) {
case GLUT_LEFT_BUTTON: // Nhan chuot trai
if(state == GLUT_DOWN)
glutIdleFunc(spinDisplay); // Khi idle thi chay ham spinDisplay
break;
case GLUT_MIDDLE_BUTTON: // Nhan nut giua
if(state == GLUT_DOWN) //glutIdleFunc(NULL);
break;
default: break;
}
}

int main(int argc, char** argv)


{
glutInit(&argc, argv);
// Khai bao su dung che do double buffer
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(250, 250);
glutInitWindowPosition(100, 100);
glutCreateWindow("HO VA TEN - Modelview matrix");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape); // Xu ly su kien cua so bi thay doi kich thuoc
glutMouseFunc(mouse); // Dang ky ham mouse cho su kien ve chuot
glutMainLoop();
return 0;
}//main

 Kết quả chạy chương trình:


Kích chuột trái vào hình chữ nhật:

5. Chương trình lab02affine.cpp: Xây dựng các hàm biến đổi affine
#include <stdlib.h>
//#include <GL/gl.h>
#include <GL/glut.h>
#include <iostream>
#include <assert.h>
#include <stdio.h>

const int WIN_SIZE = 500;

class Point;
class Vector;

/***********************
* Basic Point and Vector Classes with some standard functions

KhoaCNTT – Trường ĐHBK Đà Nẵng 6


************************/
class Point {
public:
float x, y;
Point(): x(0), y(0) { }
Point(float _x, float _y) : x(_x), y(_y) { }
static Point lerp(Point& p, Point& q, float t);
static Point lerp(Point& p, Vector& q, float t);
};

class Vector {
public:
float dx, dy;
Vector() : dx(0), dy(0) { }
Vector(Point& p, Point& q) {
dx = q.x - p.x;
dy = q.y - p.y;
}

// Returns the perp of the given Vector


Vector perp() {
Vector answer;
answer.dx = -dy;
answer.dy = dx;
return answer;
}
};

// Compute the Point that is a linear interpolation of p and q


Point Point::lerp(Point& p, Point& q, float t) {
Point answer;
answer.x = p.x + t*(q.x - p.x);
answer.y = p.y + t*(q.y - p.y);
return answer;
}

// Compute the Point that is a linear interpolation of p and v


Point Point::lerp(Point& p, Vector& v, float t) {
Point answer;
answer.x = p.x + t*v.dx;
answer.y = p.y + t*v.dy;
return answer;
}

//=====================================================

void centerWorld(double cx, double cy, double sx, double sy);


void drawRay(Point start, Point end, int ticks = 0);
void drawCoordinateFrame();
void drawHouse();
void drawScene();
void display();

// Set the world to be centered at given location With given size


void centerWorld(double cx, double cy, double sx, double sy) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(cx - sx/2, cx + sx/2, cy - sy/2, cy + sy/2);
}

// Draw a ray from start to end Include arrow and tick marks
void drawRay(Point start, Point end, int ticks) {
// First draw the line segment itself
glBegin(GL_LINES);
{
glVertex2f(start.x, start.y);
glVertex2f(end.x, end.y);
}
glEnd();
}

KhoaCNTT – Trường ĐHBK Đà Nẵng 7


// Draw the x- and y- axes(use drawRay)
void drawCoordinateFrame() {
Point origin(0, 0);
Point xPoint(10, 0);
Point yPoint(0, 10);
drawRay(origin, xPoint, 10);
drawRay(origin, yPoint, 10);
}

// Draw a simple house


void drawHouse() {
glBegin(GL_POLYGON); {
glVertex2f(0, 0);
glVertex2f(1, 0);
glVertex2f(1, 1);
glVertex2f(0, 1);
}
glEnd();
glBegin(GL_TRIANGLES); {
glVertex2f(0, 1);
glVertex2f(1, 1);
glVertex2f(0.5, 1.5);
}
glEnd();
}

// Compute the Shear Matrix


// OpenGL does not provide a Shear matrix(that I could find yet)
// Plus it illustrates how to pass ANYWAY Matrix to OpenGL
// Note: m goes down COLUMNS first...
// m1, m2, m3, m4 represent m11, m21, m31, m41
// m5, m6, m7, m8 represent m12, m22, m32, m42
// etc...
void shearMatrix(int shearX, int shearY) {
float m[] = {
1, shearY, 0, 0,
shearX, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 };
glMultMatrixf(m);
}

void printMatrix() {
float m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m);

int row, col, index;


for(row = 0; row < 4; row++) {
for(col = 0, index = row; col < 4; col++, index+=4) {
printf("%3.3f ", m[index]);
}
printf("\n");
}
}

// Draw our complex scene!


void drawScene() {
float intensity = 1.0;

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
printf("After Identity\n");
printMatrix(); printf("\n");

glColor3f(intensity, intensity, intensity);


glScaled(20, 20, 1.0); // Sx=20, Sy=20, Sz=1
printf("After Scaling\n");
printMatrix(); printf("\n");
drawCoordinateFrame(); drawHouse();

glPushMatrix();

KhoaCNTT – Trường ĐHBK Đà Nẵng 8


intensity -= 0.1;
glColor3f(intensity, intensity, intensity);
glColor3f(.0, 1.0, 1.0);
glTranslated(2, 0, 0); // dx = 2, dy = 0, dz = 0(over 2 units)
printf("After Now Translating\n");
printMatrix(); printf("\n");
drawCoordinateFrame(); drawHouse();

intensity -= 0.1;
glColor3f(intensity, intensity, intensity);
glTranslated(0, 2, 0.0);
printf("After Now Translating Again...\n");
printMatrix(); printf("\n");
drawCoordinateFrame(); drawHouse();

intensity -= 0.1;
glColor3f(intensity, intensity, intensity);
glRotated(30, 0, 0, 1); // 30 degrees about origin(z-axis)
glTranslated(0, 5, 0);
glScaled(1.2, 0.5, 1);
printf("After Rotate, Translate, Scale\n");
printMatrix(); printf("\n");
drawCoordinateFrame(); drawHouse();

glPopMatrix();
glPushMatrix();
intensity -= 0.1;
glColor3f(intensity, intensity, intensity);
glRotated(-30, 0, 0, 1); // 30 degrees about origin(z-axis)
glTranslated(0, 5, 0);
glScaled(1.2, 0.5, 1);
drawCoordinateFrame(); drawHouse();

glPopMatrix();

intensity -= 0.1;
glColor3f(intensity, intensity, intensity);
shearMatrix(1, 0);
drawCoordinateFrame(); drawHouse();
printf("At the End\n");
printMatrix(); printf("\n");

void display() {
// Set the viewport to the full screen!
glViewport(0, 0, WIN_SIZE, WIN_SIZE);

// Clear the screen


glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);

// Place origin in the center of our Frame


centerWorld(0, 0, WIN_SIZE, WIN_SIZE);

// And now draw the scene


drawScene();

glFlush();
glutSwapBuffers(); // needed for double buffering!
}

void keyboard(unsigned char key, int x, int y)


{
switch(key) {
case 27:
case 'Q':
case 'q':
exit(0);

KhoaCNTT – Trường ĐHBK Đà Nẵng 9


break;
}

// Redraw the screen on all keyboard events


glutPostRedisplay();
}

int main(int argc, char** argv) {


// Initialize the GLUT environment
glutInit(&argc, argv);

// Single-buffered, using RGB


glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(WIN_SIZE,WIN_SIZE);
glutInitWindowPosition(100,100);

// Create window, returns a unique window identifier


glutCreateWindow("XYZ - Transformers: Graphics in Disguise!");

// Set up the callback routines we will need/use


glutDisplayFunc(display);
glutKeyboardFunc(keyboard);

// Start GLUT going in its infinite event listen cycle


glutMainLoop();
return 0;
}//main

6. Chương trình lab02earth.cpp vẽ hình trái đất quay xung quanh mặt
trời
#include "Gl/glut.h"
static int year = 0, day = 0;
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);

//Loai bo mot phan cua doi tuong bi che boi doi tuong khac
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
}

void display(void)
{
// xoa color buffer va depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix(); // luu lai ma tran hien hanh
glColor3f(1.0, 0, 0); // thiet lap mau ve la mau do

// ve mat troi la mot luoi cau co tam tai goc toa do


glutWireSphere(1.0, 20, 16);

// quay mot goc tuong ung voi thoi gian trong nam
glRotatef((GLfloat) year, 0.0, 1.0, 0.0);
// tinh tien den vi tri hien tai cua trai dat tren quy dao quanh mat troi
glTranslatef(2.0, 0.0, 0.0);
// quay trai dat tuong ung voi thoi gian trong ngay
glRotatef((GLfloat) day, 0.0, 1.0, 0.0);
glColor3f(0, 0, 1.0); // thiet lap mau ve la mau blue
glutWireSphere(0.2, 10, 8); // ve trai dat
// phuc hoi lai ma tran hien hanh cu: tuong ung voi quay lai vi tri ban dau
glPopMatrix();
glutSwapBuffers();
}

void reshape(int w, int h)


{
// Thay doi kich thuoc viewport
glViewport(0, 0,(GLsizei) w,(GLsizei) h);

KhoaCNTT – Trường ĐHBK Đà Nẵng 10


/* Thao tac tren chieu */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Chieu phoi canh
gluPerspective(60.0,(GLfloat) w/(GLfloat) h, 1.0, 20.0);

/* Thao tac tren ModelView */


glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Thiet lap view
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}//reshape

void keyboard(unsigned char key, int x, int y)


{
switch(key) {
case 'd': day =(day + 10) % 360;
glutPostRedisplay();
break;
case 'D': day =(day - 10) % 360;
glutPostRedisplay();
break;
case 'y': year =(year + 5) % 360;
glutPostRedisplay();
break;
case 'Y':
year =(year - 5) % 360;
glutPostRedisplay();
break;
default:
break;
}
}//keyboard

int main(int argc, char** argv)


{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(“XYZ – Rotate Earth around sun”);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}//main

 Kết quả chạy chương trình

7. Bài tập
Cho đường thẳng PQ có P(1, 2, 0), Q(7, 14). Lập trình biểu diễn các phép biến đổi
đường thẳng PQ thông qua điều khiển bàn phím như sau:
1) Nhấn phím t, T: Dịch chuyển PG một đoạn theo khoảng cách(5, 0, 0)
2) Nhấn phím r, R: Quay PG một góc quanh trục Oy một góc 30o
3) Nhấn phím p, P: Lấy đối xứng của PG qua trục Ox
4) Nhấn phím f, F: Lấy đối xứng của PG qua trục MN
5) Nhấn phím h, H: Quay PG quanh trục MN một góc 30o
------------------------------------------------

KhoaCNTT – Trường ĐHBK Đà Nẵng 11


#include <stdlib.h>
#include <GL/glut.h>
#include <iostream>
#include <assert.h>
#include <stdio.h>
#include <cmath>

// Điểm P và Q
GLfloat P[] = {1.0f, 2.0f, 0.0f};
GLfloat Q[] = {7.0f, 14.0f, 0.0f};
// Điểm PG ban đầu là Q
GLfloat PG[] = {7.0f, 14.0f, 0.0f};

// Hàm dịch chuyển PG


void translatePG(GLfloat dx, GLfloat dy, GLfloat dz) {
PG[0] += dx;
PG[1] += dy;
PG[2] += dz;
}

// Hàm quay PG quanh trục Oy


void rotatePG(float angle) {
float rad = angle * M_PI / 180.0f;
GLfloat x = PG[0];
PG[0] = cos(rad) * x - sin(rad) * PG[2];
PG[2] = sin(rad) * x + cos(rad) * PG[2];
}

// Hàm lấy đối xứng của PG qua trục Ox


void reflectPG_Ox() {
PG[1] = -PG[1];
}

KhoaCNTT – Trường ĐHBK Đà Nẵng 12


// Hàm lấy đối xứng của PG qua trục MN
void reflectPG_MN() {
PG[0] = -PG[0];
PG[2] = -PG[2];
}

// Hàm quay PG quanh trục MN


void rotatePG_MN(float angle) {
float rad = angle * M_PI / 180.0f;
GLfloat x = PG[0];
PG[0] = cos(rad) * x - sin(rad) * PG[2];
PG[2] = sin(rad) * x + cos(rad) * PG[2];
}

// Hàm vẽ đường thẳng


void drawLine(GLfloat *start, GLfloat *end) {
glBegin(GL_LINES);
glVertex3fv(start);
glVertex3fv(end);
glEnd();
}

// Hàm vẽ một frame


void draw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);
// Vẽ đường thẳng PQ (màu trắng)
drawLine(P, Q);
glColor3f(1.0f, 0.0f, 0.0f); // Màu đỏ
// Vẽ đường thẳng PG (màu đỏ)
drawLine(P, PG);
glFlush();
}

// Callback hàm xử lý sự kiện nhấn phím


KhoaCNTT – Trường ĐHBK Đà Nẵng 13
void keyCallback(unsigned char key, int x, int y) {
switch (key) {
case 't':
case 'T':
translatePG(5.0f, 0.0f, 0.0f);
break;
case 'r':
case 'R':
rotatePG(30.0f);
break;
case 'p':
case 'P':
reflectPG_Ox();
break;
case 'f':
case 'F':
reflectPG_MN();
break;
case 'h':
case 'H':
rotatePG_MN(30.0f);
break;
}
glutPostRedisplay();
}

int main(int argc, char** argv) {


glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Line Transformation");

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10.0, 10.0, -10.0, 10.0);
KhoaCNTT – Trường ĐHBK Đà Nẵng 14
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glPointSize(5.0);

glutDisplayFunc(draw);
glutKeyboardFunc(keyCallback);

glutMainLoop();

return 0;
}

KhoaCNTT – Trường ĐHBK Đà Nẵng 15

You might also like