1) Picking의 원리
우리가 화면에서 무엇인가를 선택할때는 화면을 보고 그 위에 마우스를 올리고 클릭한다. 그러나 컴퓨터는
멍청해서 이게 어디인지 모른다. 그래서 화면을 다시 그리면서 그리는 붓에 마우스가 걸리면 그제야 그게 어딘
지 알게된다. 예를들어 아래 표에서 화살표 위치를 픽킹했다면 컴터는 화면을 다 다시 그리면서 저 칸에 그림
을 그리게 되면 "엇!! 여기 마우스가 있었군!!" 하고 알게된다.
위와 같은 원리로 픽킹을 하게 되므로 다시 그릴 때 마우스 위치에 걸리면 현재 자기가 무엇을 그리는지를
알아야 되고(Name을 이용) 검사할 칸의 크기를 알아야 되고(int형으로 가로세로 픽셀수를 정해줌) 몇 개가 어
느 위치에 그릴 때 선택되었는지(버퍼)를 알아야 한다.
2) Picking 예제
//픽킹을 위한 버퍼의 크기인데 넉넉히 줘도 된다. 모자라면 안된다. #define BUFFER_LENGTH 64 //픽킹으로 사용되는 입력은 마우스의 좌표이다. void PickingPlane(int mx, int my) { GLuint selectBuff[BUFFER_LENGTH]; GLint hits, viewport[4]; glSelectBuffer(BUFFER_LENGTH, selectBuff); //Picking에 사용될 버퍼를 설정한다. glGetIntegerv(GL_VIEWPORT, viewport);//변환에 필요한 정보인 viewport정보를 얻어온다. //여기서 부터는 랜더링이 화면에 되지 않는다. 즉, 앞에서 말한것처럼 컴퓨터가 마우스가 어디서 //걸리는지 찾기 위해서 다시 혼자 그려보는 그런 단계가 시작된다. glRenderMode(GL_SELECT); //현재의 프로젝션 메트릭스 저장. //지금부터 설정되는 메트릭스의 순서에 유의해야 한다. 기본이 Modelview인데 새로 프로젝션을 설정하는데 //이후에 생긴 변환이 현재 사용하는 변환에 영향을 주지 않도록 push matrix를 하는것이다. glMatrixMode(GL_PROJECTION); glPushMatrix();//저장. //랜더링과 같은 환경을 구현하기 위해서 똑같이 다시 그릴수 있는 변환을 한다. glLoadIdentity(); gluPickMatrix(mx,viewport[3]-my,2,2,viewport); int w = viewport[2], h = viewport[3]; if(w<=h) glOrtho(-BASE_UNIT,BASE_UNIT, -BASE_UNIT*(GLfloat)h/(GLfloat)w,BASE_UNIT*(GLfloat)h/(GLfloat)w ,-BASE_UNIT,BASE_UNIT); else glOrtho(-BASE_UNIT*(GLfloat)w/(GLfloat)h,BASE_UNIT*(GLfloat)w/(GLfloat)h, -BASE_UNIT,BASE_UNIT, -BASE_UNIT,BASE_UNIT); //똑같이 그리기 위해 변환과 네임을 쓰는건 다 그려준다. glMatrixMode(GL_MODELVIEW); glPushMatrix();//다른 부분에 영향을 주지 않도록 메트릭스 저장 RenderInit(); //다 똑같은데 이 함수만 다르다. 즉, 이름을 정해가면서 그린다.(뒤에서 다룸) DrawCube(BASE_UNIT,true); glPopMatrix(); //이상은 네임을 로드/푸시하는것 말고는 보통 상태에서 그리는 것과 같다. //앞에서 저장한 프로젝션 메트릭스를 복구하기 위해 프로젝션으로 변경. glMatrixMode(GL_PROJECTION); glPopMatrix();//복구 //랜더링을 모두 실행.- 이제 어딘지 검사하기 위해서 OpenGL혼자 그려본 것이 끝났다. //그럼 어디서 걸렸는지 녀석에게 물어보자. glFlush(); //Picknig을 종료하면서 스택을 얻어온다. 즉, 녀석에게 니가 아는걸 알려달라고 하는 것과 같다. hits = glRenderMode(GL_RENDER); //다시 그림을 그리기 위해서 모델뷰로 변경한다. 이제부터는 다시 화면에 그려진다. glMatrixMode(GL_MODELVIEW); }
'프로그래밍 > OpenGL' 카테고리의 다른 글
옥트리(octree) (0) | 2009.04.25 |
---|---|
OpenGL Viewing (0) | 2009.04.24 |
OpenGL 기초 (1) | 2009.04.23 |
void glutIdleFunc(void (*func)(void)) (0) | 2009.04.22 |
void glutPostRedisplay(void) (0) | 2009.04.22 |