UE4版本:4.24.3源码编译

Windows10 + VS2019开发环境

在先前分享的基础上,现在来梳理下App启动时默认窗口的创建流程,以及相关的类、对象之间的抽象层级:

  1. 纯C++工程配置
  2. Step By Step展示SImage控件的简单使用
  3. UE4源码,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默认窗口的创建流程的更多相关文章

  1. UE4之Slate: App启动与最外层Runtime结构

    UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...

  2. Cinder-2 窗口的创建过程

    通过TinderBox生成的代码很简单,整个代码如下: #include "cinder/app/AppNative.h" #include "cinder/gl/gl. ...

  3. 一个先进的App框架:使用Ionic创建一个简单的APP

    原文  http://www.w3cplus.com/mobile/building-simple-app-using-ionic-advanced-html5-mobile-app-framewor ...

  4. day99:MoFang:Flask-JSONRPC提供RPC接口&在APP进行窗口页面操作(窗口-帧-帧组)

    目录 1.服务端基于Flask-JSONRPC提供RPC接口 1.Flask-JSONRPC简介 2.安装Flask-JSONRPC模块 3.快速实现一个测试的RPC接口 4.移动端访问测试接口 2. ...

  5. UE4之Slate: SImage

    概述 距离上次记录<UE4之Slate:纯C++工程配置>后已经好长时间了: 这个随笔来记录并分享一下SImage控件的使用,以在屏幕上显示一张图片: 目标 通过SImage控件的展示,学 ...

  6. uCGUI窗口的创建过程分析

    一.相关结构体和变量 窗口管理结构体 /* 窗口管理结构体 共30个字节 */ struct WM_Obj { GUI_RECT Rect; //窗口尺寸(x0,y0,x1,y1) 8个字节 GUI_ ...

  7. win32 api Windows窗口的创建

    windows窗口的创建有以下几个步骤: 1.创建注册窗口类 2.创建窗口句柄 3.显示更新窗口 4.消息循环 1.创建注册窗口类 所谓创建窗口类就是定义一个WNDCLASS类对象,并将该对象进行初始 ...

  8. vc++窗口的创建过程(MFC消息机制的经典文章)

    一.什么是窗口类  在Windows中运行的程序,大多数都有一个或几个可以看得见的窗口,而在这些窗口被创建起来之前,操作系统怎么知道该怎样创建该窗口,以及用户操作该窗口的各种消息交给谁处理呢?所以VC ...

  9. Windows窗口的创建

    Windows窗口创建的基本代码: #include <Windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); i ...

随机推荐

  1. 字符串匹配 ?kmp : hash

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...

  2. Bzoj P2054 疯狂的馒头 | 并查集

    题目链接 思路:因为每次染色都会将某些馒头的颜色彻底更改,所以每个馒头的最终的颜色其实是由最后一次染色决定的,那么我们只考虑最后一次染色即可.对此,我们可以从后往前倒着染色,当目前的染色区间中存在白色 ...

  3. cf Inverse the Problem (最小生成树+DFS)

    题意: N个点.N行N列d[i][j]. d[i][j]:结点i到结点j的距离. 问这N个点是否可能是一棵树.是输出YES,否则输出NO. 思路: 假设这个完全图是由一棵树得来的,则我们对这个完全图求 ...

  4. Ubuntu中python的mysql操作

    1.在已经安装了python和MySQL数据库的前提下使用pip3 install PyMySQL命令 2. 建立链接: (1)首先使用命令python 进入编程模式,再导入包: import pym ...

  5. TCP粘"包"问题浅析及解决方案Golang代码实现

    一.粘"包"问题简介 在socket网络编程中,都是端到端通信,客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一条连接.在TCP的sock ...

  6. MySQL、Oracle批量插入SQL的通用写法

    举个例子: 现在要批量新增User对象到数据库USER表中 public class User{ //姓名 private String name; //年龄 private Integer age; ...

  7. fabric运行错误汇总

    Error generating signCA for org org1.example.com: Failed storing key [ECDSAP256]: Failed storing ECD ...

  8. [Vue]浅谈Vue3组合式API带来的好处以及选项API的坏处

    前言 如果是经验不够多的同志在学习Vue的时候,在最开始会接触到Vue传统的方式(选项式API),后边会接触到Vue3的新方式 -- 组合式API.相信会有不少同志会陷入迷茫,因为我第一次听到新的名词 ...

  9. Python 爬取妹子图(技术是无罪的)

    ... import requests from bs4 import BeautifulSoup import os import sys class mzitu(): def html(self, ...

  10. 菜鸡的Java笔记 第二十四 - java 接口的基本定义

    1.接口的基本定义以及使用形式        2.与接口有关的设计模式的初步认识        3.接口与抽象类的区别                 接口与抽象类相比,接口的使用几率是最高的,所有的 ...