OpenGL实现3D立体显示

系统 1553 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;
} 
  

最终效果图如下所示:

OpenGL实现3D立体显示

OpenGL实现3D立体显示


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论