目录
前言
本节主要补全了前文实现的菜单选项的具体功能,其中包括创建窗口、按钮的步骤。
创建窗口
Gui文件中window类用于创建窗口,其中包含两个构造函数,主要参数包括Gui实例对象、窗口名称、窗口大小、窗口坐标、窗口特性等。
Window(Gui* pGui, const char* name, uint2 size = { 0, 0 }, uint2 pos = { 0, 0 }, Gui::WindowFlags flags = Gui::WindowFlags::Default);
Window(Gui* pGui, const char* name, bool& open, uint2 size = { 0, 0 }, uint2 pos = { 0, 0 }, Gui::WindowFlags flags = Gui::WindowFlags::Default);
其中,窗口特性WindowFlags包括如下选项:
enum class WindowFlags
{
Empty = 0x0, ///< No flags
ShowTitleBar = 0x1, ///< Show a title bar
AllowMove = 0x2, ///< Allow the window move
SetFocus = 0x4, ///< Take focus when the window appears
CloseButton = 0x8, ///< Add a close button
NoResize = 0x10, ///< Disable manual resizing
AutoResize = 0x20, ///< Auto resize the window to fit it's content every frame
Default = ShowTitleBar | AllowMove | SetFocus | CloseButton
};
了解基础的底层函数后,就可以用以创建窗口。
展示帧率窗口
窗口名称为FPS,大小为{0,0},坐标为{10,25},窗口的特性包括允许移动 | 允许自动调整大小 | 窗口出现时自动聚焦。
之后使用帧对象gpFramework获取当前帧率,并在窗口中使用text实时显示文本。
void showFps(Gui* pGui)
{
Gui::Window w(pGui, "##FPS", { 0, 0 }, { 10, 25 }, Gui::WindowFlags::AllowMove | Gui::WindowFlags::AutoResize | Gui::WindowFlags::SetFocus);
std::string msg = gpFramework->getFrameRate().getMsg(gpFramework->isVsyncEnabled());
w.text(msg);
}

设置窗口大小窗口
窗口设置了五种可选大小,{1280, 720},{1920, 1080},{1920, 1200},{2560, 1440},{3840, 2160},以及自定义大小。
void winSizeUI(Gui::Window& w)
{
static const uint2 resolutions[] =
{
{1280, 720},
{1920, 1080},
{1920, 1200},
{2560, 1440},
{3840, 2160},
};
之后,定义整型变量kCustomIndex存储一般选项的索引,并使用lambda表达式将resolutions中的元素以及一般选项custom存入DropdownList 类型的列表并返回。
constexpr uint32_t kCustomIndex = uint32_t(-1);
static const auto initDropDown = [=](const uint2 resolutions[], uint32_t count) -> Gui::DropdownList
{
Gui::DropdownList list;
for (uint32_t i = 0; i < count; i++)
{
list.push_back({ i, std::to_string(resolutions[i].x) + "x" + std::to_string(resolutions[i].y) });
}
list.push_back({ kCustomIndex, "Custom" });
return list;
};
接着,同样使用lambda表达式逐一遍历resolutions,判断当前的窗口大小属于那个选项,如果都不匹配,则属于一般选项,并返回索引。
auto initDropDownVal = [=](const uint2 resolutions[], uint32_t count, uint2 screenDims)
{
for (uint32_t i = 0; i < count; i++)
{
if (screenDims == resolutions[i]) return i;
}
return kCustomIndex;
};
然后,使用getClientAreaSize函数获取当前窗口大小,并以此使用两个lambda表达式获取对应值。将需要的数据存入变量后,使用window的成员函数text创建文本,并使用tooltip函数创建工具提示。之后创建设置窗口大小的下拉菜单,并传入选项列表与当前索引。
uint2 currentRes = gpFramework->getWindow()->getClientAreaSize();
static const Gui::DropdownList dropdownList = initDropDown(resolutions, (uint32_t)arraysize(resolutions));
uint32_t currentVal = initDropDownVal(resolutions, (uint32_t)arraysize(resolutions), currentRes);
w.text("Window Size");
w.tooltip("The Window Size refers to the renderable area size (Swap-Chain dimensions)");
bool dropdownChanged = w.dropdown("##resdd", dropdownList, currentVal);
static uint2 customSize;
static bool forceCustom = false;
当选项改变时,判断索引是否为一般选项,是则强制自定义,否则使用resizeSwapChain函数重置当前窗口的大小。
若当前为自定义窗口大小,则依次生成一个var组件用于修改窗口大小数值,以及两个按钮分别实现应用当前数值与根据手动窗口改变更新数值,并将强制自定义设置为false。
if (dropdownChanged)
{
if (currentVal == kCustomIndex)
{
forceCustom = true;
}
else
{
customSize = {};
gpFramework->resizeSwapChain(resolutions[currentVal].x, resolutions[currentVal].y);
}
}
if (currentVal == kCustomIndex || forceCustom)
{
if (customSize.x == 0) customSize = currentRes;
w.var("##custres", customSize);
if (w.button("Apply##custres", true))
{
gpFramework->resizeSwapChain(customSize.x, customSize.y);
forceCustom = false;
}
if (w.button("Cancel##custres", true))
{
customSize = currentRes;
forceCustom = false;
}
}
}
}
最终编写外部调用函数,生成一个window对象并调用以上函数:
void MogwaiSettings::renderWindowSettings(Gui* pGui)
{
Gui::Window w(pGui, "Window", mShowWinSize, { 0, 0 }, { 350, 300 }, Gui::WindowFlags::AllowMove | Gui::WindowFlags::AutoResize | Gui::WindowFlags::ShowTitleBar | Gui::WindowFlags::CloseButton);
winSizeUI(w);
}
呈现的效果如下图:


本文详细介绍了在游戏引擎中如何创建窗口,包括展示帧率窗口和设置窗口大小的功能。通过Gui类的window对象,实现了窗口的创建,展示了如何实时显示帧率,并提供了多种预设窗口大小及自定义大小选项。窗口大小的设置采用了DropdownList,当选择自定义大小时,用户可以输入数值并应用。文章最后展示了实现效果。
219

被折叠的 条评论
为什么被折叠?



