使用OpenGL实现3D立体显示的程序代码

所属分类: 软件编程 / C 语言 阅读数: 204
收藏 0 赞 0 分享
由于左眼和右眼观看显示器的角度不同,利用这一角度差遮住光线就可将图像分配给右眼或者左眼,经过大脑将这两幅由差别的图像合成为一副具有空间深度和维度信息的图像,从而可以看到3D图像。
完整的实现代码如下所示:
复制代码 代码如下:

#include "stdafx.h"
#include "GL/glut.h"
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
static int big = 0;
static bool isLeftEye = false;
#define PI 3.1415926
const GLfloat R = 8.0;
static GLfloat leftMatrix[16] = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0,  0.0,
0.0, 0.0, 0.0, 1.0};
static GLfloat rightMatrix[16] = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
static GLfloat leftPersMatrix[16] = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
static GLfloat rightPersMatrix[16] = {1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0};
void init(void)

 const GLfloat SD = 0.06;
 GLfloat n = SD*R/2.0;
 //要是转秩
 //n=0;
 leftMatrix[12] = n;
 rightMatrix[12] = -n;
 //这里假设眼到屏幕为一米,以米为单位
 GLfloat p = SD/(2*1*tan(PI/6)*1);
 //p = 0.0;
 leftPersMatrix[12] = -p;
 rightPersMatrix[12] = p;
 GLfloat mat_specular[] = {0.8, 0.8, 0.0, 1.0};
 GLfloat mat_shininess[] = {50.0};
 GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
 GLfloat white_light[] = {1.0, 1.0, 1.0, 1.0};
 GLfloat yellow_light[] = {1.0, 1.0, 0.0, 1.0};
 GLfloat lmodel_ambient[] = {0.0, 0.7, 0.5, 1.0};
 glClearColor(1.0, 1.0, 1.0, 0.0);
 glShadeModel(GL_SMOOTH);
 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 glLightfv(GL_LIGHT0, GL_DIFFUSE, yellow_light);//主体的颜色
 glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);//高光的颜色
 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_DEPTH_TEST);
}
void display(void)
{
 glColorMask(1.0, 1.0,1.0,1.0);
 glClearColor(0.0,0.0,0.0,1.0);
 glClearDepth(1.0);
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 glColor3f(1.0, 1.0, 1.0);
 // 画左眼
 glMatrixMode(GL_PROJECTION);
 glPushMatrix();
 float mat[16];
 glGetFloatv(GL_PROJECTION_MATRIX,mat);
 glLoadIdentity();
 glMultMatrixf(leftPersMatrix);
 glMultMatrixf(mat);
 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();
 glGetFloatv(GL_MODELVIEW_MATRIX,mat);
 glLoadIdentity();
 glMultMatrixf(leftMatrix);
 glMultMatrixf(mat);
 glColorMask(1.0, 0.0,0.0,1.0);
 glRotatef((GLfloat) big, 0.0, 1.0, 0.0);
 glutSolidTeapot(2.0);
 glPopMatrix();
 glMatrixMode(GL_PROJECTION);
 glPopMatrix();
 glFlush();
 //画右眼
 glClearDepth(1.0);
 glClear(GL_DEPTH_BUFFER_BIT);
 glMatrixMode(GL_PROJECTION);
 glPushMatrix();
 glGetFloatv(GL_PROJECTION_MATRIX,mat);
 glLoadIdentity();
 glMultMatrixf(rightPersMatrix);
 glMultMatrixf(mat);
 glMatrixMode(GL_MODELVIEW);
 glPushMatrix();
 glGetFloatv(GL_MODELVIEW_MATRIX,mat);
 glLoadIdentity();
 glMultMatrixf(rightMatrix);
 glMultMatrixf(mat);
 glColorMask(0.0, 1.0,1.0,1.0);
 glRotatef((GLfloat) big, 0.0, 1.0, 0.0);
 glutSolidTeapot(2.0);
 glPopMatrix();
 glMatrixMode(GL_PROJECTION);
 glPopMatrix();
 glFlush();
 //glPopMatrix();
 //if(isLeftEye)
 //{ 
 // glMatrixMode(GL_PROJECTION);
 // glMultMatrixf(leftPersMatrix);
 // glMatrixMode(GL_MODELVIEW);
 // glMultMatrixf(leftMatrix);
 // glColorMask(1.0, 0.0,0.0,1.0);
 // 
 // 
 // 
 // isLeftEye = false;
 //}else
 //{ 
 // 
 // glMatrixMode(GL_PROJECTION);
 // glMultMatrixf(rightPersMatrix);
 // glMatrixMode(GL_MODELVIEW);
 // glMultMatrixf(rightMatrix);
 // glColorMask(0.0, 1.0,1.0,1.0); 
 // isLeftEye = true;
 //}
 //glRotatef((GLfloat) big, 0.0, 1.0, 0.0);
 //glutSolidTeapot(1.0);
 //glRotatef((GLfloat) big, 0.0, 1.0, 0.0);
 //glTranslatef(3.0, 0.0, 0.0);
 //glutSolidTeapot(0.5);
 glutSwapBuffers();
}
void reshape(int w, int h)
{
 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(60, (GLfloat)w/(GLfloat)h, 0.01, 20.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();
 gluLookAt(0.0, 0.0, R, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 );
}
void keyboard(unsigned char key, int x, int y)
{
 switch (key)
 {
 case 'b':
  big = (big + 1) % 360;
  glutPostRedisplay();
  break;
 case 'B':
  big = (big - 1) % 360;
  glutPostRedisplay();
  break;
 case 27:    // 按ESC键时退出程序
  exit (0);
  break;
 default:
  break;
 }
}
void spinDisplay(void)
{
 big = (big + 1) % 360;
 glutPostRedisplay();
}
int main (int argc, char** argv)
{
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
 glutInitWindowSize(500, 500);
 glutInitWindowPosition(100, 100);
 glutCreateWindow(argv[0]);
 init();
 glutDisplayFunc(display);
 glutReshapeFunc(reshape);
 glutKeyboardFunc(keyboard);
 glutIdleFunc(spinDisplay);
 glutMainLoop();
 return 0;
}

最终效果图如下所示:
更多精彩内容其他人还在看

深入解析C++中派生类的构造函数

这篇文章主要介绍了深入解析C++中派生类的构造函数,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

解析C++中多层派生时的构造函数及一些特殊形式

这篇文章主要介绍了解析C++中多层派生时的构造函数及一些特殊形式,特殊形式主要针对基类和子对象类型的构造函数内容,需要的朋友可以参考下
收藏 0 赞 0 分享

简单介绍C++编程中派生类的析构函数

这篇文章主要介绍了C++编程中派生类的析构函数,析构函数平时一般使用较少,需要的朋友可以参考下
收藏 0 赞 0 分享

深入解析C++中类的多重继承

这篇文章主要介绍了深入解析C++中类的多重继承,包括多重继承相关的二义性问题,需要的朋友可以参考下
收藏 0 赞 0 分享

详解C++中基类与派生类的转换以及虚基类

这篇文章主要介绍了详解C++中基类与派生类的转换以及虚基类,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

解析C++编程中的继承方面的运用

这篇文章主要介绍了解析C++编程中的继承方面的运用,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

详解C++编程的多态性概念

这篇文章主要介绍了C++编程的多态性概念,是C++入门学习中的基础知识,需要的朋友可以参考下
收藏 0 赞 0 分享

c++统计文件中字符个数代码汇总

本文给大家汇总介绍了3种使用C++实现统计文件中的字符个数的方法,非常的简单实用,有需要的小伙伴可以参考下。
收藏 0 赞 0 分享

详解C++编程中的虚函数

这篇文章主要介绍了详解C++编程中的虚函数,包括在什么情况下应当声明虚函数的相关讲解,需要的朋友可以参考下
收藏 0 赞 0 分享

C语言putenv()函数和getenv()函数的使用详解

这篇文章主要介绍了C语言putenv()函数和getenv()函数的使用详解,用来进行环境变量的相关操作,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多