ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 풀스크린모드가 윈도우보다 느릴 때
    3D Graphics/Open GL 2007. 4. 14. 00:02
    728x90
    --------------------
    풀스크린모드가 윈도우보다 느릴 때
    --------------------

    풀스크린 모드는 모니터의 수직주사율과 프레임률을 동기화시키기 때문에
    아무리 빨리 그려질 수 있어도 프레임률이 수직주사율정도밖에는 나오지 않는다.
    풀스크린모드에서 수직주사율과 동기화시키지 않으려면 그래픽옵션창에서
    설정하거나 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);

    '3D Graphics > Open GL' 카테고리의 다른 글

    OpenGL Animation 구현  (0) 2007.05.07
    msdn에 있는 openGL 도움말 및 레퍼런스  (0) 2007.04.18
    Open GL의 소개및 관련링크  (0) 2007.04.16
    GLSL 관련글  (0) 2007.04.16
    Open GL dll 파일 설치법  (0) 2007.03.23

    댓글

Designed by black7375.