summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-06-10 06:46:49 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-06-10 06:46:49 +0200
commitf7898053802ea38630f93034d0cd1555492fbc56 (patch)
treef81955574f7ecc24ff26ee770c45768a366d0202
parentdc913f11422e002059029cac8da2d6b9a725656a (diff)
wip
-rw-r--r--draw/anim.cpp14
-rw-r--r--main/main-impl.hpp2
-rw-r--r--resources.conf6
-rw-r--r--shaders/lightmap.cpp149
-rw-r--r--shaders/lightmap.frag23
-rw-r--r--shaders/lightmap.hpp76
-rw-r--r--shaders/lightmap.vert12
-rw-r--r--src/chunk-collision.cpp36
-rw-r--r--src/chunk.hpp14
-rw-r--r--src/tile-bbox.hpp46
-rw-r--r--userconfig-sthalik@Windows-GNU.cmake2
11 files changed, 282 insertions, 98 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp
index 03f6df76..254661e5 100644
--- a/draw/anim.cpp
+++ b/draw/anim.cpp
@@ -63,14 +63,6 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st
GL::MeshView mesh{mesh_};
const auto max_index = uint32_t(size*quad_index_count - 1);
- constexpr auto do_draw = [](tile_shader& shader, GL::Mesh& mesh_, anim_atlas* atlas, uint32_t i, uint32_t max_index) {
- GL::MeshView mesh{mesh_};
- atlas->texture().bind(0);
- mesh.setCount((int)(quad_index_count * 1));
- mesh.setIndexRange((int)(i*quad_index_count), 0, max_index);
- shader.draw(mesh);
- };
-
uint32_t i = 0;
for (const auto& x : es)
@@ -84,7 +76,11 @@ void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, st
if (!e.is_dynamic())
{
fm_assert(i < size);
- do_draw(shader, mesh_, &atlas, x.mesh_idx, max_index);
+ GL::MeshView mesh{mesh_};
+ atlas.texture().bind(0);
+ mesh.setCount((int)(quad_index_count * 1));
+ mesh.setIndexRange((int)(i*quad_index_count), 0, max_index);
+ shader.draw(mesh);
i++;
}
else
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index 3a3e4c7b..f5dc5010 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -6,6 +6,7 @@
#include "draw/wall.hpp"
#include "draw/anim.hpp"
#include "shaders/shader.hpp"
+#include "shaders/lightmap.hpp"
#include "main/clickable.hpp"
#include <vector>
#include <Corrade/Containers/String.h>
@@ -95,6 +96,7 @@ private:
[[maybe_unused]] char _dummy = (register_debug_callback(), '\0');
floormat_app& app; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
tile_shader _shader;
+ lightmap_shader _lightmap_shader;
std::vector<clickable> _clickable_scenery;
struct world _world{};
Magnum::Timeline timeline;
diff --git a/resources.conf b/resources.conf
index 2cde441c..cdd59355 100644
--- a/resources.conf
+++ b/resources.conf
@@ -5,3 +5,9 @@ filename=shaders/shader.frag
[file]
filename=shaders/shader.vert
+
+[file]
+filename=shaders/lightmap.frag
+
+[file]
+filename=shaders/lightmap.vert
diff --git a/shaders/lightmap.cpp b/shaders/lightmap.cpp
index 3575e424..8e8e1884 100644
--- a/shaders/lightmap.cpp
+++ b/shaders/lightmap.cpp
@@ -1,20 +1,153 @@
-#include "lightmap.hpp"
-#include "src/local-coords.hpp"
+#include "shaders/lightmap.hpp"
+#include "compat/assert.hpp"
+#include "src/tile-defs.hpp"
+#include "loader/loader.hpp"
+#include <Corrade/Containers/Iterable.h>
+#include <Magnum/Magnum.h>
+#include <Magnum/GL/MeshView.h>
+#include <Magnum/GL/Shader.h>
+#include <Magnum/GL/Version.h>
+//#include "src/tile-bbox.hpp"
-#ifdef __clang__
-#pragma clang diagnostic ignored "-Wfloat-equal"
+#if defined __CLION_IDE__ || defined __clang__
+#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
namespace floormat {
-lightmap_shader::~lightmap_shader() = default;
-bool lightmap_shader::light_s::operator==(const light_s&) const noexcept = default;
+namespace {
+
+constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM;
+constexpr auto chunk_offset = TILE_SIZE2/2;
+constexpr auto image_size = iTILE_SIZE2 * TILE_MAX_DIM;
+constexpr auto buffer_size = 256uz;
-static constexpr Vector2 output_size = TILE_MAX_DIM * TILE_SIZE2 * 3;
+} // namespace
-lightmap_shader::lightmap_shader()
+auto lightmap_shader::make_framebuffer() -> Framebuffer
{
+ Framebuffer framebuffer;
+
+ framebuffer.fb = GL::Framebuffer{{ {}, image_size }};
+
+ framebuffer.color = GL::Texture2D{};
+ framebuffer.color.setStorage(1, GL::TextureFormat::RGBA8, image_size);
+ //framebuffer.depth = GL::Renderbuffer{};
+ //framebuffer.depth.setStorage(GL::RenderbufferFormat::DepthComponent32F, fb_size);
+
+ framebuffer.fb.attachTexture(GL::Framebuffer::ColorAttachment{0}, framebuffer.color, 0);
+ //framebuffer.fb.attachRenderbuffer(GL::Framebuffer::BufferAttachment::Depth, framebuffer.depth);
+ framebuffer.fb.clearColor(0, Color4{0.f, 0.f, 0.f, 1.f});
+ //framebuffer.fb.clearDepth(0);
+
+ return framebuffer;
+}
+GL::Mesh lightmap_shader::make_mesh()
+{
+ GL::Mesh mesh{GL::MeshPrimitive::Triangles};
+ mesh.addVertexBuffer(_vertex_buf, 0, Position{})
+ .setIndexBuffer(_index_buf, 0, GL::MeshIndexType::UnsignedShort)
+ .setCount(int32_t(6 * buffer_size));
+ return mesh;
}
+lightmap_shader::lightmap_shader() :
+ framebuffer { make_framebuffer() },
+ _quads { ValueInit, buffer_size },
+ _indexes { ValueInit, buffer_size },
+ _vertex_buf { _quads },
+ _index_buf { _indexes },
+ _mesh { make_mesh() }
+{
+ constexpr auto min_version = GL::Version::GL330;
+ const auto version = GL::Context::current().version();
+
+ if (version < min_version)
+ fm_abort("floormat requires OpenGL version %d, only %d is supported", (int)min_version, (int)version);
+
+ GL::Shader vert{version, GL::Shader::Type::Vertex};
+ GL::Shader frag{version, GL::Shader::Type::Fragment};
+
+ vert.addSource(loader.shader("shaders/lightmap.vert"));
+ frag.addSource(loader.shader("shaders/lightmap.frag"));
+
+ CORRADE_INTERNAL_ASSERT_OUTPUT(vert.compile());
+ CORRADE_INTERNAL_ASSERT_OUTPUT(frag.compile());
+ attachShaders({vert, frag});
+ CORRADE_INTERNAL_ASSERT_OUTPUT(link());
+}
+
+void lightmap_shader::flush_vertexes()
+{
+ // todo
+}
+
+void lightmap_shader::clear()
+{
+ framebuffer.fb.clearColor(0, Color4{1.f, 0.f, 1.f, 1.f});
+ //framebuffer.fb.clearDepth(0);
+}
+
+void lightmap_shader::bind()
+{
+ framebuffer.fb.bind();
+}
+
+std::array<UnsignedShort, 6> lightmap_shader::quad_indexes(size_t N)
+{
+ using u16 = UnsignedShort;
+ return { /* 3--1 1 */
+ (u16)(0+N*4), (u16)(1+N*4), (u16)(2+N*4), /* | / /| */
+ (u16)(2+N*4), (u16)(1+N*4), (u16)(3+N*4), /* |/ / | */
+ }; /* 2 2--0 */
+}
+
+void lightmap_shader::add_light(Vector2i neighbor_offset, const light_s& light)
+{
+ fm_debug_assert(_count == 0);
+
+ constexpr auto tile_size = TILE_SIZE2.sum()/2;
+ constexpr auto scale = 2/chunk_size;
+ auto dist = std::fmax(0.f, light.dist * tile_size);
+ auto center = light.center + chunk_offset + Vector2(neighbor_offset)*chunk_size;
+ auto center_clip = Vector2{center} * scale; // clip coordinate
+ constexpr auto image_size_factor = Vector2(image_size) / Vector2(chunk_size);
+ auto center_fragcoord = center * image_size_factor; // window-relative coordinates
+
+ _indexes[0] = quad_indexes(0);
+ _quads[0] = std::array<Vector2, 4>{{
+ { dist + center_clip.x(), -dist + center_clip.y() },
+ { dist + center_clip.x(), dist + center_clip.y() },
+ { -dist + center_clip.x(), -dist + center_clip.y() },
+ { -dist + center_clip.x(), dist + center_clip.y() },
+ }};
+
+ _index_buf.setSubData(0, ArrayView<std::array<UnsignedShort, 6>>{_indexes, 1});
+ _vertex_buf.setSubData(0, ArrayView<std::array<Vector2, 4>>{_quads, 1});
+
+ setUniform(ColorIntensityUniform, Vector4{Vector3{light.color}, dist});
+ setUniform(CenterUniform, center_fragcoord);
+ setUniform(FalloffUniform, (uint32_t)light.falloff);
+ setUniform(SizeUniform, chunk_size);
+
+
+}
+
+lightmap_shader::~lightmap_shader() = default;
+
+void lightmap_shader::begin(Vector2i neighbor_offset, const light_s& light)
+{
+ fm_assert(_count == 0);
+ clear();
+ add_light(neighbor_offset, light);
+}
+
+void lightmap_shader::end()
+{
+ flush_vertexes();
+}
+
+bool light_s::operator==(const light_s&) const noexcept = default;
+
} // namespace floormat
diff --git a/shaders/lightmap.frag b/shaders/lightmap.frag
index 2179160c..8690ffcb 100644
--- a/shaders/lightmap.frag
+++ b/shaders/lightmap.frag
@@ -1,18 +1,13 @@
precision mediump float;
-struct light_u
-{
- vec4 color_and_intensity;
- vec2 center;
- uint mode;
-};
-
-#define TILE_MAX_DIM 16
-#define TILE_SIZE_X 64
-#define TILE_SIZE_Y 64
+layout (location = 0) uniform vec4 color_intensity;
+layout (location = 1) uniform vec2 center;
+layout (location = 2) uniform uint falloff;
+layout (location = 3) uniform vec2 size;
-#define CHUNK_SIZE_X (TILE_SIZE_X * TILE_MAX_DIM)
-#define CHUNK_SIZE_Y (TILE_SIZE_Y * TILE_MAX_DIM)
+out vec4 color;
-layout (location = 0) uniform vec4 color_intensity;
-layout (location = 1) uniform vec2 px;
+void main() {
+ vec3 color = color_intensity.xyz;
+ float dist = color_intensity.w;
+}
diff --git a/shaders/lightmap.hpp b/shaders/lightmap.hpp
index a2d566e6..a7204723 100644
--- a/shaders/lightmap.hpp
+++ b/shaders/lightmap.hpp
@@ -1,15 +1,32 @@
#pragma once
#include "light-falloff.hpp"
-#include <Magnum/GL/AbstractShaderProgram.h>
+#include <array>
+#include <Corrade/Containers/Array.h>
#include <Magnum/Math/Vector2.h>
-#include <Magnum/Math/Vector3.h>
#include <Magnum/Math/Vector4.h>
#include <Magnum/Math/Color.h>
+#include <Magnum/GL/AbstractShaderProgram.h>
+#include <Magnum/GL/Buffer.h>
+#include <Magnum/GL/Framebuffer.h>
+#include <Magnum/GL/Mesh.h>
+//#include <Magnum/GL/Renderbuffer.h>
+#include <Magnum/GL/Texture.h>
namespace floormat {
-struct local_coords;
+struct light_s final
+{
+ Vector2 center;
+ float dist = 1;
+ //float depth = -1 + 1e-4f;
+ Math::Color3<uint8_t> color {255, 255, 255};
+ light_falloff falloff = light_falloff::linear;
+
+ bool operator==(const light_s&) const noexcept;
+};
+
+struct chunk;
struct lightmap_shader final : GL::AbstractShaderProgram
{
@@ -18,32 +35,43 @@ struct lightmap_shader final : GL::AbstractShaderProgram
explicit lightmap_shader();
~lightmap_shader() override;
- void set_light(Vector2i neighbor_offset, local_coords pos, Vector2b offset);
- struct light light() const; // is a reader accessor needed?
-
-private:
- static Vector2i get_px_pos(Vector2i neighbor_offset, local_coords pos, Vector2b offset);
-
- struct light_u final
- {
- Vector4 color_and_intensity;
- Vector2 center;
- uint32_t mode;
+ struct Framebuffer final {
+ GL::Framebuffer fb{NoCreate};
+ //GL::Renderbuffer depth{NoCreate};
+ GL::Texture2D color{NoCreate};
};
- struct light_s final
- {
- float intensity = 1;
- Color3ub color {255, 255, 255};
- Vector2i center;
- light_falloff falloff;
+ void begin(Vector2i neighbor_offset, const light_s& light);
+ void add_chunk(Vector2i neighbor_offset, const chunk& ch);
+ void add_vertex(Vector2i neighbor_offset, const std::array<Vector2, 4>& obj);
+ void end();
+ GL::Texture2D& texture();
- bool operator==(const light_s&) const noexcept;
- };
+private:
+ static Framebuffer make_framebuffer();
+ GL::Mesh make_mesh();
+ void add_light(Vector2i neighbor_offset, const light_s& light);
+ void flush_vertexes();
+ void bind();
+ void clear();
+ static std::array<UnsignedShort, 6> quad_indexes(size_t N);
- enum { ColorUniform = 0, CenterUniform = 1, FalloffUniform = 2, DepthUniform = 3, };
+ enum : int {
+ ColorIntensityUniform = 0,
+ CenterUniform = 1,
+ FalloffUniform = 2,
+ SizeUniform = 3,
+ //DepthUniform = 4,
+ };
- light_s _light;
+ Framebuffer framebuffer;
+ Array<std::array<Vector2, 4>> _quads;
+ Array<std::array<UnsignedShort, 6>> _indexes;
+ size_t _count = 0;
+ //light_u _light_uniform;
+ //light_s _light;
+ GL::Buffer _vertex_buf{NoCreate}, _index_buf{NoCreate};
+ GL::Mesh _mesh{NoCreate};
};
} // namespace floormat
diff --git a/shaders/lightmap.vert b/shaders/lightmap.vert
index e69de29b..a044a141 100644
--- a/shaders/lightmap.vert
+++ b/shaders/lightmap.vert
@@ -0,0 +1,12 @@
+precision mediump float;
+
+layout (location = 0) uniform vec4 color_intensity;
+layout (location = 1) uniform vec2 center;
+layout (location = 2) uniform uint falloff;
+layout (location = 3) uniform vec2 size;
+
+layout (location = 0) in vec4 position;
+
+void main() {
+ gl_Position = vec4(position.x, -position.y, 0, 1);
+}
diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp
index 49b7bc7d..7cf436a0 100644
--- a/src/chunk-collision.cpp
+++ b/src/chunk-collision.cpp
@@ -3,6 +3,7 @@
#include "entity.hpp"
#include "src/RTree-search.hpp"
#include "src/chunk-scenery.hpp"
+#include "src/tile-bbox.hpp"
#include <bit>
#include <Corrade/Containers/PairStl.h>
@@ -12,41 +13,6 @@ chunk::RTree* chunk::rtree() noexcept { ensure_passability(); return &_rtree; }
namespace {
-constexpr float wall_depth = 8, wall_depth_2 = wall_depth*.5f;
-
-constexpr Vector2 tile_start(size_t k)
-{
- constexpr auto half_tile = Vector2(TILE_SIZE2)/2;
- const local_coords coord{k};
- return TILE_SIZE2 * Vector2(coord) - half_tile;
-}
-
-Pair<Vector2i, Vector2i> scenery_tile(local_coords local, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size)
-{
- auto center = iTILE_SIZE2 * Vector2i(local) + Vector2i(offset) + Vector2i(bbox_offset);
- auto min = center - Vector2i(bbox_size/2);
- auto size = Vector2i(bbox_size);
- return { min, min + size, };
-}
-
-constexpr Pair<Vector2, Vector2> whole_tile(size_t k)
-{
- auto min = tile_start(k);
- return { min, min + TILE_SIZE2, };
-}
-
-constexpr Pair<Vector2, Vector2> wall_north(size_t k)
-{
- auto min = tile_start(k) - Vector2(0, wall_depth_2);
- return { min, min + Vector2(TILE_SIZE2[0], wall_depth), };
-}
-
-constexpr Pair<Vector2, Vector2> wall_west(size_t k)
-{
- auto min = tile_start(k) - Vector2(wall_depth_2, 0);
- return { min, min + Vector2(wall_depth, TILE_SIZE2[1]), };
-}
-
constexpr object_id make_id(collision_type type, pass_mode p, object_id id)
{
return std::bit_cast<object_id>(collision_data { (object_id)type, (object_id)p, id });
diff --git a/src/chunk.hpp b/src/chunk.hpp
index 8453bf83..505e335d 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -128,13 +128,13 @@ private:
RTree _rtree;
- mutable bool _maybe_empty : 1 = true,
- _ground_modified : 1 = true,
- _walls_modified : 1 = true,
- _scenery_modified : 1 = true,
- _pass_modified : 1 = true,
- _teardown : 1 = false,
- _entities_sorted : 1 = true;
+ mutable bool _maybe_empty : 1 = true,
+ _ground_modified : 1 = true,
+ _walls_modified : 1 = true,
+ _scenery_modified : 1 = true,
+ _pass_modified : 1 = true,
+ _teardown : 1 = false,
+ _entities_sorted : 1 = true;
void ensure_scenery_buffers(scenery_scratch_buffers bufs);
static topo_sort_data make_topo_sort_data(entity& e, uint32_t mesh_idx);
diff --git a/src/tile-bbox.hpp b/src/tile-bbox.hpp
new file mode 100644
index 00000000..3275e22a
--- /dev/null
+++ b/src/tile-bbox.hpp
@@ -0,0 +1,46 @@
+#pragma once
+#include "src/tile-defs.hpp"
+#include "src/local-coords.hpp"
+#include <Magnum/Magnum.h>
+#include <Magnum/Math/Vector2.h>
+
+namespace floormat {
+
+namespace {
+constexpr float wall_depth = 8, wall_depth_2 = wall_depth*.5f;
+} // namespace
+
+constexpr Vector2 tile_start(size_t k)
+{
+ constexpr auto half_tile = Vector2(TILE_SIZE2)/2;
+ const local_coords coord{k};
+ return TILE_SIZE2 * Vector2(coord) - half_tile;
+}
+
+constexpr Pair<Vector2i, Vector2i> scenery_tile(local_coords local, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size)
+{
+ auto center = iTILE_SIZE2 * Vector2i(local) + Vector2i(offset) + Vector2i(bbox_offset);
+ auto min = center - Vector2i(bbox_size/2);
+ auto size = Vector2i(bbox_size);
+ return { min, min + size, };
+}
+
+constexpr Pair<Vector2, Vector2> whole_tile(size_t k)
+{
+ auto min = tile_start(k);
+ return { min, min + TILE_SIZE2, };
+}
+
+constexpr Pair<Vector2, Vector2> wall_north(size_t k)
+{
+ auto min = tile_start(k) - Vector2(0, wall_depth_2);
+ return { min, min + Vector2(TILE_SIZE2[0], wall_depth), };
+}
+
+constexpr Pair<Vector2, Vector2> wall_west(size_t k)
+{
+ auto min = tile_start(k) - Vector2(wall_depth_2, 0);
+ return { min, min + Vector2(wall_depth, TILE_SIZE2[1]), };
+}
+
+} // namespace floormat
diff --git a/userconfig-sthalik@Windows-GNU.cmake b/userconfig-sthalik@Windows-GNU.cmake
index 5f9766f4..7b7759ae 100644
--- a/userconfig-sthalik@Windows-GNU.cmake
+++ b/userconfig-sthalik@Windows-GNU.cmake
@@ -63,7 +63,7 @@ endfunction()
function(fm-userconfig-src)
add_compile_options(
-Wall -Wextra -Wpedantic -Wno-old-style-cast -Wno-padded
- -fconcepts-diagnostics-depth=2
+ #-fconcepts-diagnostics-depth=2
)
add_link_options(-Wno-lto-type-mismatch -Wno-odr)
add_compile_options(