diff options
-rw-r--r-- | draw/anim.cpp | 6 | ||||
-rw-r--r-- | draw/floor.cpp | 3 | ||||
-rw-r--r-- | draw/wall.cpp | 3 | ||||
-rw-r--r-- | draw/wireframe.cpp | 3 | ||||
-rw-r--r-- | floormat/main.hpp | 3 | ||||
-rw-r--r-- | main/main-impl.hpp | 6 | ||||
-rw-r--r-- | main/setup.cpp | 2 | ||||
-rw-r--r-- | shaders/lightmap.cpp | 8 | ||||
-rw-r--r-- | shaders/lightmap.hpp | 6 | ||||
-rw-r--r-- | shaders/shader.cpp | 31 | ||||
-rw-r--r-- | shaders/shader.hpp | 25 |
11 files changed, 63 insertions, 33 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp index 0270ef6d..02421ddb 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -77,10 +77,9 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st { fm_assert(i < size); GL::MeshView mesh{mesh_}; - atlas.texture().bind(0); mesh.setCount((int)(quad_index_count * 1)); mesh.setIndexRange((int)(x.mesh_idx*quad_index_count), 0, max_index); - shader.draw(mesh); + shader.draw(atlas.texture(), mesh); i++; } else @@ -105,8 +104,7 @@ void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t for (auto i = 0uz; i < 4; i++) array[i] = { pos[i], texcoords[i], depth }; _vertex_buffer.setSubData(0, array); - atlas.texture().bind(0); - shader.draw(_mesh); + shader.draw(atlas.texture(), _mesh); } void anim_mesh::draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, local_coords xy, Vector2b offset, float depth) diff --git a/draw/floor.cpp b/draw/floor.cpp index d030c5a6..8e92c966 100644 --- a/draw/floor.cpp +++ b/draw/floor.cpp @@ -25,10 +25,9 @@ void floor_mesh::draw(tile_shader& shader, chunk& c) return; if (auto len = i - last.pos; last.atlas && len > 0) { - last.atlas->texture().bind(0); mesh.setCount((int)(quad_index_count * len)); mesh.setIndexRange((int)(last.pos*quad_index_count), 0, max_index); - shader.draw(mesh); + shader.draw(last.atlas->texture(), mesh); draw_count++; } last = { atlas, i }; diff --git a/draw/wall.cpp b/draw/wall.cpp index 4562a250..f6f06c4c 100644 --- a/draw/wall.cpp +++ b/draw/wall.cpp @@ -26,10 +26,9 @@ void wall_mesh::draw(tile_shader& shader, chunk& c) return; if (auto len = i - last.pos; last.atlas && len > 0) { - last.atlas->texture().bind(0); mesh.setCount((int)(quad_index_count * len)); mesh.setIndexRange((int)(last.pos*quad_index_count), 0, max_index); - shader.draw(mesh); + shader.draw(last.atlas->texture(), mesh); draw_count++; } last = { atlas, i }; diff --git a/draw/wireframe.cpp b/draw/wireframe.cpp index 28621b8f..5d041991 100644 --- a/draw/wireframe.cpp +++ b/draw/wireframe.cpp @@ -50,8 +50,7 @@ mesh_base::mesh_base(GL::MeshPrimitive primitive, ArrayView<const void> index_da void mesh_base::draw(tile_shader& shader) { - _texture->bind(0); - shader.draw(_mesh); + shader.draw(*_texture, _mesh); } void mesh_base::set_subdata(ArrayView<const void> array) diff --git a/floormat/main.hpp b/floormat/main.hpp index b80d92ce..55b398d2 100644 --- a/floormat/main.hpp +++ b/floormat/main.hpp @@ -21,6 +21,7 @@ struct clickable; struct floor_mesh; struct wall_mesh; struct anim_mesh; +struct texture_unit_cache; struct floormat_main { @@ -77,6 +78,8 @@ struct floormat_main void set_render_vobjs(bool value); bool is_rendering_vobjs() const; + virtual struct texture_unit_cache& texture_unit_cache() = 0; + [[nodiscard]] static floormat_main* create(floormat_app& app, fm_settings&& options); [[maybe_unused]] static void debug_break(); diff --git a/main/main-impl.hpp b/main/main-impl.hpp index 2afac162..6e416549 100644 --- a/main/main-impl.hpp +++ b/main/main-impl.hpp @@ -5,6 +5,7 @@ #include "draw/floor.hpp" #include "draw/wall.hpp" #include "draw/anim.hpp" +#include "shaders/texture-unit-cache.hpp" #include "shaders/shader.hpp" #include "shaders/lightmap.hpp" #include "main/clickable.hpp" @@ -94,12 +95,15 @@ struct main_impl final : Platform::Sdl2Application, floormat_main void set_cursor(uint32_t cursor) noexcept override; uint32_t cursor() const noexcept override; + struct texture_unit_cache& texture_unit_cache() override { return _tuc; } + private: + struct texture_unit_cache _tuc; fm_settings s; [[maybe_unused]] char _dummy = (register_debug_callback(), '\0'); floormat_app& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members) tile_shader _shader; - struct lightmap_shader _lightmap_shader; + struct lightmap_shader _lightmap_shader{_tuc}; std::vector<clickable> _clickable_scenery; struct world _world{}; Magnum::Timeline timeline; diff --git a/main/setup.cpp b/main/setup.cpp index 93f3b943..15b34b2b 100644 --- a/main/setup.cpp +++ b/main/setup.cpp @@ -9,7 +9,7 @@ namespace floormat { main_impl::main_impl(floormat_app& app, fm_settings&& se, int& argc, char** argv) noexcept : Platform::Sdl2Application{Arguments{argc, argv}, make_conf(se), make_gl_conf(se)}, - s{std::move(se)}, app{app} + s{std::move(se)}, app{app}, _shader{_tuc} { if (s.vsync) { diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp index 3e3967ee..a1635fa1 100644 --- a/shaders/lightmap.cpp +++ b/shaders/lightmap.cpp @@ -170,7 +170,7 @@ std::array<Vector3, 4>& lightmap_shader::alloc_rect() } } -lightmap_shader::lightmap_shader() +lightmap_shader::lightmap_shader(texture_unit_cache& tuc) : tuc{tuc} { constexpr auto min_version = GL::Version::GL330; const auto version = GL::Context::current().version(); @@ -199,8 +199,8 @@ lightmap_shader::lightmap_shader() }}; light_mesh = make_light_mesh(GL::Buffer{blend_vertexes}, GL::Buffer{quad_indexes(0)}); - framebuffer.scratch.bind(TextureSampler); - setUniform(SamplerUniform, TextureSampler); + //framebuffer.scratch.bind(TextureSampler); + setUniform(SamplerUniform, -1); setUniform(LightColorUniform, Color3{1, 1, 1}); setUniform(SizeUniform, Vector2(1)); setUniform(CenterFragcoordUniform, Vector2(0, 0)); @@ -264,10 +264,10 @@ void lightmap_shader::add_light(Vector2 neighbor_offset, const light_s& light) mesh_view.setCount((int32_t)count*6); AbstractShaderProgram::draw(mesh_view); + setUniform(SamplerUniform, tuc.bind(framebuffer.scratch)); framebuffer.fb.mapForDraw({ { 1u, GL::Framebuffer::ColorAttachment{1} }, }); - setUniform(ModeUniform, BlendLightmapMode); AbstractShaderProgram::draw(light_mesh); } diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp index 5bd38069..2c08cc62 100644 --- a/shaders/lightmap.hpp +++ b/shaders/lightmap.hpp @@ -1,6 +1,7 @@ #pragma once #include "light-falloff.hpp" +#include "shaders/texture-unit-cache.hpp" #include <array> #include <Corrade/Containers/Array.h> #include <Corrade/Containers/Optional.h> @@ -16,6 +17,8 @@ namespace floormat { +struct texture_unit_cache; + struct light_s final { Vector2 center; @@ -31,7 +34,7 @@ struct chunk; struct lightmap_shader final : GL::AbstractShaderProgram { - explicit lightmap_shader(); + explicit lightmap_shader(texture_unit_cache& tuc); ~lightmap_shader() override; struct Framebuffer final { @@ -85,6 +88,7 @@ private: void add_rect(Vector2 neighbor_offset, Pair<Vector2, Vector2> minmax); [[nodiscard]] std::array<Vector3, 4>& alloc_rect(); + texture_unit_cache& tuc; GL::Buffer vertex_buf{NoCreate}, index_buf{NoCreate}; Array<std::array<Vector3, 4>> vertexes; // todo make a contiguous allocation Array<std::array<UnsignedShort, 6>> indexes; diff --git a/shaders/shader.cpp b/shaders/shader.cpp index 4b184057..22222842 100644 --- a/shaders/shader.cpp +++ b/shaders/shader.cpp @@ -12,7 +12,7 @@ namespace floormat { -tile_shader::tile_shader() +tile_shader::tile_shader(texture_unit_cache& tuc) : tuc{tuc} { constexpr auto min_version = GL::Version::GL330; const auto version = GL::Context::current().version(); @@ -34,7 +34,7 @@ tile_shader::tile_shader() set_tint({1, 1, 1, 1}); setUniform(OffsetUniform, Vector3(Vector2(_camera_offset), _depth_offset)); setUniform(EnableLightmapUniform, _enable_lightmap); - setUniform(SamplerUniform, 0); + setUniform(SamplerUniform, _real_sampler = _sampler); setUniform(LightmapSamplerUniform, 1); } @@ -67,7 +67,13 @@ tile_shader& tile_shader::set_lightmap_enabled(bool value) return *this; } -void tile_shader::_draw() +tile_shader& tile_shader::set_sampler(Int sampler) +{ + _sampler = sampler; + return *this; +} + +void tile_shader::draw_pre(GL::AbstractTexture& tex) { fm_assert(std::fabs(_camera_offset[0]) < 1 << 24 && std::fabs(_camera_offset[1]) < 1 << 24); fm_assert(std::fabs(_depth_offset) < 1 << 24); @@ -75,12 +81,19 @@ void tile_shader::_draw() if (_tint != _real_tint) setUniform(TintUniform, _real_tint = _tint); - if (const auto offset = Vector3(Vector2(_camera_offset), _depth_offset); - offset != _real_camera_offset) - { - _real_camera_offset = offset; - setUniform(OffsetUniform, offset); - } + const auto offset = Vector3(Vector2(_camera_offset), _depth_offset); + if (offset != _real_camera_offset) + setUniform(OffsetUniform, _real_camera_offset = offset); + + auto id = tuc.bind(tex); + set_sampler(id); + if (_sampler != _real_sampler) + setUniform(SamplerUniform, _real_sampler = _sampler); +} + +void tile_shader::draw_post(GL::AbstractTexture& tex) // NOLINT(*-convert-member-functions-to-static) +{ + (void)tex; } float tile_shader::depth_value(const local_coords& xy, float offset) noexcept diff --git a/shaders/shader.hpp b/shaders/shader.hpp index e53fb6d3..bd0f5884 100644 --- a/shaders/shader.hpp +++ b/shaders/shader.hpp @@ -1,11 +1,14 @@ #pragma once #include "tile-defs.hpp" -#include <Corrade/Utility/Move.h> +#include "shaders/texture-unit-cache.hpp" +#include <utility> #include <Magnum/GL/AbstractShaderProgram.h> #include <Magnum/Math/Vector2.h> #include <Magnum/Math/Vector3.h> #include <Magnum/Math/Vector4.h> +namespace Magnum::GL { class AbstractTexture; } + namespace floormat { struct local_coords; @@ -17,7 +20,7 @@ struct tile_shader final : private GL::AbstractShaderProgram using LightCoord = GL::Attribute<2, Vector2>; using Depth = GL::Attribute<3, float>; - explicit tile_shader(); + explicit tile_shader(texture_unit_cache& tuc); ~tile_shader() override; Vector2 scale() const { return _scale; } @@ -34,7 +37,7 @@ struct tile_shader final : private GL::AbstractShaderProgram template<typename T = float> static constexpr Math::Vector2<T> project(const Math::Vector3<T>& pt); template<typename T = float> static constexpr Math::Vector2<T> unproject(const Math::Vector2<T>& px); - template<typename T, typename... Xs> decltype(auto) draw(T&& mesh, Xs&&... xs); + template<typename T, typename... Xs> decltype(auto) draw(GL::AbstractTexture& tex, T&& mesh, Xs&&... xs); static constexpr Vector2s max_screen_tiles = {8, 8}; static constexpr float character_depth_offset = 1 + 1./64; @@ -45,15 +48,21 @@ struct tile_shader final : private GL::AbstractShaderProgram static constexpr float depth_tile_size = 1.f/(TILE_MAX_DIM * 2 * max_screen_tiles.product()); static constexpr float foreshortening_factor = 0.578125f; + tile_shader& set_sampler(Int sampler); + Int sampler() const { return _sampler; } + private: - void _draw(); + void draw_pre(GL::AbstractTexture& tex); + void draw_post(GL::AbstractTexture& tex); + texture_unit_cache& tuc; // NOLINT(*-avoid-const-or-ref-data-members) Vector2d _camera_offset; Vector4 _tint, _real_tint; Vector2 _scale; Vector3 _real_camera_offset; float _depth_offset = 0; bool _enable_lightmap : 1 = false; + Int _sampler = 0, _real_sampler; enum { ScaleUniform = 0, OffsetUniform = 1, TintUniform = 2, @@ -63,10 +72,12 @@ private: }; template<typename T, typename... Xs> -decltype(auto) tile_shader::draw(T&& mesh, Xs&&... xs) +decltype(auto) tile_shader::draw(GL::AbstractTexture& tex, T&& mesh, Xs&&... xs) { - _draw(); - return GL::AbstractShaderProgram::draw(Utility::forward<T>(mesh), Utility::forward<Xs>(xs)...); + draw_pre(tex); + decltype(auto) ret = GL::AbstractShaderProgram::draw(std::forward<T>(mesh), std::forward<Xs>(xs)...); + draw_post(tex); + return ret; } template<typename T> |