diff --git a/libs/gfx/include/psemek/gfx/renderer/simple.hpp b/libs/gfx/include/psemek/gfx/renderer/simple.hpp index 75e712a1..414f33dc 100644 --- a/libs/gfx/include/psemek/gfx/renderer/simple.hpp +++ b/libs/gfx/include/psemek/gfx/renderer/simple.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -15,11 +16,13 @@ namespace psemek::gfx // Attributes: // 0: vec3 position // 1: vec4 color (if uniform color is not set) + // 2: vec2 texcoord (if texture is present) struct render_state { drawable const * mesh = nullptr; - std::optional color; + std::optional color = std::nullopt; + texture_2d const * texture = nullptr; }; struct render_object diff --git a/libs/gfx/source/renderer/simple.cpp b/libs/gfx/source/renderer/simple.cpp index e0a0f608..ad8f1f58 100644 --- a/libs/gfx/source/renderer/simple.cpp +++ b/libs/gfx/source/renderer/simple.cpp @@ -39,7 +39,7 @@ void main() } )"; - static char const fragment_source[] = + static char const color_fragment_source[] = R"(#version 330 in vec4 color; @@ -49,16 +49,49 @@ void main() { out_color = color; } +)"; + + static char const textured_vertex_source[] = +R"(#version 330 + +uniform mat4 u_transform; + +layout (location = 0) in vec4 in_position; +layout (location = 2) in vec2 in_texcoord; + +out vec2 texcoord; + +void main() +{ + gl_Position = u_transform * in_position; + texcoord = in_texcoord; +} +)"; + + static char const textured_fragment_source[] = +R"(#version 330 + +uniform sampler2D u_texture; + +in vec2 texcoord; +out vec4 out_color; + +void main() +{ + out_color = texture(u_texture, texcoord); +} )"; struct simple_renderer::impl { - program attrib_color_program{attrib_color_vertex_source, fragment_source}; - program uniform_color_program{uniform_color_vertex_source, fragment_source}; + program attrib_color_program{attrib_color_vertex_source, color_fragment_source}; + program uniform_color_program{uniform_color_vertex_source, color_fragment_source}; + program textured_program{textured_vertex_source, textured_fragment_source}; std::vector objects; std::vector attrib_color_states; std::vector uniform_color_states; + std::vector textured_states; }; simple_renderer::simple_renderer() @@ -83,7 +116,9 @@ void main() { if (s.mesh) { - if (s.color) + if (s.texture) + impl().textured_states.push_back(s); + else if (s.color) impl().uniform_color_states.push_back(s); else impl().attrib_color_states.push_back(s); @@ -124,6 +159,22 @@ void main() impl().uniform_color_states.clear(); } + + if (!impl().textured_states.empty()) + { + impl().textured_program.bind(); + impl().textured_program["u_transform"] = opts.transform; + impl().textured_program["u_texture"] = 0; + gl::ActiveTexture(gl::TEXTURE0); + + for (auto const & s : impl().textured_states) + { + s.texture->bind(); + s.mesh->draw(); + } + + impl().textured_states.clear(); + } } }