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. 计算机网络之流量控制(停止-等待协议、滑动窗口、后退N帧协议GBN、选择重传协议SR)、滑动窗口、可靠传输机制

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/104908762 学习课程:<2019王道考研计算机网络> 学习目的 ...

  2. VS 2013 配置份openGL环境

    几个要素: 1.  在E:\Microsoft Visual Studio 12.0\VC\include下创建GL文件夹,放入glut.h头文件. 2.  C:\Windows\System32下要 ...

  3. Socket `accept queue is full ` 但是一个连接需要从SYN->ACCEPT

    由于标题长度有限制,我把想要描述的问题再次描述下: 内核通常会为每一个LISTEN状态的Socket维护两个队列: 1 accept队列: listen()函数第二个参数BACKLOG指定,表示已完成 ...

  4. httprunner3源码解读(4)parser.py

    源码结构目录 可以看到此模块定义了4个属性和12个函数,我们依次来讲解 属性源码分析 # 匹配http://或https:// absolute_http_url_regexp = re.compil ...

  5. OpenHarmony LiteOS C-SKY指令集移植指北

    摘要:本文介绍在OpenHarmony社区LiteOS-M项目中新增C-SKY指令集的开发流程,以及适配相应qemu工程的方法和步骤,供LiteOS内核相关开发者学习交流. 本文分享自华为云社区< ...

  6. ITextRenderers html生成pdf 分页+横向

    1.pdf横向生成问题:格式化html是加上 @page{size:297mm 210mm;} public static String formatPdfHtml(String html,Strin ...

  7. JS中如何将yyyy-MM-dd HH:mm:ss格式的字符串转成Date类型

    var deadline = '2019-04-11 13:11:00';   var result = new Date(deadline.replace(/-/g, '/'));

  8. java 邮件 接收与发送

    ... package com.e6soft; import java.io.BufferedReader; import java.io.FileOutputStream; import java. ...

  9. Scrapy入门到放弃05:让Item在Pipeline中飞一会儿

    前言 "又回到最初的起点,呆呆地站在镜子前". 本来这篇是打算写Spider中间件的,但是因为这一块涉及到Item,所以这篇文章先将Item讲完,顺便再讲讲Pipeline,然后再 ...

  10. Java将增加虚拟线程,挑战Go协程

    我们知道 Go 语言最大亮点之一就是原生支持并发,这得益于 Go 语言的协程机制.一个 go 语句就可以发起一个协程 (goroutin).协程本质上是一种用户态线程,它不需要操作系统来进行调度,而是 ...