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,这么多年了,也没修的很好。
相关推荐
豆沙粽子好吃嘛!13 分钟前
windows环境下g++无输出的解决方案
windows
一叶龙洲34 分钟前
安装Win11+Ubuntu25.10双系统遇到的问题
windows·ubuntu
双河子思1 小时前
Visual Studio 编程工程设置
ide·windows·visual studio
zt1985q3 小时前
本地部署消息代理软件 RabbitMQ 并实现外部访问( Windows 版本 )
运维·服务器·windows·rabbitmq·ruby
烤奶要加冰3 小时前
PyCharm 社区版全平台安装指南
ide·windows·python·pycharm·mac
ol木子李lo4 小时前
Doxygen入门指南:从注释到自动文档
c语言·c++·windows·编辑器·visual studio code·visual studio·doxygen
xier_ran5 小时前
Python从入门到精通:(2)Python 核心进阶教程从数据结构到面向对象
linux·windows·python·microsoft
richxu202510015 小时前
Linux本地部署deepseek大模型之 6. Windows本地连接远程云服务器中的MySQL常见错误的解决办法
linux·服务器·windows
Geo_V8 小时前
Windows 安装 Anaconda 并配置 PyCharm 环境
ide·windows·python·pycharm
iCxhust10 小时前
windows环境下在Bochs中运行Linux0.12系统
linux·运维·服务器·windows·minix