OpenGL에서 객체의 Select 판단여부
원본
http://www.wakayama-u.ac.jp/~tokoi/opengl/faq.html
지금까지 있던 질문
- 질문 1 : 마우스를 사용하여 개체를 선택하려면?
- 질문 2 : 마우스를 클릭 한 위치의 3 차원 위치를 계산하려면?
- 질문 3 : 투시 변환의 경우 윈도우를 리사이즈해도 표시 도형의 크기가 변하지 않게하려면?
- 질문 4 : IsoTrak 및 SuperGlobe에서 데이터를 가지고 표시가 어색되는데?
- 질문 5 : 관점을 이동하는 것이 아니라 물체를 빙빙 도는 방법은?
- 질문 6 : 원주는 어떻게 그리는 건가요?
- 질문 7 : glFrustum ()를 사용하여 정확한 입체하는 방법은?
질문 1
마우스를 사용하여 개체를 선택하려면?
답변 1
선택을 사용하면, 마우스 (또는 화면 영역)가 어떤 객체를 가리키고 (포함) 있는지를 확인할 수 있습니다.
glRenderMode (GL_SELECT)를 실행하고 선택 모드에 들어가면 개체를 렌더링해도 화면에 표시되지 않습니다. 대신 객체 드로잉시 이름 (실은 정수 값)을 붙여두면, (실제로는 표시되지 않음) 렌더링 처리에 의해 시각 체적 내에 있다고 판단 된 개체의 이름이 glSelectBuffer ()에 지정된 배열됩니다.
따라서 표시 영역을 마우스라고 클릭 한 점의 주위에 한정하여 렌더링 처리를 실시하면 그 지역에 (일부라도) 렌더링 된 개체를 선택할 수 있습니다. 이러한 표시 영역을 설정하려면 gluPickMatrix ()를 사용할 수 있습니다.
이전 여기서 큰 거짓말 써했습니다. 미안 해요. 사과에 샘플 만들었습니다.
sonson @ Pictures & Software - OpenGL - applied 에서 구체적으로 설명하고 계십니다 만, 일단 다음에 단계를 간략히 써 보겠습니다. 우선 일단 화면에 개체 (도형)을 다 써 있습니다. 그 다음 단계에서 클릭 된 개체를 찾습니다.
- glSelectBuffer (GLsizei size, GLuint * buffer)
- buffer에 GLuint 형의 배열 size에 요소 수를 지정합니다. 이 배열에 선택한 개체의 이름 외에 선택 된 위치의 깊이의 최소값과 최대 값 등이 포함되어 있기 때문에, 요소 수는 개체 수에 따라 넉넉하게 지정해야합니다. 또한 이것은 선택 모드에 들어가기 전에 (glRenderMode (GL_SELECT)을 실행하기 전에) 실행해야합니다.
- glRenderMode (GL_SELECT)
- 인수 GL_SELECT를 사용하여 선택 모드로 들어갑니다.
- glMatrixMode (GL_PROJECTION)
- 선택의 처리는 시점 좌표계에서 실시하므로, 투시 변환 행렬을 설정합니다.
- glInitName ()
- 개체의 이름 (정수)를 등록 해두면 이름 스택을 초기화합니다. 이것은 선택 모드에 들어간 후 (glRenderMode (GL_SELECT)를 실행 한 후)에 실시하지 않으면 무시됩니다.
- glPushName (-1)
- name은 그려지는 개체의 이름으로 부호가없는 정수입니다. glInitName () 직후에 glPushName (-1)을 실행하고 이름 스택의 선두에 임시 이름 (-1)을 넣어 둡니다.
- glPushMatrix ()
- 투시 변환 매트릭스를 저장합니다.
- glLoadIdentity ()
- 투시 변환 행렬을 초기화합니다.
- gluPickMatrix (GLdouble x, GLdouble y, GLdouble dx, GLdouble dy, GLint * viewport)
- 표시 영역이 마우스 포인터 주위 만 사용하도록 변환 행렬을 설정합니다. x, y는 선택 영역의 중심에서 창 좌표계에있어서의 마우스 포인터의 위치입니다. glutMotionFunc ()로 지정된 함수의 인수에 주어진 마우스 포인터의 위치는 디바이스 좌표계이므로이를 윈도우 좌표계에 다시해야합니다. dx, dy는 선택 영역의 크기입니다. viewport는 glViewport ()에서 설정 한 뷰포트의 크기가 저장되어있는 4 개의 요소 GLint 형의 배열입니다. 이것은 glGetIntegerv (GL_VIEWPORT, viewport)에서도 얻을 수 있습니다.
- glutPerspective (...)
- 이 후 정상적인 그리기와 마찬가지로 투시 변환 행렬을 설정합니다.
- glMatrixMode (GL_MODELVIEW)
- 시각 변환 매트릭스로 전환 일반적인 그리기와 마찬가지로 glutLookAt () 등을 설정 한 후 개체를 그립니다.
- glLoadName (1)
- 이름 스택의 선두에 1을 저장합니다. 이것은 1 번째 개체의 이름을 1로하고 있습니다. 이 후 1 개째의 개체를 그립니다. 같은 방법으로 2 ~ 4 개째의 개체에 이름을 설정하면서 그립니다.
- glMatrixMode (GL_PROJECTION)
- 다시 투시 변환 매트릭스로 되돌립니다.
- glPopMatrix ()
- 투시 변환 행렬을 취소합니다.
- hits = glRenderMode (GL_RENDER)
- 선택 모드를 끝납니다. hits에는 얻어진 데이터의 수가 들어갑니다. 만약 데이터가 glSerectBuffer ()에서 마련한 버퍼에 맞지 않으면 hits는 음수가됩니다.
glSerectBuffer ()의 인수에 지정된 (일차원) 배열 buffer는 다음과 같은 순서로 데이터가 저장되어 있습니다.
애니메이션 판은 한 번의 클릭으로 여러 개체가 선택 할 수 있음을 확인할 수 있습니다.
질문 2
마우스로 클릭 한 위치의 3 차원 위치를 계산하려면?
답변 2
gluUnProject () 함수를 사용합니다.
GLint gluUnProject (GLdouble winX, GLdouble winY, GLdouble winZ, const GLdouble * model, const GLdouble * proj, const GLint * view, GLdouble * objX, GLdouble * objY, GLdouble * objZ)
winX, winY는 화면의 점, 즉 마우스 포인터의 위치입니다. winZ은 그 점의 깊이입니다 만, 선택 을 사용한 경우 선택 버퍼에 들어있는 값을 사용할 수 있습니다 (선택 버퍼에 들어가있는 값은 GLuint 형식이므로 gluUnProject ()에서 사용하는 경우는 GLuint 형식의 최대 값 0xffffffff로 분할해야합니다 [ OpenGL Mailing List 의 테라 님의 댓글 ]. 다른 glReadPixels ()를 사용하여 GL_DEPTH_COMPONENT 즉 Z 버퍼에서 데이터를 읽거나 적당한 값을 설정 해놓고 스크린 공간의 관점과 (objX, objY, objZ)을 지나는 직선을 구하고, 그것 개체의 교점을 요구하는 등의 방법으로 얻을 수 있다고 생각합니다.
model, proj는 각각 GL_MODELVIEW, GL_PROJECTION 매트릭스가 포함 된 4x4 배열에서 view는 뷰포트가 포함 된 4 요소의 배열입니다. model, proj는 다음과 같이 얻을 수 있습니다 (우우 마우스 좌표의 상하를 반전하는 것을 잊었다 ...).
int wh; / * 열려있는 창의 높이 * / void resize (int w, int h) { / * 윈도우 전체를 뷰포트로하는 * / glViewport (0, 0, w, wh = h); ... } void mouse (int button, int state, int x, int y) { if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { GLdouble model [16] proj [16]; GLint view [4]; GLfloat z; GLdouble ox, oy, oz; glGetDoublev (GL_MODELVIEW_MATRIX, model); glGetDoublev (GL_PROJECTION_MATRIX, proj); glGetIntegerv (GL_VIEWPORT, view); glReadPixels (x, wh - y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT & z); gluUnProject (x, wh - y, z, model proj, view & ox & oy & oz); / * ox, oy, oz 클릭 한 곳의 3 차원 위치가 들어갈 * / } ... }
질문 3
투시 변환의 경우 창 크기를 변경했을 때 표시 도형의 크기가 변하지 않게하려면?
답변 3
gluPerspective () 대신에 glFrustum ()를 사용해보십시오.
void glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
평행 투영을 설정하는 glOrtho ()에 대해 glFrustum ()은 원근감을 설정합니다. GL u Perspective ()는 카메라 인 매개 변수를 사용하여 glFrustum ()을 설정할 수 있도록 한 유 틸리 티 라이브러리 함수입니다.
glFrustum ()의 인수는 glOrtho ()에 준하여 있고, left, right, top, bottom, near, far 6 개를 지정합니다. left, right, top, bottom 장면을 투영 화면의 크기로, near, far가 각각 전 방면 및 후방면의 위치하다고 말하는 곳까지 glOrtho ()와 동일하지만, glFrustum ()의 경우 스크린이 전 방면이라는 것이 핵심입니다.
시점은 원점에 있기 때문에 관점과 전 방면, 즉 스크린과의 거리 near 카메라의 초점 거리에 해당합니다. 따라서 화면 크기에 비해 near이 클수록 망원됩니다.
윈도우를 리사이즈했을 때에 표시 도형의 크기가 변하지 않도록하는 아이디어는 glOrtho ()와 같고, 창 크기에 비례하여 left, right, top, bottom를 설정합니다.
예를 들어 원래 크기가 WIDTH × HEIGHT 창에 화면 비율 ASPECT 화각 FOVY에 표시되는 도형의 크기를 폭 w, 높이 h로 크기를 조정했을 때도 변경되지 않도록하려면 다음 과 같이 설정하여보십시오.
여기에서도 이전 마구 써했습니다. 미안 해요.
void resize (int w, int h)
{
double scale = NEAR * tan ( FOVY * 0.5 * 3.1415926536 / 180.0);
double x = w * scale * ASPECT / WIDTH ;
double y = h * scale / HEIGHT ;
glFrustum (-x, x-y, y, NEAR , FAR );
glViewport (0, 0, w, h);
...
}
질문 4
IsoTrak 및 SuperGlobe에서 데이터를 가지고 표시가 어색되는데?
답변 4
실험 항목에서 설명한 샘플은 IsoTrak 및 SuperGlobe에서 "단일 모드"에서 데이터를 검색합니다. "단일 모드"는 컴퓨터에서 데이터를 검색 명령 (명령)를 보내고 그것에 IsoTrak 및 SuperGlobe가 응답 하나의 데이터를 보내옵니다.
따라서 데이터가 필요할하여 단일 모드에서 데이터를 검색하려고하면 데이터를 얻을 때까지의 사이에 조금 시간이 걸려 버립니다. 애니메이션을 수행하는 경우 각 프레임의 이미지를 생성 할 때마다 데이터를 검색하면이 시간 동안 화면이 어색하게되어 버립니다.
이것을 피하기 위하여는, "연속 모드"를 사용하여 항상 최신 데이터를 지속적으로 얻을 수 있도록합니다.
하지만 그러기 위해서는 IsoTrak 및 SuperGlobe에서 데이터 수치를 이미지 생성 등의 본래의 작업과 비동기 적으로 (동시에) 할 필요가 있습니다.
여기에는 몇 가지 방법이 있습니다. 하나의 방법은 데이터 검색 전용 프로그램을 따로 만들고 공유 메모리 기능 등을 이용하여 추출 된 데이터를 이미지 생성하는 프로그램에서 볼 수 있도록합니다. 또한 스레드라는 기능을 사용하면 하나의 프로그램에서 프로그램의 각 부분을 비동기 적으로 작동시킬 수 있습니다.
아래 예제에서는 먼저 startIsoTrak () / startSuperGlobe ()를 호출하여 스레드를 생성하여 비동기 적으로 데이터를 검색합니다. 이 인수는 tty 장치 이름 ( "/ dev/ttyf1"등)에서 반환 값은 읽기 스레드의 id입니다. getIsoTrak (id, 0, pos) / getSuperGlobe (id, pos)에서 꺼낸 데이터를 인수로 지정된 배열 pos에 복사합니다. 프로그램 종료시 stopIsoTrak (id) / stopSuperGlobe (id)를 호출해야합니다.
그리고, 스레드를 사용하는 경우는 컴파일시에 -lpthread 옵션을 추가하십시오. ......라고 그런데 진한 실험에서 사용하고있는 Indy에는 스레드 라이브러리를 설치 잊었으므로, 실은 다음 프로그램은 실험용 Indy에서는 컴파일 할 수 없음 (다른 컴퓨터에서는 일단 시도)구나 이것이 . 와하 하하는. 아 ~ 아.
질문 5
관점을 이동하는 것이 아니라 물체를 빙빙 도는 방법은?
답변 5
GLUT 제공된 샘플 프로그램에 포함 된 dinospin이 바로 그것을 실현하고 있습니다. 이 프로그램은 dinospin.c 및 trackball.c, trackball.h라는 3 개의 소스 파일로 구성되며, 회전이 중 trackball.c에서 실현하고 있습니다. 이것을 참고로하십시오. 또한 이런 회전은 사원으로 표현하면 취급이 용이합니다. 사원은 우지 사내 ~ 3D Coding Tips ~ 페이지가 도움이됩니다.
dinospin에서는 본격적인 트랙볼을 실현하고 있습니다 만, 여기에서는 예에 따라 부실의 구현을 생각해 보겠습니다 (라고하는 것으로,이 방법은별로 "생각한대로"에 회전 할 수 없습니다 → 다소 의도 한대로 돌 있도록 설명이 이 근처 에 있습니다.)
임의의 축을 중심으로 한 회전은 glRotated ()에서 줄 수 있습니다. 아래 예제에서는 도형의 원점을지나 (ax, ay, az)의 방향의 축을 중심으로 angle도만큼 도형을 회전합니다.
/ * 회전축 * / GLdouble ax, ay, az; / * 회전 각도 * / GLdouble angle; ... void display (void) { ... glPushMatrix (); / * 회전 * / glRotated (angle, ax, ay, az); / * 도형의 묘화 * / glBegin ( ... ); ... glEnd (); glPopMatrix (); ... }
마우스의 이동에 따라이 angle과 (ax, ay, az)를 지정하도록하면 목표는 이루지 것 같습니다. 이야기를 쉽게하기 위해 마우스 XY 평면 위를 달리는 것으로합니다. 즉 회전축은 항상 XY 평면 (az = 0)에 위치하며 시선은 Z 축에있는 것이라고합니다 (이렇게하면 시선을 Z 축에서 밖으로 이동하면 마음대로 회전 할 수 없습니다 만 ... ※ ) .
마우스를 드래그하는 동안 마우스 움직임에 따라 물체를 회전니까, 그동안 마우스의 이동 방향과 이동량을 감지해야합니다. 그래서 먼저 마우스 버튼을 눌렀을 때 그 위치 (드래그 시작점)과 그 때의 회전 각을 기록합니다.
/ * 드래그 시작 * /
int cx, cy;
/ * 드래그 시작 위치에서 회전 각도 * /
double ca;
...
void mouse (int button, int state, int x, int y)
{
switch (state) {
case GLUT_DOWN :
/ * 마우스 버튼을 누른 위치를 기록 * /
cx = x;
cy = y;
/ * 표시하고있는 물체의 회전 각을 기록 * /
ca = angle;
break;
default :
break;
}
}
그런 다음 마우스를 드래그하면 현재 마우스 포인터 위치의 드래그 시작점에서의 변위를 확인하고 그것을 바탕으로 회전축 벡터와 회전 각을 요구합니다 (이 방법은 드래그 시작점 부근에서의 거동 이 불안정 해집니다. 이것을 방지하려면 이동중인 마우스의 속도와 방향을 지속적으로 요구하고 거기에서 회전축 벡터와 회전 각을 요청해야합니다).
그 때, 회전 량이 창 크기에 의존하지 않도록 마우스 포인터의 변위를 창의 상대적인 위치에 두는 편이 좋을지도 모릅니다. 이를 위해 창의 크기에서 스케일 팩터 sx, sy을 요구해야합니다. 상수 SCALE은 마우스 포인터의 위치로부터 회전 각의 환율에 이용합니다. 이것이 360.0 경우 마우스 포인터를 창의 너비 (또는 높이)만큼 이동했을 때, 물체를 다만 한 회전시킬 수 있습니다.
물체를 회전시키는 회전축과 회전 각이 결정되면 도형을 다시 그립니다.
/ * 마우스 이동량의 배율 * / double sx, sy; # define SCALE 360.0 ... void resize (int w, int h) { / * 마우스 포인터 위치 윈도우의 상대적인 위치에 환율 용 * / sx = 1.0 / (double) w; sy = 1.0 / (double) h; ... } ... void motion (int x, int y) { double dx, dy, a; / * 마우스 포인터 위치의 끌기 시작 위치에서의 변위 * / dx = (x - cx) * sx; dy = (y - cy) * sy; / * 마우스 포인터 위치의 끌기 시작 위치에서의 거리 * / a = sqrt (dx * dx + dy * dy); if (a! = 0.0) { / * 거리를 각도로 환산하여 드래그 시작시의 회전 각에 가산 * / angle = fmod (ca + SCALE * a, 360.0); / * 마우스 포인터의 변위에서 회전축 벡터를 요청 * / ax = dy / a; ay = dx / a; az = 0.0; / * 도형의 재 묘화 * / glutPostRedisplay (); } }
위의 예에서는 az는 항상 0이기 때문에, 상수 버리고 상관 없을 것입니다. 후 마우스 드래그 할 때마다 셰이프를 다시 그릴 때 마우스의 응답이 나빠질지도 모릅니다. 이 경우 마우스 버튼을 누를 때 애니메이션을 시작 놓을 때 애니메이션을 종료 시키도록하여 마우스 드래그하여 회전축과 회전 각의 계산과 도형의 다시 그리기를 비동기 적으로 수행하도록 한 것이 좋습니다.
회전 시점 좌표계에서 수행 하도록하면 시선이 Z 축 이외의 장소에 있어도 마음대로 회전 할 수 있습니다. 그러나 이것은 공간 전체의 회전 (또는 관점 회전)입니다. 이 때 광원의 위치를 gluLookAt ()보다 나중에 설정하면 광원도 함께 회전하기 때문에 이것이 싫으면 광원의 위치도 시점 좌표계에서 설정하십시오.
그리고, 덤입니다.
질문 6
원주는 어떻게 그리는 건가요?
답변 6
물론, GLUT에는 공이나 원뿔는 있어도, 왠지 원통을 그리는 함수는 포함되어 있지 않아요. 하지만이 정도라면 스스로 작성해도 대단한 수고 아니다 생각이 듭니다만 ... 숙제하면 안됩니까?
일단 설명을 생각해 보겠습니다. 먼저 원통을 "윗면" "측면" "밑면"부분으로 나누어 있습니다. "윗면"및 "아래쪽"는 모두 단순한 원 (라고 할까 정다각형)이므로, 예를 들어 "윗면"은 다음과 같은 절차에 의해 설명 될 수 있습니다.
# include <math.h> ... double step = PI2 / (double) sides; int i; ... / * 윗면 * / glNormal3d (0.0, 1.0, 0.0); glBegin (GL_POLYGON); for (i = 0; i <sides; i + +) { double t = step * (double) i; glVertex3d (radius * sin (t), height, radius * cos (t)); } glEnd ();
변수 height는 원통의 길이, radius는 원통의 반경 sides은 원통 측면의 수 (= 표면의 변의 수)입니다. 또한 기호 상수 PI2는 "2π"입니다. 따라서 step 1면 당 중심각이 할당됩니다.
결국 sin / cos를 사용하여 원을 그리는 것과 같습니다. "밑면"도 같습니다만,면의 방향이 "윗면"고 반대되기 때문에 정점을 더듬는 순서를 "윗면"에 대해 역순으로합니다.
/ * 밑면 * / glNormal3d (0.0, -1.0, 0.0); glBegin (GL_POLYGON); for (i = sides; - i> = 0;) { double t = step * (double) i; glVertex3d (radius * sin (t), 0.0, radius * cos (t)); } glEnd ();
측면 둘레에 사각형을 나열함으로써 그릴 수 있습니다. 이때 사각형의 각 정점의 법선 벡터를 원통의 중심 축에서 그 점까지의 방향 벡터 해주고 있습니다. 이렇게하여 부드러운 음영이 베풀어 져 부드러운 측면이 표시됩니다.
/ * 측면 * / glBegin (GL_QUAD_STRIP); for (i = 0; i <= sides; i + +) { double t = step * (double) i; double x = sin (t); double z = cos (t); glNormal3d (x, 0.0, z); glVertex3f (radius * x, height, radius * z); glVertex3f (radius * x, 0.0, radius * z); } glEnd ();
sin / cos를 여러 번 계산하는 것이 신경이 쓰입니다 만, 그러한 곳에 돌진 싶은 사람은 스스로 궁리하십시오.
사실 GLU 라이브러리 안에, gluCylinder () 함수가 포함되어 있습니다. 이것은 원통의 측면 만 그리는 함수이므로, 이것과 원반을 그리는 gluDisk ()을 조합하여 원통을 그릴 수 있습니다.
또한 gluDisk () 함수는 중간에 찌를 수 있도록 파이프 같은 것도 비교적 쉽게 그릴 수 있습니다.
질문 7
glFrustum ()를 사용하여 정확한 입체하는 방법은?
답변 7
실험 부분에서 "gluLookAt ()을 사용하지 않고, gluPerspective ()를 glFrustum ()에 옮겨 시야를 늦춘 것이 엄밀」등이라고 써 있습니다 만, 실제로 무슨 일인지 설명합니다.
gluLookAt ()을 사용하여 시차를 넣으면 시선 (관점과 목표 지점과 연결하는 선)의 방향이 약간 회전 해 버립니다. 이 상태에서 시선과 수직 투영면 (전 방면하는 것은 아닙니다)에 투영 된 그림이 디스플레이에 표시됩니다.
그러나 디스플레이의 표시면은 시선에 수직하지 않기 때문에, 투영면에 투영 된 도형을 그대로 디스플레이에 표시하면 약간 차이가 생깁니다. 두 눈은 모두 디스플레이를 약간 비스듬히보고 있기 때문에, 도형은 그만큼 가로로 표시해야합니다.
이 차이는 경미한 때문에 대부분의 경우 그다지 신경이 쓰이는 것은 아닙니다. 그러나 입체감을 강조하려고 물체를 관점에 접근 한 경우에 생각처럼 입체감을 얻을 수 없다는 것이 발생합니다.
glFrustum ()은 시선을 회전시키지 않고 투영면을 늦출 수 있기 때문에이 차이를 일으키게 않고 시차를 줄 수 있습니다.
지금 왼쪽 눈과 모니터와의 거리를 D 시차 (두 눈의 간격)를 P합니다. 이 때 glFrustum ()에서 지정하는 표시 영역 중심의 왼쪽 눈의 시선에서 차이 F는 다음 식으로 구할 수 있습니다.
F = P × 0.5 × zNear / D
또한 디스플레이 표시면의 폭을 W, 높이 H면 (가로 세로 비율은 1합니다) 표시 영역의 폭은 W × zNear / D, 높이 H × zNear / D가되기 때문에, glFrustum ( )에서 지정하는 표시 영역은 다음과 같습니다. 오른쪽 눈의 경우는 P 또는 F의 부호를 반전 할뿐입니다.
left = (-W + P) × 0.5 × zNear / D =-W × 0.5 × zNear / D + F right = (W + P) × 0.5 × zNear / D = W × 0.5 × zNear / D + F bottom =-H × 0.5 × zNear / D top = H × 0.5 × zNear / D
그리고 좌우의 눈을 그 본래의 위치에 놓고 렌더링합니다. 이것은 실제로는 장면 분을 이동합니다. 위 그림의 경우는 왼쪽 눈은 장면 전체 (P / 2, 0-D) 만 동시에 이동 한 그린 다음 오른쪽 눈은 장면 전체 (-P / 2, 0-D) 만 동시 이동 한립니다.
GLdouble k = 0.5 * zNear / D; GLdouble f = P * k; GLdouble w = W * k; GLdouble h = H * k; / * 오른쪽 눈의 이미지 * / glDrawBuffer (GL_BACK_RIGHT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-w - f, w - f-h, h, zNear, zFar); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); / * 광원의 위치 등의 설정 * / ... glTranslated (-P * 0.5, 0.0-D); / * 시점의 위치 등의 설정 * / ... / * 신의 묘화 * / ... / * 좌안의 이미지 * / glDrawBuffer (GL_BACK_LEFT); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glFrustum (-w + f, w + f-h, h, zNear, zFar); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); / * 광원의 위치 등의 설정 * / ... glTranslated (P * 0.5, 0.0-D); / * 시점의 위치 등의 설정 * / ... / * 신의 묘화 * / ...