티스토리 뷰

목차

    반응형

    [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 키보드, 마우스로 도형 회전, 확대 프로그램

    반응형