OpenGL实现3D游戏编程【连载3】——3D空间模型光照初步

news2024/9/22 1:07:07

1、本节实现的内容

上一节课,我们建立了简单的坐标系,同时也显示了一个正方体,但正方体的颜色为纯红色,好像一个平面物体一样,我们这节课就可以加一些光照,并创建更多的模型,使这些物体变得更加立体一些。更多详见https://blog.csdn.net/zhooyu主页内容。

在这里插入图片描述

2、光照的认识

在OpenGL中光的种类大致可以分为平行光源、点光源和聚光灯光源三种。

2.1、平行光

从他们的名字也很好理解,平行光是从远方照射过来的光,有点类似咱们现实生活中,太阳从远处照过来的光,可以简单的理解为太阳光的每一条光线都是平行照射过来的。平行光最主要的特点,就是在一个场景中多个物体,平行光折射他们的角度基本保持一致,光照面的方向也就一致。

在这里插入图片描述

2.2、点光源

点光源,有点类似于现实生活中的蜡烛🕯,它照射出来的是散射的光,在一个场景中的多个物体,我的位置不同,照射的光面角度也不同,而且会根据与蜡烛的远近距离不同,光线照射的明暗程度也不一样。类似的还有山洞中的火把的效果,人物在黑夜里出行的时候,随着伙伴位置的不停改变,正为物体的光照面也会不停的发生改变,同时火把只能照射到人物周围的物体,离人物距离越近光照效果就越强,离人物距离越远光照强度就越差。

在这里插入图片描述

2.3、聚光灯

聚光灯有点类似于我们现实生活中的手电筒,手电筒照出去的是一个范围光,光照出去只能照到一个大致圆环范围内的物体,而且手电筒的光是有方向的,人们可以不断改变手电筒光照射的方向。同时我们手电筒可以调整光圈的大小,像我们旋转手电筒头,可以让光圈放大或者缩小。

在这里插入图片描述

3、简单平行光的设置

首先我们可以先加一个平行光,当然,这个光可以有不同的颜色,我们这里暂时模拟太阳光,让它产生一个简单白色光。这里要注意一点,GL_POSITION属性的值(x,y,z,w),w为零表示无限远,x/w,y/w,z/w分别表示光源位置。同时,我们这里使用的是GL_LIGHT0号光源,系统默认定义了GL_LIGHT0至GL_LIGHT7号光源供用户使用。


//设置并打开自定义光源

void	OpenLightExample()
{

	//GL_POSITION属性的值(x,y,z,w),w为零表示无限远,x/w,y/w,z/w表示光源位置
	
	GLfloat user_light_position[]={1.0f,1.0f,-1.0f,0.0f};
	
	//GL_AMBIENT光源发出的光,经过非常多次反射,遗留在整个光照环境中的强度(RGBA)
	
	GLfloat user_light_ambient[]={0.2f,0.2f,0.2f,1.0f};
	
	//GL_DIFFUSE光源发出的光,照射到粗糙表面时,经过漫反射所得到的光强度(RGBA)
	
	GLfloat user_light_diffuse[]={1.0f,1.0f,1.0f,1.0f};
	
	//GL_DIFFUSE光源发出的光,照射到光滑表面时,经过镜面反射所得到的光强度(RGBA)
	
	GLfloat user_light_specular[]={1.0f,1.0f,1.0f,1.0f};

	//加载设置
	
	glLightfv(GL_LIGHT0,GL_POSITION,user_light_position);
	
	glLightfv(GL_LIGHT0,GL_AMBIENT,user_light_ambient);
	
	glLightfv(GL_LIGHT0,GL_DIFFUSE,user_light_diffuse);
	
	glLightfv(GL_LIGHT0,GL_SPECULAR,user_light_specular);
	
	//开启光源和光照处理功能
	
	glEnable(GL_LIGHT0);
	
	glEnable(GL_LIGHTING);

}

//关闭光源和光照处理功能
	
void	CloseLightExample()
{
	
	glDisable(GL_LIGHT0);
	
	glDisable(GL_LIGHTING);

}

4、添加平行光

在定义了以上光线操作函数后,我们就可以在任何需要添加光照的地方添加以下代码,由于Opengl是状态机,因此,光照打开后会一直生效,直到关闭相应的光源为止。


			//打开自定义平行光

			OpenLightExample();

			//在此显示的物体将会收到光照影响

			......

			//关闭自定义平行光源

			CloseLightExample();
			

当我们添加我们太阳光后,发现我们的立方体并没有产生背光照的效果,我们的立体模型都变成了灰白色,这主要是我们没有设定物体的材质。就好比我们告诉计算机现在有了光线,但是没有告诉计算机你现在显示的立方体对光照的效果怎样,就是说你的立方体是一个金属反光材质,还是一个毛绒玩具的不反光材质?如果反光材质,它的反光程度有多少,是闪眼睛的那种反光,还是只有轻微反光的效果。

在这里插入图片描述

5、材质问题简单的解决办法

我们这里鉴于让大家能很容易的上手,就先暂时不研究具体的材质问题(嗯,复杂的材质设置会给我们带来更多的光照效果,功能非常强大,我们后期再根据需要进行阐述),我们这里就力求用最简单的语言,最容易理解的方式,去了解整个游戏程序设计的思路,需要更多还可以了解我的主页https://blog.csdn.net/zhooyu。

			//默认打开颜色材质
					
			glEnable(GL_COLOR_MATERIAL);

			//添加显示3D场景物体,如立方体等
			
			......

			//默认打开颜色材质
				
			glDisable(GL_COLOR_MATERIAL);

至此,我们的立方体显示出了应该有的光照效果,立方体各个平面之间产生了比较分明的棱线,圆也出现了渐变的关照效果,特别是正二十面体的不同面效果更漂亮。当然,我们这里并没有介绍法线的概念,光照和法线离不开,但是系统自带的以上模型已经自带法线设置,我们后期遇到具体问题在描述法线的设置和作用。

在这里插入图片描述

我们已经多添加了几个系统自带图形查看光照效果,包括一个圆球体、正二十面体和环状体,这样光照效果就好了很多。以下补充其他立体模型的生成代码:

	//显示球体
					
				glPushMatrix();
				
				glTranslatef(-5,5,0);
				
				glColor3f(0.0f,0.0f,1.0f);
				
				glutSolidSphere(2.0f,30.0f,30.0f);
					
				glPopMatrix();
				
				//显示圆环体
					
				glPushMatrix();
				
				glTranslatef(-3,2,5);
				
				glRotatef(90,1.0f,0.0f,0.0f);
				
				glColor3f(1.0f,0.0f,1.0f);

				glutSolidTorus(0.5f,1.0f,30.0f,30.0f);
					
				glPopMatrix();

				//显示二十面体
					
				glPushMatrix();

				glTranslatef(0,2,0);
				
				glColor3f(0.0f,0.6f,1.0f);

				glutSolidIcosahedron();
					
				glPopMatrix();

6、长方体地面的添加

我们显示了以上物体后,总是没有脚踏实地的,虽然现在有了三维的坐标参照,但是总感觉脚下悬空的。我们还是去创建一个地面,这样可以感觉心里踏实,这里由于没有系统自带的长方体,要自定义创建一个长方体。当然,我们现在加的只是一个感官上的地面,后期还要添加玩家在地面上的碰撞检查,我落在地面上,可以顺着地形的不同不断改变能力的高度,遇到障碍物我无法通过,如果遇到了峡谷,人物也可以自由落体势掉落到峡谷底部,但不会掉落无尽深渊的效果。更多详见https://blog.csdn.net/zhooyu主页内容。


			//显示地面

			if(true)
			{

				//长方体的八个顶点坐标

				int	vertices[8][4]={
					
					{-10,-1,-10},{-10,-1,+10},{+10,-1,+10},{+10,-1,-10},
					
					{-10,-5,-10},{-10,-5,+10},{+10,-5,+10},{+10,-5,-10},
				
				};

				//长方体六个面上顶点显示顺序

				int	indices[6][4]={{3,2,1,0},{0,1,5,4},{1,2,6,5},{2,3,7,6},{3,0,4,7},{4,5,6,7}};
				
				//逐个显示面长方体六个面
				
				for(int i=0;i<6;i++)
				{

					//设置各个面的颜色

					if(i==0)
					{
				
						glColor3f(0.0f,1.0f,0.0f);
					
					}
					else
					{
										
						glColor3f(0.8f,0.5f,0.0f);
					
					}
					
					//显示各个面
					
					glBegin(GL_QUADS);
					
					//显示各个顶点
					
					for(int j=0;j<4;j++)
					{
						
						glVertex3f(vertices[indices[i][j]][0],vertices[indices[i][j]][1],vertices[indices[i][j]][2]);
						
					}
					
					glEnd();
					
				}

			}

这里我们需要显示一个底面积很大,高度不高的长方体,并放置到我们大致脚下的位置。我们先不用VAO和VBO的高级方式,这些高级操作方式可以更有效的操作GPU显存,对我们后期的性能非常重要,随后再详细说明,我们现在用最简单的方式显示。这更多的是为了方便大家查看。

在这里插入图片描述

我们的游戏画面稍微不那么单调,但是我们还需要添加后期的纹理,物体材质,加载上下起伏但平滑的地图模型,加载3D建模制作各种物体模型,操作界面的各种按键、窗口控件,来丰富我们的游戏内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1990413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nvm 切换、安装 Node.js 版本

nvm下载路径 往下拉找到Assets 下载后&#xff0c;找到nvm-setup.exe双击&#xff0c;一直无脑下一步&#xff0c;即可安装成功。 配置环境变量&#xff08;我的是window11&#xff09; 打开任务栏设置–搜环境变量 配置好后&#xff0c;点确定一层一层关闭 windowR 打开控制…

学习C语言第23天(程序环境和预处理)

1. 程序的翻译环境和执行环境 在ANSIC的任何一种实现中&#xff0c;存在两个不同的环境 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境&#xff0c;它用于实际执行代码。 2. 详解编译链接 2.1 翻译环境 每个源文件单独经过编…

音视频剪辑库moviepy及其应用

moviepy是一个用于视频编辑的Python库&#xff0c;可以处理视频和音频文件。其常见用途&#xff1a; 视频剪辑和合并&#xff1a;剪辑/将多个视频文件合并成一个视频。 视频转换&#xff1a;将视频转换为不同的格式&#xff0c;比如将MP4文件转换为GIF。 文字和图形叠加&…

arcgis pro批量修改多个矢量的属性

在arcgis pro中&#xff0c;我想批量修改多个矢量的属性值。 比如&#xff1a; 我有两个要素&#xff1a;2021年县级和2022年县级&#xff0c;它们都有“区划码”、“曾用名”、“备注信息”这两个属性。 现在我想使用arcgis pro的脚本功能&#xff0c;使得2021年县级和2022年县…

凯特与戴安娜两位王妃:风采各异 凯特王妃虽未及婆婆影响力但效仿很有成效

最显而易见的也是必须了解的前提:戴安娜王妃是现任凯特王妃已故的婆婆 不过她们是没有见过面的婆媳,戴安娜王妃去世的那年,凯特才15岁!从阶级来看,当时的课题家族应该没有机会见到戴安娜。 凯特还没有像戴安娜一样对世界产生那么多的影响力 在英国王室的璀璨星空中,凯…

AI人工智能为企业带来的优势及应用例子

自2022年知名大型语言模型及其他 AI 产品面世至今&#xff0c;无论商界、政府以至社会各界都逐渐关注人工智能的发展&#xff0c;并纷纷引入 AI 技术&#xff0c;全球正式踏入人工智能的新纪元。根据 Statista 一份有关全球人工智能软件的数据研究&#xff0c;至2025年预测各国…

uni-app中如何使用日期选择器

uni-app中如何使用日期选择器&#xff0c;分别实现日&#xff0c;月&#xff0c;年 日 <picker mode"date" fields"day">是日的内容</picker> 月 <picker mode"date" fields"month">日期选择器</picker> 年…

Java设计模式(桥接模式)

定义 将抽象部分与它的实现部分解耦&#xff0c;使得两者都能够独立变化。 角色 抽象类&#xff08;Abstraction&#xff09;&#xff1a;定义抽象类&#xff0c;并包含一个对实现化对象的引用。 扩充抽象类&#xff08;RefinedAbstraction&#xff09;&#xff1a;是抽象化角…

软件测试工作流程(三)

软件测试的基本流程 测试需求分析阶段 阅读需求&#xff0c;理解需求&#xff0c;主要就是对业务的学习&#xff0c;分析需求点。参与需求评审会议 – 需求规格说明书测试计划阶段 编写测试计划&#xff0c;参考软件需求规格说明书&#xff0c;项目总体计划&#xff0c;内容包括…

OpenNebula-6.9.80中文详细部署安装

目录 OpenNebula介绍 主要特点 应用场景 一. 虚拟机准备 二. 下载安装 1. 导入yum源 2. 数据库配置 3. 安装包 4. 设置配置 数据存放位置 端口介绍 命令介绍 OpenNebula介绍 OpenNebula 是一个开源的云计算平台&#xff0c;主要用于创建和管理虚拟化环境。它被设…

LVS-NAT

概述 LVS&#xff08;Linux Virtual Server&#xff09;是一种常见的负载均衡技术。LVS允许客户端的请求通过负载均衡器&#xff08;Director Server&#xff09;转发到后端多台服务器&#xff08;Real Servers&#xff09;。在NAT模式下&#xff0c;负载均衡器会修改请求报文的…

Sqlilabs靶场报错注入:less1~6

报错注入&#xff1a; less-1&#xff1a;报错后的GET单引号字注入 首先做SQL注入&#xff0c;需要知道注入参数是什么&#xff0c;不是所有的参数都是id&#xff0c;也能是file等等。判断注入点&#xff0c;注入点很重要&#xff0c;如果找不到注入的地方&#xff0c;测试什么…

如何避免项目发布后用户从浏览器WebPack中看到源码

打包前在config->index.js中设置productionSourceMap为false productionSourceMap: false,

【Hive】学习笔记

Hive学习笔记 【一】Hive入门【1】什么是Hive【2】Hive的优缺点&#xff08;1&#xff09;优点&#xff08;2&#xff09;缺点 【3】Hive架构原理&#xff08;1&#xff09;用户接口&#xff1a;Client&#xff08;2&#xff09;元数据&#xff1a;Metastore&#xff08;3&…

Augmentation for small object detection

Abstract 我们对MS COCO数据集上的当前最先进模型Mask-RCNN进行了分析。我们发现小物体的ground-truth与预测的锚框之间的重叠远远低于预期的IoU阈值。我们推测这是由两个因素造成的&#xff1a;&#xff08;1&#xff09;只有少数图像包含小物体&#xff0c;&#xff08;2&am…

英特尔18A制程技术分析解读

#### 引言 尽管第二季度净亏损16亿美元以及大规模裁员计划引发了一些担忧&#xff0c;英特尔还是在8月6日宣布了其下一代18A制程技术取得重大里程碑的消息&#xff0c;并计划在2025年开始生产。 #### 技术进展 - **里程碑**&#xff1a;英特尔表示&#xff0c;这一里程碑是在…

IoTDB组件AI Node发布9个月,如何使用你了解了吗?

数据 x AI &#xff0c;第一批用户已认可&#xff01; 在工业智能化转型中&#xff0c;时序数据库与 AI 技术的结合对故障和异常预测场景的准确性和效率至关重要&#xff0c;逐渐成为行业前沿关注热点。在此方面&#xff0c;IoTDB 已迈出支持 AI 深度分析的重要一步&#xff0c…

240806-在Linux/RHEL开机中自动启动bash脚本

A. 常规方法 要在Red Hat Enterprise Linux (RHEL) 中设置开机启动的bash脚本&#xff0c;可以使用以下方法之一&#xff1a; 方法1&#xff1a;使用/etc/rc.d/rc.local 打开/etc/rc.d/rc.local文件&#xff1a; sudo vi /etc/rc.d/rc.local在文件末尾添加你想要执行的bash脚…

Plus机型成为历史?iPhone 17系列带来全新阵容

苹果公司一直以来都是科技创新的领航者&#xff0c;每一次新品发布都会引发全球消费者的热烈关注。据最新消息&#xff0c;苹果计划于2024年秋季推出全新的iPhone 17系列&#xff0c;这一代iPhone将以其独特的设计、卓越的性能和创新的功能再次刷新人们对智能手机的认知。 一、…

【算法设计题】基于front、rear和count的循环队列初始化、入队和出队操作,第6题(C/C++)

目录 第3题 基于front、rear和count的循环队列初始化、入队和出队操作 得分点&#xff08;必背&#xff09; 题解&#xff1a;基于front、rear和count的循环队列初始化、入队和出队操作 数据结构定义 代码解答 详细解释 1. 循环队列初始化 2. 循环队列入队 3. 循环队列…