프로그래밍/OpenGL2009. 4. 22. 15:19

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
Posted by 마블(이환문)