Reshape Callback
#include <GL/freeglut.h>
void MyDisplay() { //사각형을 그리기 위한 함수
glClear(GL_COLOR_BUFFER_BIT); //컬러버퍼에 초기화 색을 가함
glColor3f(0.5, 0.5, 0.5); //그리는 도형의 색상 설정 : 회색 (R,G,B가 같으면 회색)
glBegin(GL_POLYGON); //도형을 그리기 위한 시작 지점 설정, 사각형 그리기
glVertex3f(-0.5, -0.5, 0.0); //좌하단 좌표 (첫 번째 꼭짓점)
glVertex3f(0.5, -0.5, 0.0); //우하단 좌표 (두 번째 꼭짓점)
glVertex3f(0.5, 0.5, 0.0); //우상단 좌표 (세 번째 꼭짓점)
glVertex3f(-0.5, 0.5, 0.0); //좌상단 좌표 (네 번째 꼭짓점)
glEnd(); //도형 그리기 종료
glFlush(); //명령어 버퍼에 쌓인 명령어 실행
}
void MyReshape(int NewWidth, int NewHeight) {
glViewport(0, 0, NewWidth, NewHeight); //뷰포트 설정 (0, 0)부터 시작하기
GLfloat WidthFactor = (GLfloat) NewWidth / (GLfloat) 300;
GLfloat HeightFactor = (GLfloat) NewHeight / (GLfloat) 300;
//새로운 창의 크기를 기존의 300x300 크기로부터 얼마나 변화했는지 계산
glMatrixMode(GL_PROJECTION); //행렬 모드를 GL_PROJECTION으로 설정
glLoadIdentity(); //현재의 행렬 상태 초기화함.
glOrtho(-1.0 * WidthFactor, 1.0 * WidthFactor,
-1.0 * HeightFactor, 1.0 * HeightFactor, -1.0, 1.0);
//직교 좌표계를 설정하기 위해 사용됨. x축과 y축의 범위를 -widthfactor부터 widthfactor까지
//-heightfactor부터 heightfactor까지로 설정하고, z축의 범위는 -1부터 1까지로 설정
}
int main(int argc, char** argv) {
glutInit(&argc,argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB); //디스플레이 모드를 RGB 컬러 모드로 설정함
glutInitWindowSize(300, 300); //윈도우 크기 설정
glutInitWindowPosition(0, 0); //윈도우 위치 설정
glutCreateWindow("OpenGL Example Drawing"); //윈도우 생성
glClearColor(1.0, 1.0, 1.0, 1.0); //초기화 색은 백색
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutReshapeFunc(MyReshape); //리셰이프 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
더보기
glMatrixMode()는 투상 행렬을 변환대상으로 설정하라는 명령이며, glLoadIdentity()는 이 행렬에 일단 항등 행렬을 실으라는 명령어. 이 두 명령이 선행되어야 glOrtho() 함수에서 지정한 값이 해당 행렬에 곱해진다.
가시부피 = 화면에 보이고자 하는 물체의 범위를 말한다.
가시 부피를 정의하기 위한 glOrtho() 함수의 프로토타입은 다음과 같다.
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near,GLdouble far);
투상 방식에서 투상면은 가시 부피의 전방 절단면과 동일. glOrtho()에 의해 가시 부피의 모습을 조절함으로써 왜곡 해소 가능. → 투상면 자체의 종횡비가 뷰 포트의 종횡비가 일치해서 물체는 전혀 왜곡되지 않는다.
Keyboard Callback
#include <GL/freeglut.h>
void MyDisplay() { //사각형을 그리기 위한 함수
glClear(GL_COLOR_BUFFER_BIT); //컬러버퍼에 초기화 색을 가함
glColor3f(0.5, 0.5, 0.5); //그리는 도형의 색상 설정 : 회색 (R,G,B가 같으면 회색)
glBegin(GL_POLYGON); //도형을 그리기 위한 시작 지점 설정, 사각형 그리기
glVertex3f(-0.5, -0.5, 0.0); //좌하단 좌표 (첫 번째 꼭짓점)
glVertex3f(0.5, -0.5, 0.0); //우하단 좌표 (두 번째 꼭짓점)
glVertex3f(0.5, 0.5, 0.0); //우상단 좌표 (세 번째 꼭짓점)
glVertex3f(-0.5, 0.5, 0.0); //좌상단 좌표 (네 번째 꼭짓점)
glEnd(); //도형 그리기 종료
glFlush(); //명령어 버퍼에 쌓인 명령어 실행
}
void MyKeyboard(unsigned char KeyPressed, int X, int Y) {
//매개변수는 눌려진 키의 아스키 코드 값, 마우스의 현재 좌표인 x, y 값 전달됨
switch (KeyPressed){ //'q', 'Q', 혹은 ESC 키를 누르면 프로그램 종료
case 'Q':
exit(0); break;
case 'q':
exit(0); break;
case 27: //'esc' 키의 아스키 코드 값
exit(0); break;
}
}
int main(int argc, char** argv) {
glutInit(&argc,argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB); //디스플레이 모드를 RGB 컬러 모드로 설정함
glutInitWindowSize(300, 300); //윈도우 크기 설정
glutInitWindowPosition(0, 0); //윈도우 위치 설정
glutCreateWindow("OpenGL Drawing Example"); //윈도우 생성
glClearColor(1.0, 1.0, 1.0, 1.0); //초기화 색은 백색
glMatrixMode(GL_PROJECTION); //행렬 모드를 GL_PROJECTION으로 설정
glLoadIdentity(); //현재의 행렬 상태 초기화함.
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutKeyboardFunc(MyKeyboard); //키보드 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
Mouse Callback
#include <GL/freeglut.h>
GLint TopLeftX, TopLeftY, BottomRightX, BottomRightY;
//마우스로 드래그 한 사각형의 좌측 상단과 우측 하단의 좌표를 저장하기 위한 변수
void MyDisplay() { //사각형 그리기
glViewport(0, 0, 300, 300); //뷰포트 설정
glClear(GL_COLOR_BUFFER_BIT); //컬러버퍼에 초기화 색을 가함
glColor3f(0.5, 0.5, 0.5); //그릴 도형의 색상 지정 : 회색
glBegin(GL_POLYGON); //도형을 그리기 위한 시작 지점 설정, 사각형 그리기
//사각형 꼭짓점 좌표 설정 (300으로 나누어서 정규화함)
glVertex3f(TopLeftX / 300.0, (300 - TopLeftY) / 300.0, 0.0);
glVertex3f(TopLeftX / 300.0, (300 - BottomRightY) / 300.0, 0.0);
glVertex3f(BottomRightX / 300.0, (300 - BottomRightY) / 300.0, 0.0);
glVertex3f(BottomRightX / 300.0, (300 - TopLeftY) / 300.0, 0.0);
glEnd(); //도형 그리기 종료
glFlush(); //명령어 버퍼에 쌓인 명령어 실행
}
void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y) {
//마우스 버튼이 눌렸을 때 좌표를 저장
if (Button == GLUT_LEFT_BUTTON && State == GLUT_DOWN) { //왼쪽 버튼 & 버튼이 눌렸을 때
TopLeftX = X;
TopLeftY = Y;
}
}
void MyMouseMove(GLint X, GLint Y) { //마우스가 움직이는 동안 좌표 업데이트
BottomRightX = X;
BottomRightY = Y;
glutPostRedisplay();
//다른 콜백함수에서 어떤 값을 바꾸고 바뀐 값을 기준으로 새로이 화면 디스플레이를 원할 때, 화면을 다시 그리도록 하기
}
int main(int argc, char** argv) {
glutInit(&argc, argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB); //디스플레이 모드를 RGB 컬러 모드로 설정함
glutInitWindowSize(300, 300); //윈도우 크기 설정
glutInitWindowPosition(0, 0); //윈도우 위치 설정
glutCreateWindow("OpenGL Example Drawing"); //윈도우 생성
glClearColor(1.0, 1.0, 1.0, 1.0); //초기화 색은 백색
glMatrixMode(GL_PROJECTION); //행렬 모드를 GL_PROJECTION으로 설정
glLoadIdentity(); //현재의 행렬 상태 초기화함.
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutMouseFunc(MyMouseClick); //마우스 클릭 이벤트에 따른 콜백 등록
glutMotionFunc(MyMouseMove); //마우스를 누른 상태에서 움직이는 이벤트에 따른 콜백 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
더보기
- void glutMotionFunc(void(*func) (int x, int y)) : 마우스 포인터가 윈도우 내에서 움직일 때마다 호출되는 콜백 함수를 등록함. 이 콜백 함수는 현재 마우스 포인터 위치의 x, y 좌표를 인수로 받음. 마우스 버튼이 눌려져 있을 때에도 호출됨
- void glutPassiveMotionFunc(void(*func) (int x, int y)) : 마우스 버튼이 눌려지지 않은 상태에서 마우스 포인터가 윈도우 내에서 움직일 때마다 호출되는 콜백 함수를 등록함. 이 콜백 함수는 현재 마우스 포인터 위치의 x, y 좌표를 인수로 받음.
- void glutEntryFunc(void(*func) (int state)) : 윈도우로의 진입/이탈 이벤트가 발생할 때마다 호출되는 콜백 함수를 등록함. 이 콜백 함수는 현재 윈도우 상태(진입한 경우 1, 이탈한 경우 0)를 나타내는 정수값을 인수로 받음.
glutPostRedisplay() 함수는 변수 값이 변경 되었으므로 다음 이벤트 루프가 돌 때 반드시 디스플레이 함수를 다시 실행하라는 것.
'전공 > 컴퓨터 그래픽스' 카테고리의 다른 글
OpenGL 기본 틀 : 정점배열 (1) | 2023.04.11 |
---|---|
OpenGL 기본틀 : Callback 프로그래밍 (2)Menu Callback, Idle Callback, Timer Callback (0) | 2023.04.11 |
OpenGL 기본 틀 (5)_더블 버퍼링 (0) | 2023.04.09 |
OpenGL 기본 틀 (4)_윈도우와 뷰포트 (0) | 2023.04.09 |
OpenGL 기본 틀 (3)_OpenGL/GLUT 프로그램 (0) | 2023.04.09 |
댓글