2018-11-13 16:46:01 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <string>
|
2018-11-13 23:58:52 +00:00
|
|
|
#include <unordered_map>
|
|
|
|
#include <list>
|
2018-11-13 16:46:01 +00:00
|
|
|
#include <glm/glm.hpp>
|
|
|
|
|
|
|
|
#include <charcoal/Font.h>
|
2018-11-13 23:58:52 +00:00
|
|
|
#include <charcoal/TextureFactory.h>
|
|
|
|
|
2018-11-13 19:08:26 +00:00
|
|
|
#include <charcoal/Util.h>
|
|
|
|
|
2018-11-13 23:58:52 +00:00
|
|
|
#include "MeshGenerator.h"
|
2018-11-13 16:46:01 +00:00
|
|
|
|
|
|
|
#include "GLUtil.h"
|
|
|
|
#include "BuiltinPipeline.h"
|
|
|
|
#include "WithCamera.h"
|
|
|
|
#include "TextTypes.h"
|
2018-11-13 19:08:26 +00:00
|
|
|
#include "TextShaderProgram.h"
|
2018-11-13 16:46:01 +00:00
|
|
|
#include "TextBatch.h"
|
|
|
|
|
|
|
|
namespace charcoal
|
|
|
|
{
|
|
|
|
namespace builtin
|
|
|
|
{
|
|
|
|
namespace text
|
|
|
|
{
|
|
|
|
class Pipeline : private builtin::Pipeline<ShaderProgram, Batch>, public WithCamera
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
Pipeline(
|
|
|
|
Font& font
|
|
|
|
)
|
|
|
|
: m_font(font)
|
|
|
|
{
|
2018-11-13 23:58:52 +00:00
|
|
|
std::string prepared_text = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`1234567890-=[]\\;',./~!@#$%^&*()_+{}|:\"<>?";
|
|
|
|
for (char c : prepared_text)
|
|
|
|
{
|
|
|
|
std::string s(1, c);
|
|
|
|
const charcoal::image_loader::ImageRGBA& image = m_font.get_text_image(s);
|
|
|
|
m_renderables.emplace_back(
|
|
|
|
meshgenerator::gen_rect_pt<Vertex, Index>(DrawMode::DRAW_TRIANGLES, (float)image.width, (float)image.height),
|
|
|
|
TextureFactory::gen_image_texture(image),
|
2018-11-13 19:08:26 +00:00
|
|
|
TextureFactory::gen_sampler(Sampler::Wrap::CLAMP_TO_EDGE, Sampler::Wrap::CLAMP_TO_EDGE, Sampler::MagFilter::LINEAR, Sampler::MinFilter::LINEAR),
|
2018-11-13 23:58:52 +00:00
|
|
|
DrawMode::DRAW_TRIANGLES
|
|
|
|
);
|
|
|
|
m_text_batches.emplace_back(&m_renderables.back());
|
|
|
|
add_batch(&m_text_batches.back());
|
|
|
|
m_text_to_index[s] = (unsigned int)(m_batches.size() - 1);
|
|
|
|
m_text_to_width[s] = image.width;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void init_text()
|
|
|
|
{
|
|
|
|
for (Batch& batch : m_text_batches)
|
|
|
|
{
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
batch.init();
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
}
|
2018-11-13 16:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void render()
|
|
|
|
{
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 16:46:01 +00:00
|
|
|
builtin::Pipeline<ShaderProgram, Batch>::render();
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 16:46:01 +00:00
|
|
|
}
|
|
|
|
|
2018-11-13 23:58:52 +00:00
|
|
|
void reset_text()
|
|
|
|
{
|
|
|
|
for (Batch& batch : m_text_batches)
|
|
|
|
{
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
batch.reset_rendered();
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Position specified as center of left most character.
|
|
|
|
// TODO: May want to change this to be specifyable by different than center
|
|
|
|
// and maybe do top/bottom/other stuff
|
2018-11-13 16:46:01 +00:00
|
|
|
void add_text(const vec3& position, const std::string& text)
|
|
|
|
{
|
2018-11-13 23:58:52 +00:00
|
|
|
// For now, always do aa per-char calculation.
|
|
|
|
// TODO for future would be to cache the commonly used words for faster word
|
|
|
|
// rendering.
|
|
|
|
vec3 p = position;
|
|
|
|
for (char c : text)
|
|
|
|
{
|
|
|
|
std::string s(1, c);
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
m_batches[m_text_to_index[s]]->add_rendered(charcoal::Poseable(p));
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
p.x += m_text_to_width[s];
|
|
|
|
}
|
|
|
|
}
|
2018-11-13 16:46:01 +00:00
|
|
|
|
2018-11-13 23:58:52 +00:00
|
|
|
void prerender_text()
|
|
|
|
{
|
|
|
|
for (Batch& batch : m_text_batches)
|
|
|
|
{
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
batch.prerender();
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 23:58:52 +00:00
|
|
|
}
|
2018-11-13 16:46:01 +00:00
|
|
|
}
|
2018-11-13 23:58:52 +00:00
|
|
|
|
2018-11-13 16:46:01 +00:00
|
|
|
void prepare_opengl() override
|
|
|
|
{
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
glDepthFunc(GL_LESS);
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
}
|
|
|
|
|
|
|
|
void prepare_uniforms() override
|
|
|
|
{
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 16:46:01 +00:00
|
|
|
glutil::uniform_matrix(0, get_camera()->get_world_to_view_matrix());
|
2018-11-13 19:08:26 +00:00
|
|
|
CHECK_GL_ERR();
|
2018-11-13 16:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
Font& m_font;
|
2018-11-13 23:58:52 +00:00
|
|
|
std::unordered_map<std::string, unsigned int> m_text_to_index;
|
|
|
|
std::unordered_map<std::string, unsigned int> m_text_to_width;
|
|
|
|
std::list<Renderable> m_renderables;
|
|
|
|
std::list<Batch> m_text_batches;
|
2018-11-13 16:46:01 +00:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|