OpenGL: 实现立体显示

https://blog.csdn.net/augusdi/article/details/19922295

立体显示原理:设没有立体显示的模型视图矩阵ModelView为Mv,投影矩阵为Mp,则、物体空间的任何一点为P,则变换到屏幕坐标P*=Mp×Mv×P;注意前面已经说过opengl里面坐标列优先,所以矩阵都是右乘。

左眼和右眼的变换都是由中间的变换矩阵变换而来,则立体显示中左眼的变换矩阵公式为:

P(L)*=Ms(L) × Mp(L) × Mt(L) × Mv(L) × P;

右眼的矩阵变换公式为:

P(R)*=Ms(R) × Mp(R) × Mt(R) × Mv(R) × P;

其中Ms,Mt是立体显示需要而增加的变换。

程序里面有几个参数,现实世界眼睛到屏幕的距离Fd,两眼之间的距离Sd,比例尺R,如图:

如上图:没有立体显示,视点位于就是中间的蓝色位置,立体显示就是将左眼(红色),右眼(绿色)的视图分开绘制。

程序中左眼用红色去画,右眼同时用绿色和蓝色绘制。

代码:

  1.  
    #include <windows.h>
  2.  
    #include <GL/glut.h>
  3.  
    #include <math.h>
  4.  
     
  5.  
    #pragma comment(lib,"glut32.lib")
  6.  
    #pragma comment(lib,"glu32.lib")
  7.  
    #pragma comment(lib,"opengl32.lib")
  8.  
     
  9.  
    void init(void)
  10.  
    {
  11.  
    GLfloat mat_diffuse[] = { 1.0, 1.0, 0.0 };
  12.  
    GLfloat mat_specular[] = {0.8, 0.8, 0.0, 1.0};
  13.  
    GLfloat mat_shininess[] = { 300. };
  14.  
    GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
  15.  
    GLfloat light_diffuse[] = { 1.0, 1.0, 0.0 };
  16.  
    GLfloat light_ambient[] = {0.7, 0.2, 0.2, 1.0};
  17.  
     
  18.  
    glClearColor (0.0, 0.0, 0.0, 0.0);
  19.  
    glShadeModel (GL_SMOOTH);
  20.  
     
  21.  
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
  22.  
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
  23.  
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
  24.  
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  25.  
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
  26.  
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
  27.  
     
  28.  
    glEnable(GL_LIGHTING);
  29.  
    glEnable(GL_LIGHT0);
  30.  
    glEnable(GL_DEPTH_TEST);
  31.  
    }
  32.  
    /**//*----------------------------------------------------------------------------
  33.  
    * 初始化参数
  34.  
    */
  35.  
    GLfloat PI=3.1415926;
  36.  
    GLfloat Fd=5.0; //fusion distance
  37.  
    GLfloat RealScreenToEyeDistance=1.0;
  38.  
    GLfloat R = Fd / RealScreenToEyeDistance; //比例尺 R = Fd / RealScreenToEyeDistance
  39.  
    GLfloat Sd = 0.05; //两眼之间的距离
  40.  
    GLfloat aspect = 1.0; //gluLookAt函数里面的参数
  41.  
    GLfloat fovy = 60.0; //张角
  42.  
    GLfloat f = 1 / tan( (fovy * PI) / (2 * 180) ); //f=ctg(fovy/2);
  43.  
     
  44.  
    //列优先的矩阵模型视图矩阵,投影矩阵
  45.  
    GLfloat LeftModelViewMatrix[16]=
  46.  
    {
  47.  
    1.0, 0.0, 0.0, 0.0,
  48.  
    0.0, 1.0, 0.0, 0.0,
  49.  
    0.0, 0.0, 1.0, 0.0,
  50.  
    Sd * R / 2.0, 0.0, 0.0, 1.0
  51.  
    };
  52.  
     
  53.  
    GLfloat LeftProjectMatrix[16]=
  54.  
    {
  55.  
    1.0, 0.0, 0.0, 0.0,
  56.  
    0.0, 1.0, 0.0, 0.0,
  57.  
    0.0, 0.0, 1.0, 0.0,
  58.  
    -(Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0
  59.  
    };
  60.  
     
  61.  
    GLfloat RightModelViewMatrix[16]=
  62.  
    {
  63.  
    1.0, 0.0, 0.0, 0.0,
  64.  
    0.0, 1.0, 0.0, 0.0,
  65.  
    0.0, 0.0, 1.0, 0.0,
  66.  
    -Sd * R / 2.0, 0.0, 0.0, 1.0
  67.  
    };
  68.  
     
  69.  
    GLfloat RightProjectMatrix[16]=
  70.  
    {
  71.  
    1.0, 0.0, 0.0, 0.0,
  72.  
    0.0, 1.0, 0.0, 0.0,
  73.  
    0.0, 0.0, 1.0, 0.0,
  74.  
    (Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0
  75.  
    };
  76.  
     
  77.  
    //for the use of rotating
  78.  
    static GLfloat spin = 0.0;
  79.  
     
  80.  
    void display(void)
  81.  
    {
  82.  
    GLfloat matrix[16]={0.};
  83.  
     
  84.  
    glColorMask(1.0, 1.0, 1.0, 1.0);
  85.  
    glClearColor(0.0, 0.0, 0.0, 1.0);
  86.  
    glClearDepth(1.0);
  87.  
     
  88.  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  89.  
    glColor3f(1.0, 1.0, 1.0);
  90.  
     
  91.  
    //---------------------------------------------------------------------------------------------
  92.  
    //Left View port
  93.  
    glMatrixMode(GL_PROJECTION);
  94.  
    glPushMatrix();
  95.  
    {
  96.  
    glGetFloatv(GL_PROJECTION_MATRIX, matrix);
  97.  
    glLoadIdentity();
  98.  
    glMultMatrixf(LeftProjectMatrix);
  99.  
    glMultMatrixf(matrix);
  100.  
    {
  101.  
    glMatrixMode(GL_MODELVIEW);
  102.  
    glLoadIdentity();
  103.  
    glTranslated(0.0, 0.0, -Fd);
  104.  
    glPushMatrix();
  105.  
    {
  106.  
    glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  107.  
    glLoadIdentity();
  108.  
    glMultMatrixf(LeftModelViewMatrix);
  109.  
    glMultMatrixf(matrix);
  110.  
    glColorMask(1.0, 0.0, 0.0, 1.0);
  111.  
    /**//*
  112.  
    * 物体的坐标Vp
  113.  
    * 变换到屏幕坐标:Vp'= LeftProjectMatrix×Mp × LeftModelViewMatrix×Mv × Mr×Vp
  114.  
    */
  115.  
    glPushMatrix();
  116.  
    {
  117.  
    glRotatef(spin, 0.0, 1.0, 0.0);
  118.  
    glutSolidTeapot(1.0);
  119.  
    }
  120.  
    glPopMatrix();
  121.  
    }
  122.  
    }
  123.  
    glPopMatrix();
  124.  
    glMatrixMode(GL_PROJECTION);
  125.  
    }
  126.  
    glPopMatrix();
  127.  
    glFlush();
  128.  
     
  129.  
    //---------------------------------------------------------------------------------------------
  130.  
    //Right View port
  131.  
    glMatrixMode(GL_PROJECTION);
  132.  
    glPushMatrix();
  133.  
    {
  134.  
    glGetFloatv(GL_PROJECTION_MATRIX, matrix);
  135.  
    glLoadIdentity();
  136.  
    glMultMatrixf(RightProjectMatrix);
  137.  
    glMultMatrixf(matrix);
  138.  
     
  139.  
    glMatrixMode(GL_MODELVIEW);
  140.  
    glPushMatrix();
  141.  
    {
  142.  
    glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
  143.  
    glLoadIdentity();
  144.  
    glMultMatrixf(RightModelViewMatrix);
  145.  
    glMultMatrixf(matrix);
  146.  
     
  147.  
    glColorMask(0.0, 1.0, 1.0, 1.0);
  148.  
    glClearDepth(1.0);
  149.  
    glClear(GL_DEPTH_BUFFER_BIT);
  150.  
    /**//*
  151.  
    * 物体的坐标Vp
  152.  
    * 变换到屏幕坐标:Vp'= RightProjectMatrix×Mp× RightModelViewMatrix×Mv × Mr×Vp
  153.  
    */
  154.  
    glPushMatrix();
  155.  
    {
  156.  
    glRotatef(spin, 0.0, 1.0, 0.0);
  157.  
    glutSolidTeapot(1.0);
  158.  
    //glutSolidSphere(1.0, 20, 5);
  159.  
    }
  160.  
    }
  161.  
    glPopMatrix();
  162.  
     
  163.  
    glMatrixMode(GL_PROJECTION);
  164.  
    }
  165.  
    glPopMatrix();
  166.  
    glFlush ();
  167.  
     
  168.  
    glutSwapBuffers();
  169.  
    }
  170.  
     
  171.  
    void reshape (int w, int h)
  172.  
    {
  173.  
    if (h == 0)
  174.  
    {
  175.  
    h == 1;
  176.  
    }
  177.  
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
  178.  
    glMatrixMode (GL_PROJECTION);
  179.  
    glLoadIdentity();
  180.  
    //投影矩阵:Mp
  181.  
    gluPerspective(fovy, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
  182.  
    }
  183.  
    void spinDisplay(void)
  184.  
    {
  185.  
    spin = spin + 1.0;
  186.  
    if (spin > 360.0)
  187.  
    {
  188.  
    spin = spin - 360.0;
  189.  
    }
  190.  
    glutPostRedisplay();
  191.  
    }
  192.  
     
  193.  
    int main(int argc, char** argv)
  194.  
    {
  195.  
    glutInit(&argc, argv);
  196.  
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  197.  
    glutInitWindowSize (500, 500);
  198.  
    glutInitWindowPosition (100, 100);
  199.  
    glutCreateWindow (argv[0]);
  200.  
    init ();
  201.  
    glutDisplayFunc(display);
  202.  
    glutReshapeFunc(reshape);
  203.  
    glutIdleFunc(spinDisplay);
  204.  
    glutMainLoop();
  205.  
    return 0;
  206.  
    }

相关立体显示链接:http://local.wasp.uwa.edu.au/~pbourke/projection/stereorender/

http://blog.csdn.net/ryfdizuo/article/details/2327478

原文地址:https://www.cnblogs.com/jukan/p/9487577.html