From 48d673680d7de9b62275eb6c4f99ad0e2982fd9c Mon Sep 17 00:00:00 2001 From: harrand Date: Mon, 9 Dec 2024 00:50:15 +0000 Subject: [PATCH] [ren.quad] multi texture support. texture0 is colour, texture1 is unused and intended for use by those who provide a custom fragment shader --- include/tz/ren/quad.hpp | 27 ++++++++++++++++----- src/tz/ren/quad.cpp | 45 +++++++++++++++++++++++++++-------- src/tz/ren/quad.fragment.tzsl | 9 +++---- src/tz/ren/quad.vertex.tzsl | 13 ++++++---- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/include/tz/ren/quad.hpp b/include/tz/ren/quad.hpp index e4fcfa66c2..afadf70f54 100644 --- a/include/tz/ren/quad.hpp +++ b/include/tz/ren/quad.hpp @@ -116,8 +116,10 @@ namespace tz::ren float rotation = 0.0f; /// Scale factors of the quad, in both dimensions. You can change this later via @ref set_quad_scale. tz::v2f scale = tz::v2f::filled(1.0f); - /// Texture to display on the quad. Defaults to -1 (no texture). If no texture is used, then the quad will have a solid colour corresponding to @ref colour. You can change this later via @ref set_quad_texture. - std::uint32_t texture_id = -1; + /// First texture to display on the quad. Defaults to -1 (no texture). If no texture is used, then the quad will have a solid colour corresponding to @ref colour. You can change this later via @ref set_quad_texture0. + std::uint32_t texture_id0 = -1; + /// First texture to display on the quad. Defaults to -1 (no texture). If no texture is used, then the quad will have a solid colour corresponding to @ref colour. You can change this later via @ref set_quad_texture1. + std::uint32_t texture_id1 = -1; /// Colour of the quad. If the quad has no texture, this will be the exact colour of the whole quad. If the quad *does* have a texture, then the sampled texture colour will be multiplied by this value (in which case you will often want to provide {1, 1, 1}). You can change this later via @ref set_quad_colour. tz::v3f colour = tz::v3f::filled(1.0f); /// Layer value. Has no effect if layering is not enabled (see @ref quad_renderer_flag::enable_layering for more details). @@ -204,17 +206,30 @@ namespace tz::ren /** * @ingroup tz_ren_quad - * @brief Retrieve the texture-id currently being used by a quad. + * @brief Retrieve the first texture-id currently being used by a quad. * @return (-1) If the quad was not using a texture. */ - std::uint32_t get_quad_texture(quad_renderer_handle renh, quad_handle quad); + std::uint32_t get_quad_texture0(quad_renderer_handle renh, quad_handle quad); /** * @ingroup tz_ren_quad - * @brief Set a new texture-id to be used by a quad. + * @brief Retrieve the second texture-id currently being used by a quad. + * @return (-1) If the quad was not using a texture. + */ + std::uint32_t get_quad_texture1(quad_renderer_handle renh, quad_handle quad); + /** + * @ingroup tz_ren_quad + * @brief Set a new first texture-id to be used by a quad. + * + * Note: Passing -1 as the texture-id will cause the quad to no longer sample from a texture. + */ + void set_quad_texture0(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id); + /** + * @ingroup tz_ren_quad + * @brief Set a new second texture-id to be used by a quad. * * Note: Passing -1 as the texture-id will cause the quad to no longer sample from a texture. */ - void set_quad_texture(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id); + void set_quad_texture1(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id); /** * @ingroup tz_ren_quad diff --git a/src/tz/ren/quad.cpp b/src/tz/ren/quad.cpp index c01e20b5b0..014a60c34a 100644 --- a/src/tz/ren/quad.cpp +++ b/src/tz/ren/quad.cpp @@ -41,9 +41,10 @@ namespace tz::ren { tz::m4f model = tz::m4f::iden(); tz::v3f colour = {1.0f, 1.0f, 1.0f}; - std::uint32_t texture_id = -1; + std::uint32_t texture_id0 = -1; + std::uint32_t texture_id1 = -1; std::int32_t layer = 0; - std::uint32_t unused[3]; + std::uint32_t unused[2]; }; struct camera_data @@ -202,14 +203,23 @@ namespace tz::ren quad_data new_data; new_data.model = internal.transform.matrix(); new_data.colour = info.colour; - new_data.texture_id = info.texture_id; + new_data.texture_id0 = info.texture_id0; + new_data.texture_id1 = info.texture_id1; new_data.layer = info.layer; - if(info.texture_id != static_cast(-1)) + if(info.texture_id0 != static_cast(-1)) { - if(info.texture_id >= ren.texture_count) + if(info.texture_id0 >= ren.texture_count) { - UNERR(tz::error_code::invalid_value, "attempt to create quad with texture-id {}, but this is not a valid texture -- the quad renderer only has {} registered textures", info.texture_id, ren.texture_count); + UNERR(tz::error_code::invalid_value, "attempt to create quad with texture-id {}, but this is not a valid texture -- the quad renderer only has {} registered textures", info.texture_id0, ren.texture_count); + } + } + + if(info.texture_id1 != static_cast(-1)) + { + if(info.texture_id1 >= ren.texture_count) + { + UNERR(tz::error_code::invalid_value, "attempt to create quad with texture-id {}, but this is not a valid texture -- the quad renderer only has {} registered textures", info.texture_id1, ren.texture_count); } } @@ -341,17 +351,32 @@ namespace tz::ren tz::gpu::resource_write(ren.data_buffer, std::as_bytes(std::span(&colour, 1)), offset); } - std::uint32_t get_quad_texture(quad_renderer_handle renh, quad_handle quad) + std::uint32_t get_quad_texture0(quad_renderer_handle renh, quad_handle quad) + { + const auto& ren = renderers[renh.peek()]; + auto quad_data_array = tz::gpu::resource_read(ren.data_buffer); + return *reinterpret_cast(quad_data_array.data() + (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id0)); + } + + std::uint32_t get_quad_texture1(quad_renderer_handle renh, quad_handle quad) { const auto& ren = renderers[renh.peek()]; auto quad_data_array = tz::gpu::resource_read(ren.data_buffer); - return *reinterpret_cast(quad_data_array.data() + (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id)); + return *reinterpret_cast(quad_data_array.data() + (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id1)); + } + + void set_quad_texture0(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id) + { + auto& ren = renderers[renh.peek()]; + std::size_t offset = (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id0); + + tz::gpu::resource_write(ren.data_buffer, std::as_bytes(std::span(&texture_id, 1)), offset); } - void set_quad_texture(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id) + void set_quad_texture1(quad_renderer_handle renh, quad_handle quad, std::uint32_t texture_id) { auto& ren = renderers[renh.peek()]; - std::size_t offset = (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id); + std::size_t offset = (sizeof(quad_data) * quad.peek()) + offsetof(quad_data, texture_id1); tz::gpu::resource_write(ren.data_buffer, std::as_bytes(std::span(&texture_id, 1)), offset); } diff --git a/src/tz/ren/quad.fragment.tzsl b/src/tz/ren/quad.fragment.tzsl index 13886ec614..fc781a0dd1 100644 --- a/src/tz/ren/quad.fragment.tzsl +++ b/src/tz/ren/quad.fragment.tzsl @@ -3,16 +3,17 @@ shader(type = fragment); input(id = 0) vec3 tint; input(id = 1) vec2 uv; input(id = 2, flat) uint quad_id; -input(id = 3, flat) uint texture_id; -input(id = 4, flat) uint alpha_clipping; +input(id = 3, flat) uint texture_id0; +input(id = 4, flat) uint texture_id1; +input(id = 5, flat) uint alpha_clipping; output(id = 0) vec4 colour; void main() { vec4 frag_colour = vec4(tint, 0.0f); - if(texture_id != -1) + if(texture_id0 != -1) { - vec4 texcol = sample(texture_id, uv); + vec4 texcol = sample(texture_id0, uv); frag_colour.a = texcol.a; if(alpha_clipping > 0 && texcol.a < 0.05f) { diff --git a/src/tz/ren/quad.vertex.tzsl b/src/tz/ren/quad.vertex.tzsl index 6784fabccf..933fdeedf5 100644 --- a/src/tz/ren/quad.vertex.tzsl +++ b/src/tz/ren/quad.vertex.tzsl @@ -4,9 +4,10 @@ struct quad_data { mat4 model; vec3 colour; - uint texture_id; + uint texture_id0; + uint texture_id1; int layer; - uint unused[3]; + uint unused[2]; }; buffer(id = 0) const quad @@ -27,8 +28,9 @@ buffer(id = 2) const settings output(id = 0) vec3 out::tint; output(id = 1) vec2 out::uv; output(id = 2) uint out::quad_id; -output(id = 3) uint out::texture_id; -output(id = 4) uint out::alpha_clipping; +output(id = 3) uint out::texture_id0; +output(id = 4) uint out::texture_id1; +output(id = 5) uint out::alpha_clipping; vec2 quad_positions[6] = vec2[]( vec2(1.0, -1.0), vec2(1.0, 1.0), vec2(-1.0, -1.0), @@ -63,6 +65,7 @@ void main() out::tint = vec3(cur_quad.colour); out::uv = quad_texcoords[in::vertex_id % 6]; - out::texture_id = cur_quad.texture_id; + out::texture_id0 = cur_quad.texture_id0; + out::texture_id1 = cur_quad.texture_id1; out::alpha_clipping = uint(settings.value & 0x01); }