From 2f89ab16baafe7176378e8b53ffb4c50dc8cf67f Mon Sep 17 00:00:00 2001 From: Jeremie Roy Date: Wed, 8 May 2013 23:55:54 +0200 Subject: [PATCH] rework the samples --- examples/10-font/font.cpp | 2 +- examples/11-fontsdf/fontsdf.cpp | 183 +++++++------------ examples/common/font/text_buffer_manager.cpp | 31 +++- examples/common/font/text_buffer_manager.h | 10 + 4 files changed, 104 insertions(+), 122 deletions(-) diff --git a/examples/10-font/font.cpp b/examples/10-font/font.cpp index cfbf84e9e..7cd2006a0 100644 --- a/examples/10-font/font.cpp +++ b/examples/10-font/font.cpp @@ -162,7 +162,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) float view[16]; float proj[16]; - mtxLookAt(view, eye, at); + mtxLookAt(view, eye, at); //setup a top-left ortho matrix for screen space drawing float centering = 0.5f; mtxOrtho(proj, centering, width+centering,height+centering, centering,-1.0f, 1.0f); diff --git a/examples/11-fontsdf/fontsdf.cpp b/examples/11-fontsdf/fontsdf.cpp index 7df4aeddb..cefab1bcd 100644 --- a/examples/11-fontsdf/fontsdf.cpp +++ b/examples/11-fontsdf/fontsdf.cpp @@ -12,39 +12,24 @@ #include #include -static const char* s_shaderPath = NULL; -long int fsize(FILE* _file) +inline void mtxTranslate(float* _result, float x, float y, float z) { - long int pos = ftell(_file); - fseek(_file, 0L, SEEK_END); - long int size = ftell(_file); - fseek(_file, pos, SEEK_SET); - return size; + memset(_result, 0, sizeof(float)*16); + _result[0] = _result[5] = _result[10] = _result[15] = 1.0f; + _result[12] = x; + _result[13] = y; + _result[14] = z; } -static const bgfx::Memory* loadShader(const char* _shaderPath, const char* _shaderName) +inline void mtxScale(float* _result, float x, float y, float z) { - char out[512]; - strcpy(out, _shaderPath); - strcat(out, _shaderName); - strcat(out, ".bin"); - - FILE* file = fopen(out, "rb"); - if (NULL != file) - { - uint32_t size = (uint32_t)fsize(file); - const bgfx::Memory* mem = bgfx::alloc(size+1); - /*size_t ignore =*/ fread(mem->data, 1, size, file); - /*BX_UNUSED(ignore);*/ - fclose(file); - mem->data[mem->size-1] = '\0'; - return mem; - } - - return NULL; + memset(_result, 0, sizeof(float)*16); + _result[0] = x; + _result[5] = y; + _result[10] = z; + _result[15] = 1.0f; } - int _main_(int /*_argc*/, char** /*_argv*/) { uint32_t width = 1280; @@ -68,92 +53,44 @@ int _main_(int /*_argc*/, char** /*_argv*/) , 1.0f , 0 ); - - // Setup root path for binary shaders. Shader binaries are different - // for each renderer. - switch (bgfx::getRendererType() ) - { - default: - case bgfx::RendererType::Direct3D9: - s_shaderPath = "shaders/dx9/"; - break; - - case bgfx::RendererType::Direct3D11: - s_shaderPath = "shaders/dx11/"; - break; - - case bgfx::RendererType::OpenGL: - s_shaderPath = "shaders/glsl/"; - break; - - case bgfx::RendererType::OpenGLES2: - case bgfx::RendererType::OpenGLES3: - s_shaderPath = "shaders/gles/"; - break; - } - - const bgfx::Memory* mem; - mem = loadShader(s_shaderPath, "vs_font_basic"); - bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem); - mem = loadShader(s_shaderPath, "fs_font_basic"); - bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem); - bgfx::ProgramHandle _basicProgram = bgfx::createProgram(vsh, fsh); - bgfx::destroyVertexShader(vsh); - bgfx::destroyFragmentShader(fsh); - - mem = loadShader(s_shaderPath, "vs_font_distance_field"); - vsh = bgfx::createVertexShader(mem); - mem = loadShader(s_shaderPath, "fs_font_distance_field"); - fsh = bgfx::createFragmentShader(mem); - bgfx::ProgramHandle _distanceProgram = bgfx::createProgram(vsh, fsh); - bgfx::destroyVertexShader(vsh); - bgfx::destroyFragmentShader(fsh); - mem = loadShader(s_shaderPath, "vs_font_distance_field_subpixel"); - vsh = bgfx::createVertexShader(mem); - mem = loadShader(s_shaderPath, "fs_font_distance_field_subpixel"); - fsh = bgfx::createFragmentShader(mem); - bgfx::ProgramHandle _distanceSubpixelProgram = bgfx::createProgram(vsh, fsh); - bgfx::destroyVertexShader(vsh); - bgfx::destroyFragmentShader(fsh); - //init the text rendering system FontManager* fontManager = new FontManager(512); TextBufferManager* textBufferManager = new TextBufferManager(fontManager); - textBufferManager->init(_basicProgram, _distanceProgram, _distanceSubpixelProgram); //load a truetype files - TrueTypeHandle times_tt = fontManager->loadTrueTypeFromFile("c:/windows/fonts/times.ttf"); + /* + "font/droidsans.ttf", + "font/chp-fire.ttf", + "font/bleeding_cowboys.ttf", + "font/mias_scribblings.ttf", + "font/ruritania.ttf", + "font/signika-regular.ttf", + "font/five_minutes.otf" + */ + TrueTypeHandle times_tt = fontManager->loadTrueTypeFromFile("font/bleeding_cowboys.ttf"); + + //create a distance field font FontHandle distance_font = fontManager->createFontByPixelSize(times_tt, 0, 48, FONT_TYPE_DISTANCE); + //create a scalled down version of the same font (without adding anything to the atlas) + FontHandle smaller_font = fontManager->createScaledFontToPixelSize(distance_font, 32); + //preload glyph and generate (generate bitmap's) - fontManager->preloadGlyph(distance_font, L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. \n"); + fontManager->preloadGlyph(distance_font, L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,\" \n"); - uint32_t fontsCount = 0; - FontHandle fonts[64]; - fonts[fontsCount++] = distance_font; - //generate various sub distance field fonts at various size - int32_t step=4; - for(int32_t ii = 64; ii>1 ; ii-=step) - { - if(ii<32) step = 2; - //instantiate a usable font - FontHandle font = fontManager->createScaledFontToPixelSize(distance_font, ii); - fonts[fontsCount++] = font; - } //You can unload the truetype files at this stage, but in that case, the set of glyph's will be limited to the set of preloaded glyph fontManager->unloadTrueType(times_tt); - TextBufferHandle staticText = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, STATIC); - - textBufferManager->setPenPosition(staticText, 10.0f, 70.0f); - textBufferManager->setTextColor(staticText, 0xFFFFFFFF); - //textBufferManager->setTextColor(staticText, 0x000000FF); - for(uint32_t ii = 0; ii< fontsCount; ++ii) - { - textBufferManager->appendText(staticText, fonts[ii], L"The quick brown fox jumps over the lazy dog\n"); - //textBufferManager->appendText(staticText, fonts[i], L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); - } - + TextBufferHandle staticText = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, STATIC); + textBufferManager->setTextColor(staticText, 0xDD0000FF); + + //textBufferManager->appendText(staticText, distance_font, L"The quick brown fox jumps over the lazy dog\n"); + //textBufferManager->appendText(staticText, distance_font, L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n"); + textBufferManager->appendText(staticText, distance_font, L"BGFX "); + textBufferManager->appendText(staticText, smaller_font, L"bgfx"); + + + int64_t timeOffset = bx::getHPCounter(); while (!processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. @@ -169,6 +106,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) last = now; const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0/freq; + float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) ); // Use debug font to print information about this example. bgfx::dbgTextClear(); @@ -178,17 +116,36 @@ int _main_(int /*_argc*/, char** /*_argv*/) float at[3] = { 0, 0, 0.0f }; float eye[3] = {0, 0, -1.0f }; - + float view[16]; float proj[16]; - mtxLookAt(view, eye, at); + mtxLookAt(view, eye, at); float centering = 0.5f; //setup a top-left ortho matrix for screen space drawing - mtxOrtho(proj, centering, width+centering,height+centering, centering,-1.0f, 1.0f); - + mtxOrtho(proj, centering, width+centering,height+centering, centering,-1.0f, 1.0f); + // Set view and projection matrix for view 0. - bgfx::setViewTransform(0, view, proj); + bgfx::setViewTransform(0, view, proj); + TextRectangle rect = textBufferManager->getRectangle(staticText); + + float mtxA[16]; + float mtxB[16]; + float mtxC[16]; + mtxRotateZ(mtxA, time*0.37f); + mtxTranslate(mtxB, -(rect.width*0.5f), -(rect.height*0.5f), 0); + mtxMul(mtxC, mtxB, mtxA); + + float scale=4.1f+4.0f*sinf(time); + mtxScale(mtxA, scale, scale, 1.0f); + mtxMul(mtxB, mtxC, mtxA); + + mtxTranslate(mtxC, ((width)*0.5f), ((height)*0.5f), 0); + mtxMul(mtxA, mtxB, mtxC); + + // Set model matrix for rendering. + bgfx::setTransform(mtxA); + //draw your text textBufferManager->submitTextBuffer(staticText, 0); @@ -197,17 +154,11 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::frame(); } - //destroy the fonts - for(uint32_t ii=0; iidestroyFont(fonts[ii]); - } + //destroy the fonts + fontManager->destroyFont(distance_font); + fontManager->destroyFont(smaller_font); - textBufferManager->destroyTextBuffer(staticText); - - bgfx::destroyProgram(_basicProgram); - bgfx::destroyProgram(_distanceProgram); - bgfx::destroyProgram(_distanceSubpixelProgram); + textBufferManager->destroyTextBuffer(staticText); delete textBufferManager; delete fontManager; diff --git a/examples/common/font/text_buffer_manager.cpp b/examples/common/font/text_buffer_manager.cpp index 711ed0bd5..736628d1d 100644 --- a/examples/common/font/text_buffer_manager.cpp +++ b/examples/common/font/text_buffer_manager.cpp @@ -115,6 +115,9 @@ public: uint32_t getIndexSize(){ return sizeof(uint16_t); } uint32_t getTextColor(){ return toABGR(m_textColor); } + + TextRectangle getRectangle() const { return m_rectangle; } + private: void appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo); void verticalCenterLastLine(float _txtDecalY, float _top, float _bottom); @@ -147,6 +150,8 @@ private: float m_lineDescender; float m_lineGap; + TextRectangle m_rectangle; + /// FontManager* m_fontManager; @@ -195,7 +200,8 @@ TextBuffer::TextBuffer(FontManager* _fontManager) m_lineDescender = 0; m_lineGap = 0; m_fontManager = _fontManager; - + m_rectangle.width = 0; + m_rectangle.height = 0; m_vertexBuffer = new TextVertex[MAX_BUFFERED_CHARACTERS * 4]; m_indexBuffer = new uint16_t[MAX_BUFFERED_CHARACTERS * 6]; @@ -224,8 +230,10 @@ void TextBuffer::appendText(FontHandle _fontHandle, const char * _string) m_originY = m_penY; m_lineDescender = 0;// font.m_descender; m_lineAscender = 0;//font.m_ascender; + + } - + uint32_t codepoint; uint32_t state = 0; @@ -294,6 +302,8 @@ void TextBuffer::clearTextBuffer() m_lineStartIndex = 0; m_lineAscender = 0; m_lineDescender = 0; + m_rectangle.width = 0; + m_rectangle.height = 0; } void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, const GlyphInfo& _glyphInfo) @@ -307,9 +317,10 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons m_lineDescender = 0; m_lineAscender = 0; m_lineStartIndex = m_vertexCount; + return; } - + if( _font.m_ascender > m_lineAscender || (_font.m_descender < m_lineDescender) ) { if( _font.m_descender < m_lineDescender ) @@ -458,9 +469,12 @@ void TextBuffer::appendGlyph(CodePoint_t _codePoint, const FontInfo& _font, cons m_indexBuffer[m_indexCount + 5] = m_vertexCount+3; m_vertexCount += 4; m_indexCount += 6; - - //TODO see what to do when doing subpixel rendering + m_penX += _glyphInfo.m_advance_x; + if(m_penX > m_rectangle.width) m_rectangle.width = m_penX; + if( (m_penY - m_lineDescender) > m_rectangle.height) m_rectangle.height = (m_penY - m_lineDescender); + //if(x1 > m_rectangle.width) m_rectangle.width = x1; + //if(y1 > m_rectangle.height) m_rectangle.height = y1; } void TextBuffer::verticalCenterLastLine(float _dy, float _top, float _bottom) @@ -803,3 +817,10 @@ void TextBufferManager::clearTextBuffer(TextBufferHandle _handle) BufferCache& bc = m_textBuffers[_handle.idx]; bc.m_textBuffer->clearTextBuffer(); } + +TextRectangle TextBufferManager::getRectangle(TextBufferHandle _handle) const +{ + BX_CHECK( bgfx::invalidHandle != _handle.idx, "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; + return bc.m_textBuffer->getRectangle(); +} diff --git a/examples/common/font/text_buffer_manager.h b/examples/common/font/text_buffer_manager.h index 57dc818fc..91c41d0f5 100644 --- a/examples/common/font/text_buffer_manager.h +++ b/examples/common/font/text_buffer_manager.h @@ -24,6 +24,11 @@ enum TextStyleFlags STYLE_BACKGROUND = 1<<3, }; +struct TextRectangle +{ + float width, height; +}; + class TextBuffer; class TextBufferManager { @@ -54,6 +59,8 @@ public: /// Clear the text buffer and reset its state (pen/color) void clearTextBuffer(TextBufferHandle _handle); + + TextRectangle getRectangle(TextBufferHandle _handle) const; /// return the size of the text //Rectangle measureText(FontHandle fontHandle, const char * _string); @@ -80,4 +87,7 @@ private: bgfx::ProgramHandle m_basicProgram; bgfx::ProgramHandle m_distanceProgram; bgfx::ProgramHandle m_distanceSubpixelProgram; + + float m_height; + float m_width; };