Pass Renderer2D to Renderable and have each subclass of Renderable decide what the Renderer should do (like drawText(), drawRect() etc). This makes the Renderable more flexible. right now, each renderable has a texture, vertices and indices. but what if some renderables does not use textures? or more than one? What if some renderables are just a group of other renderables? (Scene Graph's). If we instead just make Renderables implement render(Renderer2D& r) interface. we can make each renderable pass the data it holds to the renderer without a hard defined interface.
176 lines
No EOL
3.3 KiB
C++
176 lines
No EOL
3.3 KiB
C++
|
|
#include <Spectre/Math/Vector4.h>
|
|
#include <Spectre/Graphics/Renderer2D.h>
|
|
#include <Spectre/Graphics/Text.h>
|
|
|
|
Text::Text() :
|
|
m_font (NULL),
|
|
m_size (22),
|
|
m_color (255, 255, 255, 255),
|
|
m_outlineColor (0, 0, 0, 255),
|
|
m_outlineWidth (0)
|
|
{
|
|
}
|
|
|
|
Text::Text(const std::string text, unsigned int size, const Font& font) :
|
|
m_font (&font),
|
|
m_size (size),
|
|
m_string (text),
|
|
m_color (255, 255, 255, 255),
|
|
m_outlineColor (0, 0, 0, 255),
|
|
m_outlineWidth (0),
|
|
m_geometryNeedsUpdate (true)
|
|
{
|
|
}
|
|
|
|
void Text::setString(const std::string& string)
|
|
{
|
|
m_string = string;
|
|
m_geometryNeedsUpdate = true;
|
|
}
|
|
|
|
const std::string& Text::getString() const
|
|
{
|
|
return m_string;
|
|
}
|
|
|
|
void Text::setCharacterSize(unsigned int size)
|
|
{
|
|
m_size = size;
|
|
m_geometryNeedsUpdate = true;
|
|
}
|
|
|
|
unsigned int Text::getCharacteSize() const
|
|
{
|
|
return m_size;
|
|
}
|
|
|
|
void Text::setFont(const Font& font)
|
|
{
|
|
m_font = &font;
|
|
m_geometryNeedsUpdate = true;
|
|
}
|
|
const Font* Text::getFont() const
|
|
{
|
|
return m_font;
|
|
}
|
|
|
|
void Text::setColor(const Color& color)
|
|
{
|
|
m_color = color;
|
|
m_geometryNeedsUpdate = true;
|
|
}
|
|
|
|
const Color& Text::getColor() const
|
|
{
|
|
return m_color;
|
|
}
|
|
|
|
void Text::setOutlineColor(const Color& color)
|
|
{
|
|
m_outlineColor = color;
|
|
}
|
|
|
|
const Color& Text::getOutlineColor() const
|
|
{
|
|
return m_outlineColor;
|
|
}
|
|
|
|
void Text::setOutlineSize(unsigned int size)
|
|
{
|
|
m_outlineWidth = size;
|
|
}
|
|
|
|
unsigned int Text::getOutlineSize() const
|
|
{
|
|
return m_outlineWidth;
|
|
}
|
|
|
|
Vector2f Text::getSize() const
|
|
{
|
|
Vector2f size;
|
|
|
|
for(int i = 0; i < m_string.size(); i++) {
|
|
|
|
Font::Glyph glyph = m_font->getGlyph(m_string[i]);
|
|
|
|
float h = glyph.size.y;
|
|
float w = glyph.advance;
|
|
|
|
if (h > size.y) {
|
|
size.y = h;
|
|
}
|
|
size.x += w;
|
|
}
|
|
return size;
|
|
}
|
|
|
|
const Texture* Text::getTexture() const
|
|
{
|
|
if (m_geometryNeedsUpdate) {
|
|
updateGeometry();
|
|
m_geometryNeedsUpdate = false;
|
|
}
|
|
return m_font->getTexture();
|
|
}
|
|
|
|
const std::vector<unsigned short>& Text::getIndices() const
|
|
{
|
|
return m_indicies;
|
|
}
|
|
|
|
const std::vector<Vertex2D>& Text::getVertices() const
|
|
{
|
|
if (m_geometryNeedsUpdate) {
|
|
updateGeometry();
|
|
m_geometryNeedsUpdate = false;
|
|
}
|
|
return m_vertices;
|
|
}
|
|
|
|
void Text::updateGeometry() const
|
|
{
|
|
Vector2f origin;
|
|
Vector2f size = getSize();
|
|
Vector4f color = getColor().toRGBAf();
|
|
|
|
m_vertices.clear();
|
|
|
|
for(int i = 0; i < m_string.length(); i++) {
|
|
|
|
Vertex2D v1, v2, v3, v4;
|
|
|
|
Font::Glyph glyph = m_font->getGlyph(m_string[i]);
|
|
|
|
if (glyph.texture) {
|
|
|
|
Vector2f vpos = origin + vec2f(glyph.offset.x, size.y - glyph.offset.y);
|
|
|
|
Vertex2D v1 = Vertex2D(vpos + vec2f( 0.0f, 0.0f), vec2f(glyph.texture_origin.x, glyph.texture_origin.y));
|
|
Vertex2D v2 = Vertex2D(vpos + vec2f( glyph.size.x, 0.0f), vec2f(glyph.texture_origin.x + glyph.size.x, glyph.texture_origin.y));
|
|
Vertex2D v3 = Vertex2D(vpos + vec2f( glyph.size.x, glyph.size.y), vec2f(glyph.texture_origin.x + glyph.size.x, glyph.texture_origin.y + glyph.size.y));
|
|
Vertex2D v4 = Vertex2D(vpos + vec2f( 0.0f, glyph.size.y), vec2f(glyph.texture_origin.x, glyph.texture_origin.y + glyph.size.y));
|
|
|
|
v1.color = color;
|
|
v2.color = color;
|
|
v3.color = color;
|
|
v4.color = color;
|
|
|
|
m_vertices.push_back(v1);
|
|
m_vertices.push_back(v2);
|
|
m_vertices.push_back(v3);
|
|
m_vertices.push_back(v4);
|
|
}
|
|
|
|
origin.x += glyph.advance;
|
|
}
|
|
|
|
int x = 0;
|
|
|
|
|
|
}
|
|
|
|
void Text::render(Renderer2D& renderer) const
|
|
{
|
|
renderer.draw(this);
|
|
} |