UE4之Slate:App默认窗口的创建流程
UE4版本:4.24.3源码编译
Windows10 + VS2019开发环境
在先前分享的基础上,现在来梳理下App启动时默认窗口的创建流程,以及相关的类、对象之间的抽象层级:
1、窗口创建流程
Q:App启动过程中,窗口是何时创建的?
Win32 API中创建窗口使用CreateWindowXX系列函数,VS中全局搜索一下CreateWindow,如下图是想要找的地方
全局搜索时不要勾选【Match whole world】
图1:全局搜索CreateWindow系列函数的调用
图一中源码路径:Source/Runtime/ApplicationCore/Private/Windows/WindowsWindow.cpp是需要找的调用;
在项目工程属性中:Debugging->Command Arguments中,添加-game参数:
VS中运行后,以Game模式启动,而非启动编辑器界面;
可以排除Editor相关的函数调用,模拟最终游戏的启动和运行流程;
VS中断点调试,拿到的调用堆栈如下图:
图2:窗口创建时的调用堆栈
从图2中可以看到,CreateWindowEx函数的调用过程中涉及到了下面几个类:
- FEngineLoop
- FPreLoadScreenManager
- UGameEngine
- FSlateApplication
- FWindowsApplication
- FWindowsWindow
定位到UGameEngine::CreateGameWindows()函数定义处,该函数创建的对象类型其实是SWindow;
// SNew宏创建一个SWindow实例(SWindow是SWidget派生类,参看前面的SImage用法)
TSharedRef<SWindow> Window = SNew(SWindow)
该SWindow实例被添加到FSlateApplication类中,被保存在SlateWindows这个数组中:定位到FSlateApplication::AddWindow()函数处可以查看
FSlateApplication::Get().AddWindow( Window, bShowImmediately );
FSlateApplication::AddWindow(...)函数内部,除了保存SWindow实例外,还会调用FSlateApplication::MakeWindow(...)创建一个FGenericWindow对象;
稍微追一下代码,会发现:
- 该FGenericWindow对象的实际类型是FWindowsWindow;
- FSlateApplication::MakeWindow(...)函数中出现的那个PlatformApplication实例,其类型为FWindowsApplication
关于PlatformApplication这个实例,参考FSlateApplication::Create(...)函数;
回到UGameEngine::CreateGameWindow()函数定义处:
SWindow实例会调用ShowWindow()函数,函数内部会调用到FWindowsWindow实例的Show()方法:该方法内部针对先前CreateWindowEx(...)函数创建的Win32窗口句柄做显示动作;
这部分分析过程中,会涉及到下面这些新出现的类:
- FGenericWindow
- FGenericApplication
- FGenericAcpplicationMisc
- FWindowsPlatformApplicationMisc
- FPlatformApplicationMisc 该类是一个typedef,指向具体平台的FXXXPlatformApplicationMisc类
- FSlateApplicationBase
以上整个UGameEngine::CreateGameWindow(...)函数调用的过程,就是窗口创建的过程;
2、类、对象的分析
类FSlateApplication继承自FSlateApplicationBase类;单例形式,管理并驱动整个Slate SWidget的渲染和事件派发等重要任务;
SWindow类抽象并封装平台Window对象;
FGenericApplication、FGenericWindow类是多平台对应类的基类,具体平台的逻辑操作在派生类中执行,实现各平台Api的封装;
3、总结、扩展
这次主要是追一下UE4引擎源码中,在Windows平台下,最基础的窗口是如何创建的;
对于其中涉及到的一些类和彼此之间的抽象关系做一个粗粒度的感性认识;
对于游戏引擎,各图形单元的渲染使用DirectX、OpenGL、Metal等底层硬件加速Api,并不依赖平台自身开发框架提供的Native控件;
窗口创建后,一般都会需要一个Content上下文初始化的工作,这块涉及到具体游戏引擎的渲染模块,以后有机会在来分享;
起始的窗口大小:
在项目工程属性中:Debugging->Command Arguments中,添加ResX=1280 ResY=720参数
ResX=1280 ResY=720参数设定窗口的启动大小:相关的代码可以参考:
static void UGameEngine::ConditionallyOverrideSettings(...);
static void UGameEngine::DetermineGameWindowResolution(...);
另外:上面全局搜索CreateWindo函数调用时,搜索结果中有出现一个WindowsPlatformSplash.cpp文件;
当中也有调用到CreateWindowEx(...)函数
这里其实就是引擎、或者VS中直接带-game参数启动时那个黑色的类似一个Loading界面的窗口
对应的图片资源在引擎Engine\Content\Splash目录下,有兴趣可以翻一下WindowsPlatformSplash.cpp源码
UE4之Slate:App默认窗口的创建流程的更多相关文章
- UE4之Slate: App启动与最外层Runtime结构
UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...
- Cinder-2 窗口的创建过程
通过TinderBox生成的代码很简单,整个代码如下: #include "cinder/app/AppNative.h" #include "cinder/gl/gl. ...
- 一个先进的App框架:使用Ionic创建一个简单的APP
原文 http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...
- day99:MoFang:Flask-JSONRPC提供RPC接口&在APP进行窗口页面操作(窗口-帧-帧组)
目录 1.服务端基于Flask-JSONRPC提供RPC接口 1.Flask-JSONRPC简介 2.安装Flask-JSONRPC模块 3.快速实现一个测试的RPC接口 4.移动端访问测试接口 2. ...
- UE4之Slate: SImage
概述 距离上次记录<UE4之Slate:纯C++工程配置>后已经好长时间了: 这个随笔来记录并分享一下SImage控件的使用,以在屏幕上显示一张图片: 目标 通过SImage控件的展示,学 ...
- uCGUI窗口的创建过程分析
一.相关结构体和变量 窗口管理结构体 /* 窗口管理结构体 共30个字节 */ struct WM_Obj { GUI_RECT Rect; //窗口尺寸(x0,y0,x1,y1) 8个字节 GUI_ ...
- win32 api Windows窗口的创建
windows窗口的创建有以下几个步骤: 1.创建注册窗口类 2.创建窗口句柄 3.显示更新窗口 4.消息循环 1.创建注册窗口类 所谓创建窗口类就是定义一个WNDCLASS类对象,并将该对象进行初始 ...
- vc++窗口的创建过程(MFC消息机制的经典文章)
一.什么是窗口类 在Windows中运行的程序,大多数都有一个或几个可以看得见的窗口,而在这些窗口被创建起来之前,操作系统怎么知道该怎样创建该窗口,以及用户操作该窗口的各种消息交给谁处理呢?所以VC ...
- Windows窗口的创建
Windows窗口创建的基本代码: #include <Windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); i ...
随机推荐
- RF射频传输,原理介绍,三分钟看懂!发射功率、接收灵敏度详解!
射频是什么? 官方说法:RF,Radio Frequency. (不懂的人,看了还是不懂,不过对于物联网行业的开发工程师.产品经理和项目经理,还是有需要对射频有个基础了解的.) 燚智能解读: 两个人, ...
- Spring Security 的注册登录流程
Spring Security 的注册登录流程 数据库字段设计 主要数据库字段要有: 用户的 ID 用户名称 联系电话 登录密码(非明文) UserDTO对象 需要一个数据传输对象来将所有注册信息发送 ...
- 决策树 机器学习,西瓜书p80 表4.2 使用信息增益生成决策树及后剪枝
使用信息增益构造决策树,完成后剪枝 目录 使用信息增益构造决策树,完成后剪枝 1 构造决策树 1 根结点的选择 色泽 信息增益 根蒂 信息增益 敲声 信息增益 纹理 信息增益 脐部 信息增益 触感 信 ...
- hdu 3887 Counting Offspring(DFS序【非递归】+树状数组)
题意: N个点形成一棵树.给出根结点P还有树结构的信息. 输出每个点的F[i].F[i]:以i为根的所有子结点中编号比i小的数的个数. 0<n<=10^5 思路: 方法一:直接DFS,进入 ...
- hdu 2189 来生一起走(DP)
题意: 有N个志愿者.指挥部需要将他们分成若干组,但要求每个组的人数必须为素数.问不同的方案总共有多少.(N个志愿者无差别,即每个组的惟一标识是:人数) 思路: 假设N个人可分为K组,将这K组的人数从 ...
- i love dingning
"如果你爱一个人,不是下课给人家买买水,不是短信发来发去,也不是周末一起出来唱唱歌聊聊天吃吃饭,而是做一个出色的人.以后的以后,可能还有别的人爱她,你要做的,是把别人都比下去.你要变得优秀, ...
- VUE项目实现主题切换
需求是 做一个深色主题和浅色主题切换的效果 方法一 多套css 这个方法也是最简单,也是最无聊的. <!-- 中心 --> <template> 动态获取父级class名称,进 ...
- Mysql 5.7 集群部署,keepalived
参考文章: https://blog.csdn.net/f18770366447/article/details/80703347 https://www.cnblogs.com/benjamin77 ...
- Lambda-让人又爱又恨的“->"
写在前边 聊到Java8新特性,我们第一反应想到的肯定是Lambda表达式和函数式接口的出现.要说ta到底有没有在一定程度上"优化"了代码的简洁性呢?抑或是ta在一定程度上给程序员 ...
- RedHat 7.0 Linux 下划分区,分区加密,配额,逻辑卷管理
1:如何划分区: 1:明确分区的对象:xxx :fdisk /dev/xxx 2:增加一个分区:n:选择主分区或者扩展分区,"p" or "e" :默认地方开始 ...