#include #include "ImageViewer.hpp" #include "../Math/MVP.hpp" namespace MC::Util { ImageViewer::ImageViewer( const GFX::Image::RawImage& image, Real window_aspect ) : m_texture(image), m_program( {GFX::Shading::Shader::Type::Vertex, vertex}, {GFX::Shading::Shader::Type::Fragment, fragment} ), m_mesh(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({}, Vector<3>::one(), {})); view_uniform.set(Math::MVP::view({}, {})); projection_uniform.set(Math::MVP::orthographic_projection(view_size * window_aspect, view_size, 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(Real window_aspect, U32 image_width, U32 image_height) { auto aspect = (Real)image_width / image_height; Real max_size = view_size * 0.8; Real width = max_size * std::min(1.0, aspect); Real height = max_size * std::min(1.0, 1/aspect); Real x = (view_size * window_aspect - width) / 2.0f; Real y = (view_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"; }