OpenGL进阶(一):多视口

发表于2017-09-14
评论0 2.4k浏览

提要

OpenGL视口(Viewport)可以看作是窗口中OpenGL的绘制输出区域,可以通过一条简单的glViewport命令设置。一般的OpenGL教程都是单视口,即整个窗口为惟一的一个视口,而下面要和大家介绍的是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);

代码实现

实现一:

  1. void renderGL()  
  2. {  
  3.     glClear (GL_COLOR_BUFFER_BIT);  
  4.     glLoadIdentity();                                   // 重置模型观察矩阵  
  5.   
  6.     for (int loop=0; loop<4; loop )                 // 循环绘制4个视口  
  7.     {  
  8.         if (loop==0)                                    // 绘制左上角的视口  
  9.         {  
  10.             // 设置视口区域  
  11.             glViewport (0, window_height/2, window_width/2, window_height/2);  
  12.             glMatrixMode (GL_PROJECTION);  
  13.             glLoadIdentity ();  
  14.             gluOrtho2D(0, window_width/2, window_height/2, 0);  
  15.         }  
  16.         if (loop==1)                                    // 绘制右上角视口  
  17.         {  
  18.   
  19.             glViewport (window_width/2, window_height/2, window_width/2, window_height/2);  
  20.             glMatrixMode (GL_PROJECTION);  
  21.             glLoadIdentity ();  
  22.             gluPerspective( 45.0, 1.0f, 0.1f, 500.0 );  
  23.         }  
  24.         if (loop==2)                                    // 绘制右下角视口  
  25.         {  
  26.             glViewport (window_width/2, 0, window_width/2, window_height/2);  
  27.             glMatrixMode (GL_PROJECTION);  
  28.             glLoadIdentity ();  
  29.             gluPerspective( 45.0, 1.0f, 0.1f, 500.0 );  
  30.         }  
  31.         if (loop==3)                                    // 绘制左下角视口  
  32.         {  
  33.             glViewport (0, 0, window_width/2, window_height/2);  
  34.             glMatrixMode (GL_PROJECTION);  
  35.             glLoadIdentity ();  
  36.             gluPerspective( 45.0, 1.0f, 0.1f, 500.0 );  
  37.         }  
  38.         glMatrixMode (GL_MODELVIEW);                              
  39.         glLoadIdentity ();  
  40.   
  41.         glClear (GL_DEPTH_BUFFER_BIT);  
  42.         if (loop==0)                                    // 绘制左上角的视图  
  43.         {  
  44.             glBegin(GL_QUADS);  
  45.             glColor3f(1.0f,0.0f,0.0f);              // 设置当前色为红色  
  46.             glVertex2i(window_width/2, 0              );  
  47.             glColor3f(0.0f,1.0f,0.0f);              // 设置当前色为绿色  
  48.             glVertex2i(0,              0              );  
  49.             glColor3f(0.0f,1.0f,1.0f);              // 设置当前色为蓝色  
  50.             glVertex2i(0, window_height/2);  
  51.             glColor3f(1.0f,1.0f,0.0f);              // 设置当前色为红色  
  52.             glVertex2i(window_width/2, window_height/2);  
  53.             glEnd();  
  54.         }  
  55.         if (loop==1)                                    // 绘制右上角的视图  
  56.         {  
  57.             glColor3f(1.0f,0.0f,1.0f);    
  58.             glTranslatef(0.0f,0.0f,-9.0f);  
  59.             glRotatef(rtri,1.0,1.0,0.0);  
  60.   
  61.             glBegin(GL_TRIANGLES);                      // 绘制三角形  
  62.             glVertex3f( 0.0f, 1.0f, 0.0f);          // 上顶点  
  63.             glVertex3f(-1.0f,-1.0f, 0.0f);          // 左下  
  64.             glVertex3f( 1.0f,-1.0f, 0.0f);          // 右下  
  65.             glEnd();                                    // 三角形绘制结束  
  66.   
  67.         }  
  68.         if (loop==2)                                    // 绘制右下角的视图  
  69.         {  
  70.             glTranslatef(0.0f,0.0f,-2.0f);  
  71.             glRotatef(-45.0f,1.0f,0.0f,0.0f);  
  72.             glRotatef(rtri,0.0f,0.0f,1.0f);  
  73.   
  74.             glBegin(GL_QUADS);  
  75.             glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f);  
  76.             glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.5f,  0.5f, 0.0f);  
  77.             glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f);  
  78.             glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f);  
  79.             glEnd();  
  80.   
  81.         }  
  82.         if (loop==3)                                    // 绘制左下角的视图  
  83.         {  
  84.             glColor3f(0.0f,0.0f,0.0f);  
  85.             glTranslatef(0.0f,0.0f,-4.0f);  
  86.             glRotatef(-rtri/2,1.0f,0.0f,0.0f);  
  87.             glRotatef(-rtri/2,0.0f,1.0f,0.0f);  
  88.             glRotatef(-rquad/2,0.0f,0.0f,1.0f);  
  89.   
  90.             glBegin(GL_QUADS);  
  91.             glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f);  
  92.             glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.3f,  0.5f, 0.0f);  
  93.             glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f);  
  94.             glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f);  
  95.             glEnd();  
  96.         }  
  97.     }  
  98.     rtri =0.2f;                                       // 旋转变量  
  99.     rquad-=0.15f;                                     // 旋转变量  
  100.     SDL_GL_SwapBuffers( );  
  101. }  

效果:



实现二:

  1. void renderGL2()  
  2. {     
  3.   
  4.     //视口一  左下角  
  5.     glEnable(GL_SCISSOR_TEST);  
  6.     glScissor(0,0,window_width/2-1,window_height/2-1);  
  7.   
  8.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  9.     glDisable(GL_SCISSOR_TEST);  
  10.   
  11.     glViewport(0,0,window_width/2-1,window_height/2-1);  
  12.     glMatrixMode(GL_PROJECTION);  
  13.     glLoadIdentity();  
  14.     gluPerspective(45.0f,(GLfloat)window_width/(GLfloat)window_height,0.1f,100.0f);  
  15.   
  16.     glMatrixMode(GL_MODELVIEW);  
  17.     glLoadIdentity();  
  18.   
  19.     //绘制部分                
  20.     glTranslatef(0.0f  ,0.0f  ,-5.0f  );    
  21.     glRotatef(rtri,0.0f  ,1.0f  ,0.0f  );    
  22.      //绘制一个三角锥    
  23.     glBegin( GL_TRIANGLE_STRIP );    
  24.     glColor3f( 1.0, 0.0, 0.0 );    
  25.     glVertex3f(  0.0,  1.0,  0.0 );    
  26.     glColor3f( 0.0, 1.0, 0.0 );    
  27.     glVertex3f(-1.0, -1.0,  1.0 );    
  28.     glColor3f( 0.0, 0.0, 1.0 );    
  29.     glVertex3f(  1.0, -1.0,  1.0 );    
  30.     glColor3f( 0.0, 1.0, 0.0 );    
  31.     glVertex3f(  1.0, -1.0, -1.0 );    
  32.     glColor3f( 1.0, 0.0, 0.0 );    
  33.     glVertex3f(  0.0,  1.0,  0.0 );    
  34.     glColor3f( 0.0, 1.0, 0.0 );    
  35.     glVertex3f(-1.0, -1.0,  1.0 );    
  36.     glEnd();    
  37.   
  38.     //视口二 左上角  
  39.     glEnable(GL_SCISSOR_TEST);  
  40.     glScissor(0,window_height/2 1,window_width/2-1,window_height/2-1);  
  41.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  42.     glDisable(GL_SCISSOR_TEST);  
  43.   
  44.     glViewport(0,window_height/2 1, window_width/2-1,   window_height/2-1);  
  45.     glMatrixMode(GL_PROJECTION);  
  46.     glLoadIdentity();  
  47.   
  48.     gluPerspective(45.0f,(GLfloat)window_width/(GLfloat)window_height,0.1f,100.0f);  
  49.   
  50.     glMatrixMode(GL_MODELVIEW);  
  51.     glLoadIdentity();  
  52.   
  53.     //绘制部分  
  54.     glColor3f(1.0f,0.0f,1.0f);  
  55.     glTranslatef(0.0f,0.0f,-9.0f);  
  56.     glRotatef(rtri,1.0,1.0,0.0);  
  57.   
  58.     glBegin(GL_TRIANGLES);                      // 绘制三角形  
  59.     glVertex3f( 0.0f, 1.0f, 0.0f);          // 上顶点  
  60.     glVertex3f(-1.0f,-1.0f, 0.0f);          // 左下  
  61.     glVertex3f( 1.0f,-1.0f, 0.0f);          // 右下  
  62.     glEnd();                                    // 三角形绘制结束  
  63.   
  64.     //视口三  右下角  
  65.     glEnable(GL_SCISSOR_TEST);  
  66.     glScissor(window_width/2 1, 0,  window_width/2-1,   window_height/2-1);  
  67.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  68.     glDisable(GL_SCISSOR_TEST);  
  69.   
  70.     glViewport(window_width/2 1,0,window_width/2-1, window_height/2-1);  
  71.     glMatrixMode(GL_PROJECTION);  
  72.     glLoadIdentity();  
  73.   
  74.     gluPerspective(45.0f,(GLfloat)window_width/(GLfloat)window_height,0.1f,100.0f);  
  75.     glMatrixMode(GL_MODELVIEW);  
  76.     glLoadIdentity();  
  77.   
  78.     //绘制部分  
  79.     glTranslatef(0.0f,0.0f,-2.0f);  
  80.     glRotatef(-45.0f,1.0f,0.0f,0.0f);  
  81.     glRotatef(rtri,0.0f,0.0f,1.0f);  
  82.   
  83.     glBegin(GL_QUADS);  
  84.     glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f);  
  85.     glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.5f,  0.5f, 0.0f);  
  86.     glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f);  
  87.     glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f);  
  88.     glEnd();  
  89.   
  90.     //视口四  右上角  
  91.     glEnable(GL_SCISSOR_TEST);  
  92.   
  93.     glScissor(window_width/2 1, window_height/2 1, window_width/2-1, window_height/2-1);  
  94.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  95.     glDisable(GL_SCISSOR_TEST);  
  96.   
  97.     glViewport(window_width/2 1,    window_height/2 1, window_width/2-1, window_height/2-1);  
  98.     glMatrixMode(GL_PROJECTION);  
  99.     glLoadIdentity();  
  100.   
  101.     gluPerspective(45.0f,(GLfloat)window_width/(GLfloat)window_height,0.1f,100.0f);  
  102.   
  103.     glMatrixMode(GL_MODELVIEW);  
  104.     glLoadIdentity();  
  105.   
  106.     //绘制部分  
  107.     glColor3f(0.0f,0.0f,0.0f);  
  108.     glTranslatef(0.0f,0.0f,-4.0f);  
  109.     glRotatef(-rtri/2,1.0f,0.0f,0.0f);  
  110.     glRotatef(-rtri/2,0.0f,1.0f,0.0f);  
  111.     glRotatef(-rquad/2,0.0f,0.0f,1.0f);  
  112.   
  113.     glBegin(GL_QUADS);  
  114.     glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.5f,  0.5f, 0.0f);  
  115.     glColor3f(0.0f,1.0f,0.0f); glVertex3f(-0.3f,  0.5f, 0.0f);  
  116.     glColor3f(0.0f,0.0f,1.0f); glVertex3f(-0.5f, -1.0f, 0.0f);  
  117.     glColor3f(0.0f,0.0f,0.0f); glVertex3f( 0.5f, -1.0f, 0.0f);  
  118.     glEnd();  
  119.     rtri =0.2f;                                       // 旋转变量  
  120.     rquad-=0.15f;                                     // 旋转变量  
  121.     SDL_GL_SwapBuffers( );  
  122. }  
  123. void initGL( int width, int height )  
  124. {  
  125.     float ratio = (float) width / (float) height;  
  126.     // Our shading model--Gouraud (smooth).   
  127.     glShadeModel( GL_SMOOTH );  
  128.     // Set the clear color.   
  129.     glClearColor( 0, 0, 0, 0 );  
  130.     // Setup our viewport.   
  131.     glViewport( 0, 0, width, height );  
  132.     //Change to the projection matrix and set our viewing volume.  
  133.     glMatrixMode( GL_PROJECTION );  
  134.     glLoadIdentity();  
  135.     gluPerspective( 60.0, ratio, 1.0, 100.0 );  
  136. }  



参考:OpenGL中的多视口

http://blog.csdn.net/silangquan/article/details/8270764

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引