Просмотр исходного кода

world: add depth to Gui drawing primitives

Daniele Bartolini 1 год назад
Родитель
Сommit
7f630d8b0f
6 измененных файлов с 63 добавлено и 40 удалено
  1. 1 0
      docs/changelog.rst
  2. 15 1
      docs/lua_api.rst
  3. 1 1
      src/device/device.cpp
  4. 5 4
      src/lua/lua_api.cpp
  5. 29 22
      src/world/gui.cpp
  6. 12 12
      src/world/gui.h

+ 1 - 0
docs/changelog.rst

@@ -18,6 +18,7 @@ Changelog
 * Fixed loading resources from bundles.
 * Added texture hot-reloading.
 * Data Compiler: fixed bundle generation.
+* Lua API: Gui drawing primitives can now specify an optional depth value for sorting.
 
 0.51.0 --- 28 Oct 2024
 ----------------------

+ 15 - 1
docs/lua_api.rst

@@ -169,20 +169,34 @@ Gui
 **move** (gui, pos)
 	Moves the Gui to *pos*.
 
-**triangle** (gui, a, b, c, color)
+**triangle** (gui, a, b, c, color [, depth])
 	Draws a triangle defined by vertices *a*, *b* and *c*.
+	Objects with a lower depth are drawn in front. If depth is omitted its value
+	is set to 0.
 
 **rect** (gui, pos, size, color)
 	Draws a rectangle.
+	If pos is a Vector3, the z element specifies the drawing depth. Objects with
+	a lower depth are drawn in front. If pos is a Vector2, the z elements is set
+	to 0.
 
 **image** (gui, pos, size, material_resource, color)
 	Draws an image.
+	If pos is a Vector3, the z element specifies the drawing depth. Objects with
+	a lower depth are drawn in front. If pos is a Vector2, the z elements is set
+	to 0.
 
 **image_uv** (gui, pos, size, uv0, uv1, material_resource, color)
 	Draws an image with explicit UV coordinates.
+	If pos is a Vector3, the z element specifies the drawing depth. Objects with
+	a lower depth are drawn in front. If pos is a Vector2, the z elements is set
+	to 0.
 
 **text** (gui, pos, font_size, str, font_resource, material_resource, color)
 	Draws text.
+	If pos is a Vector3, the z element specifies the drawing depth. Objects with
+	a lower depth are drawn in front. If pos is a Vector2, the z elements is set
+	to 0.
 
 **material** (material_resource) : Material
 	Returns the material *material_resource*.

+ 1 - 1
src/device/device.cpp

@@ -786,7 +786,7 @@ void Device::render(World &world, UnitId camera_unit)
 	bgfx::setViewMode(VIEW_SPRITE_5, bgfx::ViewMode::DepthAscending);
 	bgfx::setViewMode(VIEW_SPRITE_6, bgfx::ViewMode::DepthAscending);
 	bgfx::setViewMode(VIEW_SPRITE_7, bgfx::ViewMode::DepthAscending);
-	bgfx::setViewMode(VIEW_GUI, bgfx::ViewMode::Sequential);
+	bgfx::setViewMode(VIEW_GUI, bgfx::ViewMode::DepthDescending);
 	bgfx::setViewMode(VIEW_BLIT, bgfx::ViewMode::Sequential);
 
 	bgfx::setViewFrameBuffer(VIEW_SPRITE_0, _pipeline->_main_frame_buffer);

+ 5 - 4
src/lua/lua_api.cpp

@@ -2813,12 +2813,13 @@ void load_api(LuaEnvironment &env)
 				, stack.get_vector2(3)
 				, stack.get_vector2(4)
 				, stack.get_color4(5)
+				, stack.num_args() > 5 ? stack.get_float(6) : 0.0f
 				);
 			return 0;
 		});
 	env.add_module_function("Gui", "rect", [](lua_State *L) {
 			LuaStack stack(L);
-			stack.get_gui(1)->rect(stack.get_vector2(2)
+			stack.get_gui(1)->rect(stack.get_vector3(2)
 				, stack.get_vector2(3)
 				, stack.get_color4(4)
 				);
@@ -2826,7 +2827,7 @@ void load_api(LuaEnvironment &env)
 		});
 	env.add_module_function("Gui", "image", [](lua_State *L) {
 			LuaStack stack(L);
-			stack.get_gui(1)->image(stack.get_vector2(2)
+			stack.get_gui(1)->image(stack.get_vector3(2)
 				, stack.get_vector2(3)
 				, stack.get_resource_name(4)
 				, stack.get_color4(5)
@@ -2835,7 +2836,7 @@ void load_api(LuaEnvironment &env)
 		});
 	env.add_module_function("Gui", "image_uv", [](lua_State *L) {
 			LuaStack stack(L);
-			stack.get_gui(1)->image_uv(stack.get_vector2(2)
+			stack.get_gui(1)->image_uv(stack.get_vector3(2)
 				, stack.get_vector2(3)
 				, stack.get_vector2(4)
 				, stack.get_vector2(5)
@@ -2846,7 +2847,7 @@ void load_api(LuaEnvironment &env)
 		});
 	env.add_module_function("Gui", "text", [](lua_State *L) {
 			LuaStack stack(L);
-			stack.get_gui(1)->text(stack.get_vector2(2)
+			stack.get_gui(1)->text(stack.get_vector3(2)
 				, stack.get_int(3)
 				, stack.get_string(4)
 				, stack.get_resource_name(5)

+ 29 - 22
src/world/gui.cpp

@@ -21,6 +21,11 @@
 
 namespace crown
 {
+static inline u32 depth_u32(f32 depth)
+{
+	return u32(depth * 100.0f * 1000.0f);
+}
+
 GuiBuffer::GuiBuffer(ShaderManager &sm)
 	: _shader_manager(&sm)
 	, _num_vertices(0)
@@ -58,25 +63,25 @@ void GuiBuffer::reset()
 	bgfx::allocTransientIndexBuffer(&_index_buffer, 6144);
 }
 
-void GuiBuffer::submit(u32 num_vertices, u32 num_indices, const Matrix4x4 &world)
+void GuiBuffer::submit(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, u32 depth)
 {
 	bgfx::setVertexBuffer(0, &_vertex_buffer, _num_vertices, num_vertices);
 	bgfx::setIndexBuffer(&_index_buffer, _num_indices, num_indices);
 	bgfx::setTransform(to_float_ptr(world));
 
-	_shader_manager->submit(STRING_ID_32("gui", UINT32_C(0x66dbf9a2)), VIEW_GUI);
+	_shader_manager->submit(STRING_ID_32("gui", UINT32_C(0x66dbf9a2)), VIEW_GUI, depth);
 
 	_num_vertices += num_vertices;
 	_num_indices += num_indices;
 }
 
-void GuiBuffer::submit_with_material(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, Material *material)
+void GuiBuffer::submit_with_material(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, u32 depth, Material *material)
 {
 	bgfx::setVertexBuffer(0, &_vertex_buffer, _num_vertices, num_vertices);
 	bgfx::setIndexBuffer(&_index_buffer, _num_indices, num_indices);
 	bgfx::setTransform(to_float_ptr(world));
 
-	material->bind(*_shader_manager, VIEW_GUI);
+	material->bind(*_shader_manager, VIEW_GUI, depth);
 
 	_num_vertices += num_vertices;
 	_num_indices += num_indices;
@@ -104,7 +109,7 @@ void Gui::move(const Vector2 &pos)
 	set_translation(_world, vector3(pos.x, pos.y, 0));
 }
 
-void Gui::triangle_3d(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Color4 &color)
+void Gui::triangle_3d(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Color4 &color, f32 depth)
 {
 	VertexData *vd = (VertexData *)_buffer->vertex_buffer_end();
 	vd[0].pos.x = a.x;
@@ -133,15 +138,15 @@ void Gui::triangle_3d(const Vector3 &a, const Vector3 &b, const Vector3 &c, cons
 	inds[1] = 1;
 	inds[2] = 2;
 
-	_buffer->submit(3, 3, _world);
+	_buffer->submit(3, 3, _world, depth_u32(depth));
 }
 
-void Gui::triangle(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Color4 &color)
+void Gui::triangle(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Color4 &color, f32 depth)
 {
-	triangle_3d(vector3(a.x, a.y, 0.0f), vector3(b.x, b.y, 0.0f), vector3(c.x, c.y, 0.0f), color);
+	triangle_3d(vector3(a.x, a.y, 0.0f), vector3(b.x, b.y, 0.0f), vector3(c.x, c.y, 0.0f), color, depth);
 }
 
-void Gui::rect_3d(const Vector3 &pos, const Vector2 &size, const Color4 &color)
+void Gui::rect_3d(const Vector3 &pos, const Vector2 &size, const Color4 &color, f32 depth)
 {
 	VertexData *vd = (VertexData *)_buffer->vertex_buffer_end();
 	vd[0].pos.x = pos.x;
@@ -180,15 +185,15 @@ void Gui::rect_3d(const Vector3 &pos, const Vector2 &size, const Color4 &color)
 	inds[4] = 2;
 	inds[5] = 3;
 
-	_buffer->submit(4, 6, _world);
+	_buffer->submit(4, 6, _world, depth_u32(depth));
 }
 
-void Gui::rect(const Vector2 &pos, const Vector2 &size, const Color4 &color)
+void Gui::rect(const Vector3 &pos, const Vector2 &size, const Color4 &color)
 {
-	rect_3d(vector3(pos.x, pos.y, 0.0f), size, color);
+	rect_3d(vector3(pos.x, pos.y, 0.0f), size, color, pos.z);
 }
 
-void Gui::image_uv_3d(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color)
+void Gui::image_uv_3d(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color, f32 depth)
 {
 	VertexData *vd = (VertexData *)_buffer->vertex_buffer_end();
 	vd[0].pos.x = pos.x;
@@ -232,26 +237,27 @@ void Gui::image_uv_3d(const Vector3 &pos, const Vector2 &size, const Vector2 &uv
 	_buffer->submit_with_material(4
 		, 6
 		, _world
+		, depth_u32(depth)
 		, _material_manager->get(mr)
 		);
 }
 
-void Gui::image_uv(const Vector2 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color)
+void Gui::image_uv(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color)
 {
-	image_uv_3d(vector3(pos.x, pos.y, 0.0f), size, uv0, uv1, material, color);
+	image_uv_3d(vector3(pos.x, pos.y, 0.0f), size, uv0, uv1, material, color, pos.z);
 }
 
-void Gui::image_3d(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color)
+void Gui::image_3d(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color, f32 depth)
 {
-	image_uv_3d(pos, size, VECTOR2_ZERO, VECTOR2_ONE, material, color);
+	image_uv_3d(pos, size, VECTOR2_ZERO, VECTOR2_ONE, material, color, depth);
 }
 
-void Gui::image(const Vector2 &pos, const Vector2 &size, StringId64 material, const Color4 &color)
+void Gui::image(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color)
 {
-	image_3d(vector3(pos.x, pos.y, 0.0f), size, material, color);
+	image_3d(vector3(pos.x, pos.y, 0.0f), size, material, color, pos.z);
 }
 
-void Gui::text_3d(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color)
+void Gui::text_3d(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color, f32 depth)
 {
 	const MaterialResource *mr = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, material);
 	_material_manager->create_material(mr);
@@ -356,13 +362,14 @@ void Gui::text_3d(const Vector3 &pos, u32 font_size, const char *str, StringId64
 	_buffer->submit_with_material(num_vertices
 		, num_indices
 		, _world
+		, depth_u32(depth)
 		, _material_manager->get(mr)
 		);
 }
 
-void Gui::text(const Vector2 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color)
+void Gui::text(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color)
 {
-	text_3d(vector3(pos.x, pos.y, 0.0f), font_size, str, font, material, color);
+	text_3d(vector3(pos.x, pos.y, 0.0f), font_size, str, font, material, color, pos.z);
 }
 
 Material *Gui::material(ResourceId material_resource)

+ 12 - 12
src/world/gui.h

@@ -41,10 +41,10 @@ struct GuiBuffer
 	void reset();
 
 	///
-	void submit(u32 num_vertices, u32 num_indices, const Matrix4x4 &world);
+	void submit(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, u32 depth);
 
 	///
-	void submit_with_material(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, Material *material);
+	void submit_with_material(u32 num_vertices, u32 num_indices, const Matrix4x4 &world, u32 depth, Material *material);
 };
 
 /// Immediate mode Gui.
@@ -83,34 +83,34 @@ struct Gui
 	void move(const Vector2 &pos);
 
 	///
-	void triangle_3d(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Color4 &color);
+	void triangle_3d(const Vector3 &a, const Vector3 &b, const Vector3 &c, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void triangle(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Color4 &color);
+	void triangle(const Vector2 &a, const Vector2 &b, const Vector2 &c, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void rect_3d(const Vector3 &pos, const Vector2 &size, const Color4 &color);
+	void rect_3d(const Vector3 &pos, const Vector2 &size, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void rect(const Vector2 &pos, const Vector2 &size, const Color4 &color);
+	void rect(const Vector3 &pos, const Vector2 &size, const Color4 &color);
 
 	///
-	void image_3d(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color);
+	void image_3d(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void image(const Vector2 &pos, const Vector2 &size, StringId64 material, const Color4 &color);
+	void image(const Vector3 &pos, const Vector2 &size, StringId64 material, const Color4 &color);
 
 	///
-	void image_uv_3d(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color);
+	void image_uv_3d(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void image_uv(const Vector2 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color);
+	void image_uv(const Vector3 &pos, const Vector2 &size, const Vector2 &uv0, const Vector2 &uv1, StringId64 material, const Color4 &color);
 
 	///
-	void text_3d(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color);
+	void text_3d(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color, f32 depth = 0.0f);
 
 	///
-	void text(const Vector2 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color);
+	void text(const Vector3 &pos, u32 font_size, const char *str, StringId64 font, StringId64 material, const Color4 &color);
 
 	/// Returns the material @a material_resource.
 	Material *material(ResourceId material_resource);