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 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
九鼎科技-Leo8 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Yang.9910 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗10 小时前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ashane131411 小时前
Java list
java·windows·list
万里沧海寄云帆12 小时前
Word 插入分节符页码更新问题
windows·microsoft·word
dot.Net安全矩阵13 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
编程修仙14 小时前
Collections工具类
linux·windows·python
程序员小羊!15 小时前
高级 SQL 技巧讲解
windows
xiangshangdemayi17 小时前
Windows环境GeoServer打包Docker极速入门
windows·docker·容器·geoserver·打包·数据挂载