■ OpenGL: Selecting Object
사용자와 상호작용, 즉 인터랙티브한 효과가 필요함
- Selecting and Picking of Objects
OpenGL 의 강력한 기능 중 하나가 선택한 객체의 정보를 얻어 사용자에게 제공하고 그에 따른 반응을 할 수 있는 점
1. Selection(선택)
선택모드: 하나의 랜더링 모드, 프레임 버퍼에 픽셀이 복사되지 않음
- 기본 모델이 관측 공간내에 그려지며, 선택 버퍼 내에 히트 수가 만들어짐(정수 값을 가짐)
선택버퍼
- 물체나 모델 또는 그룹 구별하기 위해 선택버퍼를 설정해야 함
- 선택버퍼 설정 이후 해석하여 어떤 물체가 관층 공간 내에 있는지 검사 하면 됨
- 부호 없는 정수의 배열로, 각 히트 레코드는 적어도 네 개의 요소 자리를 차지 함
- 렌더링 과정에서 발생하는 히트 수를 기록하는데 사용됨
기본 모델의 이름
- 장면 내 모든 객체들의 이름을 짓는 것도 가능하지만 비효율적임
- 가장 많이 사용하는 방법은 그룹 식별(이름 목록)
- 이름 목록은 네임 스택에 저장됨
- 네임 스택 초기화 -> 이름 입력
- 선택과정에서 히트(hit)가 발생하면 현재 네임 스택에 있는 모든 이름들이 선택 버퍼 끝에 추가됨
step 1: 구분할 그룹 이름과 정수 정의
step 2: 네임 스택 초기화
step 3: 모델의 이름을 정하고 드로잉
객체를 선택하기 위해서는 랜더링 모드 변경을 해줘야 한다.
glRenderMode(GL_SELECTION); //선택모드로 변경
glRenderMode(GL_RENDER);//다시 드로잉 모드로 변경
선택버퍼
2. Picking
- 선택버퍼에서 어떤 물체가 클릭되었는지 확인
void gluPickMatrix(
GLdouble x, //Specify the center of a picking region in window coordinates.
GLdouble y,
GLdouble delX, //Specify the width and height, respectively, of the picking region in window coordinates.
GLdouble delY,
GLint * viewport //Specifies the current viewport
);
x, y 는 현재 사용자가 클릭한 공간이 되고, delX와 delY는 사용자가 클릭한 point에서 picking region이 된다. 그리고 viewport는 현재 화면 뷰포트의 포인터 변수가 된다. 여기서 사용되는 뷰 포트 정보를 가져 오기 위해 다음 함수를 사용한다.
The glGetIntegerv function returns the value or values of a selected parameter.
void WINAPI glGetIntegerv(
GLenum pname,//The parameter value to be returned. The following symbolic constants are accepted.
GLboolean *params//Returns the value or values of the specified parameter.
);
pname에 정해진 심볼을 사용한다. 이 심볼 중 GL_VIEWPORT를 사용할 경우 다음과 같다.
The params parameter returns four values: the x and y window coordinates of the viewport, followed by its width and height. See glViewport.
4개의 파라미터를 반환: x, y, width, height
즉 glGetIntegerv(GL_VIEWPORT, viewport)를 하게 되면 현재 뷰포트의 x, y, width, height 값을 viewport 변수에 리턴하게 된다.
http://msdn.microsoft.com/en-us/library/windows/desktop/ee872027(v=vs.85).aspx
즉 어떠한 객체를 picking하기 위해서는 먼저 뷰포트에 대한 정보를 가져오고 그 뷰포트 정보 중 선택된 좌료 값에 매칭되는 객체가 있는지 확인하는 과정을 가진다.
gluPickMatrix 함수를 사용하는 방법은 다음과 같다.
step 1: 현재 투영 행렬 상태 저장
step 2: glLoadIdentity 호출(단위 크기의 관측 공간 생성) - 변환된 회전이나 좌표의 행렬을 처음 상태로 돌려줌
step 3: gluPickMatrix 를 통해 관측 공간을 적절한 위치로 옴김
step 4: 원래 장면의 투영 방법을 적용
- 정확한 매핑이 안이루어 질 수 있다.
3. 정리 (객체를 선택하기 위한 단계)
step 1: 선택버퍼 선언
step 2: glSelectBuffer()함수로 선택 버퍼 할당
step 3: 현재 viewport 값 가져오기
step 4: 투영 모드 전환 및 배열 저장
step 5: 랜더링 모드 GL_SELECT 로 변환
step 6: 행렬 초기화 및 현재 마우스 클릭된 좌표의 객체 정보를 가져옴
step 7: 관점 설정 및 투영 시작
step 8: 다시 드로잉
step 9: 랜더링 모드 GL_RENDER 로 다시 돌아가면서 선택된 객체 index 값 받음
step 10: 투영 행렬 재저장
step 11: 정상 랜더링을 위한 모델 뷰로 돌아감
step 9에서 쓰이는 함수
glRenderMode(GL_RENDER)에서 어떻게 선택된 객체의 index 값을 받는가?
The call to glRenderMode(GL_RENDER) exits selection mode and returns the number of hit records stored in the selection buffer.
return:
GL_SELECT: The number of hit records transferred to the select buffer.
흠 그렇군 책에는 자세히 안써져 있다.
흣 작업 완료
ref
[1] Richard S. Wright. Jr. - Benjamin Lipchak 외 저(최연호 역), "OpenGL SuperBible", 정보문학사, pp. 651-680, 2005.
'OpenGL' 카테고리의 다른 글
OpenGL: Modern OpenGL Tutorial Text Rendering 01 (0) | 2014.05.15 |
---|---|
OpenGL: Text in OpenGL (0) | 2014.05.15 |
OpenGL: Normal Vector (0) | 2014.05.04 |
OpenGL: Index of Vertex Array (0) | 2014.05.04 |
OpenGL: Geometric and Vertex (0) | 2014.05.04 |