본문 바로가기
C++ 200제/코딩 IT 정보

[C언어] OpenGL 키보드, 마우스로 도형 회전, 확대 프로그램

by vicddory 2017. 5. 8.

[C언어] OpenGL 키보드, 마우스로 도형 회전, 확대 프로그램


일단 첨부 파일 부터 소개합니다.


OpenGL 키보드 방향키로 도형 회전 확대 (7zip으로 푸세요)


- OpenGL 예제.part1.rar [클릭]

- OpenGL 예제.part2.rar [클릭]


위의 압축 파일 2개는 예제 모음이고, 그중에 4개의 콜백 함수로 만든 도형 조작 예제는 아래를 참조하세요.


일단, 아래 캡쳐 된 그림들은 실제 실행 화면입니다. 초기엔 작은 사각형이 하나 생성됩니다.

키패드의 '+', '-' 키를 눌러 크기를 조절할 수 있어요.


[C언어] OpenGL 예제 프로그램, 시작 화면


OpenGL 예제 - 초기 실행 화면[OpenGL Mouse Keyboard Event] Callback 함수 예제, 초기 실행 화면


[C언어] OpenGL 예제 프로그램, 마우스 이벤트


OpenGL 예제 - 마우스 왼쪽 클릭[OpenGL Mouse Keyboard Event] Callback 함수 예제, 마우스 왼쪽 클릭

[C언어] OpenGL 예제 프로그램, 키보드 이벤트


OpenGL 예제 - 키패드 + 눌렀을 때[OpenGL Mouse Keyboard Event] Callback 함수 예제, 키패드 + 눌렀을 때


OpenGL 예제 - 키패드 - 눌렀을 때[OpenGL Mouse Keyboard Event] Callback 함수 예제, 키패드 - 눌렀을 때



위에 실행 화면을 구현하는 소스는 아래입니다. 주석 열심히 달아놨으니 잘 읽어보세요.


헤더 파일


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <glut.h>
#include <gl.h>
#include <glu.h>
#include <stdlib.h>
#include <stdio.h>
 
// 마우스의 휠을 사용하기 위해 3.7.6-3 버전으로 재설치
static GLfloat spin = 0.0;
 
// 도형 회전을 위한 변수. 32bit로 내부에서 표현되고 c언어에서의 자료형은 float.
static int WindowWidth = 650;
static int WindowHeight = 650;
 
// 윈도우 크기를 지정할 변수
// GLint와 GLsizei는 32bit로 내부에서 표현되고 c언어에서의 자료형은 long.
// GLuint는 GLenum, GLbitfield과 함께 32bit unsigned 형으로서 c언어에서의 자료형은 unsigned long형.
// 별도의 int형이 없기 때문에 GL을 생략한 int로 사용.
static float x1 = -5.0;
static float y1 = -5.0;
static float x2 = 5.0;
static float y2 = 5.0;
 
// 도형 크기 지정을 위한 변수
static float speed = 2.0;
cs

콜백 함수 1. Display()


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 콜백함수. 응용 프로그램이 이벤트를 처리하는 방법을 나타냄.
void display(void)
{
    // display 콜백 함수이며 void 뒤의 이름은 개별적 변경이 가능
    // display가 필요할 때 호출되도록 등록된 함수
    // glut 함수 일부는 gl함수를 호출한다.
    
    glClear(GL_COLOR_BUFFER_BIT); // 픽셀별 깊이 값을 저장할 수 있도록 선언
    glPushMatrix(); // 도형의 좌표 값 저장
    glRotatef(spin, 0.00.01.0); // 도형의 실제 회전
    glColor3f(0.00.00.0); // 도형의 색상 설정
    glRectf(x1, y1, x2, y2); // 도형의 크기 지정
    glPopMatrix(); // glPushMatrix의 값을 반환
    glutSwapBuffers();
    // 프런트 버퍼 내용이 화면에 그려지는 동안 백버퍼엔 새로운 내용이 삽입
    // 백버퍼가 꽉 차면 프런트와 백이 교체되는데 이것을 가능하게 하는 기능
}
cs


콜백 함수 2. spinDisplay()


1
2
3
4
5
6
7
8
9
10
11
// 도형의 회전을 위한 새로운 함수 설정
void spinDisplay(void)
{
    spin = spin + speed; // 왼쪽으로 도형 회전
 
    // spin의 값이 360이 되면 0으로 초기화
    if (spin > 360.0)
        spin = spin - 360.0;
 
    glutPostRedisplay(); // 변경된 사항을 다시 그림
}
cs


[C언어] OpenGL 키보드, 마우스로 도형 회전, 확대 프로그램[OpenGL Mouse Keyboard Event] Callback 함수 예제


콜백 함수 3. Init()


1
2
3
4
5
6
7
void init(void)
{
    glClearColor (1.01.01.01.0); // 배경 색상 지정
    glShadeModel (GL_FLAT); // glClearColor에 지정된 색으로 배경 채움
    // GL_SMOOTH도 쓰이는데 FLAT는 마지막으로 선택된 색상으로 도형을 채우는 것이고
    // SMOOTH는 부드럽게 칠해지며, 색상이 혼합되어 적용된다.
}
cs


콜백 함수 4. reshape()


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Window 창 크기 변환시 호출
void reshape(int w, int h)
{
    WindowWidth = w; // 변환된 창의 넓이를 저장
    WindowHeight = h; // 변환된 창의 높이를 저장
 
    glViewport (00, (GLsizei) w, (GLsizei) h);
 
    // 그림 그리는 영역을 설정
    glMatrixMode(GL_PROJECTION); // 어떻게 화면에 표시할지 설정
    glLoadIdentity(); // 기본 원근감 행렬 설정
    glOrtho(-50.050.0-50.050.0-1.01.0);
    // 보이고자 하는 영역(도형의 크기를 늘리면 확인 가능)
}
cs

마우스 이벤트 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 마우스 이벤트
void mouse(int button, int state, int x, int y)
{
    if(state == GLUT_UP) {
        if (button == GLUT_WHEEL_UP) // 휠을 위로 올릴 경우 회전 속도 증가
            speed += 0.3;
        else if( button == GLUT_WHEEL_DOWN ) // 회전 속도 감소
            speed -= 0.3;
    } // glut의 버전이 낮으면 사용이 불가능
 
    switch (button) {
        case GLUT_RIGHT_BUTTON: // 우클릭의 경우
            if (state == GLUT_DOWN) {
                glutIdleFunc(spinDisplay); // 도형 회전
                // glut은 사용자 입력을 받아들이거나 화면 윈도우를 제어하기 위한 함수로서
                // 윈도우 운영체제가 실행하는 기능.
                // NULL 값을 넘기게 되면 실행되지 않는다.
            }
        break;
 
        case GLUT_LEFT_BUTTON:
            if (state == GLUT_DOWN) { // 좌클릭의 경우
                speed += 0.8;
                glViewport (x-WindowWidth/2, WindowHeight/2-y,
                    (GLsizei)WindowWidth, (GLsizei)WindowHeight);
 
                // 좌표 위치에서 창 크기의 절반을 도형의 중심점으로 설정
                // 생략하게 되면 윈도우 전체를 도형이 사용할 수 있음
                glutPostRedisplay();
                
                // 도형의 위치를 변경하며 좌표의 위치를 출력
                printf("이동 좌표 : %d %d\n", x, y);
            }
        break;
 
        case GLUT_MIDDLE_BUTTON:
            glutIdleFunc(NULL); // 휠을 클릭을 경우 회전 중지
            break;
 
        default:
        break;
    }
}
cs


키보드 이벤트 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 키보드 이벤트
void keyboard(unsigned char key, int x, int y)
{
    switch(key) {
        case '+':
            x1 -= 1;
            y1 -= 1;
            x2 += 1;
            y2 += 1// 도형의 크기를 증가
 
            glRectf(x1, y1, x2, y2);
            glutPostRedisplay(); // 변경된 사항을 다시 그림
            break;
 
        case '-':
            x1 += 1;
            y1 += 1;
            x2 -= 1;
            y2 -= 1// 도형의 크기를 감소
 
            glRectf(x1, y1, x2, y2);
            glutPostRedisplay(); // 변경된 사항을 다시 그림
            break;
 
        default :
            break;
    }
}
cs


메인 함수


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int argc, char** argv)
{
    glutInit(&argc, argv); // glut 관련 구조체 초기화
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); // 디스플레이의 초기화 모드는 RGB
    glutInitWindowSize (WindowWidth, WindowHeight); // 윈도우의 크기 지정
    glutInitWindowPosition (7070); // 윈도우의 위치 지정
 
    glutCreateWindow (argv[0]); // 새로운 윈도우 생성
    init (); // 배경 지정
 
    glutDisplayFunc(display); // 도형을 그림
    glutReshapeFunc(reshape); // 윈도우 크기 변경에 따른 처리
    glutMouseFunc(mouse); // 마우스 이벤트 호출
    glutKeyboardFunc(keyboard); // 키보드 이벤트 호출
    glutMainLoop(); // 무한 루프
 
    return 0;
}
cs


[C언어] OpenGL 키보드, 마우스로 도형 회전, 확대 프로그램

댓글