计算机图形学opengl温暖的房间

简介

我的主页www.lovemaiow.top

只使用glut库

实现空中半岛的一座房子,可通过键盘移动

有播放音乐功能

有演示视频,设计文档

效果

演示视频

2023-12-14 22-27-41

部分代码


//***************************************************^^^**********************************************************//
//*********************************************<__音乐效果__>*****************************************************//
//***************************************************  ***********************************************************//
void bgm() {
	MCI_OPEN_PARMS op;
	op.dwCallback = NULL;
	op.lpstrAlias = NULL;
	op.lpstrDeviceType = L"MPEGAudio";			//mp3格式
	op.lpstrElementName = L"res/loveHome.wav";			//文件名
	op.wDeviceID = NULL;
	MCI_PLAY_PARMS pp;							//
	pp.dwCallback = NULL;
	pp.dwFrom = 0;								//文件开头

	UINT rs;
	rs = mciSendCommand(NULL, MCI_OPEN, MCI_OPEN_ELEMENT, (DWORD)&op);

	if (rs == 0)
	{
		MCI_PLAY_PARMS pp;
		pp.dwCallback = NULL;
		pp.dwFrom = 0;
		//设备ID 播放 
		mciSendCommand(op.wDeviceID, MCI_PLAY, MCI_NOTIFY, (DWORD)&pp);
	}

}

//***************************************************^^^**********************************************************//
//*********************************************<__装载纹理图__>***************************************************//
//***************************************************  ***********************************************************//
void loadTexture(const char* filename, GLuint& texture)// 根据位图文件的名称进行加载

{
	static GLint    ImageWidth;
	static GLint    ImageHeight;
	static GLint    PixelLength;
	static GLubyte* PixelData;
	// 打开文件
	FILE* pFile = fopen(filename, "rb"); // 文件指针
	if (pFile == 0)  // 如果没有指定位图文件名称就退出
		exit(0);
	// 读取24位bmp图象的大小信息
	fseek(pFile, 0x0012, SEEK_SET);//文件指针指向文件的开头图象的宽度和高度都是一个32位整数,在文件中的地址分别为0x0012和0x0016,于是我们可以使用以下代码来读取图象的大小信息:移动到0x0016位置
	// 由于上一句执行后本就应该在0x0016位置
	fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);//把文件内的宽度数据存放给imagewidth
	fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);
	PixelLength = ImageWidth * 3;	// 计算像素数据长度
	while (PixelLength % 4 != 0)	//bmp图像保证数据区域的长度是4的倍数,满足对齐规则要求每行的数据的长度必须是4的倍数,如果不够需要进行比特填充(以0填充),这样可以达到按行的快速存取。
		++PixelLength;//否则则读取数据过慢
	PixelLength *= ImageHeight;
	// 读取像素数据
	PixelData = (GLubyte*)malloc(PixelLength);	//动态配置缓存
	if (PixelData == 0)	exit(0);
	fseek(pFile, 0, SEEK_SET);
	fread(PixelData, PixelLength, 1, pFile);
	// 关闭文件
	fclose(pFile);
	//加载纹理
	glGenTextures(1, &texture);//用来生成纹理的数量   存储纹理索引的第一个元素指针

	glBindTexture(GL_TEXTURE_2D, texture);//绑定(指定)纹理对象将生成的纹理的名称绑定到指定的纹理上
	//纹理的定义函数
	glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, PixelData);
	//
	//纹理的控制函数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);		//纹理过滤函数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  //多个像素对一个纹素
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


	//生成一个2D纹理(Texture)。bmp图片的像素顺序是BGR所以用GL_BGR_EXT来反向加载数据
}
//室内光照
void lightinit(double x, double y)
{
	//材质反光性设置
	GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };  //镜面反射参数
	GLfloat mat_shininess[] = { 50.0 };               //高光指数
	GLfloat light_position[] = { Ox, Oy, Oz - 10, 1.0 };//灯位置(1,1,1), 最后1-开关
	GLfloat white_light[] = { 1, 1, 1, 1.0 };
	GLfloat Light_Model_Ambient[] = { 0.2 , 0.2 , 0.2 , 1.0 }; //环境光参数
	//环境反射光,漫反射光,镜面反射光
	glLightfv(GL_LIGHT0, GL_POSITION, light_position);//光源位置
	glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);   //散射光属性
	glLightfv(GL_LIGHT0, GL_SPECULAR, white_light);  //镜面反射光

	//光照材质
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Light_Model_Ambient);  //环境光参数

	if (light) {
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);//触发事件/
	}
	else {
		glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);//只用纹理,这里用GL_MODULATE,GL_DECAL和GL_BLEND
	}
	glEnable(GL_LIGHTING);   //开关:使用光
	glEnable(GL_LIGHT0);     //打开0#灯
	glEnable(GL_DEPTH_TEST); //打开深度测试
}

//地球旋转
void spinDisplay(void)
{
	std::cout << "spin" << spin << std::endl;
	spin = spin + 0.08;
	if (spin > 360.0)
	{
		spin = spin - 360.0;
	}
	glutPostRedisplay();//glutPostRedisplay 标记当前窗口需要重新绘制。通过glutMainLoop下一次循环时,窗口显示将被回调以重新显示窗口的正常面板
}

//初始化
GLUquadricObj* g_text;//曲面,制作一个包围房间的大球体做背景
void init(void)

{
	srand(unsigned(time(nullptr)));//产生不变的随机数
	glClearColor(0.0, 0.0, 0.0, 0.0);//清除颜色缓冲区,设置颜色
	glShadeModel(GL_FLAT);//设置着色模式 GL_FLAT 恒定着色,GL_SMOOTH光滑着色

	g_text = gluNewQuadric();//做月球地球这句代码需放置在绘图及显示之前定义新的二次曲面对象
	//装载位图
	loadTexture("res/red.bmp", color[0]);
	loadTexture("res/blue.bmp", color[1]);
	loadTexture("res/black.bmp", color[2]);
	loadTexture("res/wall.bmp", textureVector[0]);
	loadTexture("res/earth.bmp", textureVector[1]);
	loadTexture("res/sky.bmp", textureVector[2]);
	loadTexture("res/floor.bmp", textureVector[3]);
	loadTexture("res/bottom.bmp", textureVector[4]);
	loadTexture("res/windows.bmp", textureVector[5]);
	loadTexture("res/theGirlFir.bmp", textureVector[6]);
	loadTexture("res/theGirlSec.bmp", textureVector[7]);
	loadTexture("res/theGirlTir.bmp", textureVector[8]);
	loadTexture("res/richMan.bmp", textureVector[9]);
	loadTexture("res/bedSidePho.bmp", textureVector[10]);
	loadTexture("res/mod.bmp", textureVector[11]);
	loadTexture("res/beizi.bmp", textureVector[12]);
	loadTexture("res/zt.bmp", textureVector[13]);
	loadTexture("res/lak.bmp", textureVector[14]);
	loadTexture("res/roomBiZhiFir.bmp", textureVector[15]);
	loadTexture("res/roomBiZhiSec.bmp", textureVector[16]);

}

//贴图函数
//左右面
void mapLeftAndRight(float m, float n, float x, float y1, float y2, float z1, float z2) {

	glBegin(GL_QUADS);//纹理对应平面
	glTexCoord2f(0.0, 0.0); glVertex3f(x, y1, z1);
	glTexCoord2f(0.0, n); glVertex3f(x, y1, z2);
	glTexCoord2f(m, n); glVertex3f(x, y2, z2);
	glTexCoord2f(m, 0.0); glVertex3f(x, y2, z1);
	glEnd();
}
//前后面
void mapBeforeAndBack(float m, float n, float x1, float x2, float y, float z1, float z2) {

	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0); glVertex3f(x1, y, z1);
	glTexCoord2f(0.0, n); glVertex3f(x1, y, z2);
	glTexCoord2f(m, n); glVertex3f(x2, y, z2);
	glTexCoord2f(m, 0.0); glVertex3f(x2, y, z1);
	glEnd();
}
//上下面
void mapUpAndDown(float m, float n, float x1, float x2, float y1, float y2, float z) {

	glBegin(GL_QUADS);
	glTexCoord2f(0.0, 0.0); glVertex3f(x1, y1, z);
	glTexCoord2f(0.0, n); glVertex3f(x1, y2, z);
	glTexCoord2f(m, n); glVertex3f(x2, y2, z);
	glTexCoord2f(m, 0.0); glVertex3f(x2, y1, z);
	glEnd();
}
//--------------------------------------------------------------------------------------------------------------


//---------------------------------------------菜单响应制作-----------------------------------------------------
#define START 1
int flag = 1;
//当点击菜单时,调用回调函数 func,value 为传递给回调函数的数值,它由所选择的菜单条目对应 的整数值所决定。
void processMenuEvents(int option)
{
	//option,就是传递过来的 value 的值。
	switch (option) {
	case START:
		bgm();
		break;
	}
}

void createGLUTMenus()
{
	int menu;
	// 创建菜单并告诉 GLUT,processMenuEvents 处理菜单事件。
	menu = glutCreateMenu(processMenuEvents);
	//给菜单增加条目
	glutAddMenuEntry("哎呦~", START);
	// 把菜单和鼠标右键关联起来。
	glutAttachMenu(GLUT_RIGHT_BUTTON);
}


//-----------------------------------------------------------------------------------------------------------------
void tip() {
	std::cout << std::endl
		<< "         _       __  ______  __     ______  ____    __  ___  ______              " << std::endl
		<< "        | |     / / / ____/ / /    / ____/ / __ \\  /  |/  / / ____/             " << std::endl
		<< "        | | /| / / / __/   / /    / /     / / / / / /|_/ / / __/                 " << std::endl
		<< "        | |/ |/ / / /___  / /___ / /___  / /_/ / / /  / / / /___                 " << std::endl
		<< "        |__/|__/ /_____/ /_____/ \\____/  \\____/ /_/  /_/ /_____/               " << std::endl << std::endl;
	std::cout << "  ///" << std::endl
		<< "  ///**************************** Welcom to OurRoom! ************************" << std::endl
		<< "  ///**************************** Copyright by LIU **************************" << std::endl
		<< "  ///**************************** makeBy:loveMiaoW **************************" << std::endl
		<< "  ///**************************** email:LIU_RUI@163.com *********************" << std::endl
		<< "  ///****************************** 操作说明 ********************************" << std::endl
		<< "  ///**************************** 按键 A 更改光线强度  **********************" << std::endl
		<< "  ///**************************** 空格 space 旋转  **************************" << std::endl
		<< "  ///**************************** 鼠标右键播放音乐 **************************" << std::endl
		<< "  ///**************************** 上下键前进后退,左右键转头,WS上升下降 ****" << std::endl
		<< "  ///********* 项目地址: https://github.com/loveMiaoW/loveMiaoW.git *********" << std::endl
		<< "  ///" << std::endl << std::endl;

	std::cout
		<< "	//" << std::endl
		<< "	///                    _ooOoo_                                 ///" << std::endl
		<< "	///                   o8888888o                                ///" << std::endl
		<< "	///                    88 . 88                                 ///" << std::endl
		<< "	///                  (| ^ _ ^ | )                              ///" << std::endl
		<< "	///                    O = / O                                 ///" << std::endl
		<< "	///                ____ / `---'____                            ///" << std::endl
		<< "	///               .'  \|     |//  `.|                          ///" << std::endl
		<< "	///               / \|||  :  |||//| |                             " << std::endl
		<< "	///              / _||||| -:-|||||_-                           ///" << std::endl
		<< "	///              |   | \ -  /// |   |                             " << std::endl
		<< "	///             | _ | ''-- - / ''  |   |                       ///" << std::endl
		<< "	///             . - __  `-`  ___ / -. /                        ///" << std::endl
		<< "	///            ___`. .'  /--.--  `. . ___                      ///" << std::endl
		<< "	///          ."" '<  `.____<|>_/___.'  > '" ".                    " << std::endl
		<< "	///        | | :  `- `.; ` _ / `;.`/ - ` : | |                 ///" << std::endl
		<< "	///            `-._ __ / __ _ / . - ` /  /                     ///" << std::endl
		<< "	/// ========`-.____`-.________ / ___. - `____. - '========     ///" << std::endl
		<< "	///                     `=-- -='                               ///" << std::endl
		<< "	///  ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ///" << std::endl
		<< "	///       ^ 佛祖保佑       永不宕机       永无BUG ^            ///" << std::endl
		<< "	///  ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ///" << std::endl
		<< "	//" << std::endl;
}
//-----------------------------------------------------------------------------------------------------------------

下载链接

https://pan.baidu.com/s/1dptZ__PLIZFEH6BkyPwySg?pwd=1415

qq:652455342

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: C语言OpenGL大作业是一个通过使用C语言结合OpenGL图形库来实现的作业项目。这个项目的目的是让学生们在实践中加深对C语言计算机图形学的理解,提高编程能力和图形渲染技术。 具体而言,C语言是一种高级编程语言,而OpenGL是一种跨平台的图形库,用于渲染2D和3D图形。在这个大作业中,学生们需要利用C语言中的编程技巧来实现一些图形学的基本功能,如绘制简单的图形、处理用户交互输入、实现基本的光照效果等等。 在完成C语言OpenGL大作业时,学生们可能需要遵循一些基本步骤。首先,他们需要学习和理解C语言OpenGL库的基本知识,包括语法、图形学概念、图形渲染流程等。接下来,他们需要设计并实现自己的图形方案,包括场景的搭建、图形对象的绘制和变换等。在完成代码之后,他们会编译和运行程序,并通过调试和测试来确保其正常运行和效果达到预期。 对于C语言OpenGL大作业的评估标准则通常基于项目的完成度、代码质量和效率等方面进行。学生的代码应具有良好的结构和可读性,遵循编程规范,并能够正确地展示所学知识和技术的应用。 总之,C语言OpenGL大作业是一个能够帮助学生们深入理解C语言和图形学的重要项目。通过该项目,学生们能够锻炼编程能力、加深对图形学概念的理解,并在实践中体会编写复杂程序的过程。 ### 回答2: C语言OpenGL大作业是一项学术项目,要求学生运用C语言编写OpenGL程序,展示对图形学知识的理解和应用。这个作业通常涉及到图形渲染,光照效果,纹理映射,矩阵变换等技术的运用。 在做这个大作业之前,学生需要系统学习C语言OpenGL图形库的基础知识。他们需要掌握OpenGL的核心概念,如窗口创建、三维投影、相机控制等。此外,还需要理解OpenGL管线的工作原理,包括顶点着色器、片段着色器、几何着色器等的作用。 大作业的具体要求可能会因教师的要求或课程的不同而有所不同。学生通常会选择一个主题或场景进行展示,比如一个3D游戏的场景、一个建筑模型或一个动场景。在实现这个主题或场景时,学生需要运用所学的技术来创建和渲染3D模型,添加光照效果和纹理,实现相机控制和用户交互等。 在完成大作业的过程中,学生将会面临一些挑战和困难。首先,他们需要深入理解图形学的原理和算法,并将其转化为C语言代码。其次,他们还需要熟悉OpenGL的各种函数和接口,能够正确地调用它们来实现所需的功能。此外,学生还需要有良好的代码设计和调试能力,以便有效地组织和管理程序的结构和逻辑。 总结起来,C语言OpenGL大作业是一项考验学生图形学和编程能力的重要任务。通过完成这个作业,学生将能够深入理解图形学的概念和原理,并能够熟练运用C语言OpenGL来实现各种图形效果和交互功能。 ### 回答3: C语言OpenGL大作业是指在使用C语言编写OpenGL程序的一个大型项目。OpenGL是一个强大的图形库,可以实现各种各样的图形效果和交互性。在这个大作业中,学生通常需要编写一个具有一定复杂度的图形应用程序。 首先,我们需要理解OpenGL的基本原理和使用方法。学生需要掌握OpenGL的各种库函数和技术,如OpenGL窗口创建、图形绘制、光照效果、3D变换等。他们还需要理解图形渲染管线、着色器和顶点缓冲对象等关键概念。 对于大作业的具体主题和要求,可能会有很多选择。例如,学生可以选择实现一个简单的3D游戏,设计一个图形化界面的数据可视化工具,或者开发一个基于OpenGL的图像处理程序。 在开始实际编码之前,学生需要进行一些规划和设计工作。他们需要确定大作业的需求和功能,设计程序的整体结构和模块划分。这些步骤通常可以通过编写一个详细的设计文档和创建一个项目计划来完成。 然后,学生可以开始编写代码。使用C语言编写OpenGL程序需要一定的编程技巧和算法知识。学生需要合理地组织代码,优化性能,并解决可能遇到的各种问题和错误。 最后,学生需要进行测试和调试。他们应该确保程序能够正确运行,并满足预期的需求和功能。在测试过程中,学生可能需要使用一些调试工具和技术,如断点调试和性能分析。 总之,C语言OpenGL大作业是一个涉及图形编程和算法设计的具有挑战性的项目。通过完成这个大作业,学生可以提高他们的编程技能和对图形学的理解,同时也锻炼了他们的逻辑思维和问题解决能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值