当前位置: 首页 > news >正文

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

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建模制作各种物体模型,操作界面的各种按键、窗口控件,来丰富我们的游戏内容。

相关文章:

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

1、本节实现的内容 上一节课&#xff0c;我们建立了简单的坐标系&#xff0c;同时也显示了一个正方体&#xff0c;但正方体的颜色为纯红色&#xff0c;好像一个平面物体一样&#xff0c;我们这节课就可以加一些光照&#xff0c;并创建更多的模型&#xff0c;使这些物体变得更加…...

Python 进行反射和元编程

反射和元编程是Python中两种强大且高级的编程技术。反射允许程序在运行时检查和修改自身结构和行为&#xff0c;而元编程则是编写可以操作其他代码的代码&#xff0c;通常通过使用元类、装饰器等技术来实现。 1. 反射 反射是指程序在运行时检查和操作自身结构的能力。Python通…...

Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N]……解决

一、问题 Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.二、解决方案 1、当打包构建的时候出现这个问题&#xff0c;如果你只是打包部署&#xff0c;那么就是将maven的test禁止可以成功打包 2、当你是本地服务器启动…...

如何看待“低代码”开发平台的兴起

目录 如何看待“低代码”开发平台的兴起&#xff1f;新机遇&#xff1a;效率与质量并进的新篇章1. 提升开发效率&#xff1a;2. 降低技术门槛&#xff1a;3. 创新加速&#xff1a; 挑战&#xff1a;质量和定制化需求的考量1. 定制能力受限&#xff1a;2. 依赖性和迁移成本 &…...

React类组件与函数组件有什么异同

相同点&#xff1a; 组件是react的最小代码片段&#xff0c;无论函数组件还是类组件 在使用方式 和 最终呈现效果是一致的类组件可以用函数组件重构&#xff0c;同样函数组件也可以用类组件重构&#xff08;并不推荐&#xff09;&#xff0c;在现代浏览器中闭包 和 类的性能只…...

函数调用的过程理解_汇编角度

目录 1、调用函数流程&#xff08;main函数调用print函数&#xff09;&#xff1a;Step1 保存main函数现场地址等信息Step2 跳转到print函数的位置Step3 执行print函数的指令Step4 返回main函数&#xff0c;执行下一条指令流程连续性总结 2、其他知识总结 1、调用函数流程&…...

【Java-一些常见单列集合面试问题】

目录 1.List,Set的区别&#xff1f; 2.ArrayList与Vector区别&#xff1f; 3.Arraylist与LinkedList区别&#xff1f; 4.ArrayList的扩容机制&#xff1f; 5.HashSet、LinkedHashSet和TreeSet 区别&#xff1f; 6.HashSet如何过滤重复元素&#xff1f; 1.List,Set的区别…...

搭建个人博客需要做哪些事

文章目录 前言搭建步骤站点服务器站点域名注册域名ICP 备案公安备案域名解析 博客图床图床是什么图床搭建 博客站点搭建建站工具本地搭建博客部署 站点运营百度收录百度统计 总结 前言 花了几天时间&#xff0c;搭建了一个个人博客&#xff0c;也算是完成了年初立的一个flag&a…...

《向量数据库指南》——非结构化数据的行业需求及向量数据库的关键角色

非结构化数据的行业需求及向量数据库的关键角色 引言 在当今数字化时代,数据已成为驱动社会进步与产业升级的核心要素。随着技术的飞速发展,特别是人工智能(AI)技术的广泛应用,数据的类型与规模正以前所未有的速度增长。其中,非结构化数据作为数据海洋中的主体部分,其…...

C++:map容器的使用

一、map的使用介绍 map文档介绍 1.1 map的模版参数 Key&#xff1a;键值对中Key的类型 T&#xff1a;键值对中value的类型 Compare&#xff1a;比较器的类型&#xff0c;map中的元素是按照Key来进行比较的&#xff0c;缺省情况&#xff08;不传参数时&#xff09;按照小于来…...

C++初学(10)

10.1、共用体 共用体是一种数据格式&#xff0c;它能够存储不同的数据类型&#xff0c;但只能同时存储其中的一种类型。比如说&#xff1a;结构可以同时存储int、long、和double&#xff0c;而共用体只能存储int、long、或double。共用体的句式与结构相似&#xff0c;但含义不…...

在MAC安装Lazarus 起点 - 我们的第一个Lazarus程序!

安装Lazarus 首先到Lazarus官网&#xff0c;找到合适的版本下载页面&#xff0c;比如Mac的版本&#xff1a; https://sourceforge.net/projects/lazarus/files/Lazarus%20macOS%20x86-64/Lazarus%203.4/ 将三个文件都下载到本地&#xff0c;需要安装这三个文件&#xff1a; …...

【每日刷题】Day96

【每日刷题】Day96 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. LCP 44. 开幕式焰火 - 力扣&#xff08;LeetCode&#xff09; 2. 1022. 从根到叶的二进制数之和 - …...

EGO-Swarm 仿真环境搭建

EGO-Swarm仿真环境搭建 参考教程&#xff1a; https://github.com/ZJU-FAST-Lab/ego-planner-swarm EGO-Swarm是一种分散的异步系统解决方案&#xff0c;用于仅使用机载资源在未知的障碍物丰富的场景中进行多机器人自主导航。 1. 查看系统环境 要运行本仿真程序&#xff0c…...

【EI会议征稿通知】第九届计算机技术与机械电气工程国际学术论坛(ISCME 2024)

会议官网&#xff1a;www.is-cme.com 一轮截稿时间&#xff1a;2024年8月16日&#xff08;早投稿&#xff0c;早录用&#xff09; 大会时间&#xff1a;2024年11月8-10日 大会地点&#xff1a;中国 南京 接受/拒稿通知&#xff1a;投稿后1-2周 收录检索&#xff1a;EI Compend…...

【starRocks-docker 部署问题汇总】

Starrocks系列文章目录 例如&#xff1a;starrocks 常见问题汇总 文章目录 Starrocks系列文章目录前言一、Starrocks-be运行一段时间后,容器无法restart&#xff1f;二、等待后续跟新 前言 starrocks基于docker-compose部署的3节点分布式(3FE,3BE)&#xff0c;遇到的问题也都…...

threejs中,如何检测一个模型周边一定范围内的其它模型

在Three.js中&#xff0c;要检测一个模型&#xff08;我们可以称之为“主体模型”&#xff09;周边一定范围内的其他物体&#xff0c;你可以通过以下步骤来实现&#xff1a; 1、定义检测范围&#xff1a; 首先&#xff0c;确定你需要检测的范围&#xff0c;这通常是一个以主体…...

UDP端口可达性检测(端口扫描)工具开发

UDP端口可达性检测(端口扫描)工具开发 1、应用场景分析 主机X与主机Y部署在AB双网环境下&#xff0c;两个主机间通过UDP协议进行数据交互。应用程序发送数据时&#xff0c;优先使用A网发送数据&#xff0c;如果A网异常则通过B网发送数据。两个主机应用间没有设置心跳帧 &…...

第三届计算、通信、感知与量子技术国际会议(CCPQT 2024)会议通知

会议信息 大会官网&#xff1a;http://www.ccpqt.org/ 官方邮箱&#xff1a;ccpqt_paper126.com 会议地点&#xff1a;中国珠海 会议时间&#xff1a;2024年10月25日-10月27日 主讲嘉宾 Prof. Trung Q. Duong IEEE Fellow and AAIA Fellow Memorial University of Newfoundl…...

Qt文件读写

Qt中文件读写类简述 包含头文件#include <QFile> 读写模式如下 枚举 文件读写步骤 1 先使用string 类型来接受打开文件的返回值 QFileDialog::getOpenFileName(this,"文件","./"); //打开一个文件 2 构建文件对象 Qfile ff (qstring)接受打…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...