--------------------
풀스크린모드가 윈도우보다 느릴 때
--------------------
풀스크린 모드는 모니터의 수직주사율과 프레임률을 동기화시키기 때문에
아무리 빨리 그려질 수 있어도 프레임률이 수직주사율정도밖에는 나오지 않는다.
풀스크린모드에서 수직주사율과 동기화시키지 않으려면 그래픽옵션창에서
설정하거나 WGL_EXT_swap_control 확장함수를 사용해서 v-sync 를 켜거나 끌 수
있다.
--------------------
오픈지엘로 표현하는 마우스 포인트
--------------------
아래는 어딘가에서 무단 복사한 것임.
/* This first function sets up the screen for any type of
* overlay, including the mouse pointer, a console panel, etc.
*/
void BeginOverlay(void)
{
glPushAttrib(GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, Engine.w, 0.0, Engine.h);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
/* Now, you can draw the mouse pointer. You will need to
* provide some sort of callback that updates the Mouse global
* variables.
*/
void DrawCursor(void)
{
int x = Mouse.x;
int y = screen.h - Mouse.y;
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex2i( x, y);
glVertex2i( x + 13, y - 4);
glVertex2i( x + 4, y - 13);
glVertex2i( x + 8, y - 3);
glVertex2i( x + 17, y - 12);
glVertex2i( x + 12, y - 17);
glVertex2i( x + 12, y - 17);
glVertex2i( x + 3, y - 8);
glVertex2i( x + 8, y - 3);
glEnd();
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex2i(x + 1, y - 1);
glVertex2i(x + 11, y - 4);
glVertex2i(x + 4, y - 11);
glVertex2i(x + 8, y - 5);
glVertex2i(x + 15, y - 12);
glVertex2i(x + 12, y - 15);
glVertex2i(x + 12, y - 15);
glVertex2i(x + 5, y - 8);
glVertex2i(x + 8, y - 5);
glEnd();
}
/* Now after you are done with all overlays, put the screen
* settings back.
*/
void EndOverlay(void)
{
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glPopAttrib();
}
--------------------
풀스크린모드
--------------------
GLUT 3.7 이전버젼에서는 glutFullScreen(void) 을 사용해서 풀스크린을 사용할 수
있었지만, GLUT 3.7 이상에서는 더 유연한 인터페이스가 추가되었다.
glutGameModeString() 을 사용해서 풀스크린 width 와 height 뿐만아니라 픽셀깊이,
리프레시율까지도 정해줄 수 있다. [width]x[height]:[depth]@[hertz] 형식의 아스키
문자로 내용을 정의하며, glutEnterGameMode(void) 를 호출할 때 해당 모드로 전환하
게 된다.
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutGameModeString("640x480:16@60");
glutEnterGameMode();
--------------------
카메라 Orbit 구현(일명 TrackBall)
--------------------
여기서 카메라 Orbit 이란 3DS MAX 의 카메라 Oribit 을 말한다. 보통 TrackBall
이라는 용어도 많이 쓰인다. 카메라 회전을 위해 마우스의 드래그시에 뷰포트에
보이지 않는 구가 중앙에 있는 것으로 생각하고 그 구를 손으로 돌리듯이 움직이면
카메라 뷰포트가 회전하는 것을 구현한다. 주의할 것은
- 마우스를 드래그시에 마우스 처음 위치에서 상대적인 회전을 해야 한다는 것
(그렇게 하지 않으면 마우스를 막 돌리다보면 처음 마우스 위치에 엉뚱한
회전이 적용된다)
- 회전시켜 반바퀴 돌려보면 회전이 반대로 적용되는 경우가 있는데, 이를 위해
서는 역행렬을 구해 현재 마우스 위치벡터를 회전이 적용되기 전의 벡터로
변형시켜야 한다.
void CameraOrbiting ( float src[2], float dest[2] )
{
/*
src[0] = [드래그시작시 마우스 x 위치 -1.0 ~ 1.0];
src[1] = [드래그시작시 마우스 y 위치 -1.0 ~ 1.0];
dest[0] = [드래그중 마우스 y 위치 -1.0 ~ 1.0];
dest[1] = [드래그중 마우스 y 위치 -1.0 ~ 1.0];
*/
float p1[3], p2[3];
float tm[16], inverse_tm[16], m[16];
// 현재 TM 을 얻는다.
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tm);
// 역행렬을 구한다. (회전만을 포함하기 때문에 Trnaspose 만을 해도된다)
matrix_transpose(tm, inverse_tm); // (만들어야 함!)
p1[0] = src[0];
p1[1] = src[1];
// 길이가 1인 벡터로 가정하고 z 값을 구한다.
// sqrt(x*x + y*y + z*z) = 1
if ((p1[0]*p1[0] + p1[1]*p1[1]) > 1) { /* 원을 벗어난 마우스 위치에 대해서 */
p1[2] = 0.0F; // z 값을 0으로 한다.
}
else {
p1[2] = 1 - p1[0]*p1[0] - p1[1]*p1[1];
}
p2[0] = dest[0];
p2[1] = dest[1];
if ((p2[0]*p2[0] + p2[1]*p2[1]) > 1) {
p2[2] = 0.0F;
}
else {
p2[2] = 1 - p2[0]*p2[0] - p2[1]*p2[1];
}
// 벡터를 노말라이즈한다.
vector_normalize(p1); // (만들어야 함!)
vector_normalize(p2);
vector_mult_matrix(p1, inverse_tm); // (만들어야 함!)
vector_mult_matrix(p2, inverse_tm);
// p2 에서 p1 으로 회전하는 커터니온을 구한다. (만들어야 함!)
quat_set_from_ax(p2, p1, &orbit->quat); /* important order of p1, p2 */
// 쿼터니온을 매트릭스로 바꾼다. (만들어야 함!)
quat_to_mat(&orbit->quat, m);
// 현재 회전매트릭스를 적용한다.
glMultMatrixf((const GLfloat *)m);
}
[REF] "GRAPHICS GEMS", ANDREW S. GLASSNER, VIRTUAL TRACKBALL p462-463
--------------------
마우스 입출력관련 GLUT함수
--------------------
- glutMouseFunc() : 마우스버튼이 눌렸을 때 호출
- glutMotionFunc() : 마우스 드래그시 호출
glut 는 일반적인 버튼이 눌려지지 않은 상태에서는
Mouse Position 을 체크할 수 없다.
--------------------
Matrix 관련
--------------------
glLoadMatrixf();
glMultMatrixf();
glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)tm);
- 주의 : gluLookAt() 같은 함수가 Matrix 를 변형시킬 수 있다.
--------------------
TeaPot
--------------------
glutSolidTeapot(30.0F);