From 2944a4e20539708ad4f229a132aef7cb5151a545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 4 Mar 2013 11:19:42 +0100 Subject: [PATCH] Text: non-templated base for TextRenderer. Saves a lot of duplicated generated code. --- src/Text/Text.h | 1 + src/Text/TextRenderer.cpp | 38 +++++++--- src/Text/TextRenderer.h | 148 ++++++++++++++++++++++---------------- 3 files changed, 116 insertions(+), 71 deletions(-) diff --git a/src/Text/Text.h b/src/Text/Text.h index 4e4d49443..08b708df2 100644 --- a/src/Text/Text.h +++ b/src/Text/Text.h @@ -26,6 +26,7 @@ namespace Magnum { namespace Text { class Font; class FontRenderer; +class AbstractTextRenderer; template class TextRenderer; typedef TextRenderer<2> TextRenderer2D; typedef TextRenderer<3> TextRenderer3D; diff --git a/src/Text/TextRenderer.cpp b/src/Text/TextRenderer.cpp index c21983470..634e90244 100644 --- a/src/Text/TextRenderer.cpp +++ b/src/Text/TextRenderer.cpp @@ -154,7 +154,7 @@ struct Vertex { } -template std::tuple, std::vector, std::vector, Rectangle> TextRenderer::render(Font& font, Float size, const std::string& text) { +std::tuple, std::vector, std::vector, Rectangle> AbstractTextRenderer::render(Font& font, Float size, const std::string& text) { TextLayouter layouter(font, size, text); const UnsignedInt vertexCount = layouter.glyphCount()*4; @@ -200,7 +200,7 @@ template std::tuple, std::vector std::tuple TextRenderer::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { +std::tuple AbstractTextRenderer::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { TextLayouter layouter(font, size, text); const UnsignedInt vertexCount = layouter.glyphCount()*4; @@ -257,19 +257,28 @@ template std::tuple TextRenderersetIndexCount(indexCount) - ->addInterleavedVertexBuffer(vertexBuffer, 0, - typename Shaders::AbstractVectorShader::Position(Shaders::AbstractVectorShader::Position::Components::Two), - typename Shaders::AbstractVectorShader::TextureCoordinates()) ->setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount); return std::make_tuple(std::move(mesh), rectangle); } -template TextRenderer::TextRenderer(Font& font, const Float size): font(font), size(size), _capacity(0), vertexBuffer(Buffer::Target::Array), indexBuffer(Buffer::Target::ElementArray) { +template std::tuple TextRenderer::render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage) { + /* Finalize mesh configuration and return the result */ + auto r = AbstractTextRenderer::render(font, size, text, vertexBuffer, indexBuffer, usage); + Mesh& mesh = std::get<0>(r); + mesh.addInterleavedVertexBuffer(vertexBuffer, 0, + typename Shaders::AbstractVectorShader::Position( + Shaders::AbstractVectorShader::Position::Components::Two), + typename Shaders::AbstractVectorShader::TextureCoordinates()); + return std::move(r); +} + +AbstractTextRenderer::AbstractTextRenderer(Font& font, Float size): vertexBuffer(Buffer::Target::Array), indexBuffer(Buffer::Target::ElementArray), font(font), size(size), _capacity(0) { #ifndef MAGNUM_TARGET_GLES MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::map_buffer_range); #else @@ -278,13 +287,20 @@ template TextRenderer::TextRenderer(Font& fo #endif #endif - _mesh.setPrimitive(Mesh::Primitive::Triangles) - ->addInterleavedVertexBuffer(&vertexBuffer, 0, + /* Vertex buffer configuration depends on dimension count, done in subclass */ + _mesh.setPrimitive(Mesh::Primitive::Triangles); +} + +AbstractTextRenderer::~AbstractTextRenderer() {} + +template TextRenderer::TextRenderer(Font& font, const Float size): AbstractTextRenderer(font, size) { + /* Finalize mesh configuration */ + _mesh.addInterleavedVertexBuffer(&vertexBuffer, 0, typename Shaders::AbstractVectorShader::Position(Shaders::AbstractVectorShader::Position::Components::Two), typename Shaders::AbstractVectorShader::TextureCoordinates()); } -template void TextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage) { +void AbstractTextRenderer::reserve(const uint32_t glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage) { _capacity = glyphCount; const UnsignedInt vertexCount = glyphCount*4; @@ -322,7 +338,7 @@ template void TextRenderer::reserve(const ui CORRADE_INTERNAL_ASSERT_OUTPUT(indexBuffer.unmap()); } -template void TextRenderer::render(const std::string& text) { +void AbstractTextRenderer::render(const std::string& text) { TextLayouter layouter(font, size, text); CORRADE_ASSERT(layouter.glyphCount() <= _capacity, "Text::TextRenderer::render(): capacity" << _capacity << "too small to render" << layouter.glyphCount() << "glyphs", ); diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 33a7362c2..f4932fdf2 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -16,7 +16,7 @@ */ /** @file - * @brief Class Magnum::Text::TextRenderer + * @brief Class Magnum::Text::AbstractTextRenderer, Magnum::Text::TextRenderer, typedef Magnum::Text::TextRenderer2D, Magnum::Text::TextRenderer3D */ #include "Math/Geometry/Rectangle.h" @@ -33,6 +33,91 @@ namespace Magnum { namespace Text { +/** +@brief Base for text renderers + +Not meant to be used directly, see TextRenderer for more information. +@see TextRenderer2D, TextRenderer3D +*/ +class MAGNUM_TEXT_EXPORT AbstractTextRenderer { + public: + /** + * @brief Render text + * @param font %Font to use + * @param size %Font size + * @param text %Text to render + * + * Returns tuple with vertex positions, texture coordinates, indices + * and rectangle spanning the rendered text. + */ + static std::tuple, std::vector, std::vector, Rectangle> render(Font& font, Float size, const std::string& text); + + /** + * @brief Constructor + * @param font %Font to use + * @param size %Font size + */ + AbstractTextRenderer(Font& font, Float size); + + virtual ~AbstractTextRenderer() = 0; + + /** + * @brief Capacity for rendered glyphs + * + * @see reserve() + */ + inline UnsignedInt capacity() const { return _capacity; } + + /** @brief Rectangle spanning the rendered text */ + inline Rectangle rectangle() const { return _rectangle; } + + /** @brief Text mesh */ + inline Mesh* mesh() { return &_mesh; } + + /** + * @brief Reserve capacity for rendered glyphs + * + * Reallocates memory in buffers to hold @p glyphCount glyphs and + * prefills index buffer. Consider using appropriate @p vertexBufferUsage + * if the text will be changed frequently. Index buffer is changed + * only by calling this function, thus @p indexBufferUsage generally + * doesn't need to be so dynamic if the capacity won't be changed much. + * + * Initially zero capacity is reserved. + * @see capacity() + */ + void reserve(const UnsignedInt glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage); + + /** + * @brief Render text + * + * Renders the text to vertex buffer, reusing index buffer already + * filled with reserve(). Rectangle spanning the rendered text is + * available through rectangle(). + * + * Initially no text is rendered. + * @attention The capacity must be large enough to contain all glyphs, + * see reserve() for more information. + */ + void render(const std::string& text); + + #ifndef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif + static std::tuple MAGNUM_LOCAL render(Font& font, Float size, const std::string& text, Buffer* vertexBuffer, Buffer* indexBuffer, Buffer::Usage usage); + + Mesh _mesh; + Buffer vertexBuffer, indexBuffer; + + private: + Font& font; + Float size; + UnsignedInt _capacity; + Rectangle _rectangle; +}; + /** @brief %Text renderer @@ -98,19 +183,8 @@ for asynchronous buffer updates. @see TextRenderer2D, TextRenderer3D, Font, Shaders::AbstractVectorShader */ -template class MAGNUM_TEXT_EXPORT TextRenderer { +template class MAGNUM_TEXT_EXPORT TextRenderer: public AbstractTextRenderer { public: - /** - * @brief Render text - * @param font %Font to use - * @param size %Font size - * @param text %Text to render - * - * Returns tuple with vertex positions, texture coordinates, indices - * and rectangle spanning the rendered text. - */ - static std::tuple, std::vector, std::vector, Rectangle> render(Font& font, Float size, const std::string& text); - /** * @brief Render text * @param font %Font to use @@ -132,53 +206,7 @@ template class MAGNUM_TEXT_EXPORT TextRenderer { */ TextRenderer(Font& font, Float size); - /** - * @brief Capacity for rendered glyphs - * - * @see reserve() - */ - inline UnsignedInt capacity() const { return _capacity; } - - /** @brief Rectangle spanning the rendered text */ - inline Rectangle rectangle() const { return _rectangle; } - - /** @brief Text mesh */ - inline Mesh* mesh() { return &_mesh; } - - /** - * @brief Reserve capacity for rendered glyphs - * - * Reallocates memory in buffers to hold @p glyphCount glyphs and - * prefills index buffer. Consider using appropriate @p vertexBufferUsage - * if the text will be changed frequently. Index buffer is changed - * only by calling this function, thus @p indexBufferUsage generally - * doesn't need to be so dynamic if the capacity won't be changed much. - * - * Initially zero capacity is reserved. - * @see capacity() - */ - void reserve(const UnsignedInt glyphCount, const Buffer::Usage vertexBufferUsage, const Buffer::Usage indexBufferUsage); - - /** - * @brief Render text - * - * Renders the text to vertex buffer, reusing index buffer already - * filled with reserve(). Rectangle spanning the rendered text is - * available through rectangle(). - * - * Initially no text is rendered. - * @attention The capacity must be large enough to contain all glyphs, - * see reserve() for more information. - */ - void render(const std::string& text); - - private: - Font& font; - Float size; - UnsignedInt _capacity; - Rectangle _rectangle; - Buffer vertexBuffer, indexBuffer; - Mesh _mesh; + using AbstractTextRenderer::render; }; /** @brief Two-dimensional text renderer */