GLUT를 이용해서 입력을 처리해보자


그래픽 프로그램의 주된 기능은 출력이므로 입력기능은 사실 필요없지만, 사용자의 지시를 받아서 그래픽 상태를 변경하거나, 실행중에 변화를 관찰해보기 위해서는 입력기능이 필요하다.
GLUT는 기본적인 입력기능을 지원한다.

아래 함수들로 콜백을 지정하면 입력시 해당 함수가 호출된다.

void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));
void glutSpecialFunc(void (*func)(int key, int x, int y));
void glutMouseFunc(void (*func)(int button, int state, int x, int y));
각 콜백이 등록하는 입력함수의 원형은 인수목록의 함수 포인터 타입에 명시되어 있다.
glutKeyboardFunc의 경우 (unsigned char key, int x, int y)의 형으로 해야한다는 뜻
x, y는 키 입력시의 마우스 커서 위치인데, 실용성은 없어보인다.

Keyboard함수는 문자키만 입력받을 뿐 커서 이동키나 펑션키같은 특수키는 입력받을 수 없다.
특수키는 Special함수로 받는다. 이건 반대로 특수키만 입력받고 문자키는 입력받지 못한다.


GLUT_KEY_F1~
GLUT_KEY_LEFT
GLUT_KEY_RIGHT
GLUT_KEY_UP
GLUT_KEY_DOWN
GLUT_KEY_PAGE_UP
GLUT_KEY_PAGE_DOWN
GLUT_KEY_HOME
GLUT_KEY_END
GLUT_KEY_INSERT

Mouse 함수는 마우스 입력을 받는다. button는 눌려진 버튼의 이름이며, 
GLUT_LEFT_BUTTON
GLUT_MIDDLE_BUTTON
GLUT_RIGHT_BUTTON
셋중 하나이다.
마우스 버튼이 하나인 시스템에서는 왼쪽 버튼만 눌린다.
state는 버튼의 상태로 GLUT_UP, GLUT_DOWN이다. 
x, y인수는 마우스 버튼이 눌러진 윈도우 상의 좌표이다. 누름과 놓음에만 반응하며 이동시에는 호출되지 않는다.
마우스 이동시 콜백은 아래와 같다

void glutMotionFunc(void (*func)(int x, int y));
void glutPassiveMotionFunc(void (*func)(int x, int y));
glutMotionFunc의 콜백함수는 마우스 버튼을 누른채로 윈도우 내부에서 움직일 때 호출되며, glutPassiveMotionFunc는 버튼을 누르지 않고 움직일 때 호출되는 콜백함수를 지정해야 한다.
드래그 처리를 하려면 이 두 이벤트를 처리해야 한다.


#include <gl/glut.h>
#include <stdio.h>
 
void DoDisplay();
void DoKeyboard(unsigned char key, int x, int y);
void DoSpecial(int key, int x, int y);
void DoMouse(int button, int state, int x, int y);
 
const GLfloat size = 0.2;
const GLfloat step = 0.01;
GLfloat nx, ny;
GLboolean bGray = GL_FALSE;
 
int main()
{
     glutCreateWindow("OpenGL");
     glutDisplayFunc(DoDisplay);
     glutKeyboardFunc(DoKeyboard);
     glutSpecialFunc(DoSpecial);
     glutMouseFunc(DoMouse);
     glutMainLoop();
     return 0;
}
 
void DoKeyboard(unsigned char key, int x, int y)
{
     switch(key) {
     case 'r':
     case 'R':
          glClearColor(1.0, 0.0, 0.0, 1.0); // 배경 빨강
          break;
     case 'g':
     case 'G':
          glClearColor(0.0, 1.0, 0.0, 1.0); // 배경 초록
          break;
     case 'b':
     case 'B':
          glClearColor(0.0, 0.0, 1.0, 1.0); // 배경 파랑
          break;
     }
     glutPostRedisplay();
}
 
void DoSpecial(int key, int x, int y)
{
     switch(key) {
     case GLUT_KEY_LEFT: // 0.01만큼 x감소
          nx -= step;
          break;
     case GLUT_KEY_RIGHT: // 0.01만큼 x증가
          nx += step;
          break;
     case GLUT_KEY_UP: // 0.01만큼 y증가
          ny += step;
          break;
     case GLUT_KEY_DOWN: // 0.01만큼 y감소
          ny -= step;
          break;
     }
     char info[128];
     sprintf(info, "x=%.2f, y=%.2f", nx, ny);
     glutSetWindowTitle(info); // 제목표시줄에 x, y좌표 표시
     glutPostRedisplay();
}
 
void DoMouse(int button, int state, int x, int y)
{
     if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
          bGray = !bGray; // 삼각형 내부 색 토글
          glutPostRedisplay();
     }
}
 
void DoDisplay()
{
     glClear(GL_COLOR_BUFFER_BIT);
 
     if (bGray) {
          glColor3f(0.5, 0.5, 0.5); // TRUE : 회색
     } else {
          glColor3f(1.0, 1.0, 1.0); // FALSE : 흰색
     }
     glBegin(GL_POLYGON);
     glVertex2f(nx, ny + size);
     glVertex2f(nx - size, ny - size);
     glVertex2f(nx + size, ny - size); // 점의 이동
     glEnd();
     glFlush();
}

 

 

 

r, g, b키를 누름에따라 배경의 색이 바뀌고

마우스 버튼을 누를때 마다 삼각형의 색이 회색과 흰색으로 토글된다.

화살표 방향키를 누르면 삼각형이 이동하고 제목표시줄의 x, y좌표가 바뀐다.



끗 

'Graphics > OpenGL' 카테고리의 다른 글

OpenGL 기초 - GLUT : 애니메이션  (0) 2014.05.27
OpenGL 기초 - GLUT : 팝업메뉴  (0) 2014.05.27
OpenGL 기초 - GLUT  (0) 2014.05.19
OpenGL 기초 - 안티앨리어싱  (0) 2014.05.17
OpenGL 기초 - 블렌딩  (0) 2014.05.17
Posted by 긍정왕오킹