<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo

2021SC@SDUSC
开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo

目录

前言

正如上篇所说,本篇是为了 OvGame 的 Core 的 Game 部分,将先探究 OvGame 的其它文件: Utils 的 FPSCounter 以及 Debug 的 DriverInfo

另外,若想先大致了解该引擎各个大模块,可前往笔者这篇相关文章查看。
若想了解 OvGame 大纲,可前往笔者这篇文章

现在,让我们先了解一下 Utils 大纲及其 FPSCounter:

分析

1、Utils

1.1 大纲

Utils 文件包括了下列文件:
<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo
<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo
显然,该文件仅有一个 FPSCounter 部分,所以本篇也就直接是 Utils 的终篇了。现在开始探究 FPSCounter:

1.2 FPSCounter.h

1.2.1 头文件

#include <OvUI/Panels/PanelUndecorated.h>
#include <OvUI/Widgets/Texts/TextColored.h>

#include <OvWindowing/Window.h>

该文件包含的头文件都是来自 Overload 的其它模块,在此不多讲述,遇到再简单探究

1.2.2 主体代码

主体是一个 FPSCounter 类,作用是显示帧速率的面板,定义如下:

	class FPSCounter : public OvUI::Panels::PanelUndecorated
	{
	public:
		/**
		* Constructor
		* @param p_window
		*/
		FPSCounter(OvWindowing::Window& p_window);

		/**
		* Update the data
		* @param p_deltaTime
		*/
		void Update(float p_deltaTime);

	private:
		OvUI::Widgets::Texts::TextColored m_text;

		OvWindowing::Window& m_window;
		float m_elapsed = 0.0f;
		uint32_t m_frames = 0;
	};

首先,该类公有继承了 Overload 的模块 OvUI 中的 PanelUndecorated 类,功能是一个简单的面板,可以变形但没有样式(没有背景等),但它还层层向上公有继承了许多 OvUI::Panels 下的类,从底层至顶层依次是:

1、APanelTransformable 类,是一个本地化在画布中的面板。
2、Apanel 类,是画布的一个组件,是 UI 中的一种窗口。
3、任何小部件容器的基类 WidgetContainer 类与任何可绘制类的接口 IDrawable 类。

其次,FPSCounter 的变量还加入了有色文本类 TextColored 与窗口类 Window,此外定义了变量运行时间与帧数;函数也不多,咱们在 cpp 文件中深入探究:

1.3 FPSCounter.cpp

头文件仅有上述的 OvGame/Utils/FPSCounter.h,所以咱们直接看函数:

FPSCounter() 函数

OvGame::Utils::FPSCounter::FPSCounter(OvWindowing::Window& p_window) : m_window(p_window)
{
	m_text.color = OvUI::Types::Color::Yellow;
	m_defaultHorizontalAlignment = OvUI::Settings::EHorizontalAlignment::RIGHT;
	m_defaultPosition = { static_cast<float>(m_window.GetSize().first) - 10.0f , 10.0f };
	m_text.content = "999 FPS";
	ConsiderWidget(m_text, false);
}

这是一个构造函数,先用参数初始化表初始化窗口类对象 m_window;再初始化文本类 m_text 的 color 颜色变量为 OvUI::Types::Color 颜色结构体中的 Yellow 黄色;接着,用 OvUI::Settings::EHorizontalAlignment 水平对齐枚举类的 RIGHT 右对齐也初始化 m_defaultHorizontalAlignment,该变量来自其继承的父类 APanelTransformable 类;然后,同样是其父类 APanelTransformable 的变量 m_defaultPosition,用 m_window 的 GetSize().first 获得窗口宽度,设置默认位置;接着,m_text 设置其文本变量 content;

最后,调用父类 WidgetContainer 的函数 ConsiderWidget(),该函数的两个参数意义依次是部件类、如何管理内存。其中后者的实现方式是用三目运算符,判断若 true,则赋值 INTERNAL_MANAGMENT(内部管理);若 false,则赋值 EXTERNAL_MANAGMENT(外部管理),这两个词都是 OvUI 的 EMemoryMode 枚举类。然后,ConsiderWidget() 函数会将传入的部件类与管理内存的方式通过 make_pair() 绑定存储。

Update() 函数

void OvGame::Utils::FPSCounter::Update(float p_deltaTime)
{
	m_elapsed += p_deltaTime;

	++m_frames;

	if (m_elapsed >= 0.1f)
	{
		m_text.content = std::to_string(static_cast<int>(1.f / (m_elapsed / static_cast<float>(m_frames)))) + " FPS";
		SetPosition({ static_cast<float>(m_window.GetSize().first) - 10.0f , 10.0f });
		SetAlignment(OvUI::Settings::EHorizontalAlignment::RIGHT, OvUI::Settings::EVerticalAlignment::TOP);

		m_elapsed = 0.f;
		m_frames = 0;
	}
}

该函数负责更新数据:首先,运行时间 m_elapsed 增加传入的单位时间,帧数自加一;然后判断,如果 m_elapsed 超过 0.1f,即 0.1 秒,则通过;接着,先更新 m_text 的内容为计算后的当前帧率,再调用父类 APanelTransformable 的 SetPosition(),用 m_window 的 GetSize().first 获得窗口宽度,设置其在窗口中的位置,以及 APanelTransformable 的 SetAlignment() 设置水平右对齐与竖直顶对齐;最后重置时间与帧数为 0,为了下次计算帧率。

至此,FPSCounter 部分,也是 Utils 文件的所有内容就了解完了,并不复杂。其中,代码多处用到了 OvUI::Panels 下的各种类的函数,这不属于笔者的探究范围,感兴趣的读者请自行了解。接下来,咱们继续探究 Debug 文件:

2、Debug

2.1 大纲

Debug 文件包含了以下内容:
<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo
<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo
可见 Debug 共包括了三部分:DriverInfo、FrameInfo、GameProfiler。那么本篇就先探究 DriverInfo。

值得一提的是,Debug 的文件有进行下述命令:

#ifdef _DEBUG
// …… 程序段 ……
#endif

这是条件编译命令,此处的含义是:如果 “_DEBUG” 被定义过了,就执行包含的所有程序段。由于 Debug 所有文件都使用了该命令且代码都含于其中,之后其所有源码展示就不再展示该命令了。

2.2 DriverInfo.h

2.2.1 头文件

#include <OvRendering/Core/Renderer.h>
#include <OvWindowing/Window.h>

#include <OvUI/Panels/PanelUndecorated.h>
#include <OvUI/Widgets/Texts/TextColored.h>

该文件包含的都是 Overload 其它模块的头文件,在此暂不详述

2.2.2 主要代码

主要代码是一个 DriverInfo 类,负责生成显示 Driver Information,驱动程序(硬件和软件)信息,的面板,定义如下:

	class DriverInfo : public OvUI::Panels::PanelUndecorated
	{
	public:
		/**
		* Constructor
		* @param p_renderer
		* @param p_window
		*/
		DriverInfo(OvRendering::Core::Renderer& p_renderer, OvWindowing::Window& p_window);
	};

该类和上文的 Utils 中的 FPSCounter 类一样,继承了 OvUI 模块中的 PanelUndecorated 类,不再重复叙述;而该类自己也并不复杂,只包含了一个公有构造函数。

2.3 DriverInfo.cpp

该文件的头文件仅有上述的 DriverInfo.h,所以直接看唯一的函数:

DriverInfo() 函数

OvGame::Debug::DriverInfo::DriverInfo(OvRendering::Core::Renderer& p_renderer, OvWindowing::Window& p_window)
{
	m_defaultHorizontalAlignment = OvUI::Settings::EHorizontalAlignment::RIGHT;
	m_defaultVerticalAlignment = OvUI::Settings::EVerticalAlignment::BOTTOM;
	m_defaultPosition.x = static_cast<float>(p_window.GetSize().first) - 10.f;
	m_defaultPosition.y = static_cast<float>(p_window.GetSize().second) - 10.f;

	CreateWidget<OvUI::Widgets::Texts::TextColored>("Vendor: "	+ p_renderer.GetString(GL_VENDOR), OvUI::Types::Color::Yellow);
	CreateWidget<OvUI::Widgets::Texts::TextColored>("Hardware: " + p_renderer.GetString(GL_RENDERER), OvUI::Types::Color::Yellow);
	CreateWidget<OvUI::Widgets::Texts::TextColored>("OpenGL Version: " + p_renderer.GetString(GL_VERSION), OvUI::Types::Color::Yellow);
	CreateWidget<OvUI::Widgets::Texts::TextColored>("GLSL Version: " + p_renderer.GetString(GL_SHADING_LANGUAGE_VERSION), OvUI::Types::Color::Yellow);
}

该构造函数就能直接生成一个信息面板:首先,传入的两个参数意义分别是渲染器和窗口;其次,和 FPSCounter 中的操作一样,设置文本右对齐和底对齐,部件的初始位置距离窗口边界 10.f 计量单位;最后,连续调用 CreateWidget(),依次展示 Vendor(供应商)、Hardware(硬件)、OpenGL Version(OpenGL 版本)、GLSL Version(GLSL 版本)。

最后使用的 CreateWidget() 函数,是其父类 WidgetContainer 类的模板函数,能生成一个按需设定的部件。此处传入的模板是有色文本类 TextColored,传入的参数是展示的内容字符串和文本颜色。其中,内容的组成是硬件 / 软件名文本、加上由渲染器 p_renderer 的 GetString() 调用 glfw 的 glGetString() 获得所需的信息,并以字符串形式返回的字符串。

总结

本篇文章探究的两个部分 —— Utils 的 FPSCounter 以及 Debug 的 DriverInfo —— 功能都是一些部件的展示,用到的主要是 OvUI 中的函数,所以思路并不复杂。另外,OvGame 的 Core 文件的 Utils 部分在本篇也全部探究完毕了。

下一篇,笔者将继续探究 Debug 的剩余两部分 FrameInfo 与 GameProfiler

<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvGame(四)—— Utils(终)大纲及 FPSCounter & Debug(上)大纲及 DriverInfo

上一篇:MyBatis缓存机制(一级缓存,二级缓存,Java面试资料集合


下一篇:vscode 调试 webpack 打包