diff options
author | 2021-08-10 20:28:56 +0200 | |
---|---|---|
committer | 2021-08-10 20:28:56 +0200 | |
commit | 1a6a018fc3b393e6f769d7db3aea397175aba459 (patch) | |
tree | 1fd0418f1044b221537c682e3e7f02a4a2a72af2 /3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp | |
parent | 702c9b45cc3a0d3eaaf29cd595b7e3511316a348 (diff) |
Update bgfx to latest
Diffstat (limited to '3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp')
-rw-r--r-- | 3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp | 522 |
1 files changed, 465 insertions, 57 deletions
diff --git a/3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp b/3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp index 92c2143adfe..131fecf3ae7 100644 --- a/3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp +++ b/3rdparty/bgfx/examples/common/font/text_buffer_manager.cpp @@ -21,6 +21,16 @@ #include "fs_font_distance_field.bin.h" #include "vs_font_distance_field_subpixel.bin.h" #include "fs_font_distance_field_subpixel.bin.h" +#include "vs_font_distance_field_outline.bin.h" +#include "fs_font_distance_field_outline.bin.h" +#include "vs_font_distance_field_outline_image.bin.h" +#include "fs_font_distance_field_outline_image.bin.h" +#include "vs_font_distance_field_drop_shadow.bin.h" +#include "fs_font_distance_field_drop_shadow.bin.h" +#include "vs_font_distance_field_drop_shadow_image.bin.h" +#include "fs_font_distance_field_drop_shadow_image.bin.h" +#include "vs_font_distance_field_outline_drop_shadow_image.bin.h" +#include "fs_font_distance_field_outline_drop_shadow_image.bin.h" static const bgfx::EmbeddedShader s_embeddedShaders[] = { @@ -30,6 +40,16 @@ static const bgfx::EmbeddedShader s_embeddedShaders[] = BGFX_EMBEDDED_SHADER(fs_font_distance_field), BGFX_EMBEDDED_SHADER(vs_font_distance_field_subpixel), BGFX_EMBEDDED_SHADER(fs_font_distance_field_subpixel), + BGFX_EMBEDDED_SHADER(vs_font_distance_field_outline), + BGFX_EMBEDDED_SHADER(fs_font_distance_field_outline), + BGFX_EMBEDDED_SHADER(vs_font_distance_field_outline_image), + BGFX_EMBEDDED_SHADER(fs_font_distance_field_outline_image), + BGFX_EMBEDDED_SHADER(vs_font_distance_field_drop_shadow), + BGFX_EMBEDDED_SHADER(fs_font_distance_field_drop_shadow), + BGFX_EMBEDDED_SHADER(vs_font_distance_field_drop_shadow_image), + BGFX_EMBEDDED_SHADER(fs_font_distance_field_drop_shadow_image), + BGFX_EMBEDDED_SHADER(vs_font_distance_field_outline_drop_shadow_image), + BGFX_EMBEDDED_SHADER(fs_font_distance_field_outline_drop_shadow_image), BGFX_EMBEDDED_SHADER_END() }; @@ -45,6 +65,36 @@ public: TextBuffer(FontManager* _fontManager); ~TextBuffer(); + uint32_t getOutlineColor() + { + return m_outlineColor; + } + + float getOutlineWidth() + { + return m_outlineWidth; + } + + uint32_t getDropShadowColor() + { + return m_dropShadowColor; + } + + float getDropShadowOffsetU() + { + return m_dropShadowOffset[0]; + } + + float getDropShadowOffsetV() + { + return m_dropShadowOffset[1]; + } + + float getDropShadowSoftener() + { + return m_dropShadowSoftener; + } + void setStyle(uint32_t _flags = STYLE_NORMAL) { m_styleFlags = _flags; @@ -75,6 +125,39 @@ public: m_strikeThroughColor = toABGR(_rgba); } + void setOutlineColor(uint32_t _rgba = 0x000000FF) + { + m_outlineColor = toABGR(_rgba); + } + + void setOutlineWidth(float _outlineWidth = 3.0f) + { + m_outlineWidth = _outlineWidth; + } + + void setDropShadowColor(uint32_t _rgba = 0x000000FF) + { + m_dropShadowColor = toABGR(_rgba); + } + + /* + void setDropShadowWidth(float _dropShadowWidth = 3.0f) + { + m_dropShadowWidth = _dropShadowWidth; + } + */ + + void setDropShadowOffset(float u, float v) + { + m_dropShadowOffset[0] = u; + m_dropShadowOffset[1] = v; + } + + void setDropShadowSoftener(float smoother) + { + m_dropShadowSoftener = smoother; + } + void setPenPosition(float _x, float _y) { m_penX = _x; m_penY = _y; @@ -142,7 +225,7 @@ public: } private: - void appendGlyph(FontHandle _handle, CodePoint _codePoint); + void appendGlyph(FontHandle _handle, CodePoint _codePoint, bool shadow); void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom); static uint32_t toABGR(uint32_t _rgba) @@ -154,6 +237,29 @@ private: ; } + void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL) + { + m_vertexBuffer[_i].x = _x; + m_vertexBuffer[_i].y = _y; + m_vertexBuffer[_i].rgba = _rgba; + m_styleBuffer[_i] = _style; + } + + void setOutlineColor(uint32_t _i, uint32_t _rgbaOutline) + { + m_vertexBuffer[_i].rgbaOutline = _rgbaOutline; + } + + struct TextVertex + { + float x, y; + int16_t u, v, w, t; + int16_t u1, v1, w1, t1; + int16_t u2, v2, w2, t2; + uint32_t rgba; + uint32_t rgbaOutline; + }; + uint32_t m_styleFlags; // color states @@ -164,6 +270,15 @@ private: uint32_t m_underlineColor; uint32_t m_strikeThroughColor; + // outline state + float m_outlineWidth; + uint32_t m_outlineColor; + + // drop shadow state + float m_dropShadowOffset[2]; + uint32_t m_dropShadowColor; + float m_dropShadowSoftener; + //position states float m_penX; float m_penY; @@ -175,24 +290,11 @@ private: float m_lineDescender; float m_lineGap; + CodePoint m_previousCodePoint; + TextRectangle m_rectangle; FontManager* m_fontManager; - void setVertex(uint32_t _i, float _x, float _y, uint32_t _rgba, uint8_t _style = STYLE_NORMAL) - { - m_vertexBuffer[_i].x = _x; - m_vertexBuffer[_i].y = _y; - m_vertexBuffer[_i].rgba = _rgba; - m_styleBuffer[_i] = _style; - } - - struct TextVertex - { - float x, y; - int16_t u, v, w, t; - uint32_t rgba; - }; - TextVertex* m_vertexBuffer; uint16_t* m_indexBuffer; uint8_t* m_styleBuffer; @@ -204,11 +306,15 @@ private: TextBuffer::TextBuffer(FontManager* _fontManager) : m_styleFlags(STYLE_NORMAL) - , m_textColor(0xffffffff) - , m_backgroundColor(0xffffffff) - , m_overlineColor(0xffffffff) - , m_underlineColor(0xffffffff) - , m_strikeThroughColor(0xffffffff) + , m_textColor(UINT32_MAX) + , m_backgroundColor(UINT32_MAX) + , m_overlineColor(UINT32_MAX) + , m_underlineColor(UINT32_MAX) + , m_strikeThroughColor(UINT32_MAX) + , m_outlineWidth(3.0f) + , m_outlineColor(0x000000ff) + , m_dropShadowColor(0x0000005a) + , m_dropShadowSoftener(1.0f) , m_penX(0) , m_penY(0) , m_originX(0) @@ -216,6 +322,7 @@ TextBuffer::TextBuffer(FontManager* _fontManager) , m_lineAscender(0) , m_lineDescender(0) , m_lineGap(0) + , m_previousCodePoint(0) , m_fontManager(_fontManager) , m_vertexBuffer(new TextVertex[MAX_BUFFERED_CHARACTERS * 4]) , m_indexBuffer(new uint16_t[MAX_BUFFERED_CHARACTERS * 6]) @@ -226,6 +333,8 @@ TextBuffer::TextBuffer(FontManager* _fontManager) { m_rectangle.width = 0; m_rectangle.height = 0; + m_dropShadowOffset[0] = 0.00f; + m_dropShadowOffset[1] = 0.00f; } TextBuffer::~TextBuffer() @@ -244,6 +353,7 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string, const c m_lineDescender = 0; m_lineAscender = 0; m_lineGap = 0; + m_previousCodePoint = 0; } CodePoint codepoint = 0; @@ -253,17 +363,41 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char* _string, const c { _end = _string + bx::strLen(_string); } - BX_CHECK(_end >= _string); + BX_ASSERT(_end >= _string); + + const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); + if (font.fontType & FONT_TYPE_MASK_DISTANCE_DROP_SHADOW) + { + float savePenX = m_penX; + float savePenY = m_penY; + CodePoint savePreviousCodePoint = m_previousCodePoint; + TextRectangle saveRectangle = m_rectangle; + + const char* origString = _string; + for (; *_string && _string < _end ; ++_string) + { + if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT ) + { + appendGlyph(_fontHandle, codepoint, true); + } + } + _string = origString; + + m_penX = savePenX; + m_penY = savePenY; + m_previousCodePoint = savePreviousCodePoint; + m_rectangle = saveRectangle; + } for (; *_string && _string < _end ; ++_string) { if (utf8_decode(&state, (uint32_t*)&codepoint, *_string) == UTF8_ACCEPT ) { - appendGlyph(_fontHandle, codepoint); + appendGlyph(_fontHandle, codepoint, false); } } - BX_CHECK(state == UTF8_ACCEPT, "The string is not well-formed"); + BX_ASSERT(state == UTF8_ACCEPT, "The string is not well-formed"); } void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string, const wchar_t* _end) @@ -275,18 +409,39 @@ void TextBuffer::appendText(FontHandle _fontHandle, const wchar_t* _string, cons m_lineDescender = 0; m_lineAscender = 0; m_lineGap = 0; + m_previousCodePoint = 0; } if (_end == NULL) { _end = _string + wcslen(_string); } - BX_CHECK(_end >= _string); + BX_ASSERT(_end >= _string); + + const FontInfo& font = m_fontManager->getFontInfo(_fontHandle); + if (font.fontType & FONT_TYPE_MASK_DISTANCE_DROP_SHADOW) + { + float savePenX = m_penX; + float savePenY = m_penY; + CodePoint savePreviousCodePoint = m_previousCodePoint; + TextRectangle saveRectangle = m_rectangle; + + for (const wchar_t* _current = _string; _current < _end; ++_current) + { + uint32_t _codePoint = *_current; + appendGlyph(_fontHandle, _codePoint, true); + } + + m_penX = savePenX; + m_penY = savePenY; + m_previousCodePoint = savePreviousCodePoint; + m_rectangle = saveRectangle; + } for (const wchar_t* _current = _string; _current < _end; ++_current) { uint32_t _codePoint = *_current; - appendGlyph(_fontHandle, _codePoint); + appendGlyph(_fontHandle, _codePoint, false); } } @@ -336,17 +491,18 @@ void TextBuffer::clearTextBuffer() m_lineAscender = 0; m_lineDescender = 0; m_lineGap = 0; + m_previousCodePoint = 0; m_rectangle.width = 0; m_rectangle.height = 0; } -void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) +void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint, bool shadow) { if (_codePoint == L'\t') { for (uint32_t ii = 0; ii < 4; ++ii) { - appendGlyph(_handle, L' '); + appendGlyph(_handle, L' ', shadow); } return; } @@ -355,11 +511,13 @@ void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) BX_WARN(NULL != glyph, "Glyph not found (font handle %d, code point %d)", _handle.idx, _codePoint); if (NULL == glyph) { + m_previousCodePoint = 0; return; } if( m_vertexCount/4 >= MAX_BUFFERED_CHARACTERS) { + m_previousCodePoint = 0; return; } @@ -373,6 +531,7 @@ void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) m_lineDescender = font.descender; m_lineAscender = font.ascender; m_lineStartIndex = m_vertexCount; + m_previousCodePoint = 0; return; } @@ -392,11 +551,64 @@ void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) verticalCenterLastLine( (txtDecals), (m_penY - m_lineAscender), (m_penY + m_lineAscender - m_lineDescender + m_lineGap) ); } - float kerning = 0 * font.scale; + float kerning = m_fontManager->getKerning(_handle, m_previousCodePoint, _codePoint); m_penX += kerning; const GlyphInfo& blackGlyph = m_fontManager->getBlackGlyph(); const Atlas* atlas = m_fontManager->getAtlas(); + const AtlasRegion& atlasRegion = atlas->getRegion(glyph->regionIndex); + + if (shadow) + { + if (atlasRegion.getType() != AtlasRegion::TYPE_BGRA8) + { + float extraXOffset = m_dropShadowOffset[0]; + float extraYOffset = m_dropShadowOffset[1]; + + float x0 = m_penX + (glyph->offset_x) + extraXOffset; + float y0 = (m_penY + m_lineAscender + (glyph->offset_y) + extraYOffset ); + float x1 = (x0 + glyph->width); + float y1 = (y0 + glyph->height); + + bx::memSet(&m_vertexBuffer[m_vertexCount], 0, sizeof(TextVertex) * 4); + + atlas->packUV(glyph->regionIndex + , (uint8_t*)m_vertexBuffer + , sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u2) + , sizeof(TextVertex) + ); + + uint32_t adjustedDropShadowColor = ((((m_dropShadowColor & 0xff000000) >> 8) * (m_textColor >> 24)) & 0xff000000) | (m_dropShadowColor & 0x00ffffff); + setVertex(m_vertexCount + 0, x0, y0, adjustedDropShadowColor); + setVertex(m_vertexCount + 1, x0, y1, adjustedDropShadowColor); + setVertex(m_vertexCount + 2, x1, y1, adjustedDropShadowColor); + setVertex(m_vertexCount + 3, x1, y0, adjustedDropShadowColor); + + m_indexBuffer[m_indexCount + 0] = m_vertexCount + 0; + m_indexBuffer[m_indexCount + 1] = m_vertexCount + 1; + m_indexBuffer[m_indexCount + 2] = m_vertexCount + 2; + m_indexBuffer[m_indexCount + 3] = m_vertexCount + 0; + m_indexBuffer[m_indexCount + 4] = m_vertexCount + 2; + m_indexBuffer[m_indexCount + 5] = m_vertexCount + 3; + m_vertexCount += 4; + m_indexCount += 6; + } + + m_penX += glyph->advance_x; + if (m_penX > m_rectangle.width) + { + m_rectangle.width = m_penX; + } + + if ( (m_penY +m_lineAscender - m_lineDescender+m_lineGap) > m_rectangle.height) + { + m_rectangle.height = (m_penY +m_lineAscender - m_lineDescender+m_lineGap); + } + + m_previousCodePoint = _codePoint; + + return; + } if (m_styleFlags & STYLE_BACKGROUND && m_backgroundColor & 0xff000000) @@ -515,21 +727,54 @@ void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) m_indexCount += 6; } - float x0 = m_penX + (glyph->offset_x); - float y0 = (m_penY + m_lineAscender + (glyph->offset_y) ); - float x1 = (x0 + glyph->width); - float y1 = (y0 + glyph->height); + if (!shadow && atlasRegion.getType() == AtlasRegion::TYPE_BGRA8) + { + bx::memSet(&m_vertexBuffer[m_vertexCount], 0, sizeof(TextVertex) * 4); - atlas->packUV(glyph->regionIndex - , (uint8_t*)m_vertexBuffer - , sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u) - , sizeof(TextVertex) - ); + atlas->packUV(glyph->regionIndex + , (uint8_t*)m_vertexBuffer + , sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u1) + , sizeof(TextVertex) + ); + + float glyphScale = glyph->bitmapScale; + float glyphWidth = glyph->width * glyphScale; + float glyphHeight = glyph->height * glyphScale; + float x0 = m_penX + (glyph->offset_x); + float y0 = (m_penY + (font.ascender + -font.descender - glyphHeight) / 2); + float x1 = (x0 + glyphWidth); + float y1 = (y0 + glyphHeight); + + setVertex(m_vertexCount + 0, x0, y0, m_textColor); + setVertex(m_vertexCount + 1, x0, y1, m_textColor); + setVertex(m_vertexCount + 2, x1, y1, m_textColor); + setVertex(m_vertexCount + 3, x1, y0, m_textColor); + } + else if (!shadow) + { + bx::memSet(&m_vertexBuffer[m_vertexCount], 0, sizeof(TextVertex) * 4); + + atlas->packUV(glyph->regionIndex + , (uint8_t*)m_vertexBuffer + , sizeof(TextVertex) * m_vertexCount + offsetof(TextVertex, u) + , sizeof(TextVertex) + ); + + float x0 = m_penX + (glyph->offset_x); + float y0 = (m_penY + m_lineAscender + (glyph->offset_y) ); + float x1 = (x0 + glyph->width); + float y1 = (y0 + glyph->height); - setVertex(m_vertexCount + 0, x0, y0, m_textColor); - setVertex(m_vertexCount + 1, x0, y1, m_textColor); - setVertex(m_vertexCount + 2, x1, y1, m_textColor); - setVertex(m_vertexCount + 3, x1, y0, m_textColor); + setVertex(m_vertexCount + 0, x0, y0, m_textColor); + setVertex(m_vertexCount + 1, x0, y1, m_textColor); + setVertex(m_vertexCount + 2, x1, y1, m_textColor); + setVertex(m_vertexCount + 3, x1, y0, m_textColor); + + setOutlineColor(m_vertexCount + 0, m_outlineColor); + setOutlineColor(m_vertexCount + 1, m_outlineColor); + setOutlineColor(m_vertexCount + 2, m_outlineColor); + setOutlineColor(m_vertexCount + 3, m_outlineColor); + } m_indexBuffer[m_indexCount + 0] = m_vertexCount + 0; m_indexBuffer[m_indexCount + 1] = m_vertexCount + 1; @@ -550,6 +795,8 @@ void TextBuffer::appendGlyph(FontHandle _handle, CodePoint _codePoint) { m_rectangle.height = (m_penY +m_lineAscender - m_lineDescender+m_lineGap); } + + m_previousCodePoint = _codePoint; } void TextBuffer::verticalCenterLastLine(float _dy, float _top, float _bottom) @@ -598,26 +845,69 @@ TextBufferManager::TextBufferManager(FontManager* _fontManager) , true ); + m_distanceDropShadowProgram = bgfx::createProgram( + bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_font_distance_field_drop_shadow") + , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_font_distance_field_drop_shadow") + , true + ); + + m_distanceDropShadowImageProgram = bgfx::createProgram( + bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_font_distance_field_drop_shadow_image") + , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_font_distance_field_drop_shadow_image") + , true + ); + + m_distanceOutlineProgram = bgfx::createProgram( + bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_font_distance_field_outline") + , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_font_distance_field_outline") + , true + ); + + m_distanceOutlineImageProgram = bgfx::createProgram( + bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_font_distance_field_outline_image") + , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_font_distance_field_outline_image") + , true + ); + + m_distanceOutlineDropShadowImageProgram = bgfx::createProgram( + bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_font_distance_field_outline_drop_shadow_image") + , bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_font_distance_field_outline_drop_shadow_image") + , true + ); + m_vertexLayout .begin() .add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float) .add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Int16, true) + .add(bgfx::Attrib::TexCoord1, 4, bgfx::AttribType::Int16, true) + .add(bgfx::Attrib::TexCoord2, 4, bgfx::AttribType::Int16, true) .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true) + .add(bgfx::Attrib::Color1, 4, bgfx::AttribType::Uint8, true) .end(); s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler); + u_dropShadowColor = bgfx::createUniform("u_dropShadowColor", bgfx::UniformType::Vec4); + u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4); } TextBufferManager::~TextBufferManager() { - BX_CHECK(m_textBufferHandles.getNumHandles() == 0, "All the text buffers must be destroyed before destroying the manager"); + BX_ASSERT(m_textBufferHandles.getNumHandles() == 0, "All the text buffers must be destroyed before destroying the manager"); delete [] m_textBuffers; + bgfx::destroy(u_params); + + bgfx::destroy(u_dropShadowColor); bgfx::destroy(s_texColor); bgfx::destroy(m_basicProgram); bgfx::destroy(m_distanceProgram); bgfx::destroy(m_distanceSubpixelProgram); + bgfx::destroy(m_distanceOutlineProgram); + bgfx::destroy(m_distanceOutlineImageProgram); + bgfx::destroy(m_distanceDropShadowProgram); + bgfx::destroy(m_distanceDropShadowImageProgram); + bgfx::destroy(m_distanceOutlineDropShadowImageProgram); } TextBufferHandle TextBufferManager::createTextBuffer(uint32_t _type, BufferType::Enum _bufferType) @@ -637,7 +927,7 @@ TextBufferHandle TextBufferManager::createTextBuffer(uint32_t _type, BufferType: void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; m_textBufferHandles.free(_handle.idx); @@ -680,7 +970,7 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, bgfx::ViewId _id, int32_t _depth) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; @@ -706,12 +996,17 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, bgfx::ViewId break; case FONT_TYPE_DISTANCE: + { program = m_distanceProgram; bgfx::setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, 0.0f, 0.0f }; + bgfx::setUniform(u_params, ¶ms); break; + } case FONT_TYPE_DISTANCE_SUBPIXEL: program = m_distanceSubpixelProgram; @@ -721,6 +1016,84 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, bgfx::ViewId , bc.textBuffer->getTextColor() ); break; + + case FONT_TYPE_DISTANCE_OUTLINE: + { + program = m_distanceOutlineProgram; + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, 0.0f, bc.textBuffer->getOutlineWidth() }; + bgfx::setUniform(u_params, ¶ms); + break; + } + + case FONT_TYPE_DISTANCE_OUTLINE_IMAGE: + { + program = m_distanceOutlineImageProgram; + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, 0.0f, bc.textBuffer->getOutlineWidth() }; + bgfx::setUniform(u_params, ¶ms); + break; + } + + case FONT_TYPE_DISTANCE_DROP_SHADOW: + { + program = m_distanceDropShadowProgram; + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + + uint32_t dropShadowColor = bc.textBuffer->getDropShadowColor(); + float dropShadowColorVec[4] = { ((dropShadowColor >> 16) & 0xff) / 255.0f, ((dropShadowColor >> 8) & 0xff) / 255.0f, (dropShadowColor & 0xff) / 255.0f, (dropShadowColor >> 24) / 255.0f }; + bgfx::setUniform(u_dropShadowColor, &dropShadowColorVec); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, bc.textBuffer->getDropShadowSoftener(), 0.0 }; + bgfx::setUniform(u_params, ¶ms); + break; + } + + case FONT_TYPE_DISTANCE_DROP_SHADOW_IMAGE: + { + program = m_distanceDropShadowImageProgram; + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + + uint32_t dropShadowColor = bc.textBuffer->getDropShadowColor(); + float dropShadowColorVec[4] = { ((dropShadowColor >> 16) & 0xff) / 255.0f, ((dropShadowColor >> 8) & 0xff) / 255.0f, (dropShadowColor & 0xff) / 255.0f, (dropShadowColor >> 24) / 255.0f }; + bgfx::setUniform(u_dropShadowColor, &dropShadowColorVec); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, bc.textBuffer->getDropShadowSoftener(), 0.0 }; + bgfx::setUniform(u_params, ¶ms); + break; + } + + case FONT_TYPE_DISTANCE_OUTLINE_DROP_SHADOW_IMAGE: + { + program = m_distanceOutlineDropShadowImageProgram; + bgfx::setState(0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA) + ); + + uint32_t dropShadowColor = bc.textBuffer->getDropShadowColor(); + float dropShadowColorVec[4] = { ((dropShadowColor >> 16) & 0xff) / 255.0f, ((dropShadowColor >> 8) & 0xff) / 255.0f, (dropShadowColor & 0xff) / 255.0f, (dropShadowColor >> 24) / 255.0f }; + bgfx::setUniform(u_dropShadowColor, &dropShadowColorVec); + + float params[4] = { 0.0f, (float)m_fontManager->getAtlas()->getTextureSize() / 512.0f, bc.textBuffer->getDropShadowSoftener(), bc.textBuffer->getOutlineWidth() }; + bgfx::setUniform(u_params, ¶ms); + break; + } + } switch (bc.bufferType) @@ -816,84 +1189,119 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, bgfx::ViewId void TextBufferManager::setStyle(TextBufferHandle _handle, uint32_t _flags) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setStyle(_flags); } void TextBufferManager::setTextColor(TextBufferHandle _handle, uint32_t _rgba) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setTextColor(_rgba); } void TextBufferManager::setBackgroundColor(TextBufferHandle _handle, uint32_t _rgba) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setBackgroundColor(_rgba); } void TextBufferManager::setOverlineColor(TextBufferHandle _handle, uint32_t _rgba) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setOverlineColor(_rgba); } void TextBufferManager::setUnderlineColor(TextBufferHandle _handle, uint32_t _rgba) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setUnderlineColor(_rgba); } void TextBufferManager::setStrikeThroughColor(TextBufferHandle _handle, uint32_t _rgba) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setStrikeThroughColor(_rgba); } +void TextBufferManager::setOutlineColor(TextBufferHandle _handle, uint32_t _rgba) +{ + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + bc.textBuffer->setOutlineColor(_rgba); +} + +void TextBufferManager::setOutlineWidth(TextBufferHandle _handle, float _outlineWidth) +{ + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + bc.textBuffer->setOutlineWidth(_outlineWidth); +} + +void TextBufferManager::setDropShadowColor(TextBufferHandle _handle, uint32_t _rgba) +{ + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + bc.textBuffer->setDropShadowColor(_rgba); +} + +void TextBufferManager::setDropShadowOffset(TextBufferHandle _handle, float _u, float _v) +{ + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + bc.textBuffer->setDropShadowOffset(_u, _v); +} + +void TextBufferManager::setDropShadowSoftener(TextBufferHandle _handle, float smoother) +{ + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + bc.textBuffer->setDropShadowSoftener(smoother); +} + void TextBufferManager::setPenPosition(TextBufferHandle _handle, float _x, float _y) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->setPenPosition(_x, _y); } void TextBufferManager::appendText(TextBufferHandle _handle, FontHandle _fontHandle, const char* _string, const char* _end) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->appendText(_fontHandle, _string, _end); } void TextBufferManager::appendText(TextBufferHandle _handle, FontHandle _fontHandle, const wchar_t* _string, const wchar_t* _end) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->appendText(_fontHandle, _string, _end); } void TextBufferManager::appendAtlasFace(TextBufferHandle _handle, uint16_t _faceIndex) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->appendAtlasFace(_faceIndex); } void TextBufferManager::clearTextBuffer(TextBufferHandle _handle) { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; bc.textBuffer->clearTextBuffer(); } TextRectangle TextBufferManager::getRectangle(TextBufferHandle _handle) const { - BX_CHECK(bgfx::isValid(_handle), "Invalid handle used"); + BX_ASSERT(bgfx::isValid(_handle), "Invalid handle used"); BufferCache& bc = m_textBuffers[_handle.idx]; return bc.textBuffer->getRectangle(); } |