From eeedd2061bee36f49ea20e898e8edf3676bd15b5 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Wed, 23 Feb 2022 13:25:39 +0100 Subject: flush --- atlas.cpp | 23 +++-- atlas.hpp | 1 + defs.hpp | 1 + main.cpp | 216 ++++++++++++++++++++++++++++++++++++++--------- shaders/tile-shader.frag | 5 +- shaders/tile-shader.vert | 7 +- tile-shader.cpp | 8 ++ tile-shader.hpp | 6 +- 8 files changed, 213 insertions(+), 54 deletions(-) diff --git a/atlas.cpp b/atlas.cpp index 5b6310fd..d6b6a0c2 100644 --- a/atlas.cpp +++ b/atlas.cpp @@ -17,8 +17,8 @@ atlas_texture::atlas_texture(const Trade::ImageData2D& image, Vector2i dims) : tex_.setWrapping(GL::SamplerWrapping::ClampToEdge) .setMagnificationFilter(GL::SamplerFilter::Linear) .setMinificationFilter(GL::SamplerFilter::Linear) - .setMaxAnisotropy(8) - .setStorage(6, GL::textureFormat(image.format()), image.size()) + .setMaxAnisotropy(0) + .setStorage(1, GL::textureFormat(image.format()), image.size()) .setSubImage(0, {}, image); } @@ -41,10 +41,21 @@ std::array atlas_texture::floor_quad(Vector3 center, Vector2 size) { float x = size[0]*.5f, y = size[1]*.5f; return {{ - { x + center[0], -y + center[1], 0}, - { x + center[0], y + center[1], 0}, - {-x + center[0], -y + center[1], 0}, - {-x + center[0], y + center[1], 0}, + { x + center[0], -y + center[1], center[2]}, + { x + center[0], y + center[1], center[2]}, + {-x + center[0], -y + center[1], center[2]}, + {-x + center[0], y + center[1], center[2]}, + }}; +} + +std::array atlas_texture::wall_quad(Vector3 center, Vector3 size) +{ + float x = size[0]*.5f, y = size[1]*.5f, z = size[2]; + return {{ + { x + center[0], -y + center[1], + center[2] }, + { x + center[0], -y + center[1], z+ center[2] }, + {-x + center[0], y + center[1], + center[2] }, + {-x + center[0], y + center[1], z+ center[2] }, }}; } diff --git a/atlas.hpp b/atlas.hpp index ee94d5d0..43c858de 100644 --- a/atlas.hpp +++ b/atlas.hpp @@ -12,6 +12,7 @@ struct atlas_texture final atlas_texture(const Trade::ImageData2D& img, Vector2i dims); std::array texcoords_for_id(int id) const; static std::array floor_quad(Vector3 center, Vector2 size); + static std::array wall_quad(Vector3 center, Vector3 size); static std::array indices(int N); GL::Texture2D& texture() { return tex_; } constexpr int size() const { return dims_.product(); } diff --git a/defs.hpp b/defs.hpp index f680c4b9..299da7df 100644 --- a/defs.hpp +++ b/defs.hpp @@ -80,3 +80,4 @@ struct key_error final : exception { #define ERR(...) GAME_DEBUG_OUT("error: ", __VA_ARGS__) #define DEBUG(...) GAME_DEBUG_OUT("", __VA_ARGS__) +#define progn(...) [&]{__VA_ARGS__;}() diff --git a/main.cpp b/main.cpp index a19ea6df..561fbdf2 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,9 @@ #include "atlas.hpp" #include "loader.hpp" #include "tile-shader.hpp" +#include "defs.hpp" + +#include #include #include @@ -15,10 +18,11 @@ #include #include -#include #include -#include #include +#include +#include +#include namespace Magnum::Examples { @@ -29,20 +33,40 @@ struct application final : Platform::Application explicit application(const Arguments& arguments); virtual ~application(); void drawEvent() override; + void update(float dt); + void keyPressEvent(KeyEvent& event) override; + void keyReleaseEvent(KeyEvent& event) override; + void do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated); - GL::Mesh _mesh; + enum class key { + camera_up, camera_left, camera_right, camera_down, camera_reset, + MAX + }; + + GL::Mesh _mesh, _mesh2; tile_shader _shader; std::shared_ptr atlas = //loader.tile_atlas("../share/game/images/tiles.tga", {8,4}); //loader.tile_atlas("../share/game/images/tiles2.tga", {8,5}); - //loader.tile_atlas("../share/game/images/metal1.tga", {2, 2}); - loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); + loader.tile_atlas("../share/game/images/metal1.tga", {1, 1}); + //loader.tile_atlas("../share/game/images/floor1.tga", {4, 4}); + std::shared_ptr atlas2 = + loader.tile_atlas("../share/game/images/tiles2.tga", {8, 5}); + + std::uint64_t time_ticks = 0, time_freq = SDL_GetPerformanceFrequency(); + Vector3 camera_offset; + std::bitset<(std::size_t)key::MAX> keys{0ul}; + + float get_dt(); static glm::mat<4, 4, double> make_projection(Vector2i window_size, Vector3 offset); + static glm::mat<4, 4, double> make_view(Vector3 offset); static float projection_size_ratio(); Matrix4x4 make_projection(Vector3 offset) const; }; +using namespace Math::Literals; + float application::projection_size_ratio() { auto m = make_projection({1, 1}, {}); @@ -50,19 +74,20 @@ float application::projection_size_ratio() return (float)(pos[0] / pos[3]); } -glm::mat<4, 4, double> application::make_projection(Vector2i window_size, Vector3 offset) -{ +glm::mat<4, 4, double> application::make_view(Vector3 offset) { using vec3 = glm::vec<3, double>; - using mat4 = glm::mat<4, 4, double>; - double x = window_size[0]*.5, y = window_size[1]*.5, w = 2*std::sqrt(x*x+y*y); - auto m = glm::ortho(-x, x, -y, y, -w, w); - //m = glm::ortho(-.5, .5, -.5, .5, -100, 100); - m = glm::scale(m, { 1., 0.6, 1. }); + auto m = glm::scale(glm::mat<4, 4, double>{1}, { 1., .6, 1. }); + //auto m = glm::mat<4, 4, double>{1}; m = glm::translate(m, { (double)offset[0], (double)-offset[1], (double)offset[2] }); m = glm::rotate(m, glm::radians(std::asin(1./std::sqrt(2))), vec3(1, 0, 0)); - m = glm::rotate(m, glm::radians(-45.), vec3(0, 0, 1)); + m = glm::rotate(m, glm::radians(45.), vec3(0, 0, 1)); + return m; +} - return glm::mat4(m); +glm::mat<4, 4, double> application::make_projection(Vector2i window_size, Vector3 offset) +{ + double x = window_size[0]*.5, y = window_size[1]*.5, w = 1 << 16; + return glm::mat4(glm::ortho(-x, x, -y, y, -w, w) * make_view(offset)); } Matrix4x4 application::make_projection(Vector3 offset) const @@ -71,63 +96,170 @@ Matrix4x4 application::make_projection(Vector3 offset) const } application::application(const Arguments& arguments): - Platform::Application{arguments, Configuration{} - .setTitle("Test") - .setSize({1024, 768}, dpi_policy::Physical)} + Platform::Application{ + arguments, + Configuration{} + .setTitle("Test") + .setSize({1024, 768}, dpi_policy::Physical), + GLConfiguration{} + //.setSampleCount(16) + } { struct QuadVertex { Vector3 position; Vector2 textureCoordinates; - // todo gl_FragDepth }; - std::vector vertices; vertices.reserve(64*64*4); - std::vector indices; indices.reserve(256); + std::vector vertices; vertices.reserve(1024); + std::vector indices; indices.reserve(1024); + + float ratio = projection_size_ratio(); + auto sz = Vector2{100, 100} * ratio; + + { + int k = 0; + for (int j = -2; j <= 2; j++) + for (int i = -2; i <= 2; i++) + { + if (i == 0 && j == 0) + continue; + auto positions = atlas->floor_quad({(float)(sz[0]*i), (float)(sz[1]*j), 0}, sz); + auto texcoords = atlas->texcoords_for_id(k % atlas->size()); + auto indices_ = atlas->indices(k); - auto sz = Vector2{50, 50} * projection_size_ratio(); + for (unsigned x = 0; x < 4; x++) + vertices.push_back({ positions[x], texcoords[x] }); + for (auto x : indices_) + indices.push_back(x); + k++; + } - int k = 0; - for (int j = -2; j <= 2; j++) - for (int i = -2; i <= 2; i++) + _mesh.setCount((int)indices.size()) + .addVertexBuffer(GL::Buffer{vertices}, 0, + tile_shader::Position{}, tile_shader::TextureCoordinates{}) + .setIndexBuffer(GL::Buffer{indices}, 0, GL::MeshIndexType::UnsignedShort); + } + + vertices.clear(); + indices.clear(); + + { + auto positions = atlas2->wall_quad({}, Vector3(sz[0], sz[1], sz[1])); + //auto positions = atlas->floor_quad({(float)(sz[0]*0), (float)(sz[1]*0), sz[1]*2}, sz); + auto texcoords = atlas->texcoords_for_id(0); + auto indices_ = atlas->indices(0); + for (unsigned x = 0; x < 4; x++) { - auto positions = atlas->floor_quad({(float)(sz[0]*i), (float)(sz[1]*j), 0}, sz); - auto texcoords = atlas->texcoords_for_id(k % atlas->size()); - auto indices_ = atlas->indices(k); - - for (unsigned x = 0; x < 4; x++) - vertices.push_back({ positions[x], texcoords[x] }); - for (auto x : indices_) - indices.push_back(x); - k++; + Utility::Debug{} << "wall" << x << positions[x]; + vertices.push_back({ positions[x], texcoords[x] }); } + for (auto x : indices_) + indices.push_back(x); + + _mesh2.setCount((int)indices.size()) + .addVertexBuffer(GL::Buffer{vertices}, 0, + tile_shader::Position{}, tile_shader::TextureCoordinates{}) + .setIndexBuffer(GL::Buffer{indices}, 0, GL::MeshIndexType::UnsignedShort); + } - _mesh.setCount((int)indices.size()) - .addVertexBuffer(GL::Buffer{vertices}, 0, - tile_shader::Position{}, tile_shader::TextureCoordinates{}) - .setIndexBuffer(GL::Buffer{indices}, 0, GL::MeshIndexType::UnsignedShort); + (void)get_dt(); } void application::drawEvent() { GL::defaultFramebuffer.clear(GL::FramebufferClear::Color | GL::FramebufferClear::Depth); - //GL::Renderer::enable(GL::Renderer::Feature::DepthTest); - //GL::Renderer::setDepthMask(true); + GL::Renderer::setDepthMask(true); + GL::Renderer::setDepthFunction(GL::Renderer::DepthFunction::LessOrEqual); + GL::Renderer::enable(GL::Renderer::Feature::DepthTest); - using namespace Math::Literals; + { + float dt = get_dt(); + update(dt); + } + { + auto projection = make_projection(camera_offset); + //auto ratio = projection_size_ratio(); + float y_scale = 1.f/windowSize()[1]; + _shader.set_projection(projection, y_scale); + } + +#if 1 _shader - .set_projection(make_projection({})) - .set_color(0xffffff_rgbf) .bindTexture(atlas->texture()) .draw(_mesh); +#endif +#if 1 + _shader + .bindTexture(atlas2->texture()) + .draw(_mesh2); +#endif swapBuffers(); + redraw(); +} + +void application::update(float dt) +{ + constexpr float pixels_per_second = 10; + if (keys[(int)key::camera_up]) + camera_offset += Vector3(0, -1, 0) * dt * pixels_per_second; + else if (keys[(int)key::camera_down]) + camera_offset += Vector3(0, 1, 0) * dt * pixels_per_second; + if (keys[(int)key::camera_left]) + camera_offset += Vector3(-1, 0, 0) * dt * pixels_per_second; + else if (keys[(int)key::camera_right]) + camera_offset += Vector3(1, 0, 0) * dt * pixels_per_second; + + if (keys[(int)key::camera_reset]) + camera_offset = {}; +} + +void application::do_key(KeyEvent::Key k, KeyEvent::Modifiers m, bool pressed, bool repeated) +{ + using Mods = KeyEvent::Modifiers; + + (void)m; + (void)repeated; + + key x = key::MAX; + + switch (k) + { + using enum KeyEvent::Key; + case W: x = key::camera_up; break; + case A: x = key::camera_left; break; + case S: x = key::camera_down; break; + case D: x = key::camera_right; break; + case Home: x = key::camera_reset; break; + default: (void)0; break; + } + + if (x != key::MAX) + keys[(std::size_t)x] = pressed; +} + +float application::get_dt() +{ + const std::uint64_t t = SDL_GetPerformanceCounter(); + float dt = (float)((t - time_ticks) / (double)time_freq); + time_ticks = t; + return dt; } application::~application() { loader_::destroy(); } +void application::keyPressEvent(Platform::Sdl2Application::KeyEvent& event) +{ + do_key(event.key(), event.modifiers(), true, event.isRepeated()); +} + +void application::keyReleaseEvent(Platform::Sdl2Application::KeyEvent& event) +{ + do_key(event.key(), event.modifiers(), false, false); +} } // namespace Magnum::Examples diff --git a/shaders/tile-shader.frag b/shaders/tile-shader.frag index 624fc8c5..2d3de0b2 100644 --- a/shaders/tile-shader.frag +++ b/shaders/tile-shader.frag @@ -1,11 +1,14 @@ uniform vec3 color = vec3(1.0, 1.0, 1.0); -uniform sampler2D textureData; +layout(location = 2) uniform sampler2D textureData; +layout(location = 1) uniform float y_scale; in vec2 interpolatedTextureCoordinates; +in float interpolated_frag_depth; out vec4 fragmentColor; void main() { fragmentColor.rgb = color*texture(textureData, interpolatedTextureCoordinates).rgb; fragmentColor.a = 1.0; + gl_FragDepth = -interpolated_frag_depth * y_scale; } diff --git a/shaders/tile-shader.vert b/shaders/tile-shader.vert index 7a5bd1c3..cc90bae5 100644 --- a/shaders/tile-shader.vert +++ b/shaders/tile-shader.vert @@ -2,12 +2,15 @@ precision highp float; layout(location = 0) in vec4 position; layout(location = 1) in vec2 textureCoordinates; -uniform mat4 projection; +layout(location = 0) uniform mat4 projection; +layout(location = 1) uniform float y_scale; out vec2 interpolatedTextureCoordinates; +out float interpolated_frag_depth; void main() { interpolatedTextureCoordinates = textureCoordinates; - gl_Position = projection * position; + gl_Position = projection * vec4(position.xy, 0, position.w) + vec4(0, position.z * y_scale, 0, 0); + interpolated_frag_depth = position.z; } diff --git a/tile-shader.cpp b/tile-shader.cpp index 3477a00c..12bf7fde 100644 --- a/tile-shader.cpp +++ b/tile-shader.cpp @@ -27,6 +27,7 @@ tile_shader::tile_shader() _color_uniform = uniformLocation("color"); _projection_uniform = uniformLocation("projection"); + _y_scale_uniform = uniformLocation("y_scale"); setUniform(uniformLocation("textureData"), TextureUnit); } @@ -37,4 +38,11 @@ tile_shader& tile_shader::bindTexture(GL::Texture2D& texture) return *this; } +tile_shader& tile_shader::set_projection(const Matrix4& mat, float y_scale) +{ + setUniform(_projection_uniform, mat); + setUniform(_y_scale_uniform, y_scale); + return *this; +} + } // namespace Magnum::Examples diff --git a/tile-shader.hpp b/tile-shader.hpp index ea3c57ce..4be4fe4e 100644 --- a/tile-shader.hpp +++ b/tile-shader.hpp @@ -14,15 +14,15 @@ struct tile_shader : GL::AbstractShaderProgram explicit tile_shader(); - auto& set_color(const Color3& color) { setUniform(_color_uniform, color); return *this; } - auto& set_projection(const Math::Matrix4& mat) { setUniform(_projection_uniform, mat); return *this; } + tile_shader& set_color(const Color3& color) { setUniform(_color_uniform, color); return *this; } + tile_shader& set_projection(const Math::Matrix4& mat, float y_scale); tile_shader& bindTexture(GL::Texture2D& texture); private: enum: Int { TextureUnit = 0 }; - Int _color_uniform, _projection_uniform; + Int _color_uniform, _projection_uniform, _y_scale_uniform; }; } // namespace Magnum::Examples -- cgit v1.2.3