summary refs log tree commit diff
path: root/src/Util
diff options
context:
space:
mode:
Diffstat (limited to 'src/Util')
-rw-r--r--src/Util/ImageViewer.cpp29
-rw-r--r--src/Util/ImageViewer.hpp7
-rw-r--r--src/Util/Sampler.hpp36
3 files changed, 58 insertions, 14 deletions
diff --git a/src/Util/ImageViewer.cpp b/src/Util/ImageViewer.cpp
index b4d8c6e..7fd5867 100644
--- a/src/Util/ImageViewer.cpp
+++ b/src/Util/ImageViewer.cpp
@@ -5,13 +5,14 @@
 namespace MC::Util {
 
 ImageViewer::ImageViewer(
-        GFX::Image::RawImage& image
+        GFX::Image::RawImage& image,
+        float window_aspect
 ) : m_texture(image),
     m_program(
         {GFX::Shading::Shader::Type::Vertex, ImageViewer::vertex},
         {GFX::Shading::Shader::Type::Fragment, ImageViewer::fragment}
     ),
-    m_mesh(GFX::Binder::load(default_mesh)) {
+    m_mesh(GFX::Binder::load(create_mesh(window_aspect, image.width(), image.height()))) {
     m_program.bind();
     auto model_uniform = m_program.uniform("model_matrix");
     auto view_uniform = m_program.uniform("view_matrix");
@@ -19,7 +20,7 @@ ImageViewer::ImageViewer(
 
     model_uniform.set(Math::MVP::model({}, {}));
     view_uniform.set(Math::MVP::view({}, {}));
-    projection_uniform.set(Math::MVP::orthographic_projection(1000, 800, 0.0f, 100.0f));
+    projection_uniform.set(Math::MVP::orthographic_projection(1000 * window_aspect, 1000, 0.0f, 100.0f));
 
     m_program.unbind();
 }
@@ -34,19 +35,27 @@ void ImageViewer::render() {
     m_program.unbind();
 }
 
-GFX::Mesh ImageViewer::create_default_mesh() {
+GFX::Mesh ImageViewer::create_mesh(float window_aspect, uint32_t image_width, uint32_t image_height) {
+    auto aspect = (float)image_width / image_height;
+    float max_size = 500.0f;
+    float width = max_size * std::min(1.0f, aspect);
+    float height = max_size * std::min(1.0f, 1/aspect);
+
+    float x = max_size * window_aspect - width / 2.0f;
+    float y = max_size - height / 2.0f;
+
     return {{
         std::vector<Vector<3>>{
-            {300.0f, 200.0f,   0.0f},   // top left
-            {300.0f, 600.0f, 0.0f},   // bottom left
-            {700.0f, 600.0f, 0.0f},   // bottom right
-            {700.0f, 200.0f,   0.0f } // top right
+            {x, y, 0.0f}, // top left
+            {x, y + height, 0.0f}, // bottom left
+            {x + width, y + height, 0.0f}, // bottom right
+            {x + width, y, 0.0f}  // top right
         },
         std::vector<Vector<2>>{
-            {1.0f, 1.0f},
-            {1.0f, 0.0f,},
             {0.0f, 0.0f},
             {0.0f, 1.0f},
+            {1.0f, 1.0f},
+            {1.0f, 0.0f},
         },
     }, {0, 1, 2, 0, 2, 3}};
 }
diff --git a/src/Util/ImageViewer.hpp b/src/Util/ImageViewer.hpp
index cb2dda0..2e4efe3 100644
--- a/src/Util/ImageViewer.hpp
+++ b/src/Util/ImageViewer.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <ostream>
 #include "../GFX/Image/RawImage.hpp"
 #include "../GFX/Binder.hpp"
 #include "../GFX/Texture.hpp"
@@ -9,13 +10,11 @@ namespace MC::Util {
 
 class ImageViewer {
 public:
-    explicit ImageViewer(GFX::Image::RawImage& image);
+    explicit ImageViewer(GFX::Image::RawImage& image, float window_aspect);
 
     void render();
 private:
-    static GFX::Mesh create_default_mesh();
-
-    static inline GFX::Mesh default_mesh = create_default_mesh();
+    static GFX::Mesh create_mesh(float window_aspect, uint32_t image_width, uint32_t image_height);
 
     static const char* vertex;
     static const char* fragment;
diff --git a/src/Util/Sampler.hpp b/src/Util/Sampler.hpp
new file mode 100644
index 0000000..3a4ff4f
--- /dev/null
+++ b/src/Util/Sampler.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+#include <functional>
+#include "../Math/Vector.hpp"
+#include "../Math/Grid.hpp"
+
+namespace MC::Util {
+
+template<size_t D, typename T>
+class Sampler {
+    using Pos = Vector<D>;
+    using Sample = std::function<T(Pos)>;
+    using Interpolate = std::function<T(Pos, Sample)>;
+public:
+    Sampler(
+        Sample sample,
+        Pos offset = {},
+        float scale = 1.0f,
+        Interpolate interpolate = nearest_interpolation
+    ) : m_sample([=](Sampler::Pos pos) -> T {
+        return interpolate(pos, [=](Sampler::Pos p) -> T { return sample(p * scale + offset); });
+    }) {}
+
+    T sample(Pos at) {
+        return m_sample(at);
+    }
+
+    static T nearest_interpolation(Pos pos, Sample sample) {
+        return sample(pos);
+    }
+
+private:
+    Sample m_sample;
+};
+
+}
\ No newline at end of file