30 พฤษภาคม 2553

เรนเดอร์ OpenGL ให้เป็น Full Screen ด...

เรนเดอร์ OpenGL ให้เป็น Full Screen ด้วย Game Mode
ในการจะฉายภาพลงไปในโดยใช้โปรเจ็คเตอร์เพื่อให้ภาพทั้งหมดเต็มพื้นที่ของโปรเจ็คเตอร์
เราจึงต้อง เรนเดอร์ภาพแบบเต็มจอ ซึ่งมีขั้นตอนมากกว่าการสั่งตำแหน่งจุดเริ่มต้นของ Viewport และขนาดไม่ได้
แต่ยังต้องเซ็ทเรื่องการใช้ Buffer และการสั่งเข้าหรือออกโหมด Full Screen ผ่านทาง Keyboard อีกด้วย
#include <GL/glut.h>
#include <math.h>

//angle of rotation
float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 90, angle=0.0;

void init (void)
{
    glEnable (GL_DEPTH_TEST); //enable the depth testing
    /*
    * if enable lighting wire geometry some line don't display
    */
    //glEnable (GL_LIGHTING); //enable the lighting
    glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
    glShadeModel (GL_FLAT); //set the shader to smooth shader

}


void drawing()
{
    /*
    * Wire Box
    */
    glPushMatrix ();
        glColor3f (1.0, 1.0, 1.0);
        glRotatef (45, 0.0, 1.0, 0.0);
        glutWireCube (50);
    glPopMatrix ();

}
void display (void)
{
    glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer
    glLoadIdentity();  
    /*
    * camera position, x,y,z, looking at x,y,z, Up Positions of the camera
    */
    gluLookAt
    (
        0.0, 0.0, 190.0,/* camera */
        0.0, 0.0, 0.0,    /* lens towards */
        0.0, 1.0, 0.0   /* up-vector */
    );
    /*
    * start drawing object
    */
    drawing(); //call the cube drawing function

    glutSwapBuffers(); //swap the buffers
    angle+=0.1; //increase the angle
}


void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport to the current window specifications
    /*
    * Projector Projection Parameter
    */
    glMatrixMode (GL_PROJECTION); //set the matrix to projection
    glLoadIdentity ();
    gluPerspective (33.5, 4.0/3.0, 140.0, 300); //set the perspective (angle of sight, width, height, , depth)

    glMatrixMode (GL_MODELVIEW); //set the matrix back to model

    
    
}

void keyboard (unsigned char key, int x, int y) {
    if (key=='q')
    {
    xrot += 1;
    if (xrot >360) xrot -= 360;
    }

    if (key=='z')
    {
    xrot -= 1;
    if (xrot < -360) xrot += 360;
    }

    if (key=='w')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f);
    xpos += float(sin(yrotrad)) ;
    zpos -= float(cos(yrotrad)) ;
    ypos -= float(sin(xrotrad)) ;
    }

    if (key=='s')
    {
    float xrotrad, yrotrad;
    yrotrad = (yrot / 180 * 3.141592654f);
    xrotrad = (xrot / 180 * 3.141592654f);
    xpos -= float(sin(yrotrad));
    zpos += float(cos(yrotrad)) ;
    ypos += float(sin(xrotrad));
    }

    if (key=='d')
    {
    yrot += 1;
    if (yrot >360) yrot -= 360;
    }

    if (key=='a')
    {
    yrot -= 1;
    if (yrot < -360)yrot += 360;
    }
    if (key==27)
    {
    glutLeaveGameMode(); //set the resolution how it was
    exit(0); //quit the program
    }
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set the display to Double buffer, with depth
    glutGameModeString( "1024x768:32@30" ); //the settings for fullscreen mode
    glutEnterGameMode(); //set glut to fullscreen using the settings in the line above
    init (); //call the init function
    glutDisplayFunc (display); //use the display function to draw everything
    glutIdleFunc (display); //update any variables in display, display can be changed to anyhing, as long as you move the variables to be updated, in this case, angle++;
    glutReshapeFunc (reshape); //reshape the window accordingly

    glutKeyboardFunc (keyboard); //check the keyboard
    glutMainLoop (); //call the main loop
    return 0;
}

โดยมีฟังก์ชันสำคัญๆดังนี้
glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set the display to Double buffer, with depth
ใช้สร้าง Buffer แบบคู่สำหรับเก็บภาพที่เกิดจากการเรนเดอร์

glutGameModeString( "1024x768:32@30" ); //the settings for fullscreen mode
เช็ทหน้าจอให้ใช้ความละเอียด 1024 x 768 สี 32 บิต อัตราการรีเฟตที่ 30 เฟรมต่อวินาที
ต้องเรียกฟังกชัน glutGameModeString ก่อน glutEnterGameMode

glutEnterGameMode(); //set glut to fullscreen using the settings in the line above
เริ่มเข้าสู่ภาพเต็มจอตามที่ได้เซ็ทไว้ในฟังก์ชัน glutGameModeString

glutLeaveGameMode(); //set the resolution how it was
ออกจากภาพเต็มจอ เมื่อเราส่ังภาพเต็มจอจะไม่มีกรอบวินโดวส์ทำให้ไม่มีปุ่ม กากบาท มุมขวาบนที่ใช้ปิดโปรแกรม
ทำให้เราต้องเพิ่งพาการใช้งาน Keyboard เมื่อกดคีย์ Esc ค่อยไปเรียกฟังก์ชันนี้อีกที

glutKeyboardFunc (keyboard); //check the keyboard
กำหนดให้เมื่อกดคีย์บอร์ดแล้วไปเรียกฟังก์ชัน keyboard();

ภายในฟังก์ชันคียบอร์ด ให้ทำการดักจับคีย์ที่ผู้ใช้กด
void keyboard (unsigned char key, int x, int y) {
    if (key==27)
    {
    glutLeaveGameMode(); //set the resolution how it was
    exit(0); //quit the program
    }
}
เช็คคีย์ว่าเท่ากับ 27 หรือไม่ซึ่งตรงกับ ASCII ของปุ่ม ESC

glutSwapBuffers(); //swap the buffers
เมื่อมีการวาดภาพต้องมีการสลับบัฟเฟอร์ระหว่าง Back ไปหา Front Buffer
หากฟังก์ชันนี้มีการทำ glFlush ให้อยู่แล้วไม่ต้องใช้หลายครั้งให้ซ้ำซ้อน

ไม่มีความคิดเห็น: