Menu Callback
Menu Callback
#include <GL/freeglut.h>
GLboolean IsSphere = true;
//IsSphere 변수 선언하고 True로 초기화 : 메뉴에서 선택된 도형을 결정하는데 사용
void MyDisplay() { //화면에 도형을 그리는 함수
glClear(GL_COLOR_BUFFER_BIT); //컬러버퍼 초기화
glColor3f(0.5, 0.0, 0.5); //그릴 도형의 색상 지정
if (IsSphere) //IsSphere가 참이면 구 그리기
glutWireSphere(0.2, 15, 15);
else //거짓이면 도넛을 그리기
glutWireTorus(0.1, 0.3, 40, 20);
glFlush(); //그리기 명령 실행
}
void MyMainMenu(int entryID) { //메뉴 아이템이 선택될 때마다 호출됨, 전달된 아이디에 따라...
if (entryID == 1) //"Draw Sphere" 아이템 선택되어 IsSphere 변수 true로 설정
IsSphere = true;
else if (entryID == 2) //"Draw Torus" 아이템 선택되어 IsSphere 변수 false로 설정
IsSphere = false;
else if (entryID == 3) //"Exit" 아이템 선택되어 프로그램 종료
exit(0);
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(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
GLint MyMainMenuID = glutCreateMenu(MyMainMenu); //메뉴 콜백 함수를 등록, 그 결과 등록된 메뉴 아이디 값이 리턴됨
//현 메뉴에 메뉴 항목을 추가함
glutAddMenuEntry("Draw Sphere", 1);
glutAddMenuEntry("Draw Torus", 2);
glutAddMenuEntry("Exit", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON); //지정한 마우스 버튼에 현 메뉴를 할당함 : 우클릭 버튼
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
Cascaded Menu
#include <GL/freeglut.h>
#include <iostream>
GLboolean IsSphere = true;
GLboolean IsSmall = true;
//IsSphere와 IsSmall이라는 전역 변수가 선언됨. 도형의 종류와 크기 결정
void MyDisplay() { //화면에 도형을 그리는 함수
glClear(GL_COLOR_BUFFER_BIT); //컬러버퍼 초기화
glColor3f(0.5, 0.0, 0.5); //그릴 도형의 색상 지정
if ((IsSphere) && (IsSmall))
glutWireSphere(0.2, 15, 15); //작은 원구
else if ((IsSphere) && (!IsSmall))
glutWireSphere(0.4, 15, 15); //큰 원구
else if ((!IsSphere) && (IsSmall))
glutWireTorus(0.1, 0.3, 40, 20); //작은 원환체
else
glutWireTorus(0.2, 0.5, 40, 20); //큰 원환체
glFlush(); //그리기 명령 실행
}
void MyMainMenu(int entryID) { //메뉴 아이템이 선택될 때마다 호출됨,
if (entryID == 1)
IsSphere = true; //원구 그리기
else if (entryID == 2)
IsSphere = false; //원환체 그리기
else if (entryID == 3)
exit(0); //프로그램 종료
glutPostRedisplay();
//다른 콜백 함수에서 어떤 값을 바꾸고 바뀐 값을 기준으로 새로이 화면 디스플레이를 원할 때..
}
void MySubMenu(int entryID) {
if (entryID == 1)
IsSmall = true; //작은 크기로 그리기
else if (entryID == 2)
IsSmall = false; //큰 크기로 그리기
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(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
GLint MySubMenuID = glutCreateMenu(MySubMenu);//서브 메뉴 콜백 함수를 등록, 그 결과 등록된 메뉴 아이디 값이 리턴됨
//서브 메뉴 항목 추가
glutAddMenuEntry("Small One", 1);
glutAddMenuEntry("Big One", 2);
GLint MyMainMenuID = glutCreateMenu(MyMainMenu);//메인 메뉴 콜백 함수를 등록, 그 결과 등록된 메뉴 아이디 값이 리턴됨
//현 메뉴에 메뉴 항목을 추가함
glutAddMenuEntry("Draw Sphere", 1);
glutAddMenuEntry("Draw Torus", 2);
glutAddSubMenu("Change Size", MySubMenuID); //현 메뉴 중 하나로서 서브 메뉴 항목을 추가함
glutAddMenuEntry("Exit", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON); //지정한 마우스 버튼에 현 메뉴를 할당함 : 우클릭 버튼
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
더보기
- int glutCreateMenu(void(*func)(int value)) : 새로운 메뉴를 생성하고 해당 메뉴에 대한 함수를 등록함.
- void glutSetMenu(int id) : 현재 메뉴를 설정함.
- void glutAddMenuEntry(char *name,int value) : 현재 메뉴에 새로운 항목을 추가. 항목 이름과 항목을 선택했을 때 호출될 값(value)을 지정함.
- int glutAttachMenu(int button) : 마우스 버튼 이벤트와 현재 메뉴를 연결 예를 들어, GLUT_RIGHT_BUTTON을 인수로 전달하면 마우스 오른쪽 버튼 클릭시 메뉴가 나타남.
- void glutaddSubMenu(char *name, int menu) : 하위 메뉴를 생성하고 현재 메뉴에 추가. name은 하위 메뉴 이름, menu는 하위 메뉴에 대한 메뉴 ID. 이 함수는 메뉴 계층 구조를 만드는 데 사용됨.
Idle Callback
#include <GL/freeglut.h>
GLfloat Delta = 0.0; //사각형을 오른쪽으로 조금씩 옮기는데 사용함 (사각형이 이동하는 양)
void MyDisplay() {
glClear(GL_COLOR_BUFFER_BIT); //기존의 컬러 버퍼 내용을 지우라는 것. glClearColor(1.0, 1.0, 1.0, 1.0) 사용
glColor3f(0.0, 0.5, 0.8); //그리는 도형의 색상 설정
glBegin(GL_POLYGON); //사각형 그리기
glVertex3f(-1.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, 0.5, 0.0);
glVertex3f(-1.0 + Delta, 0.5, 0.0);
glEnd(); //도형 그리기 종료
glutSwapBuffers();
//증가된 델타 값을 사용하여 새로이 그려질 사각형은 백 버퍼에 기록되며 그동한 현재 화면에 보이는 내용은 현재 프런트 버퍼에 있는 이전 사각형임
//버퍼 스와핑 명령에 의해 새로 생성된 사각형을 보일 수 있게 됨
}
void MyIdle() {
Delta = Delta + 0.001; //Delta 값을 증가시킴
glutPostRedisplay();
//다른 콜백함수에서 어떤 값을 바꾸고 바뀐 값을 기준으로 새로이 화면 디스플레이를 원할 때, 화면을 다시 그리도록 하기
}
int main(int argc, char** argv) {
glutInit(&argc, argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);//디스플레이 모드를 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(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutIdleFunc(MyIdle); //아이들 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
더보기
- 이벤트 루프를 돌 때마다 GLUT는 큐에 쌓인 이벤트를 검사함.
- glClear()를 기존의 컬러 버퍼 내용을 다 지우라는 의미로, 이게 없다면 새로운 사각형이 이전 사각형이 위에 겹쳐서 기록 되므로 원하는 바가 아니다. = 러버 밴딩 : 이전의 그림을 지우고, 배경색을 다시 칠하고.
- 애니메이션 등의 동적인 변화를 위해 사용됨. glutIdleFunc() 함수를 사용하여 Idle 콜백 함수 등록
Timer Callback
Timer Callback 1
#include <GL/freeglut.h>
GLfloat Delta = 0.0;
//사각형을 오른쪽으로 조금씩 옮기는데 사용함 (사각형이 이동하는 양)
void MyDisplay() { //도형 그리는 함수
glClear(GL_COLOR_BUFFER_BIT); //기존의 컬러 버퍼 내용을 지우라는 것. glClearColor(1.0, 1.0, 1.0, 1.0) 사용
glColor3f(0.0, 0.5, 0.8); //그리는 도형의 색상 설정
glBegin(GL_POLYGON); //사각형 그리기
glVertex3f(-1.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, -0.5, 0.0);
glVertex3f(0.0 + Delta, 0.5, 0.0);
glVertex3f(-1.0 + Delta, 0.5, 0.0);
glEnd(); //도형 그리기 종료
glutSwapBuffers();
//증가된 델타 값을 사용하여 새로이 그려질 사각형은 백 버퍼에 기록되며 그동한 현재 화면에 보이는 내용은 현재 프런트 버퍼에 있는 이전 사각형임
//버퍼 스와핑 명령에 의해 새로 생성된 사각형을 보일 수 있게 됨
}
void MyTimer(int Value) {
Delta = Delta + 0.001; //Delta 값을 증가시킴
glutPostRedisplay();
//다른 콜백함수에서 어떤 값을 바꾸고 바뀐 값을 기준으로 새로이 화면 디스플레이를 원할 때, 화면을 다시 그리도록 하기
glutTimerFunc(40, MyTimer, 1);
/*일정한 시간간격이 지나면 발생하는 이벤트가 타이머 이벤트 이며, 타이머 콜백은 이 이벤트에 대응하는 콜백함수임
40 msec 의미, 1은 넘겨줄 파라미터. GLUT 타이머는 타이머 함수가 등록되면 단 한번만 타이머 이벤트를 발생시킴.
콜백함수의 마지막에 콜백등록함수를 다시 써 줌으로써 해결함*/
}
int main(int argc, char** argv) {
glutInit(&argc, argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);//디스플레이 모드를 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(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); //뷰포트의 좌표계 설정
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutTimerFunc(40, MyTimer, 1); //타이머 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
Timer Callback 2
#include <GL/freeglut.h>
#include <time.h>
unsigned char PALETTE[16][3] = { //팔레트 배열 : 16개의 색상 값(RGB)을 저장하는 배열
{ 255, 255, 255 }, // WHITE
{ 0, 255, 255 }, // CYAN
{ 255, 0, 255 }, // PURPLE
{ 0, 0, 255 }, // BLUE
{ 192, 192, 192 }, // LIGHT GRAY
{ 128, 128, 128 }, // DARK GRAY
{ 0, 128, 128 }, // DARK TEAL
{ 128, 0, 128 }, // DARK PURPLE
{ 0, 0, 128 }, // DARK BLUE
{ 255, 255, 0 }, // YELLOW
{ 0, 255, 0 }, // GREEN
{ 128, 128, 0 }, // DARK YELLOW
{ 0, 128, 0 }, // DARK GREEN
{ 255, 0, 0 }, // RED
{ 128, 0, 0 }, // DARK RED
{ 0, 0, 0 }, // BLACK
};
GLfloat Delta = 0.0; //애니메이션에서 사용되는 변수. 각 라인이 얼마나 그려졌는지 나타냄
GLint Index = 0; //PALETTE 배열에서 현재 사용되는 색상의 인덱스를 저장하는 변수
//현재 사용되는 색상 값
GLfloat Red = 0.0;
GLfloat Green = 0.0;
GLfloat Blue = 0.0;
void MyDisplay() {
//각 프레임마다 호출되어 그려지는 함수. 팔레트 배열에서 index에 해당하는 색상으로 두 개의 라인 그림
Red = PALETTE[Index][0] / 255.0f;
Green = PALETTE[Index][1] / 255.0f;
Blue = PALETTE[Index][2] / 255.0f;
glColor3f(Red, Green, Blue); //그리는 선의 색상 설정
glBegin(GL_LINES); //선 그리기
glVertex3f(-1.0 + Delta, 1.0, 0.0); //Delta 변수를 사용해서 선을 회전시킴
glVertex3f( 1.0 - Delta, -1.0, 0.0);
glVertex3f(-1.0, -1.0 + Delta, 0.0);
glVertex3f( 1.0, 1.0 - Delta, 0.0);
glEnd(); //선 그리기 종료
glutSwapBuffers();
}
void MyTimer(int Value) { //일정 시간마다 호출되어 Delta 값을 변경하고, index 값이 변할 때마다 화면 지움
if (Delta < 2.0f)
Delta = Delta + 0.01; //Delta 값을 증가시킴
else {
Delta = 0.0;
if (++Index >= 15) { //팔레트의 인덱스 값이 변경됨. 화면을 지우고 다시 그리기 위해 glClear 호출
Index = 0;
glClear(GL_COLOR_BUFFER_BIT);
}
}
glutPostRedisplay();
//다른 콜백함수에서 어떤 값을 바꾸고 바뀐 값을 기준으로 새로이 화면 디스플레이를 원할 때, 화면을 다시 그리도록 하기
glutTimerFunc(10, MyTimer, 1);
//첫 파라미터는 10msec를 의미하지만, 큐 프런트에 다른 이벤트가 있는 경우에는 그보다 늦어질 수 있음.
}
int main(int argc, char** argv) {
glutInit(&argc, argv); //GLUT 라이브러리를 초기화함
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);//디스플레이 모드를 RGB 컬러 모드로 설정 & 더블 버퍼링 활성화
glutInitWindowSize(500, 500); //윈도우 크기 설정
glutInitWindowPosition(0, 0); //윈도우 위치 설정
glutCreateWindow("OpenGL Timer Animation Sample"); //윈도우 생성
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); //뷰포트의 좌표계 설정
glutTimerFunc(10, MyTimer, 1); //타이머 콜백 함수 등록
glutDisplayFunc(MyDisplay); //디스플레이 콜백 함수 등록
glutMainLoop(); //이벤트 루프 실행
return 0;
}
더보기
타이머 이벤트 : 일정 시간이 지나면 발생하는 이벤트
'전공 > 컴퓨터 그래픽스' 카테고리의 다른 글
모델변환과 시점변환 (1)좌표계 (0) | 2023.04.11 |
---|---|
OpenGL 기본 틀 : 정점배열 (1) | 2023.04.11 |
OpenGL 기본틀 : Callback 프로그래밍 (1)Reshape Callback, Keyboard Callback, Mouse Callback (0) | 2023.04.10 |
OpenGL 기본 틀 (5)_더블 버퍼링 (0) | 2023.04.09 |
OpenGL 기본 틀 (4)_윈도우와 뷰포트 (0) | 2023.04.09 |
댓글