C++ VS OpenGL绘制教室三维立体旋转图像

2021/6/1 20:21:07

本文主要是介绍C++ VS OpenGL绘制教室三维立体旋转图像,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++ VS OpenGL绘制教室三维立体旋转图像

如需安装运行环境或远程调试,可加QQ905733049, 或QQ2945218359由专业技术人员远程协助!

运行结果如下:

步骤:

第一步:安装VS2019

第二步:VS2019安装OpenGL

第三步:新建项目

第四步:导入代码文件

第五步:运行

主要代码:

#include<windows.h>
#include<math.h>
#include<time.h>
#pragma warning(disable:4996)
/*******************************定义程序中所用的常数变量******************************************/
GLfloat light_position1[] = { 0,28,0,1.0 };
GLfloat model_ambient[] = { 0.05f,0.05f,0.05f,1.0f };
GLfloat mat_specular[] = { 0.8,1.0,1.0,1.0 };
GLfloat mat_shininess[] = { 5.0 };
GLfloat mat_ambient[] = { 0.1,0.1,0.1,1 };
GLfloat white_light[] = { 1.0,1.0,1.0,1.0 };
GLfloat light[] = { 1.0,1.0,1.0,1 };
GLfloat light_position0[] = { 0,28,20,1.0 };

GLUquadricObj* qobj;
int           fantheta = 0;
BOOL          TurnOn = FALSE;

// 当前时间,时 分 秒
float h = 0.0f;
float m = 0.0f;
float s = 0.0f;
const GLfloat PI = 3.141592653f;
/************************定义视点结构*********************************************************/
typedef struct EyePoint
{
	GLfloat	x;
	GLfloat y;
	GLfloat z;
}EyePoint;
EyePoint 	myEye;
EyePoint    vPoint;
EyePoint    up;
GLfloat pro_up_down = 29.0f;
GLfloat vAngle = 0;
/****************************载入位图作为纹理的相关函数************************************/
#define BMP_Header_Length 54

int power_of_two(int n)
{
	if (n <= 0)
		return 0;
	return (n & (n - 1)) == 0;
}
/****************************载入一副位图作为纹理,返回的是纹理编号**********************************************/
GLuint load_texture(const char* file_name)
{

	// 读取文件中图象的宽度和高度
	fseek(pFile, 0x0012, SEEK_SET);
	fread(&width, 4, 1, pFile);
	fread(&height, 4, 1, pFile);
	fseek(pFile, BMP_Header_Length, SEEK_SET);
	// 计算每行像素所占字节数,并根据此数据计算总像素字节数
	{
		GLint line_bytes = width * 3;
		while (line_bytes % 4 != 0)
			++line_bytes;
		total_bytes = line_bytes * height;
	}
	// 根据总像素字节数分配内存
	pixels = (GLubyte*)malloc(total_bytes);
	if (pixels == 0)
	{
		fclose(pFile);
		return 0;
	}
	// 读取像素数据
	if (fread(pixels, total_bytes, 1, pFile) <= 0)

		GLint max;
		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);//获得OpenGL所支持的最大纹理

		if (!power_of_two(width) || !power_of_two(height) || width > max || height > max)
		{
			const GLint new_width = 256;
			const GLint new_height = 256; // 规定缩放后新的大小为边长的正方形
			GLint new_line_bytes, new_total_bytes;
			GLubyte* new_pixels = 0;
			// 计算每行需要的字节数和总字节数
			new_line_bytes = new_width * 3;
			while (new_line_bytes % 4 != 0)
				++new_line_bytes;
			new_total_bytes = new_line_bytes * new_height;
			// 分配内存
			new_pixels = (GLubyte*)malloc(new_total_bytes);
			if (new_pixels == 0)
			{
				free(pixels);
				fclose(pFile);
				return 0;
			}
			// 进行像素缩放
			gluScaleImage(GL_RGB, width, height, GL_UNSIGNED_BYTE, pixels, new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);
			// 释放原来的像素数据,把 pixels 指向新的像素数据,并重新设置 width 和 height
			free(pixels);
			pixels = new_pixels;
			width = new_width;
			height = new_height;
		}

}
/**********************************定义各个纹理对象的名称************************************/
GLuint texblackboard, texwindow, texdesk, texsound;
GLuint texceiling, texdoor, texfloor, texbackwall, texpole;
GLuint texairfro, texairback, texhighland, texsdesk, texclock;
/*******************************绘制相关函数**************************************************/

//绘制教室这个大场景
void drawscence()
{
	//设置材质相关参数
	/*指定材质对漫射光的反射率,第一个参数决定该材质运用于图元的正面还是反面
	第二个参数表示对何种光进行设置,GL_AMBIENT(环境光)、GL_DIFFUSE(漫射光)、
	GL_AMBIENT_AND_DIFFUSE(环境光和漫射光)、GL_SPECULAR(平行/镜面光,
	第三个参数是一个四维数组,这个数组描述了反光率的RGBA值,每一项取值都为0-1之间*/
	glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);
	glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat);
	glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess);
	glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

	//首先绘制天花板
	glEnable(GL_TEXTURE_2D);//开启2D纹理功能

	glBindTexture(GL_TEXTURE_2D, texceiling);//绑定纹理
	//glColor3f(0.3, 0.3, 0.3);//设置颜色,黑色
	//glColor3f(255, 255, 255);
	glBegin(GL_QUADS);//画四边形

	glNormal3f(0.0f, -1.0f, 0.0f);//用于定义法线向量
	/*glTexCoord2f绘制图形时指定纹理的坐标,第一个是X轴坐标,0.0是纹理的左侧,0.5是纹理的中点,1.0是纹理的右侧,
	第二个是Y轴坐标,0.0是纹理的底部,0.5是纹理的中点,1.0是纹理的顶部,
	为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,
	纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角,纹理的左上坐标是X:0.0,Y:1.0f,四边形的左上顶点是X:-1.0,Y:1.0。*/
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-40.0f, 30.0f, 30.0f);//四边形的点
	glTexCoord2f(0.0f, 3.0f); glVertex3f(-40.0f, 30.0f, -30.0f);
	glTexCoord2f(6.0f, 3.0f); glVertex3f(40.0f, 30.0f, -30.0f);
	glTexCoord2f(6.0f, 0.0f); glVertex3f(40.0f, 30.0f, 30.0f);
	glEnd();
	glDisable(GL_TEXTURE_2D);


	//................................风扇................................................//
	GLuint m = 0;


	qobj = gluNewQuadric();//初始化二次曲面并创建一个指向二次曲面的指针 

//...............................右边的风扇.............................//
	glPushMatrix();//压入堆栈,保证此处坐标变换不影响外部大环境 
	glTranslatef(20.0, 5.0, -10.0 - 40 * m);  //风扇的位置
	if (TurnOn == TRUE)  //如果TurnOn为1
	{
		fantheta += 10;  //风扇转过的角度fantheta不断增加


	}
	glRotatef(fantheta, 0, 1, 0);        //风扇旋转



	glPushMatrix();//压入堆栈
	glColor3f(0.7, 0.7, 0.7);

	glTranslatef(0, 20, 0.0);//平移变换
	glScalef(1, 0.05, 1);//缩放变换
	glRotatef(240, 0, 1, 0);//绕y周旋转240度	
	gluCylinder(qobj, 1, 3, 10, 20, 20);//绘制一个底面圆半径为1、顶面圆半径为2、高为10的圆锥体
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);//定义材质光照
	glPopMatrix();//弹出堆栈
//.............风扇的杆...........................//

	glPushMatrix();//压入堆栈
	glTranslatef(0, 33, 0.0);//平移变换
	glRotatef(90, 1, 0, 0);//缩放变换
	gluCylinder(qobj, 0.5, 0.5, 13, 10, 10);//绘制一个半径为0.5、高为13的圆锥体
	glPopMatrix();//弹出堆栈

	glPopMatrix();//弹出堆栈

//................左边的风扇...........................................//

	glPushMatrix();
	glTranslatef(-20.0, 5.0, -10.0 - 40 * m);
	if (TurnOn == TRUE)
	{
		fantheta += 10;

	}

	glRotatef(fantheta, 0, 1, 0);
	//..........风扇中间的扁圆形....................//

	glPushMatrix();//风扇中间的扁圆形
	glColor3f(0.7, 0.7, 0.7);
	glTranslatef(0.0, 20.0, 0.0);
	glScalef(1, 0.3, 1);
	gluSphere(qobj, 2, 20, 20);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
	glPopMatrix();
	//............风扇旋转120度的扇叶...............//		

	glPushMatrix();//风扇旋转120度的扇叶
	glColor3f(0.7, 0.7, 0.7);
	glTranslatef(0, 20, 0.0);
	glScalef(1, 0.05, 1);
	glRotatef(120, 0, 1, 0);
	gluCylinder(qobj, 1, 3, 10, 20, 20);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
	glPopMatrix();
	//............风扇不做旋转的扇叶.................//

	glPushMatrix();//风扇不做旋转的扇叶
	glColor3f(0.7, 0.7, 0.7);
	glTranslatef(0, 20, 0.0);
	glScalef(1, 0.05, 1);
	gluCylinder(qobj, 1, 3, 10, 20, 20);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
	glPopMatrix();
	//.............风扇旋转240度的扇叶...............//

	glPushMatrix();//风扇旋转240度的扇叶
	glColor3f(0.7, 0.7, 0.7);
	glTranslatef(0, 20, 0.0);
	glScalef(1, 0.05, 1);
	glRotatef(240, 0, 1, 0);
	gluCylinder(qobj, 1, 3, 10, 20, 20);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_Diffuse);
	glPopMatrix();
	//.............风扇的杆...........................//

	glPushMatrix();
	glTranslatef(0, 33, 0.0);
	glRotatef(90, 1, 0, 0);
	gluCylinder(qobj, 0.5, 0.5, 13, 10, 10);
	glPopMatrix();
	glPopMatrix();




	

	//绘制黑板
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texblackboard);
	glBegin(GL_QUADS);
	glNormal3f(0.0f, 0.0f, 1.0f); //用于定义法线向量
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-20.0, 8.0f, -29.9f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-20.0, 18.0f, -29.9f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(20.0, 18.0f, -29.9f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(20.0, 8.0f, -29.9f);
	glEnd();
	glDisable(GL_TEXTURE_2D);

	//画黑板上方的灯
	GLfloat blacklight[] = { 0.9,0.9,0.9,1 };//颜色(R,G,B,A),A仅用于颜色混合函数激活之后
	glColor3f(1.0f, 1.0f, 1.0f);
	//glColor3f(255, 255, 255);
	glPushMatrix();//把当前的模型视图矩阵压入堆栈中保存下来
	glTranslatef(-15, 20.4, -29.5);//平移函数,参数含义:位移
	glScalef(8.0f, 0.8, 1.0f);//缩放函数,参数含义:倍数
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blacklight);
	glutSolidCube(1.0f);//绘制边长为1的实心立方体,立方体的中心位于原点
	glPopMatrix();
	glPushMatrix();
	glTranslatef(12, 20.4, -29.5);
	glScalef(8.0f, 0.8, 1.0f);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blacklight);
	glutSolidCube(1.0f);
	glPopMatrix();
	//绘制教室前边一块高地并贴纹理
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texhighland);
	//贴上面
	glBegin(GL_QUADS);
	glNormal3f(0.0f, 1.0f, 0.0f); //用于定义法线向量
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -30.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f, 1.5f, -30.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f, 1.5f, -22.0f);
	glEnd();
	//贴左边
	glBegin(GL_QUADS);
	glNormal3f(0.0f, 0.0f, 1.0f); //用于定义法线向量
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 0, -22.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -30.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(-30.0f, 0, -30.0f);
	glEnd();
	//贴前边
	glBegin(GL_QUADS);
	glNormal3f(0.0f, 1.0f, 0.0f); //用于定义法线向量
	glTexCoord2f(0.0f, 0.0f); glVertex3f(-30.0f, 0, -22.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(-30.0f, 1.5f, -22.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(30.0f, 1.5f, -22.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(30.0f, 0, -22.0f);
	glEnd();

	//glColor3f(255, 255, 255);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, texdoor);
	glBegin(GL_QUADS);
	glNormal3f(-1.0f, 0.0f, 0.0f); //用于定义法线向量
	glTexCoord2f(0.0f, 0.0f); glVertex3f(39.9f, 0.0f, -25.0f);
	glTexCoord2f(0.0f, 1.0f); glVertex3f(39.9f, 14.0f, -25.0f);
	glTexCoord2f(1.0f, 1.0f); glVertex3f(39.9f, 14.0f, -19.0f);
	glTexCoord2f(1.0f, 0.0f); glVertex3f(39.9f, 0.0f, -19.0f);
	glEnd();
	glDisable(GL_TEXTURE_2D);
	//绘制音响
	glColor3f(0.0f, 0.0f, 0.0f);
	//glColor3f(255, 255, 255);
	glPushMatrix();
	glTranslatef(-37.5, 26.25f, -5.5f);
	glScalef(1.0f, 1.5f, 1.0f);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sound);
	glutSolidCube(1.0f);
	glPopMatrix();
	glPushMatrix();
	glTranslatef(37.5, 26.25f, -5.5f);
	glScalef(1.0f, 1.5f, 1.0f);
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sound);
	glutSolidCube(1.0f);
	glPopMatrix();



}
/**************************************绘制投影仪***********************************************/
void drawprojector()
{
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(1.0f, 0.0f, 1.0f); //用于定义法线向量
	glVertex3f(-40.0f, 30.0f, -30.0 + 10 * sqrt(2));
	glVertex3f(-40.0 + 10 * sqrt(2), 30.0f, -30.0f);//固定的两个点
	glVertex3f(-40.0 + 10 * sqrt(2), pro_up_down, -30.0f);
	glVertex3f(-40.0f, pro_up_down, -30.0 + 10 * sqrt(2));//下降或升起时改变的点
	glEnd();
	glColor3f(0.0f, 0.0f, 0.0f);
	glLineWidth(4.0f);
	glBegin(GL_LINES);
	glVertex3f(-25.0f, 30.0f, -15.0f);
	glVertex3f(-25.0f, 25.0f, -15.0f);
	glEnd();
	glColor3f(0.5f, 0.5f, 0.5f);
	glPushMatrix();
	glTranslatef(-25.0f, 24.0f, -15.0f);
	glScalef(4.0f, 2.0f, 2.0f);
	glutSolidCube(1.0f);
	glPopMatrix();
	glColor3f(0.0, 0.0, 0.0);
	glBegin(GL_LINE_LOOP);//给出的点会绘制为一个环(所有的点首尾相接)
	glVertex3f(-40.0f, 30.0f, -30.0 + 10 * sqrt(2));
	glVertex3f(-40.0 + 10 * sqrt(2), 30.0f, -30.0f);

	}
}
//绘制椅子
void drawchairs()
{
	GLfloat chair[] = { 1.0f, 1.0f, 0.45f, 1.0f };// { 0.1, 0.67, 0.62 };
	for (int j = 0; j <= 4; j++)
	{
		for (int i = 0; i <= 1; i++)
		{
			//画椅子底部
			glColor3f(0.1, 0.67, 0.62);
			glPushMatrix();
			glTranslatef(-20 + i * 40, 3.1, -14.5 + j * 8);
			glScalef(10, 0.2, 3);
			glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, chair);
			glutSolidCube(1.0f);
			glPopMatrix();
			//画椅子靠背
			glColor3f(0.1, 0.67, 0.62);
			glPushMatrix();
			glTranslatef(-20 + i * 40, 5, -13 + j * 8);
			glScalef(10, 4, 0.2);
			glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, chair);
			glutSolidCube(1.0f);
			glPopMatrix();
			//画椅子腿
			glColor3f(0.0, 0.0, 0.0);
			glBegin(GL_LINES);
			glLineWidth(3.0f);
			glVertex3f(-25 + i * 40, 3.0f, -13 + j * 8);
			glVertex3f(-25 + i * 40, 0.0f, -13 + j * 8);
			glEnd();
			glColor3f(0.0, 0.0, 0.0);
			glBegin(GL_LINES);
			glLineWidth(3.0f);
			glVertex3f(-15.0 + i * 40, 3.0f, -13 + j * 8);
			glVertex3f(-15.0 + i * 40, 0.0f, -13 + j * 8);
			glEnd();
			glColor3f(0.0, 0.0, 0.0);
			glBegin(GL_LINES);
			glLineWidth(3.0f);
			glVertex3f(-25.0 + i * 40, 0.0f, -12.5 + j * 8);
			glVertex3f(-25 + i * 40, 0.0f, -13.5 + j * 8);
			glEnd();
			glColor3f(0.0, 0.0, 0.0);
			glBegin(GL_LINES);
			glLineWidth(3.0f);
			glVertex3f(-15 + i * 40, 0.0f, -12.5 + j * 8);
			glVertex3f(-15 + i * 40, 0.0f, -13.5 + j * 8);
			glEnd();



/*******************************************响应普通键盘操作,w,s,a,d以及退出esc键*******************************/
GLvoid OnKeyboard(unsigned char key, int x, int y)
{
	switch (key)
	{
	case 97://a 向左
		myEye.x -= 0.5;
		vPoint.x -= 0.5;
		if (myEye.x <= -38)
			myEye.x = -38;
		break;
	case 100://d 向右
		myEye.x += 0.5;
		vPoint.x += 0.5;
		if (myEye.x >= 38)
			myEye.x = 38;
		break;
	case 119://w 向前
		myEye.z -= 0.5;
		if (myEye.z <= -28)
			myEye.z = -28;
		break;
	case 115://s 向后
		myEye.z += 0.5;
		if (myEye.z >= 28)
			myEye.z = 28;
		break;
	case 27://esc
		exit(0);

	}
	reshape(WinWidth, WinHeight);//窗口刷新
	glutPostRedisplay();

}
/****************************************响应特殊键盘操作******************************************************/
GLvoid OnSpecial(int key, int x, int y)//上下左右
{
	switch (key)
	{
	case GLUT_KEY_LEFT:
		vAngle -= 0.05;
		break;
	case GLUT_KEY_RIGHT:
		vAngle += 0.05;
		break;
	case GLUT_KEY_UP:
		myEye.y += 0.05;
		if (myEye.y >= 30)
			myEye.y = 30;

		break;
	case GLUT_KEY_DOWN:
		myEye.y -= 0.5;
		if (myEye.y <= 0)
			myEye.y = 30;
		break;
	case GLUT_KEY_PAGE_DOWN://PageDown键
		myEye.z += 0.5;
		if (myEye.z >= 30)
			myEye.z = 30;
		break;
	case GLUT_KEY_PAGE_UP://PageUp键
		myEye.z -= 0.5;
		if (myEye.z <= -30)
			myEye.z = -30;
		break;
	case GLUT_KEY_F1:
		projectup();
		break;
	case GLUT_KEY_F2:
		projectdown();
		break;
	case GLUT_KEY_F3:
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
		glEnable(GL_LIGHT1);
		break;
	case GLUT_KEY_F4:
		//glDisable(GL_TEXTURE_2D);
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glDisable(GL_LIGHT1);
		break;
	case GLUT_KEY_F5:
		TurnOn = true;
		break;
	case GLUT_KEY_F6:
		TurnOn = false;
		break;
	}
	reshape(WinWidth, WinHeight);
	glutPostRedisplay();
}
GLvoid OnIdle()
{
	glutPostRedisplay();// 重画
	//当回调函数处理完键盘事件后,显示函数会自动被调用,屏幕会被重绘.这样,GLUT程序会过于频繁的调用显示函数,抢占cpu资源
	//选择性的告诉GLUT去调用显示函数(glutPostRedisplay函数会标记当前窗体来重新显示)
	//目的:节省cpu资源,保持我们的GLUT程序的占用行为不生效.
}
/*************************************初始化函数,对各项参数进行初始化*********************************************/
void initial()
{
	glClearColor(0, 0, 0, 0);
	glEnable(GL_TEXTURE_2D);

	/*设置纹理跟材质的融合方式,这里是只是用纹理,覆盖模型的材质*/
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	/*********************************************对灯光进行初始化****************************************************/
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model_ambient);//将背景光设定为全局值
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);//把无限远的观察点改为局部观察点
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);//指定物体前面镜面反射的颜色
	glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);//指定物体前面镜面反射的指数
	/*设置点光源*/
	/*GL_POSITION指定光源位置,GL_AMBIENT表示各种光线照射到该材质上,经过很多次反射后最终遗留在环境中的光线强度(颜色),
	对背景(环境)光有贡献。GL_DIFFUSE表示光线照射到该材质上,经过漫反射后形成的光线强度(颜色)。
	GL_SPECULAR表示光线照射到该材质上,经过镜面反射后形成的光线强度(颜色)。通常,GL_AMBIENT和GL_DIFFUSE都取相同的值,
	可以达到比较真实的效果。使用GL_AMBIENT_AND_DIFFUSE可以同时设置GL_AMBIENT和GL_DIFFUSE属性。*/
	/*glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
	glLightfv(GL_LIGHT0, GL_AMBIENT, mat_ambient);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, light);
	glLightfv(GL_LIGHT0, GL_SPECULAR, light);*/

	/*设置平行光源*/
	glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
	glLightfv(GL_LIGHT1, GL_AMBIENT, mat_ambient);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, white_light);
	glLightfv(GL_LIGHT1, GL_SPECULAR, white_light);


	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT1);
	glEnable(GL_COLOR_MATERIAL);//激活

	/**********************************************************************************************/
	/*glShadeModel函数用于控制opengl中绘制指定两点间其他点颜色的过渡模式,
	GL_SMOOTH(默认)将制定的两点颜色进行插值,绘制之间的其他点*/
	glShadeModel(GL_SMOOTH);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);	//指定材料着色的面
	//glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);	//指定材料对镜面光的反射
	glEnable(GL_DEPTH_TEST);//	
}
void print()
{
	printf("**************************************************** \n");
	printf(" \n");
	printf("操作按键信息提示: \n");
	printf("上键和下键分别控制视角向下和向上 \n");
	printf("左键和右键分别控制向左环视和向右环视 \n");
	printf("w,s,a,d键分别表示向前,后,左,右,进行平移(注意键盘大小写)\n");
	printf("pgup和pgdn分别控制向前漫游和向后漫游 \n");
	printf("F5、F6键分别控制风扇的开、关 \n");
	printf("F3、F4键分别控制开灯、关灯 \n");
	printf("F1、F2键分别控制投影仪放下和收起 \n");
	printf("ESC键退出窗口 \n");
	printf(" \n");

}
int main(int argc, char* argv[])
{
	myEye.x = 0;
	myEye.y = 15;
	myEye.z = 25;
	vPoint.x = 0;
	vPoint.y = 15;
	vPoint.z = -30;
	up.x = 0;
	up.y = 1;
	up.z = 0;
	vAngle = 0;
	/*启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,
	如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层。*/
	glEnable(GL_DEPTH_TEST);
	glutInit(&argc, argv);
	/*定义显示方式,GLUT_RGBA指定一个RGBA窗口,GLUT_SINGLE.单缓冲区窗口*/
	glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE);

	glutInitWindowPosition(400, 0);//设置初始窗口的位置(窗口左上角相对于桌面坐标(x,y))
	glutInitWindowSize(800, 600);//设置窗口大小
	glutCreateWindow("classroom");
	initial();//创建显示窗口
	SetupRC();//(2)
	glutDisplayFunc(&myDisplay);
	glutTimerFunc(1000, timerFunc, 1);//(1)
	//glutDisplayFunc(&myDisplay);//注册显示回调函数,包含重绘场景所需的所有代码
	glutReshapeFunc(reshape);//注册窗口改变回调函数
	glutKeyboardFunc(OnKeyboard);//注册键盘响应事件
	//对键盘上特殊的4个方向按键的响应函数
	glutSpecialFunc(OnSpecial);
	glutIdleFunc(OnIdle);//注册闲置响应函数,该函数调用放在主程序main()中,通常利用它可实现简单动画。
	///***************************************设置纹理***********************************************/
	texblackboard = load_texture("blackboard.bmp");
	texwindow = load_texture("window.bmp");
	texsound = load_texture("sound.bmp");
	texceiling = load_texture("ceiling.bmp");
	texdoor = load_texture("door.bmp");
	texfloor = load_texture("floor.bmp");
	texbackwall = load_texture("backwall.bmp");
	texpole = load_texture("pole.bmp");
	texairfro = load_texture("airconditionfront.bmp");
	texairback = load_texture("airconditionback.bmp");
	texhighland = load_texture("gaodi.bmp");
	texsdesk = load_texture("sdesk.bmp");
	texclock = load_texture("clock.bmp");
	///************************************************************************************************/
	print();
	//开始显示
	glutMainLoop();//进入事件处理循环
	return 0;
}

运行结果如下:

 



这篇关于C++ VS OpenGL绘制教室三维立体旋转图像的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程