23 个不稳定版本 (11 个破坏性更新)
0.12.1 | 2024年6月8日 |
---|---|
0.12.0 | 2024年2月19日 |
0.11.0 | 2023年10月18日 |
0.9.5 | 2023年4月18日 |
0.2.1 | 2022年3月29日 |
#63 in GUI
每月468次下载
在 4 个工具包 中使用
1MB
7K SLoC
Notan
Notan 是一个简单且可移植的层,旨在让您在上面轻松创建自己的多媒体应用程序,而无需过多关注特定平台的代码。
主要目标是提供一套 API 和工具,可以以舒适的方式使用它们来创建项目,而无需强制任何结构或模式,始终尽量不干扰您。
社区
- Discord:加入我们!
示例
- 在线演示.
你想打开一个窗口吗?
use notan::prelude::*;
#[notan_main]
fn main() -> Result<(), String> {
notan::init().build()
}
你想画一个三角形吗?
use notan::prelude::*;
use notan::draw::*;
#[notan_main]
fn main() -> Result<(), String> {
notan::init().draw(draw)
.add_config(DrawConfig)
.build()
}
fn draw(gfx: &mut Graphics) {
let mut draw = gfx.create_draw();
draw.clear(Color::BLACK);
draw.triangle((400.0, 100.0), (100.0, 500.0), (700.0, 500.0));
gfx.render(&draw);
}
直接渲染这个三角形怎么样?
use notan::prelude::*;
//language=glsl
const VERT: ShaderSource = notan::vertex_shader! {
r#"
#version 450
layout(location = 0) in vec2 a_pos;
layout(location = 1) in vec3 a_color;
layout(location = 0) out vec3 v_color;
void main() {
v_color = a_color;
gl_Position = vec4(a_pos - 0.5, 0.0, 1.0);
}
"#
};
//language=glsl
const FRAG: ShaderSource = notan::fragment_shader! {
r#"
#version 450
precision mediump float;
layout(location = 0) in vec3 v_color;
layout(location = 0) out vec4 color;
void main() {
color = vec4(v_color, 1.0);
}
"#
};
#[derive(AppState)]
struct State {
clear_options: ClearOptions,
pipeline: Pipeline,
vbo: Buffer,
}
#[notan_main]
fn main() -> Result<(), String> {
notan::init_with(setup).draw(draw).build()
}
fn setup(gfx: &mut Graphics) -> State {
let clear_options = ClearOptions::color(Color::new(0.1, 0.2, 0.3, 1.0));
let vertex_info = VertexInfo::new()
.attr(0, VertexFormat::Float32x2)
.attr(1, VertexFormat::Float32x3);
let pipeline = gfx
.create_pipeline()
.from(&VERT, &FRAG)
.with_vertex_info(&vertex_info)
.build()
.unwrap();
#[rustfmt::skip]
let vertices = [
0.5, 1.0, 1.0, 0.2, 0.3,
0.0, 0.0, 0.1, 1.0, 0.3,
1.0, 0.0, 0.1, 0.2, 1.0,
];
let vbo = gfx
.create_vertex_buffer()
.with_info(&vertex_info)
.with_data(&vertices)
.build()
.unwrap();
State {
clear_options,
pipeline,
vbo,
}
}
fn draw(gfx: &mut Graphics, state: &mut State) {
let mut renderer = gfx.create_renderer();
renderer.begin(Some(state.clear_options));
renderer.set_pipeline(&state.pipeline);
renderer.bind_buffer(&state.vbo);
renderer.draw(0, 3);
renderer.end();
gfx.render(&renderer);
}
需要更多示例吗?
当然!请检查示例文件夹。您将找到一些示例,涵盖渲染、窗口、输入等各个方面...
安装
从 crates.io 将 notan
添加到您的项目中。主分支应始终是 crates.io
上的最新版本。
WebAssembly
我们将网络视为一等公民。WebAssembly 编译非常简单,我们建议您使用 trunk。您只需将一个 index.html
文件添加到您的项目中,并运行 trunk serve
来查看它的工作情况。
以下是一个简单的 index.html
文件作为示例
<html>
<head>
<title>Notan App</title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
content="minimal-ui, width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<style>
html, body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
background-color: #252526;
}
* {
outline: none;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<canvas id="notan_canvas"></canvas>
</body>
</html>
但是,您也可以使用 wasm-bindgen 或 wasm-pack。
工作原理
非常简单,Notan 定义了一组用于不同事物的 API(如窗口、图形、输入、音频等)作为“核心”。在这个“核心”下面存在的是 backends
,它们是 crate,为任何平台添加支持,管理特定平台的代码,并将其转换为我们的“核心”API。任何人都可以轻松地创建和使用自定义后端。而且,在“核心”之上,我们可以构建更易于使用的 API,这些 API 可以与为 Notan 制作的任何后端一起使用。
然后最终用户只需担心在 Notan 之上构建他们的应用程序即可,无论编译目标如何,都应该是没有问题的。当然,如果您想针对不同的目标,仍然需要考虑一些事情,编写可移植的代码有时可能会有点棘手,但 Notan 应该能帮助解决其中的大部分问题。
支持的平台
- Web 浏览器(《tt class="src-rs">wasm32》) - WebGL2
- 窗口 - OpenGL 3.3
- MacOS - OpenGL 3.3
- Linux - OpenGL 3.3
这些平台当前使用的图形后端是 glow.rs,它使我们能够轻松地针对 WebGL2、GL 和 GL ES。
性能
人们喜欢看到性能数据和基准测试(我也很喜欢),但事实是,如果没有完整的计算上下文,任何基准测试或数据都毫无意义。
我们还没有检查(尚未)代码的哪些部分可以更改以改善性能。保持良好的 API、小的样板代码和良好的性能之间的平衡并不是一件容易的事情。然而,这正是我们从项目一开始就试图实现的事情。
Notan 努力为用户提供简单构建事物的工具,性能将取决于许多因素,包括用户的代码。
让我们看一个简单的例子,2D 绘图 API 是在图形 API 之上构建的,它有很多改进的空间,但我在我的机器上运行示例 draw_bunnymark 时获得了一些不错的数字。
在 Macbook(2.3Hz i9 - 16GB RAM)上
- 本地:85000 只兔子在 60FPS
- Chrome:78000 只兔子在 60FPS
在高端桌面电脑上(Archlinux)
- 本地:205000 只兔子在 60FPS
- Chrome:131000 只兔子在 60FPS
请记住,bunnymark
的条件在真实项目中很少见。然而,它被广泛用于测试 2D 绘图 API 的性能。
集成
Notan 被设计成尽可能模块化。它足够灵活,允许使用插件更改事件生命周期(例如:FpsLimit),或者允许我们使用 图形扩展(例如:egui 或 draw)在图形 API 上轻松绘制自定义内容。
任何后端都可以通过使用 init_with_backend
仅在代码中轻松地 插入。
我们把这些插件或图形扩展包含在项目的一部分中,作为功能标志。然而,每个人都可以创建他们自己的插件或扩展来扩展 Notan。
为什么?
我一直寻找一个项目,可以让我使用一个代码库创建多媒体应用程序(我的情况是游戏),不拘泥于如何实现,支持多个平台,并将 Web 视为第一公民。
我一直觉得找到合适的东西很棘手,直到我发现了 Haxe 和 Kha,这对完美的组合。然而,我对构建系统的一些方面并不满意,比如工具和IDE的缺乏,以及语言本身的一些操作。所以,过了一段时间后,我决定再次寻找,我发现 Rust 在其他目标中有一个出色的 WebAssembly 编译器,并且满足所有这些条件。
在过去三年里,我在不同的仓库中以不同的名字多次“从头开始”工作在这个项目上。这是我学习 Rust 和 OpenGL 的地方,可以说这是我沙盒和爱好。
然而,我认为在当前状态下,这个项目可能比对我更有用。
Notan 这个名字来自 not an engine
。项目的核心目的是作为一个基础,提供一组基本但有用的功能。
它们包括:
- 平台抽象(桌面、移动等)
- 窗口管理
- 图形渲染
- 文本渲染
- 2D 绘图 API
- 音频
- 输入(键盘、鼠标等)
- 简单的 UI 通过 egui
其他一切,如粒子、物理等,都不在项目的范围内,可以通过外部crate、插件或扩展添加。尽管如此,如果您认为某些内容应该成为项目的一部分,我们总是可以讨论。
那么,接下来是什么?
逐步改进项目,目标是更加成熟和更好的API、修复、更好的平台支持、更多图形后端等...
许可证
该项目根据您的选择,受 Apache License, Version 2.0 或 MIT 许可证 的许可。
贡献
除非您明确声明,否则您根据 Apache 2.0 许可证定义的任何旨在包含在本项目中的有意贡献,都应如上所述双许可,不附加任何额外条款或条件。
依赖
~9–51MB
~1M SLoC