ABOUT ME

IT 기업에 근무하는 S/W 개발자이자입니다. Server 개발 및 DevOps, S/W Test Automation을 주로 다루고 있습니다.

  • 풀스크린모드가 윈도우보다 느릴 때
    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' 카테고리의 다른 글

    댓글

Designed by black7375.