From 375f17060a67fe59d08ff907c0986ba4bac1e9c4 Mon Sep 17 00:00:00 2001 From: bkaradzic Date: Mon, 3 Jun 2013 23:16:02 -0700 Subject: [PATCH] DX11/GL: Fixed font subpixel issues. --- examples/10-font/font.cpp | 4 +- examples/11-fontsdf/fontsdf.cpp | 49 ++++---- examples/common/cube_atlas.cpp | 114 +++++++++++------- examples/common/cube_atlas.h | 10 +- examples/common/font/fs_font_basic.sc | 11 +- .../common/font/fs_font_distance_field.sc | 24 ++-- .../font/fs_font_distance_field_subpixel.sc | 42 +++---- examples/common/font/text_buffer_manager.cpp | 19 ++- examples/common/font/text_buffer_manager.h | 17 +-- examples/common/font/varying.def.sc | 1 - examples/common/font/vs_font_basic.sc | 4 +- .../common/font/vs_font_distance_field.sc | 2 +- .../font/vs_font_distance_field_subpixel.sc | 6 +- examples/common/fpumath.h | 17 +++ 14 files changed, 166 insertions(+), 154 deletions(-) diff --git a/examples/10-font/font.cpp b/examples/10-font/font.cpp index 38f1c1388..82cc33b5d 100644 --- a/examples/10-font/font.cpp +++ b/examples/10-font/font.cpp @@ -127,7 +127,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) //create a static text buffer compatible with alpha font //a static text buffer content cannot be modified after its first submit. - TextBufferHandle staticText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, STATIC); + TextBufferHandle staticText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Static); // The pen position represent the top left of the box of the first line // of text. @@ -169,7 +169,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) textBufferManager->appendText(staticText, fonts[0], L"dog\n"); // Create a transient buffer for real-time data. - TextBufferHandle transientText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, TRANSIENT); + TextBufferHandle transientText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Transient); while (!processEvents(width, height, debug, reset) ) { diff --git a/examples/11-fontsdf/fontsdf.cpp b/examples/11-fontsdf/fontsdf.cpp index d7a57d11d..60f76a5bf 100644 --- a/examples/11-fontsdf/fontsdf.cpp +++ b/examples/11-fontsdf/fontsdf.cpp @@ -150,15 +150,15 @@ int _main_(int /*_argc*/, char** /*_argv*/) FontManager* fontManager = new FontManager(512); TextBufferManager* textBufferManager = new TextBufferManager(fontManager); - TrueTypeHandle font_tt = loadTtf(fontManager, "font/special_elite.ttf"); + TrueTypeHandle font = loadTtf(fontManager, "font/special_elite.ttf"); // Create a distance field font. - FontHandle base_distance_font = fontManager->createFontByPixelSize(font_tt, 0, 48, FONT_TYPE_DISTANCE); + FontHandle fontSdf = fontManager->createFontByPixelSize(font, 0, 48, FONT_TYPE_DISTANCE); // Create a scaled down version of the same font (without adding anything to the atlas). - FontHandle scaled_font = fontManager->createScaledFontToPixelSize(base_distance_font, 14); + FontHandle fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, 14); - TextLineMetrics metrics(fontManager->getFontInfo(scaled_font) ); + TextLineMetrics metrics(fontManager->getFontInfo(fontScaled) ); uint32_t lineCount = metrics.getLineCount(bigText); float visibleLineCount = 20.0f; @@ -167,13 +167,20 @@ int _main_(int /*_argc*/, char** /*_argv*/) const char* textEnd = 0; metrics.getSubText(bigText, 0, (uint32_t)visibleLineCount, textBegin, textEnd); - TextBufferHandle scrollableBuffer = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, TRANSIENT); + TextBufferHandle scrollableBuffer = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, BufferType::Transient); textBufferManager->setTextColor(scrollableBuffer, 0xFFFFFFFF); - textBufferManager->appendText(scrollableBuffer, scaled_font, textBegin, textEnd); + textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd); MouseState mouseState; int32_t scrollArea = 0; + const int32_t guiPanelWidth = 250; + const int32_t guiPanelHeight = 200; + float textScroll = 0.0f; + float textRotation = 0.0f; + float textScale = 1.0f; + float textSize = 14.0f; + while (!processEvents(width, height, debug, reset, &mouseState) ) { imguiBeginFrame(mouseState.m_mx @@ -185,24 +192,16 @@ int _main_(int /*_argc*/, char** /*_argv*/) , height ); - const int guiPanelWidth = 250; - const int guiPanelHeight = 200; - imguiBeginScrollArea("Text Area", width - guiPanelWidth - 10, 10, guiPanelWidth, guiPanelHeight, &scrollArea); imguiSeparatorLine(); - static float textScroll = 0.0f; - static float textRotation = 0.0f; - static float textScale = 1.0f; - static float textSize = 14.0f; - bool recomputeVisibleText = false; recomputeVisibleText |= imguiSlider("Number of lines", &visibleLineCount, 1.0f, 177.0f , 1.0f); - if(imguiSlider("Font size", &textSize, 6.0f, 64.0f , 1.0f)) + if (imguiSlider("Font size", &textSize, 6.0f, 64.0f , 1.0f) ) { - fontManager->destroyFont(scaled_font); - scaled_font = fontManager->createScaledFontToPixelSize(base_distance_font, (uint32_t) textSize); - metrics = TextLineMetrics(fontManager->getFontInfo(scaled_font) ); + fontManager->destroyFont(fontScaled); + fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, (uint32_t) textSize); + metrics = TextLineMetrics(fontManager->getFontInfo(fontScaled) ); recomputeVisibleText = true; } @@ -210,11 +209,11 @@ int _main_(int /*_argc*/, char** /*_argv*/) imguiSlider("Rotate", &textRotation, 0.0f, (float) M_PI *2.0f , 0.1f); recomputeVisibleText |= imguiSlider("Scale", &textScale, 0.1f, 10.0f , 0.1f); - if( recomputeVisibleText) + if (recomputeVisibleText) { textBufferManager->clearTextBuffer(scrollableBuffer); metrics.getSubText(bigText,(uint32_t)textScroll, (uint32_t)(textScroll+visibleLineCount), textBegin, textEnd); - textBufferManager->appendText(scrollableBuffer, scaled_font, textBegin, textEnd); + textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd); } imguiEndScrollArea(); @@ -235,7 +234,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) const double freq = double(bx::getHPFrequency() ); const double toMs = 1000.0 / freq; - // Use debug font to print information about this example. + // Use debug font to print32_t information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/11-fontsdf"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use a single distance field font to render text of various size."); @@ -256,7 +255,7 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::setViewTransform(0, view, proj); //very crude approximation :( - float textAreaWidth = 0.5f * 66.0f * fontManager->getFontInfo(scaled_font).maxAdvanceWidth; + float textAreaWidth = 0.5f * 66.0f * fontManager->getFontInfo(fontScaled).maxAdvanceWidth; float textRotMat[16]; float textCenterMat[16]; @@ -289,10 +288,10 @@ int _main_(int /*_argc*/, char** /*_argv*/) bgfx::frame(); } - fontManager->destroyTtf(font_tt); + fontManager->destroyTtf(font); // Destroy the fonts. - fontManager->destroyFont(base_distance_font); - fontManager->destroyFont(scaled_font); + fontManager->destroyFont(fontSdf); + fontManager->destroyFont(fontScaled); textBufferManager->destroyTextBuffer(scrollableBuffer); diff --git a/examples/common/cube_atlas.cpp b/examples/common/cube_atlas.cpp index dcd7be198..3750e1cb3 100644 --- a/examples/common/cube_atlas.cpp +++ b/examples/common/cube_atlas.cpp @@ -261,6 +261,9 @@ Atlas::Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount) { BX_CHECK(_textureSize >= 64 && _textureSize <= 4096, "Invalid _textureSize %d.", _textureSize); BX_CHECK(_maxRegionsCount >= 64 && _maxRegionsCount <= 32000, "Invalid _maxRegionsCount %d.", _maxRegionsCount); + + init(); + m_layers = new PackedLayer[24]; for (int ii = 0; ii < 24; ++ii) { @@ -270,15 +273,11 @@ Atlas::Atlas(uint16_t _textureSize, uint16_t _maxRegionsCount) m_regions = new AtlasRegion[_maxRegionsCount]; m_textureBuffer = new uint8_t[ _textureSize * _textureSize * 6 * 4 ]; memset(m_textureBuffer, 0, _textureSize * _textureSize * 6 * 4); - uint32_t flags = 0; - const bgfx::Memory* mem = NULL; m_textureHandle = bgfx::createTextureCube(6 , _textureSize , 1 , bgfx::TextureFormat::BGRA8 - , flags - , mem ); } @@ -291,10 +290,11 @@ Atlas::Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _reg { BX_CHECK(_regionCount <= 64 && _maxRegionsCount <= 4096, "_regionCount %d, _maxRegionsCount %d", _regionCount, _maxRegionsCount); + init(); + m_regions = new AtlasRegion[_regionCount]; m_textureBuffer = new uint8_t[getTextureBufferSize()]; - uint32_t flags = 0; memcpy(m_regions, _regionBuffer, _regionCount * sizeof(AtlasRegion) ); memcpy(m_textureBuffer, _textureBuffer, getTextureBufferSize() ); @@ -302,7 +302,7 @@ Atlas::Atlas(uint16_t _textureSize, const uint8_t* _textureBuffer, uint16_t _reg , _textureSize , 1 , bgfx::TextureFormat::BGRA8 - , flags + , BGFX_TEXTURE_NONE , bgfx::makeRef(m_textureBuffer, getTextureBufferSize() ) ); } @@ -314,6 +314,29 @@ Atlas::~Atlas() delete[] m_textureBuffer; } +void Atlas::init() +{ + m_texelSize = float(UINT16_MAX) / float(m_textureSize); + float texelHalf = m_texelSize/2.0f; + switch (bgfx::getRendererType()) + { + case bgfx::RendererType::Direct3D9: + m_texelOffset[0] = 0.0f; + m_texelOffset[1] = 0.0f; + break; + + case bgfx::RendererType::Direct3D11: + m_texelOffset[0] = texelHalf; + m_texelOffset[1] = texelHalf; + break; + + default: + m_texelOffset[0] = texelHalf; + m_texelOffset[1] = -texelHalf; + break; + } +} + uint16_t Atlas::addRegion(uint16_t _width, uint16_t _height, const uint8_t* _bitmapBuffer, AtlasRegion::Type _type, uint16_t outline) { if (m_regionCount >= m_maxRegionCount) @@ -326,12 +349,10 @@ uint16_t Atlas::addRegion(uint16_t _width, uint16_t _height, const uint8_t* _bit uint32_t idx = 0; while (idx < m_usedLayers) { - if (m_layers[idx].faceRegion.getType() == _type) + if (m_layers[idx].faceRegion.getType() == _type + && m_layers[idx].packer.addRectangle(_width + 1, _height + 1, xx, yy) ) { - if (m_layers[idx].packer.addRectangle(_width + 1, _height + 1, xx, yy) ) - { - break; - } + break; } idx++; @@ -432,17 +453,22 @@ void Atlas::packUV(uint16_t _regionHandle, uint8_t* _vertexBuffer, uint32_t _off packUV(region, _vertexBuffer, _offset, _stride); } +static void writeUV(uint8_t* _vertexBuffer, int16_t _x, int16_t _y, int16_t _z, int16_t _w) +{ + uint16_t* xyzw = (uint16_t*)_vertexBuffer; + xyzw[0] = _x; + xyzw[1] = _y; + xyzw[2] = _z; + xyzw[3] = _w; +} + void Atlas::packUV(const AtlasRegion& _region, uint8_t* _vertexBuffer, uint32_t _offset, uint32_t _stride) const { - static const int16_t minVal = INT16_MIN; - static const int16_t maxVal = INT16_MAX; - float texMult = (float)(maxVal - minVal) / ( (float)(m_textureSize) ); - - int16_t x0 = (int16_t)( ( (float)_region.x * texMult) - float(INT16_MAX) ); - int16_t y0 = (int16_t)( ( (float)_region.y * texMult) - float(INT16_MAX) ); - int16_t x1 = (int16_t)( ( ( (float)_region.x + _region.width) * texMult) - float(INT16_MAX) ); - int16_t y1 = (int16_t)( ( ( (float)_region.y + _region.height) * texMult) - float(INT16_MAX) ); - int16_t ww = (int16_t)( (float(INT16_MAX) / 4.0f) * (float) _region.getComponentIndex() ); + int16_t x0 = (int16_t)( ( (float)_region.x * m_texelSize + m_texelOffset[0]) - float(INT16_MAX) ); + int16_t y0 = (int16_t)( ( (float)_region.y * m_texelSize + m_texelOffset[1]) - float(INT16_MAX) ); + int16_t x1 = (int16_t)( ( ( (float)_region.x + _region.width) * m_texelSize + m_texelOffset[0]) - float(INT16_MAX) ); + int16_t y1 = (int16_t)( ( ( (float)_region.y + _region.height) * m_texelSize + m_texelOffset[1]) - float(INT16_MAX) ); + int16_t ww = (int16_t)( (float(INT16_MAX) / 4.0f) * (float)_region.getComponentIndex() ); _vertexBuffer += _offset; switch (_region.getFaceIndex() ) @@ -452,44 +478,44 @@ void Atlas::packUV(const AtlasRegion& _region, uint8_t* _vertexBuffer, uint32_t x1 = -x1; y0 = -y0; y1 = -y1; - writeUV(_vertexBuffer, maxVal, y0, x0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, maxVal, y1, x0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, maxVal, y1, x1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, maxVal, y0, x1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MAX, y0, x0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MAX, y1, x0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MAX, y1, x1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MAX, y0, x1, ww); _vertexBuffer += _stride; break; case 1: // -X y0 = -y0; y1 = -y1; - writeUV(_vertexBuffer, minVal, y0, x0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, minVal, y1, x0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, minVal, y1, x1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, minVal, y0, x1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MIN, y0, x0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MIN, y1, x0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MIN, y1, x1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, INT16_MIN, y0, x1, ww); _vertexBuffer += _stride; break; case 2: // +Y - writeUV(_vertexBuffer, x0, maxVal, y0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x0, maxVal, y1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, maxVal, y1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, maxVal, y0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, INT16_MAX, y0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, INT16_MAX, y1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, INT16_MAX, y1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, INT16_MAX, y0, ww); _vertexBuffer += _stride; break; case 3: // -Y y0 = -y0; y1 = -y1; - writeUV(_vertexBuffer, x0, minVal, y0, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x0, minVal, y1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, minVal, y1, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, minVal, y0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, INT16_MIN, y0, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, INT16_MIN, y1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, INT16_MIN, y1, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, INT16_MIN, y0, ww); _vertexBuffer += _stride; break; case 4: // +Z y0 = -y0; y1 = -y1; - writeUV(_vertexBuffer, x0, y0, maxVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x0, y1, maxVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, y1, maxVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, y0, maxVal, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, y0, INT16_MAX, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, y1, INT16_MAX, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, y1, INT16_MAX, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, y0, INT16_MAX, ww); _vertexBuffer += _stride; break; case 5: // -Z @@ -497,10 +523,10 @@ void Atlas::packUV(const AtlasRegion& _region, uint8_t* _vertexBuffer, uint32_t x1 = -x1; y0 = -y0; y1 = -y1; - writeUV(_vertexBuffer, x0, y0, minVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x0, y1, minVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, y1, minVal, ww); _vertexBuffer += _stride; - writeUV(_vertexBuffer, x1, y0, minVal, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, y0, INT16_MIN, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x0, y1, INT16_MIN, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, y1, INT16_MIN, ww); _vertexBuffer += _stride; + writeUV(_vertexBuffer, x1, y0, INT16_MIN, ww); _vertexBuffer += _stride; break; } } diff --git a/examples/common/cube_atlas.h b/examples/common/cube_atlas.h index 2c8c3d59b..4e3345ff2 100644 --- a/examples/common/cube_atlas.h +++ b/examples/common/cube_atlas.h @@ -147,13 +147,7 @@ public: } private: - static void writeUV(uint8_t* _vertexBuffer, int16_t _x, int16_t _y, int16_t _z, int16_t _w) - { - ( (uint16_t*) _vertexBuffer)[0] = _x; - ( (uint16_t*) _vertexBuffer)[1] = _y; - ( (uint16_t*) _vertexBuffer)[2] = _z; - ( (uint16_t*) _vertexBuffer)[3] = _w; - } + void Atlas::init(); struct PackedLayer; PackedLayer* m_layers; @@ -165,6 +159,8 @@ private: bgfx::TextureHandle m_textureHandle; uint16_t m_textureSize; + float m_texelSize; + float m_texelOffset[2]; uint16_t m_regionCount; uint16_t m_maxRegionCount; diff --git a/examples/common/font/fs_font_basic.sc b/examples/common/font/fs_font_basic.sc index 1d57655ed..a40db9d0a 100644 --- a/examples/common/font/fs_font_basic.sc +++ b/examples/common/font/fs_font_basic.sc @@ -4,13 +4,10 @@ $input v_color0, v_texcoord0 SAMPLERCUBE(u_texColor, 0); -uniform float u_inverse_gamma; - void main() -{ +{ vec4 color = textureCube(u_texColor, v_texcoord0.xyz); - int index = int(v_texcoord0.w*4.0 + 0.5); - float a = color.bgra[index]; - //a = pow(a, u_inverse_gamma); //I'll deal with gamma later - gl_FragColor = vec4(v_color0.rgb, v_color0.a * a); + int index = int(v_texcoord0.w*4.0 + 0.5); + float a = color.bgra[index]; + gl_FragColor = vec4(v_color0.rgb, v_color0.a * a); } diff --git a/examples/common/font/fs_font_distance_field.sc b/examples/common/font/fs_font_distance_field.sc index be311fa25..b256ae10f 100644 --- a/examples/common/font/fs_font_distance_field.sc +++ b/examples/common/font/fs_font_distance_field.sc @@ -8,20 +8,14 @@ uniform float u_inverse_gamma; void main() { - vec4 color = textureCube(u_texColor, v_texcoord0.xyz); - int index = int(v_texcoord0.w*4.0 + 0.5); - float distance = color.bgra[index]; - - float dx = length(dFdx(v_texcoord0.xyz)); - float dy = length(dFdy(v_texcoord0.xyz)); - float w = 16.0*0.5*(dx+dy); + vec4 color = textureCube(u_texColor, v_texcoord0.xyz); + int index = int(v_texcoord0.w*4.0 + 0.5); + float distance = color.bgra[index]; - // alternatives that seems to give identical results - //float w = 16.0*max(dx,dy); - //float w = 16.0*length(vec2(dx,dy))/sqrt(2.0); - //float w = 16.0*length(fwidth(v_texcoord0.xyz))/sqrt(2.0); + float dx = length(dFdx(v_texcoord0.xyz) ); + float dy = length(dFdy(v_texcoord0.xyz) ); + float w = 16.0*0.5*(dx+dy); - float a = smoothstep(0.5-w, 0.5+w, distance); - //a = pow(a, u_inverse_gamma); //I'll deal with gamma later - gl_FragColor = vec4(v_color0.rgb, v_color0.a*a); -} \ No newline at end of file + float a = smoothstep(0.5-w, 0.5+w, distance); + gl_FragColor = vec4(v_color0.rgb, v_color0.a*a); +} diff --git a/examples/common/font/fs_font_distance_field_subpixel.sc b/examples/common/font/fs_font_distance_field_subpixel.sc index 5a2bd31a2..33416f30a 100644 --- a/examples/common/font/fs_font_distance_field_subpixel.sc +++ b/examples/common/font/fs_font_distance_field_subpixel.sc @@ -4,37 +4,25 @@ $input v_color0, v_texcoord0 SAMPLERCUBE(u_texColor, 0); -uniform float u_inverse_gamma; - void main() { - int index = int(v_texcoord0.w*4.0 + 0.5); - vec3 dx3 = dFdx(v_texcoord0.xyz); - vec3 dy3 = dFdy(v_texcoord0.xyz); - vec3 decal = 0.166667 * dx3; - vec3 sampleLeft = v_texcoord0.xyz - decal; - vec3 sampleRight = v_texcoord0.xyz + decal; + int index = int(v_texcoord0.w*4.0 + 0.5); + vec3 dx3 = dFdx(v_texcoord0.xyz); + vec3 dy3 = dFdy(v_texcoord0.xyz); + vec3 decal = 0.166667 * dx3; + vec3 sampleLeft = v_texcoord0.xyz - decal; + vec3 sampleRight = v_texcoord0.xyz + decal; - float left_dist = textureCube(u_texColor, sampleLeft).bgra[index]; - float right_dist = textureCube(u_texColor, sampleRight).bgra[index]; + float left_dist = textureCube(u_texColor, sampleLeft).zyxw[index]; + float right_dist = textureCube(u_texColor, sampleRight).zyxw[index]; - //vec3 centerUV = 0.5 * (sampleLeft + sampleRight); - //float dist = textureCube(u_texColor, centerUV).bgra[index]; - float dist = 0.5 * (left_dist + right_dist); + float dist = 0.5 * (left_dist + right_dist); - float dx = length(dx3); - float dy = length(dy3); - float w = 16.0*0.5*(dx+dy); + float dx = length(dx3); + float dy = length(dy3); + float w = 16.0*0.5*(dx+dy); - vec3 sub_color = smoothstep(0.5 -w, 0.5 + w, vec3(left_dist, dist, right_dist)); - gl_FragColor.rgb = sub_color*v_color0.a; - //gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(u_inverse_gamma,u_inverse_gamma,u_inverse_gamma)); - gl_FragColor.a = dist*v_color0.a; - - //AR,AG,AB are the intensities gotten from the subpixel rendering engine. - //BR,BG,BB are the old background pixels. - //DR,DG,DB are the new background pixels. - //DR = A*AR*R + (1-(A*AR))*BR - //DG = A*AG*G + (1-(A*AG))*BG - //DB = A*AB*B + (1-(A*AB))*BB + vec3 sub_color = smoothstep(0.5 - w, 0.5 + w, vec3(left_dist, dist, right_dist)); + gl_FragColor.xyz = sub_color*v_color0.w; + gl_FragColor.w = dist*v_color0.w; } diff --git a/examples/common/font/text_buffer_manager.cpp b/examples/common/font/text_buffer_manager.cpp index 4a7248fe9..c6c4a1cf2 100644 --- a/examples/common/font/text_buffer_manager.cpp +++ b/examples/common/font/text_buffer_manager.cpp @@ -615,7 +615,6 @@ TextBufferManager::TextBufferManager(FontManager* _fontManager) m_vertexDecl.end(); u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv); - u_inverse_gamma = bgfx::createUniform("u_inverse_gamma", bgfx::UniformType::Uniform1f); } TextBufferManager::~TextBufferManager() @@ -624,14 +623,13 @@ TextBufferManager::~TextBufferManager() delete[] m_textBuffers; bgfx::destroyUniform(u_texColor); - bgfx::destroyUniform(u_inverse_gamma); bgfx::destroyProgram(m_basicProgram); bgfx::destroyProgram(m_distanceProgram); bgfx::destroyProgram(m_distanceSubpixelProgram); } -TextBufferHandle TextBufferManager::createTextBuffer(uint32_t _type, BufferType _bufferType) +TextBufferHandle TextBufferManager::createTextBuffer(uint32_t _type, BufferType::Enum _bufferType) { uint16_t textIdx = m_textBufferHandles.alloc(); BufferCache& bc = m_textBuffers[textIdx]; @@ -662,7 +660,7 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) switch (bc.bufferType) { - case STATIC: + case BufferType::Static: { bgfx::IndexBufferHandle ibh; bgfx::VertexBufferHandle vbh; @@ -674,7 +672,7 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) break; - case DYNAMIC: + case BufferType::Dynamic: bgfx::DynamicIndexBufferHandle ibh; bgfx::DynamicVertexBufferHandle vbh; ibh.idx = bc.indexBufferHandle; @@ -684,7 +682,7 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) break; - case TRANSIENT: //naturally destroyed + case BufferType::Transient: // destroyed every frame break; } } @@ -692,6 +690,7 @@ void TextBufferManager::destroyTextBuffer(TextBufferHandle _handle) void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, int32_t _depth) { BX_CHECK(bgfx::invalidHandle != _handle.idx, "Invalid handle used"); + BufferCache& bc = m_textBuffers[_handle.idx]; uint32_t indexSize = bc.textBuffer->getIndexCount() * bc.textBuffer->getIndexSize(); @@ -699,8 +698,6 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, const bgfx::Memory* mem; bgfx::setTexture(0, u_texColor, m_fontManager->getAtlas()->getTextureHandle() ); - float inverse_gamme = 1.0f / 2.2f; - bgfx::setUniform(u_inverse_gamma, &inverse_gamme); switch (bc.fontType) { @@ -732,7 +729,7 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, switch (bc.bufferType) { - case STATIC: + case BufferType::Static: { bgfx::IndexBufferHandle ibh; bgfx::VertexBufferHandle vbh; @@ -761,7 +758,7 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, } break; - case DYNAMIC: + case BufferType::Dynamic: { bgfx::DynamicIndexBufferHandle ibh; bgfx::DynamicVertexBufferHandle vbh; @@ -798,7 +795,7 @@ void TextBufferManager::submitTextBuffer(TextBufferHandle _handle, uint8_t _id, } break; - case TRANSIENT: + case BufferType::Transient: { bgfx::TransientIndexBuffer tib; bgfx::TransientVertexBuffer tvb; diff --git a/examples/common/font/text_buffer_manager.h b/examples/common/font/text_buffer_manager.h index af177d3bf..d5520fd2e 100644 --- a/examples/common/font/text_buffer_manager.h +++ b/examples/common/font/text_buffer_manager.h @@ -11,11 +11,14 @@ BGFX_HANDLE(TextBufferHandle); /// type of vertex and index buffer to use with a TextBuffer -enum BufferType +struct BufferType { - STATIC, - DYNAMIC, - TRANSIENT + enum Enum + { + Static, + Dynamic, + Transient, + }; }; /// special style effect (can be combined) @@ -40,7 +43,7 @@ public: TextBufferManager(FontManager* _fontManager); ~TextBufferManager(); - TextBufferHandle createTextBuffer(uint32_t _type, BufferType _bufferType); + TextBufferHandle createTextBuffer(uint32_t _type, BufferType::Enum _bufferType); void destroyTextBuffer(TextBufferHandle _handle); void submitTextBuffer(TextBufferHandle _handle, uint8_t _id, int32_t _depth = 0); @@ -75,7 +78,7 @@ private: uint16_t indexBufferHandle; uint16_t vertexBufferHandle; TextBuffer* textBuffer; - BufferType bufferType; + BufferType::Enum bufferType; uint32_t fontType; }; @@ -84,7 +87,7 @@ private: FontManager* m_fontManager; bgfx::VertexDecl m_vertexDecl; bgfx::UniformHandle u_texColor; - bgfx::UniformHandle u_inverse_gamma; + bgfx::UniformHandle u_fontParam; bgfx::ProgramHandle m_basicProgram; bgfx::ProgramHandle m_distanceProgram; bgfx::ProgramHandle m_distanceSubpixelProgram; diff --git a/examples/common/font/varying.def.sc b/examples/common/font/varying.def.sc index 720e9a733..595b21dc7 100644 --- a/examples/common/font/varying.def.sc +++ b/examples/common/font/varying.def.sc @@ -6,4 +6,3 @@ vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0); vec4 v_texcoord0 : TEXCOORD0 = vec4(0.0, 0.0, 0.0, 0.0); vec4 v_sampleLeft : TEXCOORD1 = vec4(0.0, 0.0, 0.0, 0.0); vec4 v_sampleRight : TEXCOORD2 = vec4(0.0, 0.0, 0.0, 0.0); - diff --git a/examples/common/font/vs_font_basic.sc b/examples/common/font/vs_font_basic.sc index f17e6a6d8..a1940656d 100644 --- a/examples/common/font/vs_font_basic.sc +++ b/examples/common/font/vs_font_basic.sc @@ -5,7 +5,7 @@ $output v_color0, v_texcoord0 void main() { - gl_Position = mul(u_modelViewProj, vec4(a_position, 0.0, 1.0) ); - v_texcoord0 = a_texcoord0; + gl_Position = mul(u_modelViewProj, vec4(a_position, 0.0, 1.0) ); + v_texcoord0 = a_texcoord0; v_color0 = a_color0; } diff --git a/examples/common/font/vs_font_distance_field.sc b/examples/common/font/vs_font_distance_field.sc index e007d6c9b..a1940656d 100644 --- a/examples/common/font/vs_font_distance_field.sc +++ b/examples/common/font/vs_font_distance_field.sc @@ -4,7 +4,7 @@ $output v_color0, v_texcoord0 #include "../../common/common.sh" void main() -{ +{ gl_Position = mul(u_modelViewProj, vec4(a_position, 0.0, 1.0) ); v_texcoord0 = a_texcoord0; v_color0 = a_color0; diff --git a/examples/common/font/vs_font_distance_field_subpixel.sc b/examples/common/font/vs_font_distance_field_subpixel.sc index cfdfd9384..a1940656d 100644 --- a/examples/common/font/vs_font_distance_field_subpixel.sc +++ b/examples/common/font/vs_font_distance_field_subpixel.sc @@ -4,12 +4,8 @@ $output v_color0, v_texcoord0 #include "../../common/common.sh" void main() -{ +{ gl_Position = mul(u_modelViewProj, vec4(a_position, 0.0, 1.0) ); v_texcoord0 = a_texcoord0; v_color0 = a_color0; - - //vec3 decal = dFdx(a_texcoord0.xyz); - //v_sampleLeft = a_texcoord0 + decal; - //v_sampleRight = a_texcoord0 - decal; } diff --git a/examples/common/fpumath.h b/examples/common/fpumath.h index aaf9cacff..67f6b4037 100644 --- a/examples/common/fpumath.h +++ b/examples/common/fpumath.h @@ -27,6 +27,11 @@ inline float flerp(float _a, float _b, float _t) return _a + (_b - _a) * _t; } +inline float fsign(float _a) +{ + return _a < 0.0f ? -1.0f : 1.0f; +} + inline void vec3Add(float* __restrict _result, const float* __restrict _a, const float* __restrict _b) { _result[0] = _a[0] + _b[0]; @@ -279,6 +284,18 @@ inline void vec3MulMtx(float* __restrict _result, const float* __restrict _vec, _result[2] = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; } +inline void vec3MulMtxH(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat) +{ + float xx = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _mat[12]; + float yy = _vec[0] * _mat[ 1] + _vec[1] * _mat[5] + _vec[2] * _mat[ 9] + _mat[13]; + float zz = _vec[0] * _mat[ 2] + _vec[1] * _mat[6] + _vec[2] * _mat[10] + _mat[14]; + float ww = _vec[0] * _mat[ 3] + _vec[1] * _mat[7] + _vec[2] * _mat[11] + _mat[15]; + float invW = fsign(ww)/ww; + _result[0] = xx*invW; + _result[1] = yy*invW; + _result[2] = zz*invW; +} + inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat) { _result[0] = _vec[0] * _mat[ 0] + _vec[1] * _mat[4] + _vec[2] * _mat[ 8] + _vec[3] * _mat[12];