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,这么多年了,也没修的很好。
相关推荐
邂逅岁月2 小时前
珍藏多年的计算机内核结构大全笔记,掌握计算机工作原理真不难
java·开发语言·windows·笔记·系统架构·计算机外设·计算机硬件
特立独行的猫a3 小时前
MySQL8.0在windows下的下载安装及详细使用
windows
AlexMercer10124 小时前
【Python】列表
开发语言·网络·windows·笔记·python
lxlmycsdnfree6 小时前
程序员必知的 89 个操作系统核心概念
windows
西邮彭于晏11 小时前
差分进化算法
windows·python·算法
分享者花花14 小时前
恢复出厂设置后如何从 iPhone 恢复数据
windows·macos·ios·智能手机·excel·cocoa·iphone
苦藤新鸡15 小时前
用网络编程完成windows和linux跨平台之间的通信(服务器)
linux·网络·windows
雪 狼19 小时前
unity对于文件夹的操作
windows·unity·游戏引擎
爱分享的码瑞哥1 天前
Rust 进阶教程
开发语言·windows·rust
初学️计算1 天前
网络协议与标准
运维·服务器·windows