栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

<2021SC@SDUSC>开源游戏引擎Overload代码分析四:OvEditor——Utils,Settings,Resources

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

<2021SC@SDUSC>开源游戏引擎Overload代码分析四:OvEditor——Utils,Settings,Resources

2021SC@SDUSC

Overload代码分析四:OvEditor——Utils,Settings,Resources
  • 前言
  • 一、Utils
    • ActorCreationMenu.h
    • ActorCreationMenu.cpp
  • 二、Settings
    • EditorSettings.cpp
    • EditorSettings.h
  • 三、Resources
    • RawTextures.h
    • RawShaders.h
    • RawShaders.cpp
  • 总结

前言

这是Overload引擎相关的第六篇文章,同时也是OvEditor分析的第一篇。Overload引擎的Github主页在这里。

本篇文章主要会介绍OvEditor中三个文件夹所包含的h和cpp文件,分别是Utils,Settings和Resources文件夹。其中,前两个文件夹包含的内容较少,而Resources文件夹中因为有默认shader的缘故,内容会比较多。

一、Utils ActorCreationMenu.h
#include 

namespace OvUI::Widgets::Menu
{
    class MenuList;
}

namespace OvCore::ECS
{
    class Actor;
}

namespace OvEditor::Utils
{
    
    class ActorCreationMenu
    {
    public:
        
        ActorCreationMenu() = delete;

        
        static void GenerateActorCreationMenu(OvUI::Widgets::Menu::MenuList& p_menuList, OvCore::ECS::Actor* p_parent = nullptr, std::optional> p_onItemClicked = {});
    };
}

头文件很简短,引入了其他命名空间来定义类ActorCreationMenu,不过并没有启用构造函数,下个函数的具体内容在cpp文件中再讲。

ActorCreationMenu.cpp
std::function Combine(std::function p_a, std::optional> p_b)
{
    if (p_b.has_value())
    {
        return [=]()
        {
            p_a();
            p_b.value()();
        };
    }

    return p_a;
}

template
std::function ActorWithComponentCreationHandler(OvCore::ECS::Actor* p_parent, std::optional> p_onItemClicked)
{
    return Combine(EDITOR_BIND(CreateMonoComponentActor, true, p_parent), p_onItemClicked);
}

std::function ActorWithModelComponentCreationHandler(OvCore::ECS::Actor* p_parent, const std::string& p_modelName, std::optional> p_onItemClicked)
{
    return Combine(EDITOR_BIND(CreateActorWithModel, ":Models\" + p_modelName + ".fbx", true, p_parent, p_modelName), p_onItemClicked);
}

void OvEditor::Utils::ActorCreationMenu::GenerateActorCreationMenu(OvUI::Widgets::Menu::MenuList& p_menuList, OvCore::ECS::Actor* p_parent, std::optional> p_onItemClicked)
{
    using namespace OvUI::Widgets::Menu;
    using namespace OvCore::ECS::Components;

    p_menuList.CreateWidget("Create Empty").ClickedEvent += Combine(EDITOR_BIND(CreateEmptyActor, true, p_parent, ""), p_onItemClicked);

    auto& primitives = p_menuList.CreateWidget("Primitives");
    auto& physicals = p_menuList.CreateWidget("Physicals");
    auto& lights = p_menuList.CreateWidget("Lights");
    auto& audio = p_menuList.CreateWidget("Audio");
    auto& others = p_menuList.CreateWidget("Others");

    primitives.CreateWidget("Cube").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Cube", p_onItemClicked);
    primitives.CreateWidget("Sphere").ClickedEvent            += ActorWithModelComponentCreationHandler(p_parent, "Sphere", p_onItemClicked);
    primitives.CreateWidget("Cone").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Cone", p_onItemClicked);
    primitives.CreateWidget("Cylinder").ClickedEvent          += ActorWithModelComponentCreationHandler(p_parent, "Cylinder", p_onItemClicked);
    primitives.CreateWidget("Plane").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Plane", p_onItemClicked);
    primitives.CreateWidget("Gear").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Gear", p_onItemClicked);
    primitives.CreateWidget("Helix").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Helix", p_onItemClicked);
    primitives.CreateWidget("Pipe").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Pipe", p_onItemClicked);
    primitives.CreateWidget("Pyramid").ClickedEvent           += ActorWithModelComponentCreationHandler(p_parent, "Pyramid", p_onItemClicked);
    primitives.CreateWidget("Torus").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Torus", p_onItemClicked);
    physicals.CreateWidget("Physical Box").ClickedEvent       += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    physicals.CreateWidget("Physical Sphere").ClickedEvent    += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    physicals.CreateWidget("Physical Capsule").ClickedEvent   += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Point").ClickedEvent                 += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Directional").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Spot").ClickedEvent                  += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Ambient Box").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Ambient Sphere").ClickedEvent        += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    audio.CreateWidget("Audio Source").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    audio.CreateWidget("Audio Listener").ClickedEvent         += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    others.CreateWidget("Camera").ClickedEvent                += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
}

这里定义了三个函数用于辅助当前函数,Combine()函数用到了许多C++现代特性。首先是function类模板,使用它可以让函数声明变得简单,但我们在此并不着重于介绍C++特性,所以有兴趣的可以查阅相关文章;然后像是lambda表达式,可以让函数使用更直接快捷,具体可看这里;还有std::optional类型,实际上就是对编程中常见的初始空值的代替,介绍可以看这里。有了以上的基础,这个Combine()函数就不是很难理解了,具体实现就是先判断p_b是否非空,如果是,那就执行p_a()函数和p_b内部所含的函数;如果为空值,就返回p_a()函数。
剩下的两个辅助用的函数ActorWithComponentCreationHandler()和ActorWithModelComponentCreationHandler(),就是Combine()函数具体使用的又一层封装。p_a是把属性或者模型和对应的变量绑定,p_b是鼠标点击。
最后的GenerateActorCreationMenu(),下面一句是用给定menulist生成了物体创建菜单:

p_menuList.CreateWidget("Create Empty").ClickedEvent += Combine(EDITOR_BIND(CreateEmptyActor, true, p_parent, ""), p_onItemClicked);

而接下来的又一大串则是充当回调函数的作用,类型是看由谁调用:

    primitives.CreateWidget("Cube").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Cube", p_onItemClicked);
    primitives.CreateWidget("Sphere").ClickedEvent            += ActorWithModelComponentCreationHandler(p_parent, "Sphere", p_onItemClicked);
    primitives.CreateWidget("Cone").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Cone", p_onItemClicked);
    primitives.CreateWidget("Cylinder").ClickedEvent          += ActorWithModelComponentCreationHandler(p_parent, "Cylinder", p_onItemClicked);
    primitives.CreateWidget("Plane").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Plane", p_onItemClicked);
    primitives.CreateWidget("Gear").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Gear", p_onItemClicked);
    primitives.CreateWidget("Helix").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Helix", p_onItemClicked);
    primitives.CreateWidget("Pipe").ClickedEvent              += ActorWithModelComponentCreationHandler(p_parent, "Pipe", p_onItemClicked);
    primitives.CreateWidget("Pyramid").ClickedEvent           += ActorWithModelComponentCreationHandler(p_parent, "Pyramid", p_onItemClicked);
    primitives.CreateWidget("Torus").ClickedEvent             += ActorWithModelComponentCreationHandler(p_parent, "Torus", p_onItemClicked);
    physicals.CreateWidget("Physical Box").ClickedEvent       += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    physicals.CreateWidget("Physical Sphere").ClickedEvent    += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    physicals.CreateWidget("Physical Capsule").ClickedEvent   += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Point").ClickedEvent                 += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Directional").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Spot").ClickedEvent                  += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Ambient Box").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    lights.CreateWidget("Ambient Sphere").ClickedEvent        += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    audio.CreateWidget("Audio Source").ClickedEvent           += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    audio.CreateWidget("Audio Listener").ClickedEvent         += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);
    others.CreateWidget("Camera").ClickedEvent                += ActorWithComponentCreationHandler(p_parent, p_onItemClicked);

二、Settings EditorSettings.cpp
#include "OvEditor/Settings/EditorSettings.h"

这个cpp文件的作用只是包含头文件,所以咱们就讲讲头文件。

EditorSettings.h
namespace OvEditor::Settings
{
	
	class EditorSettings
	{
	public:
		template
		class Property
		{
		public:
			
			Property(T p_value) : m_value(p_value) {}

			
			OvTools::Eventing::Event OnValueChanged;

			
			inline T& operator=(T p_value)
			{
				Set(p_value);
				return m_value;
			}

			
			inline void Set(T p_value)
			{
				m_value = p_value;
				OnValueChanged.Invoke(m_value);
			}

			inline operator T()
			{
				return m_value;
			}

			
			inline T Get() const
			{
				return m_value;
			}

		private:
			T m_value;
		};

		
		EditorSettings() = delete;

		inline static Property ShowGeometryBounds = { false };
		inline static Property ShowLightBounds = { false };
		inline static Property ShowGeometryFrustumCullingInSceneView = { false };
		inline static Property ShowLightFrustumCullingInSceneView = { false };
		inline static Property LightBillboardScale = { 0.5f };
		inline static Property TranslationSnapUnit = { 1.0f };
		inline static Property RotationSnapUnit = { 15.0f };
		inline static Property ScalingSnapUnit = { 1.0f };
	};
}

在EditorSettings类中还有Property类,Property内的定义很简单,维护了一个模板类型值;构造函数是赋默认值;有在改变数值时的事件,重载了“=”和“()”运算符,和set()以及get()函数一样,都是赋值和读值;至于EditorSettings类,则没有构造函数,同时只定义了一些默认属性。

三、Resources RawTextures.h
#define BUTTON_PLAY		
#define BUTTON_PAUSE	
#define BUTTON_STOP		
#define BUTTON_NEXT		
#define BUTTON_REFRESH	
#define ICON_FILE		
#define ICON_TEXTURE	
#define ICON_SOUND		
#define ICON_SHADER		
#define ICON_script		
#define ICON_SCENE		
#define ICON_MODEL		
#define ICON_FONT		
#define ICON_FOLDER		
#define ICON_MATERIAL	
#define EMPTY_TEXTURE	
#define BILL_PLIGHT		
#define BILL_ASLIGHT	
#define BILL_ABLIGHT	
#define BILL_SLIGHT		
#define BILL_DLIGHT		

这段代码不复杂,但实在是太长了,所以在这里并没有放全部,只是把名称放了进来。从这个头文件的名字就可以看出,这其实是定义了一些默认图片,由于需要给出每个像素的灰度值,所以才会特别的长,具体其实没有什么好说的。

RawShaders.h
namespace OvEditor::Resources
{
	
	class RawShaders
	{
	public:
		
		static std::pair GetGrid();

		
		static std::pair GetGizmo();

		
		static std::pair GetBillboard();
	};
}

定义了RawShaders类,事实上就是三个shader,具体留待cpp中讲解。

RawShaders.cpp

我本打算在这篇文章中写完cpp,但因为shader使用的hlsl和正常的c++还不太一样,所以我决定新开一篇文章专门用于介绍此文件,在此就不说了。

总结

这篇文章介绍的都是一些比较简单的辅助文件,接下来要介绍的shader会比较不一样,它被包含在RawShaders.cpp中,并且是预定义好的,需要花费一些篇幅。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/384728.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号