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. Netfilter和iptables介绍

    前言 在开始Kubernetes的网络之前我们先来学习Netfilter,Netfilter可能了解的人比较少,但是iptables用过 Linux的都应该知道.本文主要介绍Netfilter与ipt ...

  2. Android App隐私合规检测辅助工具(Camille)

    Camille Android App隐私合规检测辅助工具,项目仓库:https://github.com/zhengjim/camille 简介 现如今APP隐私合规十分重要,各监管部门不断开展AP ...

  3. 初步认识express,并创建web服务器,挂载静态资源

    1.Express简介 1.1什么是Express 官方给出的概念:Express 是基于 Node.js 平台,快速.开放.极简的 Web 开发框架,官方网址 相似用途:Express 的作用和 N ...

  4. ES6-字符串-模板字符串(复习+学习)

    昨天学习了字符串对象和字符串的表示,就是利用utf-8等不同的编码方式,还有许多的对象方法,都是处理字符串的方法,挺方便的,今天我学习了一下字符串模板,这里记录i一下学习的笔记,当然,今天学习了部分内 ...

  5. RDD的详解、创建及其操作

    RDD的详解 RDD:弹性分布式数据集,是Spark中最基本的数据抽象,用来表示分布式集合,支持分布式操作! RDD的创建 RDD中的数据可以来源于2个地方:本地集合或外部数据源 RDD操作 分类 转 ...

  6. Linux usb 3. Host 详解

    文章目录 1. 简介 2. Usb Core 驱动设备模型 2.1 Usb Device Layer 2.1.1 device (struct usb_device) 2.1.2 driver (st ...

  7. tmux会话断电保存自动恢复

    tmux可以用于会话管理,通过建立session,可以保证当前设备和服务期断开连接之后,会话中的指令继续运行,非常适合用于执行需要长时间运行的任务. 但是tmux也有一个问题,那就是session在服 ...

  8. mysql根据条件决定是否插入数据

    这个问题其实分两个方面: 1.根据表的主键决定数据是否插入. 2.根据表的非主键决定是否插入. 假设有表DOC_INFO(医生表),联合主键HOS_ID(医院代码),DEPT_CODE(科室代码),D ...

  9. requests的get请求基本使用

    官方文档 https://docs.python-requests.org/zh_CN/latest/   快速上手 https://docs.python-requests.org/zh_CN/la ...

  10. selenium的 元素定位、元素信息、交互

    selenium的元素定位? 元素定位:自动化要做的就是模拟鼠标和键盘来操作来操作这些元素,点击.输入等等.操作这些元素前首先 要找到它们,WebDriver提供很多定位元素的方法 方法: 1.fin ...