RmlUi 初试,hello world

前言

最近在研究GUI的各个方面,最后被导向了web render,真的是一言难尽。

这里就其中一个比较有意思的项目 RmlUi 浅试一下,没想要还挺麻烦!这里留下note以供后人参考。

环境搭建

Windows + VS2022 + pre-binary library

需要指出的是 RmlUi官方的sample和demo很烂,对,可以说很烂!
因为按照他们的教程和示例,我玩了两天也没搞出来一个hello world!
也可能是我水平太菜了吧,但是我还是认为官方的资料是真的不行,只能提供思路的参考。

以当前最新版本v5.1为例,关键步骤如下:

  1. VS创建一个console C++项目,我们以x86为目标
  2. 将从 https://github.com/mikke89/RmlUi/releases 下载 RmlUi-vs2017-win32.zip. 解压到指定目录,将对应 include/lib/link 三件套手动配置到project中。添加 freetype.lib 的文件夹路径到project, 添加 freetype.lib, RmlCore.lib依赖。
  3. 添加 Backends文件夹到 include, 复制 freetype.dll, RmlCore.Dll到可执行文件夹。
  4. 修改 主 cpp文件。内容参考下面。
  5. 直接编译,100% 各种error! 并且没有教程可以参考!

到这里,你需要考虑一个问题:

你的GUI跑在什么后端上?

什么意思呢?

你的GUI渲染引擎是什么?OpenGL? Vulkan? SDL?
你的绘制引擎是什么?SDL? FLFW? SDL? X11? Win32?

如果回答不了,这里就无法进行下去了。

当然,有人说,我想要 GDI + Win32。我不想使用显卡渲染!

对不起,不好意思,这个也不支持!!

RmlUi 实际上是一个更侧重2D/3D渲染的引擎,对于UI渲染的目标就是 显卡/SDL 渲染!

那么,我能选择的是什么呢?

渲染引擎可选:GL2/GL3/SDL/VK
绘制引擎可选:SFML/SDL/WIn32/GLFW/X11

注意:以上两种选择,目前不支持自由组合!!


这里我选择了windows上最容易准备的环境:SDL + SDL, 这个组合官方有现成的支持!


继续配置:

  • 将SDL和SDL_image的release包从GitHub下载下来,include/lib/link 三件套配置好
  • 在VS project中将 RmlUi_Platform_SDL.h/.cpp, RmlUi_Renderer_SDL.h/.cpp, RmlUi_Backend_SDL_SDLrenderer.cpp 三套源文件加入。
  • 准备 字体ttf 文件, 需要中文的,字体也要支持中文。
  • 准备 rml 和 rcss 文件。
    这里需要注意,rcss一定要通过 rml 中的 link 方式加载进去。
  • 最后,debug 起来, 注意查看 VS 调试窗口的提示!

几个常见问题:

1. Font load error。
	大概率是字体路径或者权限问题,确保有读写权限。
2. No font face。font-family xxx ?
	rcss 文件可能没加载,或者widget没有设置 font-family.
	所有widget都需要设置,最好使用*筛选器设置全部的。
	
	还有一种可能:你没有在rml中link 正确的rcss文件。一定要查看debug窗口里的提升输出。

参考代码

cpp 复制代码
// rmldemo.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <RmlUi/Core.h>
#include <RmlUi_Backend.h>

struct ApplicationData {
	bool show_text = true;
	Rml::String animal = "dog";
} my_data;

int main()
{
	int window_width = 1024;
	int window_height = 768;

	// Initializes the shell which provides common functionality used by the included samples.
	//if (!Shell::Initialize())
	//	return -1;
	// 
	// Constructs the system and render interfaces, creates a window, and attaches the renderer.
	if (!Backend::Initialize("Template Tutorial", window_width, window_height, true))
	{
		//Shell::Shutdown();
		return -1;
	}

	// Install the custom interfaces constructed by the backend before initializing RmlUi.
	Rml::SetSystemInterface(Backend::GetSystemInterface());
	Rml::SetRenderInterface(Backend::GetRenderInterface());

	// RmlUi initialisation.
	Rml::Initialise();

	// Create the main RmlUi context.
	Rml::Context* context = Rml::CreateContext("main", Rml::Vector2i(window_width, window_height));
	if (!context)
	{
		Rml::Shutdown();
		Backend::Shutdown();
		//Shell::Shutdown();
		return -1;
	}

	//Rml::Debugger::Initialise(context);
	 
	// Tell RmlUi to load the given fonts.
	Rml::LoadFontFace("C:\\myfont\\MappleMono\\MapleMono-NF-CN-Regular.ttf");
	// Fonts can be registered as fallback fonts, as in this case to display emojis.
	//Rml::LoadFontFace("C:\\Users\\andy\\Desktop\\myfont\\JetBrainsMono\\JetBrainsMono-Regular.ttf", true);

	// Set up data bindings to synchronize application data.
	if (Rml::DataModelConstructor constructor = context->CreateDataModel("animals"))
	{
		constructor.Bind("show_text", &my_data.show_text);
		constructor.Bind("animal", &my_data.animal);
	}

	// Load and show the tutorial document.
	if (Rml::ElementDocument* document = context->LoadDocument("hello.rml"))
		document->Show();

	bool running = true;
	while (running)
	{
		running = Backend::ProcessEvents(context, nullptr, true);

		context->Update();

		Backend::BeginFrame();
		context->Render();
		Backend::PresentFrame();
	}

	// Shutdown RmlUi.
	Rml::Shutdown();

	Backend::Shutdown();
	//Shell::Shutdown();

	return 0;
}

hello.rml

html 复制代码
<rml>
<head>
	<title>Hello world</title>
	<link type="text/rcss" href="hello.rcss"/>
</head>
<body data-model="animals">
	<h1>RmlUi</h1>
	<p>Hello <span id="world">world</span>!</p>
	<p data-if="show_text">The quick brown fox jumps over the lazy {{animal}}.</p>
	<input type="text" data-value="animal"/>
</body>
</rml>

hello.rcss

css 复制代码
* {
 font-family: "Maple Mono NF CN";
}
body {
	font-size: 18px;
	color: #02475e;
	background: #fefecc;
	text-align: center;
	padding: 2em 1em;
	position: absolute;
	border: 2px #ccc;
	width: 500px;
	height: 200px;
	margin: auto;
}
		
h1 {
	color: #f6470a;
	font-size: 1.5em;
	font-weight: bold;
	margin-bottom: 0.7em;
}
		
p { 
	margin: 0.7em 0;
}
		
input.text {
	background-color: #fff;
	color: #555;
	border: 2px #999;
	padding: 5px;
	tab-index: auto;
	cursor: text;
	box-sizing: border-box;
	width: 200px;
	font-size: 0.9em;
}

后记

如果不想使用SDL,使用OpenGL怎么办呢?

和一开始的问题一样:你选择什么组合?

我们以 GFLW + OpenGL2 为例:

  • 需要准备 OpenGL2 开发SDK,将三件套添加到 project 中。
  • 需要添加 RmlUi_Backend_GLFW_GL2.h/.cpp, RmlUi_Platform_GLFW.h/.cpp, RmlUi_Renderer_GL2.h/.cpp 添加到project中。
  • 如果遇到 OpenGL2 依赖其他 image库一类的,继续下载对应 SDK 添加到 project中。

备注: RmlUi 对输入法支持不行,目前作者还在开发中。

个人估计,IME 这块开源项目想要自己实现,几乎不可能!参考flutter,这么多年了,也没修的很好。
相关推荐
弗锐土豆4 小时前
Windows系统中Oracle VM VirtualBox的安装
windows·虚拟机·virtualbox
秋の花4 小时前
【JAVA基础】Java集合基础
java·开发语言·windows
零意@7 小时前
ubuntu切换不同版本的python
windows·python·ubuntu
写bug的小屁孩9 小时前
前后端交互接口(三)
运维·服务器·数据库·windows·用户界面·qt6.3
hairenjing112311 小时前
在 Android 手机上从SD 卡恢复数据的 6 个有效应用程序
android·人工智能·windows·macos·智能手机
plmm烟酒僧13 小时前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
Jtti16 小时前
Windows系统服务器怎么设置远程连接?详细步骤
运维·服务器·windows
小奥超人16 小时前
PPT文件设置了修改权限,如何取消权?
windows·经验分享·microsoft·ppt·办公技巧
gonghw40317 小时前
DearPyGui学习
python·gui
hairenjing11231 天前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word