歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL編程指南之多視口

提要

OpenGL視口(Viewport)可以看作是窗口中OpenGL的繪制輸出區域,可以通過一條簡單的glViewport命令設置。一般的OpenGL教程都是單視口,即整個窗口為惟一的一個視口,Nehe的OpenGL教程是我最早見到涉及多視口的。與單視口程序相比,多視口程序的變化主要是:

(一)多視口程序不能在窗口resize/reshape時直接調用glViewport,而應該在此時記下窗口大小,然後在繪制場景時多次調用glViewport設置每個視口的位置和大小;

(二)對於每個視口,應分別調用glMatrixMode(GL_PROJECTION)和glMatrixMode(GL_MODELVIEW)以設置投影和建模矩陣。

多視口的最常見的應用,就是3DMax中的多視口建模,每一個觀察口都從不同的方向去觀察模型,從而很方便地去獲取模型當前的狀態。

還有就是賽車游戲中的後視鏡等等.

具體實現的思路就是對每個視口進行獨立的渲染。

函數解析

下面是需要調用到的一些OpenGL的函數。

glLoadIdentity()

重置當前指定的矩陣為單位矩陣.

glViewport(GLint x,GLint y,GLsizei width,GLsizei height)

在窗口中定義一個像素矩形,最終將圖像映射到這個矩形中。

void gluOrtho2D(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top)

建立了一個可視的二位平面區域。這個和用glOrtho函數的當near=0,far=1時效果是一樣。

void gluPerspective(GLdouble fovy, GLdouble aspect,GLdouble zNear,GLdouble zFar)

這個函數指定了觀察的視景體(frustum為錐台的意思,通常譯為視景體)在世界坐標系中的具體大小,一般而言,其中的參數aspect應該與窗口的寬高比大小相同。

void glScissor(GLint x,GLint y,GLsizei width,GLsizei height)

設置一個裁剪窗口,前兩個參數為窗口左下角位置,後兩個參數是窗口的寬度和高度。

使用前一定要glEnable(GL_SCISSOR_TEST);

代碼實現

實現一:

void renderGL() 

    glClear (GL_COLOR_BUFFER_BIT); 
    glLoadIdentity();                                  // 重置模型觀察矩陣 
 
    for (int loop=0; loop<4; loop++)                // 循環繪制4個視口 
    { 
        if (loop==0)                                    // 繪制左上角的視口 
        { 
            // 設置視口區域 
            glViewport (0, window_height/2, window_width/2, window_height/2); 
            glMatrixMode (GL_PROJECTION); 
            glLoadIdentity (); 
            gluOrtho2D(0, window_width/2, window_height/2, 0); 
        } 
        if (loop==1)                                    // 繪制右上角視口 
        { 
 
            glViewport (window_width/2, window_height/2, window_width/2, window_height/2); 
            glMatrixMode (GL_PROJECTION); 
            glLoadIdentity (); 
            gluPerspective( 45.0, 1.0f, 0.1f, 500.0 ); 
        } 
        if (loop==2)                                    // 繪制右下角視口 
        { 
            glViewport (window_width/2, 0, window_width/2, window_height/2); 
            glMatrixMode (GL_PROJECTION); 
            glLoadIdentity (); 
            gluPerspective( 45.0, 1.0f, 0.1f, 500.0 ); 
        } 
        if (loop==3)                                    // 繪制左下角視口 
        { 
            glViewport (0, 0, window_width/2, window_height/2); 
            glMatrixMode (GL_PROJECTION); 
            glLoadIdentity (); 
            gluPerspective( 45.0, 1.0f, 0.1f, 500.0 ); 
        } 
        glMatrixMode (GL_MODELVIEW);                             
        glLoadIdentity (); 
 
        glClear (GL_DEPTH_BUFFER_BIT); 
        if (loop==0)                                    // 繪制左上角的視圖 
        { 
            glBegin(GL_QUADS); 
            glColor3f(1.0f,0.0f,0.0f);              // 設置當前色為紅色 
            glVertex2i(window_width/2, 0              ); 
            glColor3f(0.0f,1.0f,0.0f);              // 設置當前色為綠色 
            glVertex2i(0,              0              ); 
            glColor3f(0.0f,1.0f,1.0f);              // 設置當前色為藍色 
            glVertex2i(0, window_height/2); 
            glColor3f(1.0f,1.0f,0.0f);              // 設置當前色為紅色 
            glVertex2i(window_width/2, window_height/2); 
            glEnd(); 
        } 
        if (loop==1)                                    // 繪制右上角的視圖 
        { 
            glColor3f(1.0f,0.0f,1.0f);   
            glTranslatef(0.0f,0.0f,-9.0f); 
            glRotatef(rtri,1.0,1.0,0.0); 
 
            glBegin(GL_TRIANGLES);                      // 繪制三角形 
            glVertex3f( 0.0f, 1.0f, 0.0f);          // 上頂點 
            glVertex3f(-1.0f,-1.0f, 0.0f);          // 左下 
            glVertex3f( 1.0f,-1.0f, 0.0f);          // 右下 
            glEnd();                                    // 三角形繪制結束 
 
        } 
        if (loop==2)                                    // 繪制右下角的視圖 
        { 
            glTranslatef(0.0f,0.0f,-2.0f); 
            glRotatef(-45.0f,1.0f,0.0f,0.0f); 
            glRotatef(rtri,0.0f,0.0f,1.0f); 
 
            glBegin(GL_QUADS); 
            glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f); 
            glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.5f,  0.5f, 0.0f); 
            glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f); 
            glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f); 
            glEnd(); 
 
        } 
        if (loop==3)                                    // 繪制左下角的視圖 
        { 
            glColor3f(0.0f,0.0f,0.0f); 
            glTranslatef(0.0f,0.0f,-4.0f); 
            glRotatef(-rtri/2,1.0f,0.0f,0.0f); 
            glRotatef(-rtri/2,0.0f,1.0f,0.0f); 
            glRotatef(-rquad/2,0.0f,0.0f,1.0f); 
 
            glBegin(GL_QUADS); 
            glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f); 
            glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.3f,  0.5f, 0.0f); 
            glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f); 
            glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f); 
            glEnd(); 
        } 
    } 
    rtri+=0.2f;                                      // 旋轉變量 
    rquad-=0.15f;                                    // 旋轉變量 
    SDL_GL_SwapBuffers( ); 

效果:

Copyright © Linux教程網 All Rights Reserved