summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--draw/anim.cpp6
-rw-r--r--draw/floor.cpp3
-rw-r--r--draw/wall.cpp3
-rw-r--r--draw/wireframe.cpp3
-rw-r--r--floormat/main.hpp3
-rw-r--r--main/main-impl.hpp6
-rw-r--r--main/setup.cpp2
-rw-r--r--shaders/lightmap.cpp8
-rw-r--r--shaders/lightmap.hpp6
-rw-r--r--shaders/shader.cpp31
-rw-r--r--shaders/shader.hpp25
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>