Callback Initialize Input Devices do if There Is
답신(Callback, 콜백)함수 이벤트모드 프로세싱 Initialize Input Devices; do { if (There Is an Event on the Event Queue) switch (Event Type) { case Keyboard Event: Get Event Record, Run Keyboard Callback case Mouse Event: Get Event Record, Run Mouse Callback . . . } else Do Background Process } while (User Does Not Request Escape); 답신함수 – 이벤트 종류별로 프로그램이 처리해야 할 내용을 함수로 구현 MS 윈도우 운영체제 자체도 일종의 이벤트 구동 시스템이다 11
디스플레이리스트 - 예제 디스플레이 리스트의 정의 #define BOX 1 // 또는 다른 사용되지 않는 정수 gl. New. List(BOX, GL_COMPILE); // cf. GL_COMPILE_AND_EXECUTE gl. Begin(GL_POLYGON); gl. Color 3 f(1. 0, 0. 0); gl. Vertex 2 f(-1. 0, -1. 0); gl. Vertex 2 f( 1. 0, 1. 0); gl. Vertex 2 f(-1. 0, 1. 0); gl. End(); gl. End. List(); 디스플레이 리스트의 실행을 요청 gl. Call. List(BOX); 16
이벤트-구동 입력의 프로그래밍 답신 연결 함수들 glut. Display. Func glut. Mouse. Func glut. Reshape. Func glut. Keyboard. Func glut. Idle. Func glut. Motion. Func glut. Passive. Motion. Func 예 : 마우스 답신함수의 연결 glut. Mouse. Func(mouse) 예 : 마우스 답신함수의 정의 void mouse(int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) exit(); } 18
이벤트-구동 입력의 프로그래밍 int main(int argc, char **argv) { glut. Init(&argc, argv); glut. Init. Display. Mode(GLUT_SINGLE|GLUT_RGB); glut. Init. Window. Size(ww, wh); //전역 정의된 초기 윈도우 크 기 glut. Create. Window("square"); myinit(); glut. Reshape. Func(my. Reshape); glut. Mouse. Func(mouse); glut. Display. Func(display); glut. Main. Loop(); } 19
이벤트-구동 입력의 프로그래밍 void mouse(int btn, int state, int x, int y) { if(btn==GLUT_LEFT_BUTTON && state==GLUT_DOWN) draw. Square(x, y); if(btn==GLUT_RIGHT_BUTTON && state==GLUT_DOWN) exit(0); } /* 전역 변수 */ GLsizei wh = 500, ww = 500; /* 초기 윈도우 크기 */ GLfloat size = 3. 0; /* 사각형 변 길이의 절반 */ void myinit(void) { gl. Viewport(0, 0, ww, wh); gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); glu. Ortho 2 D(0. 0, (GLdouble)ww, 0. 0, (GLdouble)wh); gl. Matrix. Mode(GL_MODELVIEW); gl. Clear. Color(0. 0, 1. 0); } 21
이벤트-구동 입력의 프로그래밍 void draw. Square(int x, int y) { y=wh-y; gl. Color 3 ub( (char)rand()%256, (char)rand()%256); gl. Begin(GL_POLYGON); gl. Vertex 2 f(x+size, y+size); gl. Vertex 2 f(x-size, y-size); gl. Vertex 2 f(x+size, y-size); gl. End(); gl. Flush(); } 22
Reshape 방법 original reshaped 27
재구성 답신(Reshape callback) void my. Reshape(GLsizei w, GLsizei h) { /* 클리핑 상자 조절 */ gl. Matrix. Mode(GL_PROJECTION); gl. Load. Identity(); glu. Ortho 2 D(0. 0, (GLdouble)w, 0. 0, (GLdouble)h); gl. Matrix. Mode(GL_MODELVIEW); gl. Load. Identity(); /* 뷰포트의 조절과 지우기 */ gl. Viewport(0, 0, w, h); gl. Clear(GL_COLOR_BUFFER_BIT); gl. Flush(); /* 전역변수로 저장된 새 윈도우 크기 */ ww=w; wh=h; } 29
키보드 사용하기 glut. Keyboard. Func(mykey) void mykey(unsigned char key, int x, int y) 눌려진 키의 ASCII코드와 마우스 위치를 반환 glut. Keyboard. Up. Func(mykey) void mykey(unsigned char key, int x, int y) { if(key == ‘Q’ || key == ‘q’) exit(0); } 31
특수키와 수정키 GLUT는 특수키를 glut. h에 정의해 놓음 function key 1: GLUT_KEY_F 1 위 화살표 키: GLUT_KEY_UP • if(key == ‘GLUT_KEY_F 1’ …… glut. Get. Modifiers()을 이용하여 눌려진 수정키를 체크 GLUT_ACTIVE_SHIFT GLUT_ACTIVE_CTRL GLUT_ACTIVE_ALT 32
간단한 메뉴의 정의 main. c에서 glut. Create. Menu(demo_menu); glut. Add. Menu. Entry(“quit”, 1); glu. Add. Menu. Entry(“increase squre size”, 2); glu. Add. Menu. Entry(“decrease squre size”, 3); glut. Attach. Menu(GLUT_RIGHT_BUTTON); void demo_menu(int { switch(id) { case 1 break; case 2 break; case 3 break; } id) : exit(0); : size = 2*size; : if (size>1) size = size/2; glut. Post. Redisplay(); } 37
간단한 메뉴의 정의 sub_menu = glut. Create. Menu(size_menu); glut. Add. Menu. Entry("increase square size", 2); glut. Add. Menu. Entry("decrease square size", 3); glut. Create. Menu(top_menu); glut. Add. Menu. Entry("quit", 1); glut. Add. Sub. Menu("Resize", sub_menu); glut. Attach. Menu(GLUT_RIGHT_BUTTON); 38
대화식 프로그램의 애니메이션 회전 정방형 void display() { gl. Clear(GL_COLOR_BUFFER_BIT); gl. Begin(GL_POLYGON) thetar = theta/(180. 0/3. 14159); gl. Vertex 2 f(cos(thetar), sin(thetar)); gl. Vertex 2 f(-sin(thetar), cos(thetar)); gl. Vertex 2 f(-cos(thetar), -sin(thetar)); gl. Vertex 2 f(sin(thetar), -cos(thetar)); gl. End(); } 39
대화식 프로그램의 애니메이션 glut. Idlefunc(idle); =========== void idle() { theta +=2; if(theta >= 360. 0) theta -=360. 0; glut. Post. Redisplay(); } =========== glut. Mousefunc(mouse); =========== void mouse(int button, int state, int x, int y) { if(button ==GLUT_LEFT_BUTTON && state==GLUT_DOWN) glut. Idle. Func(idle); if(button ==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN) glut. Idle. Func(NULL); } 40
이중 버퍼링 하나의 컬러 버퍼를 사용하는 대신 다음과 같은 두 개의 버퍼를 사 용한다. 전면 버퍼(Front Buffer) : 디스플레이되는 곳 후면 버퍼(Back Buffer) : 그리는 곳 main. c에서 이중 버퍼링을 사용하기 위한 변경 glut. Init. Display. Mode(GL_RGB | GL_DOUBLE) display callback 의 끝에서 교체함수사용. void mydisplay() { gl. Clear(). /* draw graphics here */. glut. Swap. Buffers() } cf. gl. Draw. Buffer(GL_BACK); //디폴트 gl. Draw. Buffer(GL_FRONT_AND_BACK); 42
타이머의 사용 idle 콜백합수의 문제점은? int n = 60; // 설정하려는 프레임률 glut. Timer. Func(100, my. Timer, n); void my. Timer(int v) { glut. Post. Redisplay; glut. Timer. Func(1000/n, my. Timer, v); } 44
Open. GL에서의 XOR 2 bit사이에 16개의 가능한 논리연산이 있다. 모두 Open. GL에서 제공 우선 논리연산을 enable한다. • gl. Enable(GL_COLOR_LOGIC_OP) 논리연산을 선택 • gl. Logic. Op(GL_XOR) • gl. Logic. Op(GL_COPY) (default) 51
- Slides: 51