Browse Source

DX11/GL: Fixed font subpixel issues.

bkaradzic 12 years ago
parent
commit
375f17060a

+ 2 - 2
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) )
 	{

+ 24 - 25
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);
 

+ 70 - 44
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;
 	}
 }

+ 3 - 7
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;

+ 4 - 7
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);
 }

+ 9 - 15
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);
-}
+	float a = smoothstep(0.5-w, 0.5+w, distance);
+	gl_FragColor = vec4(v_color0.rgb, v_color0.a*a);
+}

+ 15 - 27
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;
 }

+ 8 - 11
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;

+ 10 - 7
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;

+ 0 - 1
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);
-

+ 2 - 2
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;
 }

+ 1 - 1
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;

+ 1 - 5
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;
 }

+ 17 - 0
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];