#include #include "ImageViewer.hpp" #include "../Math/MVP.hpp" namespace MC::Util { ImageViewer::ImageViewer( 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(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"); auto projection_uniform = m_program.uniform("projection_matrix"); model_uniform.set(Math::MVP::model({}, {})); view_uniform.set(Math::MVP::view({}, {})); projection_uniform.set(Math::MVP::orthographic_projection(1000 * window_aspect, 1000, 0.0f, 100.0f)); m_program.unbind(); } void ImageViewer::render() { m_program.bind(); m_texture.bind(); m_mesh.bind(); glDrawElements(GL_TRIANGLES, m_mesh.size(), GL_UNSIGNED_INT, nullptr); m_mesh.unbind(); m_texture.unbind(); m_program.unbind(); } 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>{ {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>{ {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, }, }, {0, 1, 2, 0, 2, 3}}; } const char* ImageViewer::vertex = R"v( #version 330 core uniform mat4 model_matrix; uniform mat4 view_matrix; uniform mat4 projection_matrix; layout (location = 0) in vec3 position; layout (location = 1) in vec2 tex_coord; out vec2 frag_tex_coord; void main() { gl_Position = projection_matrix * view_matrix * model_matrix * vec4(position, 1.0); frag_tex_coord = tex_coord; })v"; const char* ImageViewer::fragment = R"f( #version 330 core uniform sampler2D image; in vec2 frag_tex_coord; out vec4 color; void main() { color = texture(image, frag_tex_coord); })f"; }