Implement texture rendering in gfx::painter
This commit is contained in:
parent
fb9dceea5e
commit
77125540e6
2 changed files with 87 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <psemek/gfx/color.hpp>
|
#include <psemek/gfx/color.hpp>
|
||||||
|
#include <psemek/gfx/texture.hpp>
|
||||||
#include <psemek/geom/vector.hpp>
|
#include <psemek/geom/vector.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
#include <psemek/geom/matrix.hpp>
|
#include <psemek/geom/matrix.hpp>
|
||||||
|
|
@ -57,6 +58,8 @@ namespace psemek::gfx
|
||||||
geom::vector<float, 2> text_size(std::string_view str, font f = font::font_9x12, float scale = 1.f);
|
geom::vector<float, 2> text_size(std::string_view str, font f = font::font_9x12, float scale = 1.f);
|
||||||
void text(geom::point<float, 2> const & p, std::string_view str, text_options const & opts);
|
void text(geom::point<float, 2> const & p, std::string_view str, text_options const & opts);
|
||||||
|
|
||||||
|
void texture(texture_2d const & texture, geom::box<float, 2> const & box);
|
||||||
|
|
||||||
// 3D
|
// 3D
|
||||||
void axes(geom::point<float, 3> const & p, float length, float width);
|
void axes(geom::point<float, 3> const & p, float length, float width);
|
||||||
void sphere(geom::point<float, 3> const & p, float radius, color const & c, int quality = 6);
|
void sphere(geom::point<float, 3> const & p, float radius, color const & c, int quality = 6);
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,38 @@ void main()
|
||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
static const char texture_vertex_source[] =
|
||||||
|
R"(#version 330
|
||||||
|
|
||||||
|
uniform mat4 u_transform;
|
||||||
|
|
||||||
|
layout (location = 0) in vec4 in_position;
|
||||||
|
layout (location = 1) in vec2 in_texcoord;
|
||||||
|
|
||||||
|
out vec2 texcoord;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = u_transform * in_position;
|
||||||
|
texcoord = in_texcoord;
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
static const char texture_fragment_source[] =
|
||||||
|
R"(#version 330
|
||||||
|
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
|
in vec2 texcoord;
|
||||||
|
|
||||||
|
out vec4 out_color;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
out_color = texture(u_texture, texcoord);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
namespace psemek::gfx
|
namespace psemek::gfx
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -92,10 +124,18 @@ namespace psemek::gfx
|
||||||
geom::point<std::uint16_t, 2> texcoord;
|
geom::point<std::uint16_t, 2> texcoord;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct texture_vertex
|
||||||
|
{
|
||||||
|
geom::point<float, 3> position;
|
||||||
|
geom::point<std::uint16_t, 2> texcoord;
|
||||||
|
};
|
||||||
|
|
||||||
gfx::program program{vertex_source, fragment_source};
|
gfx::program program{vertex_source, fragment_source};
|
||||||
gfx::program text_program{text_vertex_source, text_fragment_source};
|
gfx::program text_program{text_vertex_source, text_fragment_source};
|
||||||
|
gfx::program texture_program{texture_vertex_source, texture_fragment_source};
|
||||||
gfx::mesh mesh;
|
gfx::mesh mesh;
|
||||||
gfx::mesh text_mesh;
|
gfx::mesh text_mesh;
|
||||||
|
gfx::mesh texture_mesh;
|
||||||
|
|
||||||
std::vector<vertex> vertices;
|
std::vector<vertex> vertices;
|
||||||
std::vector<std::uint32_t> indices;
|
std::vector<std::uint32_t> indices;
|
||||||
|
|
@ -103,12 +143,22 @@ namespace psemek::gfx
|
||||||
std::vector<text_vertex> text_vertices;
|
std::vector<text_vertex> text_vertices;
|
||||||
std::vector<std::uint32_t> text_indices;
|
std::vector<std::uint32_t> text_indices;
|
||||||
|
|
||||||
gfx::texture_2d font_texture;
|
struct texture_render_data
|
||||||
|
{
|
||||||
|
std::vector<texture_vertex> vertices;
|
||||||
|
std::vector<std::uint32_t> indices;
|
||||||
|
texture_2d const * texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<texture_render_data> textures;
|
||||||
|
|
||||||
|
texture_2d font_texture;
|
||||||
|
|
||||||
impl()
|
impl()
|
||||||
{
|
{
|
||||||
mesh.setup<geom::vector<float, 3>, gfx::normalized<color_rgba>>();
|
mesh.setup<geom::vector<float, 3>, gfx::normalized<color_rgba>>();
|
||||||
text_mesh.setup<geom::point<float, 3>, gfx::normalized<color_rgba>, geom::point<std::uint16_t, 2>>();
|
text_mesh.setup<geom::point<float, 3>, gfx::normalized<color_rgba>, geom::point<std::uint16_t, 2>>();
|
||||||
|
texture_mesh.setup<geom::point<float, 3>, gfx::normalized<geom::point<std::uint16_t, 2>>>();
|
||||||
|
|
||||||
util::memory_istream font_data(resource::font_9x12);
|
util::memory_istream font_data(resource::font_9x12);
|
||||||
font_texture.load(gfx::read_pbm(font_data));
|
font_texture.load(gfx::read_pbm(font_data));
|
||||||
|
|
@ -231,6 +281,24 @@ namespace psemek::gfx
|
||||||
text3d(geom::point{p[0], p[1], 0.f}, str, opts, geom::matrix<float, 3, 3>::identity());
|
text3d(geom::point{p[0], p[1], 0.f}, str, opts, geom::matrix<float, 3, 3>::identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void painter::texture(gfx::texture_2d const & texture, geom::box<float, 2> const & box)
|
||||||
|
{
|
||||||
|
impl::texture_render_data data;
|
||||||
|
data.texture = &texture;
|
||||||
|
|
||||||
|
data.indices = {0, 1, 2, 2, 1, 3};
|
||||||
|
|
||||||
|
std::uint16_t lo = 0;
|
||||||
|
std::uint16_t hi = 65535;
|
||||||
|
|
||||||
|
data.vertices.push_back({{box[0].min, box[1].min, 0.f}, {lo, lo}});
|
||||||
|
data.vertices.push_back({{box[0].max, box[1].min, 0.f}, {hi, lo}});
|
||||||
|
data.vertices.push_back({{box[0].min, box[1].max, 0.f}, {lo, hi}});
|
||||||
|
data.vertices.push_back({{box[0].max, box[1].max, 0.f}, {hi, hi}});
|
||||||
|
|
||||||
|
impl().textures.push_back(data);
|
||||||
|
}
|
||||||
|
|
||||||
void painter::axes(geom::point<float, 3> const & p, float length, float width)
|
void painter::axes(geom::point<float, 3> const & p, float length, float width)
|
||||||
{
|
{
|
||||||
geom::vector<float, 3> const d[3]
|
geom::vector<float, 3> const d[3]
|
||||||
|
|
@ -450,6 +518,10 @@ namespace psemek::gfx
|
||||||
|
|
||||||
void painter::render(geom::matrix<float, 4, 4> const & transform)
|
void painter::render(geom::matrix<float, 4, 4> const & transform)
|
||||||
{
|
{
|
||||||
|
gl::ActiveTexture(gl::TEXTURE0);
|
||||||
|
|
||||||
|
gl::Disable(gl::CULL_FACE);
|
||||||
|
|
||||||
impl().mesh.load(impl().vertices, impl().indices, gl::TRIANGLES, gl::STREAM_DRAW);
|
impl().mesh.load(impl().vertices, impl().indices, gl::TRIANGLES, gl::STREAM_DRAW);
|
||||||
impl().vertices.clear();
|
impl().vertices.clear();
|
||||||
impl().indices.clear();
|
impl().indices.clear();
|
||||||
|
|
@ -468,6 +540,17 @@ namespace psemek::gfx
|
||||||
impl().text_program["u_texture_size"] = impl().font_texture.size();
|
impl().text_program["u_texture_size"] = impl().font_texture.size();
|
||||||
impl().font_texture.bind();
|
impl().font_texture.bind();
|
||||||
impl().text_mesh.draw();
|
impl().text_mesh.draw();
|
||||||
|
|
||||||
|
impl().texture_program.bind();
|
||||||
|
impl().texture_program["u_transform"] = transform;
|
||||||
|
impl().texture_program["u_texture"] = 0;
|
||||||
|
for (auto const & data : impl().textures)
|
||||||
|
{
|
||||||
|
impl().texture_mesh.load(data.vertices, data.indices, gl::TRIANGLES, gl::STREAM_DRAW);
|
||||||
|
data.texture->bind();
|
||||||
|
impl().texture_mesh.draw();
|
||||||
|
}
|
||||||
|
impl().textures.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue