summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-02-23 13:25:39 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-02-23 13:25:39 +0100
commiteeedd2061bee36f49ea20e898e8edf3676bd15b5 (patch)
tree4e22a3d50d6f97992aa3b46d00b276ddac928e6a
parent920aa82a3a05402cc0489a8d9e0b9b2f4a4e3117 (diff)
flush
-rw-r--r--atlas.cpp23
-rw-r--r--atlas.hpp1
-rw-r--r--defs.hpp1
-rw-r--r--main.cpp216
-rw-r--r--shaders/tile-shader.frag5
-rw-r--r--shaders/tile-shader.vert7
-rw-r--r--tile-shader.cpp8
-rw-r--r--tile-shader.hpp6
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<Vector3, 4> 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<Vector3, 4> 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<Vector2, 4> texcoords_for_id(int id) const;
static std::array<Vector3, 4> floor_quad(Vector3 center, Vector2 size);
+ static std::array<Vector3, 4> wall_quad(Vector3 center, Vector3 size);
static std::array<UnsignedShort, 6> 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 <bitset>
#include <Corrade/Containers/ArrayViewStl.h>
#include <Corrade/PluginManager/Manager.h>
@@ -15,10 +18,11 @@
#include <Magnum/Platform/Sdl2Application.h>
#include <Magnum/Trade/AbstractImporter.h>
-#include <Magnum/GlmIntegration/Integration.h>
#include <glm/glm.hpp>
-#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
+#include <glm/ext/matrix_transform.hpp>
+#include <Magnum/GlmIntegration/Integration.h>
+#include <SDL_timer.h>
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_texture> 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<atlas_texture> 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<double>(-.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<QuadVertex> vertices; vertices.reserve(64*64*4);
- std::vector<UnsignedShort> indices; indices.reserve(256);
+ std::vector<QuadVertex> vertices; vertices.reserve(1024);
+ std::vector<UnsignedShort> 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<float>& 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<float>& 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