OpenGL 콜백함수
2020. 9. 21. 20:06ㆍComputer Graphics/OpenGl
마우스 콜백
마우스가 움직이거나 눌러질 때 발생하는 함수를 의미한다.
아래와 같은 네가지 함수가 존재한다.
glutMouseFunc(void (*func)(int button, int state, int x, int y));
glutMotionFunc(void (*func)(int x, int y));
glutPassiveMotionFunc(void (*func)(int x, int y));
glutEntryFunc(void(*func)(int state));
glutMouseFunc(void (*func)(int button, int state, int x, int y));
마우스 버튼을 눌렀을때 와 땔때 모두 사용할 수 있다.
button에는 GLUT_LEFT_BUTTON, GLUT_RIGHT_BUTTON, GLUT_MIDDLE_BUTTON 을 통해 가운데 버튼, 왼쪽 버튼, 오른쪽 버튼을 구분해서 함수를 실행시킬 수 있다.
glutPassiveMotionFunc(void (*func)(int x, int y));
마우스를 안누르고 있을 때 움직이면 해당 좌표값을 콜백함수에 넘겨준다.
glutEntryFunc(void (*func)(int state));
윈도우 창으로 들어갈 때와 나올때를 선택해 이벤트를 발생시킬 수 있다.
예제 코드
//
// main.cpp
// Week3
//
// Created by 이상훈 on 2020/09/21.
// Copyright © 2020 이상훈. All rights reserved.
//
#include <iostream>
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <stdlib.h>
#define _WINDOW_HEIGHT 600
#define _WINDOW_WIDTH 600
GLfloat r = 1.0, g= 1.0, b = 1.0;
GLint cur_x = -1, cur_y = -1;
int mode, mode_visual = 1, canClick = 0;
void reshape(int width, int height){
glViewport(0, 0, width, height);
GLfloat f_w = (GLfloat)width/(GLfloat)_WINDOW_WIDTH;
GLfloat f_h = (GLfloat)height/(GLfloat)_WINDOW_HEIGHT;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 * f_w, 1.0 * f_w, -1.0 * f_h, 1.0 * f_h, -1, 1);
}
void display(){
glClear(GL_COLOR_BUFFER_BIT);
if(mode_visual == 1){
if (mode == 0)
glutWireSphere(0.3, 15, 15);
else
glutWireTeapot(0.7);
}else{
}
glFlush();
}
void mouseBtn(int btn, int states, int x, int y){
if(btn == GLUT_LEFT_BUTTON && states == GLUT_UP ){
mode = (mode + 1) % 2;
glutPostRedisplay();
}
}
void mouseDrag(int x, int y){
GLint dx, dy;
canClick = 0;
if (cur_x >= 0 || cur_y >= 0){
dx = abs(x - cur_x);
dy = abs(y - cur_y);
GLint sum = dx + dy;
g = (g - 0.1) < 0? 0 : g - 0.1;
b = (b - 0.1) < 0? 0 : b - 0.1;
glColor3f(r, g, b);
glutPostRedisplay();
}
cur_x = x;
cur_y = y;
}
void winEntry(int state){
if (state == GLUT_LEFT)
mode_visual = 0;
else
mode_visual = 1;
glutPostRedisplay();
}
int main(int argc, char * argv[]) {
glutInit(&argc, argv);// 초기화
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("title");
glutInitWindowSize(_WINDOW_WIDTH, _WINDOW_HEIGHT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMotionFunc(mouseDrag);
glutMouseFunc(mouseBtn);
glutEntryFunc(winEntry);
glutMainLoop();
return 0;
}
메뉴 콜백
메뉴를 추가하는 방법을 학습해볼 것입니다.
int glutCreateMenu(void(*func )(int value));
메뉴 콜백함수 등록. 메뉴의 아이디 리턴!
glutSetMenu(int id); id 번호를 가진 메뉴를 현재 메뉴로 설정
glutAddMenuEntry(char* name, int value); 현재 메뉴에 엔트리 추가!
int glutAttachMenu(int button); 특정 마우스 버튼에 현 메뉴 할당!
glutAddSubMenu(char *name, int menu); 현재 메뉴에 서브메뉴 추가
예제 코드
//
// main.cpp
// Week3
//
// Created by 이상훈 on 2020/09/21.
// Copyright © 2020 이상훈. All rights reserved.
//
#include <iostream>
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <stdlib.h>
#define _WINDOW_HEIGHT 600
#define _WINDOW_WIDTH 600
GLfloat r = 1.0, g= 1.0, b = 1.0;
GLint cur_x = -1, cur_y = -1;
int mode;
void reshape(int width, int height){
glViewport(0, 0, width, height);
GLfloat f_w = (GLfloat)width/(GLfloat)_WINDOW_WIDTH;
GLfloat f_h = (GLfloat)height/(GLfloat)_WINDOW_HEIGHT;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0 * f_w, 1.0 * f_w, -1.0 * f_h, 1.0 * f_h, -1, 1);
}
void display(){
glClear(GL_COLOR_BUFFER_BIT);
if(mode == 0){
}else if(mode == 1){
glutWireSphere(0.3, 15, 15);
}else if(mode == 2){
glutWireTorus(0.2, 0.5, 15, 15);
}else
glutWireTeapot(0.3);
glFlush();
}
void mouseDrag(int x, int y){
GLint dx, dy;
if (cur_x >= 0 || cur_y >= 0){
dx = abs(x - cur_x);
dy = abs(y - cur_y);
GLint sum = dx + dy;
g = (g - 0.1) < 0? 0 : g - 0.1;
b = (b - 0.1) < 0? 0 : b - 0.1;
glColor3f(r, g, b);
glutPostRedisplay();
}
cur_x = x;
cur_y = y;
}
void selectMenu(int value){
if (value == 2)
exit(0);
}
void selectSubMenu(int value){
mode = value;
glutPostRedisplay();
}
int main(int argc, char * argv[]) {
glutInit(&argc, argv);// 초기화
glutInitDisplayMode(GLUT_RGB);
glutCreateWindow("title");
glutInitWindowSize(_WINDOW_WIDTH, _WINDOW_HEIGHT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMotionFunc(mouseDrag);
int subMenuId = glutCreateMenu(selectSubMenu);
glutSetMenu(subMenuId);
glutAddMenuEntry("Sphere", 1);
glutAddMenuEntry("Torus", 2);
glutAddMenuEntry("Teapot", 3);
int mainMenuId = glutCreateMenu(selectMenu);
glutSetMenu(mainMenuId);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutAddSubMenu("3D Model", subMenuId);
glutAddMenuEntry("Exit", 2);
glutMainLoop();
return 0;
}
더블 버퍼링
버퍼를 두개를 두어 데이터의 처리와 전송을 끊킴없이 동시에 할 수 있는 기술이다.
//
// main.cpp
// week3_example3
//
// Created by 이상훈 on 2020/09/21.
// Copyright © 2020 이상훈. All rights reserved.
//
#include <GLUT/GLUT.h>
#include <OpenGL/OpenGL.h>
#include <iostream>
GLfloat Delta = 0.0;
void MyDisplay(){
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
glColor3f(0.0, 0.5, 0.8);
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.01;
glutPostRedisplay();
glutTimerFunc(20, MyTimer, value);
}
int main(int argc, char * argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutCreateWindow("OPENGL WINDOW");
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, -1.0);
glutDisplayFunc(MyDisplay);
glutTimerFunc(20, MyTimer, 1);
glutMainLoop();
return 0;
}
'Computer Graphics > OpenGl' 카테고리의 다른 글
Mac OpenGL 설치 (3) | 2020.09.01 |
---|