[OpenGL] Callback 함수 이해 1

심주흔·2024년 3월 25일
0

컴퓨터그래픽스

목록 보기
5/7
post-thumbnail

🍀 Event Handling

☘️ 이벤트 종류

  • 윈도우 : 크기 조절, 이동, 겹침 ...등
  • 마우스 : 마우스 버튼 클릭
  • 마우스 움직임: 마우스 이동
  • 키보드 : 키보드가 눌리거나 릴리즈
  • Idle : 아무런 이벤트가 없는 경우

☘️ GLUT Callback 함수

  • glutDisplayFunc
  • glutMouseFunc
  • glutReshapeFunc
  • glutKeyboardFunc
  • glutIdleFunc
  • glutMotionFunc, glutPassiveMotionFunc

☘️ Display Callback 함수의 호출 경우

  1. 처음 윈도우를 열 때
  2. 윈도우 위치를 옮길 때
  3. 윈도우 크기를 조절할 때
  4. 앞 윈도우에 가려져 안 보이던 뒤 윈도우가 활성화 되어 앞으로 드러날 때
  5. glutPostRedisplay() 함수에 의해 이벤트 큐에 flag가 게시될 때

    1~3번 호출 경우는 reshape 이벤트와 동일: reshape 콜백 함수가 실행되면 새로 조정된 뷰포트 및 투상범위를 기준으로 자동으로 디스플레이 콜백함수가 실행

🌱 Display callback 함수 등록

void glutDisplayFunc(void (*func)(int width, int height) );

☘️ Reshape Callback 함수의 호출 경우

  1. 처음 윈도우를 열 때
  2. 윈도우 위치를 옮길 때
  3. 윈도우 크기를 조절할 때

🌱 Display callback 함수 등록

void glutReshapeFunc(void (*func)(int width, int height) );

☘️ 실습코드

//visual stdio 기준
//#include <glut.h>
//#include <stdlib.h>
//#include <GL/glut.h>

#define GL_SILENCE_DEPRECATION      //버전 오류 해결
#include <iostream>
#include <OpenGL/gl.h>
#include <OpenGl/glu.h>
#include <GLUT/glut.h>

void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_SMOOTH); //flat 보다 시간이 많이 걸림.

}

void triangle(void) {
    glBegin(GL_TRIANGLES);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f(-0.5, -0.5);
    glColor3f(0.0, 1.0, 0.0);
    glVertex2f(0.5, -0.5);
    glColor3f(0.0, 0.0, 1.0);
    glVertex2f(-0.5, 0.5);
    glEnd();
}


void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    triangle();
    glFlush();
}


void reshape(int new_w, int new_h) {
    glViewport(0, 0, new_w, new_h);
    float WidthFactor = (float) new_w / 300.0;
    float HeightFactor = (float)new_h / 300.0;

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(-1.0 * WidthFactor, 1.0 * WidthFactor, -1.0 * HeightFactor, 1.0 * HeightFactor);
}


int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(300, 300);       //초기 창의 크기를 결정한다.
    glutInitWindowPosition(100, 100);   //화면 기준 창이 나타나는 공간을 설정한다. 좌상단 원점 기준
    glutCreateWindow(argv[0]);          //glutMainLoop()가 호출되면 보여줌.
    init();
    glutDisplayFunc(display);           //콜백함수
    glutReshapeFunc(reshape);           //콜백함수
    glutMainLoop();
    return 0;
}

🍀 Shadeing Model 선택

☘️ void glShadeModel(Glenum mode);

  • 셰이딩 모델을 선택
  • 물체의 색상 적용은 정점 기준
  • Flat Shading 또는 Smooth Shading 을 선택
  • Flat Shading : 지정된 하나의 색으로 렌더링
  • Smooth Shading : 각 정점의 색을 부드럽게 혼합하여 렌더링

🍀 키보드 입력에 의한 호출

void glutKeyboardFunc(void(*func)(unsigned char key, int x, int y));

특수키 입력
void glutSpecialFunc(void(*func)(int key, int x, int y));

🍀 마우스 입력에 대한 호출

glutMouseFunc 은 윈도우 안에서 마우스 버튼을 누르거나 놓을 때 사용

☘️ Mousecallback 함수 등록

void glutMouseFunc(void(*func)(int button, int state, int x, int y));

x,y 는 마우스의 현재 위치

🌱 glutMotionFunc

: 윈도우 안에서 하나 또는 그 이상의 마우스 버튼이 눌린 상태로 움직일 때 호출
void glutPassiveMotionFunc(void (*func)(int x, int y));

🌱 glutPassiveMotionFunc

: 아무런 마우스 버튼이 눌리지 않은 상태로 움직일 때 호출 됨
void glutPassiveMotionFunc(void (*func)(int x, int y));

☘️ 실습코드

#define GL_SILENCE_DEPRECATION      //버전 오류 해결

#include <iostream>
#include <OpenGL/gl.h>
#include <OpenGl/glu.h>
#include <GLUT/glut.h>


void init(void) {
    glClearColor(0.0, 0.0, 0.0, 0.0);

}

void display(void) {
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glFlush();
}

void mouseProcess(int button, int state, int x, int y) {
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
        printf("Left mouse button is pressed.. \n\n");
    }

    else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN) {
        printf("Middle mouse button is pressed..\n\n");
    }

    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
        printf("Right mouse button is pressed..\n\n");
    }

    else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
        printf("Left mouse button is released..\n\n");
    }

    else if (button == GLUT_MIDDLE_BUTTON && state == GLUT_UP) {
        printf("Middle mouse button is released..\n\n");
    }

    else if (button == GLUT_RIGHT_BUTTON && state == GLUT_UP) {
        printf("Right mouse button is released..\n\n");
    }
}

    void mousePassiveMotion(int x, int y){
        printf("Current mouse position: %d, %d\n", x, y);
    }

    void mouseActiveMotion(int x, int y) {
        printf("Pressed mouse position: %d, %d\n", x, y);
    }

    void mouseEntry(int state) {
        if (state == GLUT_LEFT) {
            printf("Mouse is outside of window..\n\n");
        }
        else if (state == GLUT_ENTERED) {
            printf("Mouse is inside of window..\n\n");
        }
    }

    void keyboard(unsigned char key, int x, int y) {
        switch (key) {
        case 'a':
            printf("a is pressed .. %d, %d\a\n", x, y);
            break;
        case 'b':
            printf("b is pressed .. %d, %d\a\n", x, y);
            break;
        case 27:
            exit(0);
            break;
        }
    }

    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
        glutInitWindowSize(500, 500);
        glutInitWindowPosition(100, 100);
        glutCreateWindow("Mouse and keyboard");
        init();
        glutDisplayFunc(display);
        glutKeyboardFunc(keyboard);
        glutMouseFunc(mouseProcess);
        glutPassiveMotionFunc(mousePassiveMotion);
        glutMotionFunc(mouseActiveMotion);
        glutEntryFunc(mouseEntry);


        glutMainLoop();
        return 0;
    }

마우스와 키보드의 입력에 따라 callback 함수가 호출되어 값 return

profile
이봐... 해보기는 했어?

0개의 댓글