OpenGL: 实现立体显示(源代码)

转载 2016年11月16日 18:14:12

立体显示原理:设没有立体显示的模型视图矩阵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,如图:


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

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



新建win32 console工程


// OpenGLTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <gl/glut.h>
#include <math.h>

#pragma comment(lib, "glut32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "opengl32.lib")


/**//*----------------------------------------------------------------------------
	*    初始化参数
	*/
GLfloat PI = 3.1415926;
GLfloat Fd = 5.0;            //fusion distance  
GLfloat RealScreenToEyeDistance = 1.0;
GLfloat R = Fd / RealScreenToEyeDistance;    //比例尺 R =  Fd / RealScreenToEyeDistance  
GLfloat Sd = 0.05;                        //两眼之间的距离  
GLfloat aspect = 1.0;                        //gluLookAt函数里面的参数  
GLfloat fovy = 60.0;                        //张角  
GLfloat f = 1 / tan((fovy * PI) / (2 * 180));    //f=ctg(fovy/2);  

//列优先的矩阵模型视图矩阵,投影矩阵  
GLfloat LeftModelViewMatrix[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,
	Sd * R / 2.0, 0.0, 0.0, 1.0
};

GLfloat LeftProjectMatrix[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,
	-(Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0
};

GLfloat RightModelViewMatrix[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,
	-Sd * R / 2.0, 0.0, 0.0, 1.0
};

GLfloat RightProjectMatrix[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,
	(Sd * f) / (2.0 * Fd * aspect), 0.0, 0.0, 1.0
};

//for the use of rotating  
static GLfloat spin = 0.0;

void init(void)
{
	GLfloat mat_diffuse[] = { 1.0, 1.0, 0.0 };
	GLfloat mat_specular[] = { 0.8, 0.8, 0.0, 1.0 };
	GLfloat mat_shininess[] = { 300. };
	GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
	GLfloat light_diffuse[] = { 1.0, 1.0, 0.0 };
	GLfloat light_ambient[] = { 0.7, 0.2, 0.2, 1.0 };

	glClearColor(0.0, 0.0, 0.0, 0.0);
	glShadeModel(GL_SMOOTH);

	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);
	glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	glEnable(GL_DEPTH_TEST);
}

void display(void)
{
	GLfloat matrix[16] = { 0. };

	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);

	//---------------------------------------------------------------------------------------------  
	//Left View port  
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	{
		glGetFloatv(GL_PROJECTION_MATRIX, matrix);
		glLoadIdentity();
		glMultMatrixf(LeftProjectMatrix);
		glMultMatrixf(matrix);
		{
			glMatrixMode(GL_MODELVIEW);
			glLoadIdentity();
			glTranslated(0.0, 0.0, -Fd);
			glPushMatrix();
			{
				glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
				glLoadIdentity();
				glMultMatrixf(LeftModelViewMatrix);
				glMultMatrixf(matrix);
				glColorMask(1.0, 0.0, 0.0, 1.0);
				/**//*
					*  物体的坐标Vp
					*  变换到屏幕坐标:Vp'= LeftProjectMatrix×Mp × LeftModelViewMatrix×Mv × Mr×Vp
					*/
				glPushMatrix();
				{
					glRotatef(spin, 0.0, 1.0, 0.0);
					glutSolidTeapot(1.0);
				}
				glPopMatrix();
			}
		}
		glPopMatrix();
		glMatrixMode(GL_PROJECTION);
	}
	glPopMatrix();
	glFlush();

	//---------------------------------------------------------------------------------------------  
	//Right View port  
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	{
		glGetFloatv(GL_PROJECTION_MATRIX, matrix);
		glLoadIdentity();
		glMultMatrixf(RightProjectMatrix);
		glMultMatrixf(matrix);

		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		{
			glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
			glLoadIdentity();
			glMultMatrixf(RightModelViewMatrix);
			glMultMatrixf(matrix);

			glColorMask(0.0, 1.0, 1.0, 1.0);
			glClearDepth(1.0);
			glClear(GL_DEPTH_BUFFER_BIT);
			/**//*
				*  物体的坐标Vp
				*    变换到屏幕坐标:Vp'= RightProjectMatrix×Mp× RightModelViewMatrix×Mv × Mr×Vp
				*/
			glPushMatrix();
			{
				glRotatef(spin, 0.0, 1.0, 0.0);
				glutSolidTeapot(1.0);
				//glutSolidSphere(1.0, 20, 5);  
			}
		}
		glPopMatrix();

		glMatrixMode(GL_PROJECTION);
	}
	glPopMatrix();
	glFlush();

	glutSwapBuffers();
}

void reshape(int w, int h)
{
	if (h == 0)
	{
		h = 1;
	}
	glViewport(0, 0, (GLsizei)w, (GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	//投影矩阵:Mp  
	gluPerspective(fovy, (GLfloat)w / (GLfloat)h, 1.0, 20.0);
}
void spinDisplay(void)
{
	spin = spin + 1.0;
	if (spin > 360.0)
	{
		spin = spin - 360.0;
	}
	glutPostRedisplay();
}

int _tmain(int argc, _TCHAR* 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);
	glutIdleFunc(spinDisplay);
	glutMainLoop();
	return 0;
}



OpenGL--代码解读

OpenGL代码解读
  • qiaogua
  • qiaogua
  • 2016年11月27日 11:40
  • 1707

OpenGL实现3D魔方游戏源代码

首先这个程序是建立的是Windows应用程序,建立控制台程序是不能运行的,另外,项目——项目属性——配置属性——常规-----使用多字节字符集,这样编译才能够通过的,否则如果选择使用 Unicode ...
  • Hackbuteer1
  • Hackbuteer1
  • 2011年08月11日 17:59
  • 17305

opengl实例源代码,全是精华!

  • 2010年02月26日 11:33
  • 16.53MB
  • 下载

OpenGL编3D游戏实例源代码

  • 2009年12月17日 22:24
  • 8.35MB
  • 下载

OpenGL程序:实例练习

说起编程作图,大概还有很多人想起TC的#include 吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率、16色来做吗?显然是不行的。 本帖的目...
  • u014800094
  • u014800094
  • 2016年11月14日 12:09
  • 2918

【OpenGL】详解第一个OpenGL程序

OpenGL能做的事情太多了!很多程序也看起来很复杂。但是!所有O
  • candycat1992
  • candycat1992
  • 2014年11月26日 16:00
  • 59060

实战OpenGL三维可视化系统开发与源码精解(源程序)

  • 2010年03月11日 18:48
  • 5.71MB
  • 下载

OpenGL 超酷三维动画DEMO 附源代码

  • 2007年08月26日 18:15
  • 1.39MB
  • 下载

openGL程序示例代码——旋转的玉石

最近交期末作业,学了一下openGL,感觉学到的在这列一下
  • u013394782
  • u013394782
  • 2014年06月11日 20:44
  • 456

自动生成迷宫和迷宫自动寻路OpenGL版(源代码+演示程序)

  • 2012年12月14日 19:00
  • 686KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:OpenGL: 实现立体显示(源代码)
举报原因:
原因补充:

(最多只允许输入30个字)