Browse Source

Changed Font/Text rendering from Texture Maps to Signed Distance Field Maps to dramatically improve scaling.

seanpaultaylor 12 years ago
parent
commit
7e639e4da5
54 changed files with 189 additions and 89 deletions
  1. 6 3
      gameplay/res/shaders/font.frag
  2. 0 1
      gameplay/res/shaders/font.vert
  3. 1 1
      gameplay/src/Bundle.cpp
  4. 1 0
      gameplay/src/Form.cpp
  5. BIN
      samples/browser/res/common/arial.gpb
  6. BIN
      samples/browser/res/common/arial14.gpb
  7. BIN
      samples/browser/res/common/arial18.gpb
  8. BIN
      samples/browser/res/common/badaboom.gpb
  9. BIN
      samples/browser/res/common/baroque.gpb
  10. BIN
      samples/browser/res/common/custom.gpb
  11. 8 8
      samples/browser/res/common/default.theme
  12. BIN
      samples/browser/res/common/dynamic.gpb
  13. BIN
      samples/browser/res/common/fishfingers.gpb
  14. BIN
      samples/browser/res/common/neuropol.gpb
  15. BIN
      samples/browser/res/common/pirulen.gpb
  16. BIN
      samples/browser/res/common/squarehead.gpb
  17. 1 1
      samples/browser/res/common/text.form
  18. 1 1
      samples/browser/src/Audio3DSample.cpp
  19. 1 1
      samples/browser/src/BillboardSample.cpp
  20. 1 1
      samples/browser/src/CreateSceneSample.cpp
  21. 1 1
      samples/browser/src/GamepadSample.cpp
  22. 1 1
      samples/browser/src/GestureSample.cpp
  23. 1 1
      samples/browser/src/InputSample.cpp
  24. 1 1
      samples/browser/src/LightSample.cpp
  25. 1 1
      samples/browser/src/LoadSceneSample.cpp
  26. 1 1
      samples/browser/src/MeshBatchSample.cpp
  27. 1 1
      samples/browser/src/MeshPrimitiveSample.cpp
  28. 1 1
      samples/browser/src/PhysicsCollisionObjectSample.cpp
  29. 1 1
      samples/browser/src/PostProcessSample.cpp
  30. 1 1
      samples/browser/src/SamplesGame.cpp
  31. 1 1
      samples/browser/src/SpriteBatchSample.cpp
  32. 1 1
      samples/browser/src/TerrainSample.cpp
  33. 9 9
      samples/browser/src/TextSample.cpp
  34. 1 1
      samples/browser/src/TextureSample.cpp
  35. 1 1
      samples/browser/src/TriangleSample.cpp
  36. BIN
      samples/character/res/common/arial.gpb
  37. BIN
      samples/character/res/common/arial40.gpb
  38. BIN
      samples/lua/res/arial.gpb
  39. BIN
      samples/lua/res/arial40.gpb
  40. BIN
      samples/mesh/res/arial.gpb
  41. BIN
      samples/mesh/res/arial40.gpb
  42. BIN
      samples/particles/res/arial.gpb
  43. BIN
      samples/racer/res/common/arial.gpb
  44. BIN
      samples/racer/res/common/arial40.gpb
  45. 6 6
      samples/racer/res/common/menu.theme
  46. BIN
      samples/spaceship/res/airstrip.gpb
  47. BIN
      samples/spaceship/res/airstrip28.gpb
  48. 4 4
      samples/spaceship/res/menu.theme
  49. 2 0
      tools/encoder/gameplay-encoder.vcxproj
  50. 6 0
      tools/encoder/gameplay-encoder.vcxproj.filters
  51. 2 2
      tools/encoder/gameplay-encoder.vcxproj.user
  52. 12 0
      tools/encoder/src/Base.h
  53. 1 0
      tools/encoder/src/Material.cpp
  54. 113 37
      tools/encoder/src/TTFFontEncoder.cpp

+ 6 - 3
gameplay/res/shaders/font.frag

@@ -1,5 +1,6 @@
 #ifdef OPENGL_ES
 #ifdef OPENGL_ES
 precision highp float;
 precision highp float;
+#extension GL_OES_standard_derivatives : enable
 #endif
 #endif
 
 
 // Uniforms
 // Uniforms
@@ -9,9 +10,11 @@ uniform sampler2D u_texture;
 varying vec2 v_texCoord;
 varying vec2 v_texCoord;
 varying vec4 v_color;
 varying vec4 v_color;
 
 
-
 void main()
 void main()
-{
+{ 
     gl_FragColor = v_color;
     gl_FragColor = v_color;
-    gl_FragColor.a = texture2D(u_texture, v_texCoord).a * v_color.a;
+    float distance = texture2D(u_texture, v_texCoord).a;
+    float smoothing = fwidth(distance);
+    float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
+    gl_FragColor.a = alpha * v_color.a;
 }
 }

+ 0 - 1
gameplay/res/shaders/font.vert

@@ -10,7 +10,6 @@ uniform mat4 u_projectionMatrix;
 varying vec2 v_texCoord;
 varying vec2 v_texCoord;
 varying vec4 v_color;
 varying vec4 v_color;
 
 
-
 void main()
 void main()
 {
 {
     gl_Position = u_projectionMatrix * vec4(a_position, 1);
     gl_Position = u_projectionMatrix * vec4(a_position, 1);

+ 1 - 1
gameplay/src/Bundle.cpp

@@ -1705,7 +1705,7 @@ Font* Bundle::loadFont(const char* id)
     }
     }
 
 
     // Create the texture for the font.
     // Create the texture for the font.
-    Texture* texture = Texture::create(Texture::ALPHA, width, height, textureData, true);
+    Texture* texture = Texture::create(Texture::ALPHA, width, height, textureData, false);
 
 
     // Free the texture data (no longer needed).
     // Free the texture data (no longer needed).
     SAFE_DELETE_ARRAY(textureData);
     SAFE_DELETE_ARRAY(textureData);

+ 1 - 0
gameplay/src/Form.cpp

@@ -576,6 +576,7 @@ void Form::draw()
             _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
             _spriteBatch = SpriteBatch::create(_frameBuffer->getRenderTarget()->getTexture());
             GP_ASSERT(_spriteBatch);
             GP_ASSERT(_spriteBatch);
         }
         }
+
         _spriteBatch->start();
         _spriteBatch->start();
         _spriteBatch->draw(_bounds.x, _bounds.y, 0, _bounds.width, _bounds.height, 0, _v1, _u2, 0, Vector4::one());
         _spriteBatch->draw(_bounds.x, _bounds.y, 0, _bounds.width, _bounds.height, 0, _v1, _u2, 0, Vector4::one());
         _spriteBatch->finish();
         _spriteBatch->finish();

BIN
samples/browser/res/common/arial.gpb


BIN
samples/browser/res/common/arial14.gpb


BIN
samples/browser/res/common/arial18.gpb


BIN
samples/browser/res/common/badaboom.gpb


BIN
samples/browser/res/common/baroque.gpb


BIN
samples/browser/res/common/custom.gpb


+ 8 - 8
samples/browser/res/common/default.theme

@@ -213,8 +213,8 @@ theme mainMenu
         {
         {
             skin = underliner
             skin = underliner
             textColor = #ffffffff
             textColor = #ffffffff
-            font = res/common/arial18.gpb
-            fontSize = 25
+            font = res/common/arial.gpb
+            fontSize = 24
             textAlignment = ALIGN_BOTTOM_HCENTER
             textAlignment = ALIGN_BOTTOM_HCENTER
         }
         }
     }
     }
@@ -234,7 +234,7 @@ theme mainMenu
             skin = mainNormal
             skin = mainNormal
             imageList = normalImages
             imageList = normalImages
 
 
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 18
             fontSize = 18
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -289,7 +289,7 @@ theme mainMenu
 
 
         stateNormal
         stateNormal
         {
         {
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
         }
         }
 
 
@@ -312,7 +312,7 @@ theme mainMenu
         stateNormal
         stateNormal
         {
         {
             imageList = normalImages
             imageList = normalImages
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 14
             fontSize = 14
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -334,14 +334,14 @@ theme mainMenu
     {
     {
         stateNormal
         stateNormal
         {
         {
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
             textAlignment = ALIGN_VCENTER_LEFT
             textAlignment = ALIGN_VCENTER_LEFT
         }
         }
 
 
         stateActive
         stateActive
         {
         {
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
             textAlignment = ALIGN_VCENTER_LEFT
             textAlignment = ALIGN_VCENTER_LEFT
         }
         }
@@ -365,7 +365,7 @@ theme mainMenu
         stateNormal
         stateNormal
         {
         {
             textColor = #ffffffff
             textColor = #ffffffff
-            font = res/common/arial18.gpb
+            font = res/common/arial.gpb
             fontSize = 26
             fontSize = 26
             textAlignment = ALIGN_BOTTOM_HCENTER
             textAlignment = ALIGN_BOTTOM_HCENTER
         }
         }

BIN
samples/browser/res/common/dynamic.gpb


BIN
samples/browser/res/common/fishfingers.gpb


BIN
samples/browser/res/common/neuropol.gpb


BIN
samples/browser/res/common/pirulen.gpb


BIN
samples/browser/res/common/squarehead.gpb


+ 1 - 1
samples/browser/res/common/text.form

@@ -26,7 +26,7 @@ form textTest
         autoWidth = true
         autoWidth = true
         height = 50
         height = 50
         consumeInputEvents = false
         consumeInputEvents = false
-        text = Font (arial18)
+        text = Font (arial)
     }
     }
 
 
     button wrapButton : fontButton
     button wrapButton : fontButton

+ 1 - 1
samples/browser/src/Audio3DSample.cpp

@@ -24,7 +24,7 @@ Audio3DSample::Audio3DSample()
 void Audio3DSample::initialize()
 void Audio3DSample::initialize()
 {
 {
     setMultiTouch(true);
     setMultiTouch(true);
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
     // Load game scene from file
     // Load game scene from file
     _scene = Scene::load("res/common/box.gpb");
     _scene = Scene::load("res/common/box.gpb");
 
 

+ 1 - 1
samples/browser/src/BillboardSample.cpp

@@ -34,7 +34,7 @@ void BillboardSample::initialize()
     setMultiTouch(true);
     setMultiTouch(true);
 
 
 	// Create the font and scene
 	// Create the font and scene
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 	_scene = Scene::create();
 	_scene = Scene::create();
 
 
 	// Initialize the camera
 	// Initialize the camera

+ 1 - 1
samples/browser/src/CreateSceneSample.cpp

@@ -67,7 +67,7 @@ CreateSceneSample::CreateSceneSample()
 void CreateSceneSample::initialize()
 void CreateSceneSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Create a new empty scene.
     // Create a new empty scene.
     _scene = Scene::create();
     _scene = Scene::create();

+ 1 - 1
samples/browser/src/GamepadSample.cpp

@@ -23,7 +23,7 @@ void GamepadSample::initialize()
     if (_gamepad && _gamepad->isVirtual())
     if (_gamepad && _gamepad->isVirtual())
         _gamepad->getForm()->setEnabled(true);
         _gamepad->getForm()->setEnabled(true);
 
 
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
     _status = "Looking for gamepads...";
     _status = "Looking for gamepads...";
 }
 }
 
 

+ 1 - 1
samples/browser/src/GestureSample.cpp

@@ -20,7 +20,7 @@ void GestureSample::initialize()
     setMultiTouch(true);
     setMultiTouch(true);
 
 
     // Load font
     // Load font
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
     assert(_font);
     assert(_font);
 
 
     bool anySupported = false;
     bool anySupported = false;

+ 1 - 1
samples/browser/src/InputSample.cpp

@@ -21,7 +21,7 @@ void InputSample::initialize()
     setMultiTouch(true);
     setMultiTouch(true);
 
 
     // Load font
     // Load font
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
     assert(_font);
     assert(_font);
 
 
     // Reuse part of the gamepad texture as the crosshair in this sample.
     // Reuse part of the gamepad texture as the crosshair in this sample.

+ 1 - 1
samples/browser/src/LightSample.cpp

@@ -43,7 +43,7 @@ LightSample::LightSample()
 void LightSample::initialize()
 void LightSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
 	// Load the scene
 	// Load the scene
 	_scene = Scene::load("res/common/lightBrickWall.gpb");
 	_scene = Scene::load("res/common/lightBrickWall.gpb");

+ 1 - 1
samples/browser/src/LoadSceneSample.cpp

@@ -14,7 +14,7 @@ LoadSceneSample::LoadSceneSample()
 void LoadSceneSample::initialize()
 void LoadSceneSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     _scene = Scene::load("res/common/sample.scene");
     _scene = Scene::load("res/common/sample.scene");
 
 

+ 1 - 1
samples/browser/src/MeshBatchSample.cpp

@@ -43,7 +43,7 @@ void MeshBatchSample::initialize()
 {
 {
     setMultiTouch(true);
     setMultiTouch(true);
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     Matrix::createOrthographic(getWidth(), getHeight(), -1.0f, 1.0f, &_worldViewProjectionMatrix);
     Matrix::createOrthographic(getWidth(), getHeight(), -1.0f, 1.0f, &_worldViewProjectionMatrix);
     _meshBatch = createMeshBatch(Mesh::TRIANGLES);
     _meshBatch = createMeshBatch(Mesh::TRIANGLES);

+ 1 - 1
samples/browser/src/MeshPrimitiveSample.cpp

@@ -190,7 +190,7 @@ MeshPrimitiveSample::MeshPrimitiveSample()
 void MeshPrimitiveSample::initialize()
 void MeshPrimitiveSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Create an orthographic projection matrix.
     // Create an orthographic projection matrix.
     float width = getWidth() / (float)getHeight();
     float width = getWidth() / (float)getHeight();

+ 1 - 1
samples/browser/src/PhysicsCollisionObjectSample.cpp

@@ -21,7 +21,7 @@ PhysicsCollisionObjectSample::PhysicsCollisionObjectSample()
 void PhysicsCollisionObjectSample::initialize()
 void PhysicsCollisionObjectSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     _scene = Scene::load("res/common/physics.scene");
     _scene = Scene::load("res/common/physics.scene");
     // Use the aspect ratio of the display instead of the aspect ratio defined in the scene file.
     // Use the aspect ratio of the display instead of the aspect ratio defined in the scene file.

+ 1 - 1
samples/browser/src/PostProcessSample.cpp

@@ -79,7 +79,7 @@ PostProcessSample::PostProcessSample()
 
 
 void PostProcessSample::initialize()
 void PostProcessSample::initialize()
 {
 {
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Load game scene from file
     // Load game scene from file
     _scene = Scene::load("res/common/duck.gpb");
     _scene = Scene::load("res/common/duck.gpb");

+ 1 - 1
samples/browser/src/SamplesGame.cpp

@@ -16,7 +16,7 @@ SamplesGame::SamplesGame()
 
 
 void SamplesGame::initialize()
 void SamplesGame::initialize()
 {
 {
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     for (size_t i = 0; i < _categories->size(); ++i)
     for (size_t i = 0; i < _categories->size(); ++i)
     {
     {

+ 1 - 1
samples/browser/src/SpriteBatchSample.cpp

@@ -49,7 +49,7 @@ SpriteBatchSample::SpriteBatchSample()
 void SpriteBatchSample::initialize()
 void SpriteBatchSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Create an orthographic projection matrix.
     // Create an orthographic projection matrix.
     float width = getWidth() / (float)getHeight();
     float width = getWidth() / (float)getHeight();

+ 1 - 1
samples/browser/src/TerrainSample.cpp

@@ -55,7 +55,7 @@ void TerrainSample::initialize()
     SAFE_RELEASE(bundle);
     SAFE_RELEASE(bundle);
 
 
     // Load font
     // Load font
-	_font = Font::create("res/common/arial18.gpb");
+	_font = Font::create("res/common/arial.gpb");
 
 
     // Setup form
     // Setup form
     _form = Form::create("res/common/terrain/terrain.form");
     _form = Form::create("res/common/terrain/terrain.form");

+ 9 - 9
samples/browser/src/TextSample.cpp

@@ -9,11 +9,11 @@
 
 
 std::string _fontNames[] =
 std::string _fontNames[] =
 {
 {
-    "arial18",
-    "dynamic",
-    "pirulen",
-    "squarehead",
+    "arial",
     "baroque",
     "baroque",
+    "badaboom",
+    "fishfingers",
+    "neuropol",
     "custom",
     "custom",
 };
 };
 
 
@@ -95,14 +95,14 @@ void TextSample::render(float elapsedTime)
     char fps[5];
     char fps[5];
     sprintf(fps, "%u", getFrameRate());
     sprintf(fps, "%u", getFrameRate());
 
 
-    _fonts[1]->start();
+    _fonts[0]->start();
 
 
-    _fonts[1]->drawText(fps, 245, 5, Vector4(0, 0.5f, 1, 1), _fonts[0]->getSize());
+    _fonts[0]->drawText(fps, 245, 5, Vector4(0, 0.5f, 1, 1), _fonts[0]->getSize());
     
     
     _form->draw();
     _form->draw();
 
 
     unsigned int size = (float)_font->getSize() * _scale;
     unsigned int size = (float)_font->getSize() * _scale;
-    if (_font != _fonts[1])
+    if (_font != _fonts[0])
         _font->start();
         _font->start();
 
 
     if (_simple)
     if (_simple)
@@ -135,11 +135,11 @@ void TextSample::render(float elapsedTime)
         _font->drawText(".", area.x + area.width, area.y + area.height, Vector4::fromColor(0x0000ffff), size);
         _font->drawText(".", area.x + area.width, area.y + area.height, Vector4::fromColor(0x0000ffff), size);
     }
     }
 
 
-    if (_font != _fonts[1])
+    if (_font != _fonts[0])
     {
     {
         _font->finish();
         _font->finish();
     }
     }
-    _fonts[1]->finish();
+    _fonts[0]->finish();
 }
 }
 
 
 void TextSample::touchEvent(Touch::TouchEvent event, int x, int y, unsigned int contactIndex)
 void TextSample::touchEvent(Touch::TouchEvent event, int x, int y, unsigned int contactIndex)

+ 1 - 1
samples/browser/src/TextureSample.cpp

@@ -49,7 +49,7 @@ TextureSample::TextureSample()
 void TextureSample::initialize()
 void TextureSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Create an empty scene.
     // Create an empty scene.
     _scene = Scene::create();
     _scene = Scene::create();

+ 1 - 1
samples/browser/src/TriangleSample.cpp

@@ -49,7 +49,7 @@ TriangleSample::TriangleSample()
 void TriangleSample::initialize()
 void TriangleSample::initialize()
 {
 {
     // Create the font for drawing the framerate.
     // Create the font for drawing the framerate.
-    _font = Font::create("res/common/arial18.gpb");
+    _font = Font::create("res/common/arial.gpb");
 
 
     // Create an orthographic projection matrix.
     // Create an orthographic projection matrix.
     float width = getWidth() / (float)getHeight();
     float width = getWidth() / (float)getHeight();

BIN
samples/character/res/common/arial.gpb


BIN
samples/character/res/common/arial40.gpb


BIN
samples/lua/res/arial.gpb


BIN
samples/lua/res/arial40.gpb


BIN
samples/mesh/res/arial.gpb


BIN
samples/mesh/res/arial40.gpb


BIN
samples/particles/res/arial.gpb


BIN
samples/racer/res/common/arial.gpb


BIN
samples/racer/res/common/arial40.gpb


+ 6 - 6
samples/racer/res/common/menu.theme

@@ -119,7 +119,7 @@ theme menuTheme
             skin = mainNormal
             skin = mainNormal
             imageList = normalImages
             imageList = normalImages
 
 
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 18
             fontSize = 18
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -141,7 +141,7 @@ theme menuTheme
 
 
         stateNormal
         stateNormal
         {
         {
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
         }
         }
 
 
@@ -161,7 +161,7 @@ theme menuTheme
         stateNormal
         stateNormal
         {
         {
             imageList = normalImages
             imageList = normalImages
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 14
             fontSize = 14
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -183,14 +183,14 @@ theme menuTheme
     {
     {
         stateNormal
         stateNormal
         {
         {
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
             textAlignment = ALIGN_VCENTER_LEFT
             textAlignment = ALIGN_VCENTER_LEFT
         }
         }
 
 
         stateActive
         stateActive
         {
         {
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             fontSize = 20
             fontSize = 20
             textAlignment = ALIGN_VCENTER_LEFT
             textAlignment = ALIGN_VCENTER_LEFT
         }
         }
@@ -201,7 +201,7 @@ theme menuTheme
         stateNormal
         stateNormal
         {
         {
             textColor = #ffffffff
             textColor = #ffffffff
-            font = res/common/arial40.gpb
+            font = res/common/arial.gpb
             fontSize = 26
             fontSize = 26
             textAlignment = ALIGN_TOP_HCENTER
             textAlignment = ALIGN_TOP_HCENTER
         }
         }

BIN
samples/spaceship/res/airstrip.gpb


BIN
samples/spaceship/res/airstrip28.gpb


+ 4 - 4
samples/spaceship/res/menu.theme

@@ -147,7 +147,7 @@ theme menuTheme
             skin = mainNormal
             skin = mainNormal
             imageList = normalImages
             imageList = normalImages
 
 
-            font = res/airstrip28.gpb
+            font = res/airstrip.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 15
             fontSize = 15
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -169,7 +169,7 @@ theme menuTheme
 
 
         stateNormal
         stateNormal
         {
         {
-            font = res/airstrip28.gpb
+            font = res/airstrip.gpb
             fontSize = 30
             fontSize = 30
         }
         }
 
 
@@ -184,7 +184,7 @@ theme menuTheme
         stateNormal
         stateNormal
         {
         {
             imageList = normalImages
             imageList = normalImages
-            font = res/airstrip28.gpb
+            font = res/airstrip.gpb
             textColor = #ffffffff
             textColor = #ffffffff
             fontSize = 15
             fontSize = 15
             textAlignment = ALIGN_VCENTER_HCENTER
             textAlignment = ALIGN_VCENTER_HCENTER
@@ -224,7 +224,7 @@ theme menuTheme
         {
         {
             skin = empty
             skin = empty
             textColor = #ffffffff
             textColor = #ffffffff
-            font = res/airstrip28.gpb
+            font = res/airstrip.gpb
             fontSize = 25
             fontSize = 25
             textAlignment = ALIGN_TOP_HCENTER
             textAlignment = ALIGN_TOP_HCENTER
         }
         }

+ 2 - 0
tools/encoder/gameplay-encoder.vcxproj

@@ -18,6 +18,7 @@
     <ClCompile Include="src\Camera.cpp" />
     <ClCompile Include="src\Camera.cpp" />
     <ClCompile Include="src\Constants.cpp" />
     <ClCompile Include="src\Constants.cpp" />
     <ClCompile Include="src\Curve.cpp" />
     <ClCompile Include="src\Curve.cpp" />
+    <ClCompile Include="src\edtaa3func.c" />
     <ClCompile Include="src\EncoderArguments.cpp" />
     <ClCompile Include="src\EncoderArguments.cpp" />
     <ClCompile Include="src\Effect.cpp" />
     <ClCompile Include="src\Effect.cpp" />
     <ClCompile Include="src\FBXSceneEncoder.cpp" />
     <ClCompile Include="src\FBXSceneEncoder.cpp" />
@@ -65,6 +66,7 @@
     <ClInclude Include="src\Camera.h" />
     <ClInclude Include="src\Camera.h" />
     <ClInclude Include="src\Constants.h" />
     <ClInclude Include="src\Constants.h" />
     <ClInclude Include="src\Curve.h" />
     <ClInclude Include="src\Curve.h" />
+    <ClInclude Include="src\edtaa3func.h" />
     <ClInclude Include="src\EncoderArguments.h" />
     <ClInclude Include="src\EncoderArguments.h" />
     <ClInclude Include="src\Effect.h" />
     <ClInclude Include="src\Effect.h" />
     <ClInclude Include="src\FBXSceneEncoder.h" />
     <ClInclude Include="src\FBXSceneEncoder.h" />

+ 6 - 0
tools/encoder/gameplay-encoder.vcxproj.filters

@@ -136,6 +136,9 @@
     <ClCompile Include="src\Sampler.cpp">
     <ClCompile Include="src\Sampler.cpp">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="src\edtaa3func.c">
+      <Filter>src</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\VertexElement.h">
     <ClInclude Include="src\VertexElement.h">
@@ -273,6 +276,9 @@
     <ClInclude Include="src\Sampler.h">
     <ClInclude Include="src\Sampler.h">
       <Filter>src</Filter>
       <Filter>src</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="src\edtaa3func.h">
+      <Filter>src</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <None Include="src\Vector2.inl">
     <None Include="src\Vector2.inl">

+ 2 - 2
tools/encoder/gameplay-encoder.vcxproj.user

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
-    <LocalDebuggerCommandArguments>
-    </LocalDebuggerCommandArguments>
+    <LocalDebuggerCommandArguments>-s 72 -p arial.ttf</LocalDebuggerCommandArguments>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
     <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
     <LocalDebuggerEnvironment>
     <LocalDebuggerEnvironment>
     </LocalDebuggerEnvironment>
     </LocalDebuggerEnvironment>
+    <LocalDebuggerWorkingDirectory>.\Debug</LocalDebuggerWorkingDirectory>
   </PropertyGroup>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
     <LocalDebuggerEnvironment>
     <LocalDebuggerEnvironment>

+ 12 - 0
tools/encoder/src/Base.h

@@ -25,8 +25,20 @@ using std::size_t;
 using std::min;
 using std::min;
 using std::max;
 using std::max;
 
 
+#if defined(WIN32)
+    #pragma warning( disable : 4005 )
+    #pragma warning( disable : 4172 )
+    #pragma warning( disable : 4244 )
+    #pragma warning( disable : 4267 )
+    #pragma warning( disable : 4311 )
+    #pragma warning( disable : 4390 )
+    #pragma warning( disable : 4800 )
+    #pragma warning( disable : 4996 )
+#endif
+
 // PNG
 // PNG
 #include <png.h>
 #include <png.h>
+#include "edtaa3func.h"
 
 
 // Defines
 // Defines
 #ifndef M_1_PI        
 #ifndef M_1_PI        

+ 1 - 0
tools/encoder/src/Material.cpp

@@ -1,6 +1,7 @@
 #include "Material.h"
 #include "Material.h"
 #include "FileIO.h"
 #include "FileIO.h"
 #include "StringUtil.h"
 #include "StringUtil.h"
+#include "edtaa3func.h"
 
 
 namespace gameplay
 namespace gameplay
 {
 {

+ 113 - 37
tools/encoder/src/TTFFontEncoder.cpp

@@ -34,6 +34,79 @@ static void writeString(FILE* fp, const char* str)
     }
     }
 }
 }
 
 
+unsigned char* createDistanceFieldMap(unsigned char* img, unsigned int width, unsigned int height)
+{
+    short* xDistance = (short*)malloc(width * height * sizeof(short));
+    short* yDistance = (short*)malloc(width * height * sizeof(short));
+    double* gx = (double*)calloc(width * height, sizeof(double));
+    double* gy = (double*)calloc(width * height, sizeof(double));
+    double* data = (double*)calloc(width * height, sizeof(double));
+    double* outside = (double*)calloc(width * height, sizeof(double));
+    double* inside = (double*)calloc(width * height, sizeof(double));
+    unsigned int i;
+
+    // Convert img into double (data)
+    double imgMin = 255;
+    double imgMax = -255;
+    for (i = 0; i < width * height; ++i)
+    {
+        double v = img[i];
+        data[i] = v;
+        if (v > imgMax) 
+            imgMax = v;
+        if (v < imgMin) 
+            imgMin = v;
+    }
+    // Rescale image levels between 0 and 1
+    for (i = 0; i < width * height; ++i)
+    {
+        data[i] = (img[i] - imgMin) / imgMax;
+    }
+    // Compute outside = edtaa3(bitmap); % Transform background (0's)
+    computegradient(data, width, height, gx, gy);
+    edtaa3(data, gx, gy, height, width, xDistance, yDistance, outside);
+    for (i = 0; i < width * height; ++i)
+    {
+        if (outside[i] < 0 )
+            outside[i] = 0.0;
+    }
+    // Compute inside = edtaa3(1-bitmap); % Transform foreground (1's)
+    memset(gx, 0, sizeof(double) * width * height);
+    memset(gy, 0, sizeof(double) * width * height);
+    for (i = 0; i < width * height; ++i)
+    {
+        data[i] = 1 - data[i];
+    }
+    computegradient(data, width, height, gx, gy);
+    edtaa3(data, gx, gy, height, width, xDistance, yDistance, inside);
+    for (i = 0; i < width * height; ++i)
+    {
+        if( inside[i] < 0 )
+            inside[i] = 0.0;
+    }
+    // distmap = outside - inside; % Bipolar distance field
+    unsigned char* out = (unsigned char*)malloc(sizeof(unsigned char) * width * height);
+    for (i = 0; i < width * height; ++i)
+    {
+        outside[i] -= inside[i];
+        outside[i] = 128 + outside[i] * 16;
+        if (outside[i] < 0) 
+            outside[i] = 0;
+        if (outside[i] > 255) 
+            outside[i] = 255;
+        out[i] = 255 - (unsigned char) outside[i];
+    }
+    free(xDistance);
+    free(yDistance);
+    free(gx);
+    free(gy);
+    free(data);
+    free(outside);
+    free(inside);
+
+    return out;
+}
+
 int writeFont(const char* inFilePath, const char* outFilePath, unsigned int fontSize, const char* id, bool fontpreview = false)
 int writeFont(const char* inFilePath, const char* outFilePath, unsigned int fontSize, const char* id, bool fontpreview = false)
 {
 {
     Glyph glyphArray[END_INDEX - START_INDEX];
     Glyph glyphArray[END_INDEX - START_INDEX];
@@ -56,13 +129,8 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         return -1;
         return -1;
     }
     }
     
     
-    // Set the pixel size.
-    error = FT_Set_Char_Size(
-            face,           // handle to face object.
-            0,              // char_width in 1/64th of points.
-            fontSize * 64,   // char_height in 1/64th of points.
-            0,              // horizontal device resolution (defaults to 72 dpi if resolution (0, 0)).
-            0 );            // vertical device resolution.
+    // Set the pixel size.  char_width in 1/64th of points.
+    error = FT_Set_Char_Size(  face,  0, fontSize * 64, 0, 0 ); 
     
     
     if (error)
     if (error)
     {
     {
@@ -72,9 +140,9 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
 
 
     // Save glyph information (slot contains the actual glyph bitmap).
     // Save glyph information (slot contains the actual glyph bitmap).
     FT_GlyphSlot slot = face->glyph;
     FT_GlyphSlot slot = face->glyph;
-    
     int actualfontHeight = 0;
     int actualfontHeight = 0;
-    int rowSize = 0; // Stores the total number of rows required to all glyphs.
+    // Stores the total number of rows required to all glyphs.
+    int rowSize = 0;
     
     
     // Find the width of the image.
     // Find the width of the image.
     for (unsigned char ascii = START_INDEX; ascii < END_INDEX; ++ascii)
     for (unsigned char ascii = START_INDEX; ascii < END_INDEX; ++ascii)
@@ -103,7 +171,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     int penX = 0;
     int penX = 0;
     int penY = 0;
     int penY = 0;
     int row = 0;
     int row = 0;
-    
+
     double powerOf2 = 2;
     double powerOf2 = 2;
     unsigned int imageWidth = 0;
     unsigned int imageWidth = 0;
     unsigned int imageHeight = 0;
     unsigned int imageHeight = 0;
@@ -135,7 +203,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
             int glyphWidth = slot->bitmap.pitch;
             int glyphWidth = slot->bitmap.pitch;
             int glyphHeight = slot->bitmap.rows;
             int glyphHeight = slot->bitmap.rows;
 
 
-            advance = glyphWidth + GLYPH_PADDING; //((int)slot->advance.x >> 6) + GLYPH_PADDING;
+            advance = glyphWidth + GLYPH_PADDING; 
 
 
             // If we reach the end of the image wrap aroud to the next row.
             // If we reach the end of the image wrap aroud to the next row.
             if ((penX + advance) > (int)imageWidth)
             if ((penX + advance) > (int)imageWidth)
@@ -158,11 +226,10 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
             // Move Y back to the top of the row.
             // Move Y back to the top of the row.
             penY = row * rowSize;
             penY = row * rowSize;
 
 
-            if (ascii == (END_INDEX-1))
+            if (ascii == (END_INDEX - 1))
             {
             {
                 textureSizeFound = true;
                 textureSizeFound = true;
             }
             }
-
             i++;
             i++;
         }
         }
     }
     }
@@ -183,7 +250,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     }
     }
     
     
     // Allocate temporary image buffer to draw the glyphs into.
     // Allocate temporary image buffer to draw the glyphs into.
-    unsigned char* imageBuffer = (unsigned char *)malloc(imageWidth * imageHeight);
+    unsigned char* imageBuffer = (unsigned char*)malloc(imageWidth * imageHeight);
     memset(imageBuffer, 0, imageWidth * imageHeight);
     memset(imageBuffer, 0, imageWidth * imageHeight);
     penX = 0;
     penX = 0;
     penY = 0;
     penY = 0;
@@ -203,7 +270,7 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         int glyphWidth = slot->bitmap.pitch;
         int glyphWidth = slot->bitmap.pitch;
         int glyphHeight = slot->bitmap.rows;
         int glyphHeight = slot->bitmap.rows;
 
 
-        advance = glyphWidth + GLYPH_PADDING;//((int)slot->advance.x >> 6) + GLYPH_PADDING;
+        advance = glyphWidth + GLYPH_PADDING;
 
 
         // If we reach the end of the image wrap aroud to the next row.
         // If we reach the end of the image wrap aroud to the next row.
         if ((penX + advance) > (int)imageWidth)
         if ((penX + advance) > (int)imageWidth)
@@ -238,14 +305,12 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
         glyphArray[i].uvCoords[3] = (float)(penY + rowSize) / (float)imageHeight;
         glyphArray[i].uvCoords[3] = (float)(penY + rowSize) / (float)imageHeight;
 
 
         // Set the pen position for the next glyph
         // Set the pen position for the next glyph
-        penX += advance; // Move X to next glyph position
+        penX += advance;
         i++;
         i++;
     }
     }
-
-
-    FILE *gpbFp = fopen(outFilePath, "wb");
     
     
     // File header and version.
     // File header and version.
+    FILE *gpbFp = fopen(outFilePath, "wb");
     char fileHeader[9]     = {'«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n'};
     char fileHeader[9]     = {'«', 'G', 'P', 'B', '»', '\r', '\n', '\x1A', '\n'};
     fwrite(fileHeader, sizeof(char), 9, gpbFp);
     fwrite(fileHeader, sizeof(char), 9, gpbFp);
     fwrite(gameplay::GPB_VERSION, sizeof(char), 2, gpbFp);
     fwrite(gameplay::GPB_VERSION, sizeof(char), 2, gpbFp);
@@ -255,23 +320,18 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     writeString(gpbFp, id);             // Ref id
     writeString(gpbFp, id);             // Ref id
     writeUint(gpbFp, 128);              // Ref type
     writeUint(gpbFp, 128);              // Ref type
     writeUint(gpbFp, ftell(gpbFp) + 4); // Ref offset (current pos + 4 bytes)
     writeUint(gpbFp, ftell(gpbFp) + 4); // Ref offset (current pos + 4 bytes)
-    
-    // Write Font object.
-    
+
     // Family name.
     // Family name.
     writeString(gpbFp, face->family_name);
     writeString(gpbFp, face->family_name);
 
 
     // Style.
     // Style.
-    // TODO: Switch based on TTF style name and write appropriate font style unsigned int
-    // For now just hardcoding to 0.
-    //char* style = face->style_name;
-    writeUint(gpbFp, 0); // 0 == PLAIN
+    // TODO: Switch based on TTF style name and write appropriate font style unsigned int for now just hardcoding to 0 = PLAIN.
+    writeUint(gpbFp, 0);
 
 
     // Font size.
     // Font size.
     writeUint(gpbFp, rowSize);
     writeUint(gpbFp, rowSize);
 
 
-    // Character set.
-    // TODO: Empty for now
+    // Character set. TODO: Empty for now
     writeString(gpbFp, "");
     writeString(gpbFp, "");
     
     
     // Glyphs.
     // Glyphs.
@@ -279,32 +339,48 @@ int writeFont(const char* inFilePath, const char* outFilePath, unsigned int font
     writeUint(gpbFp, glyphSetSize);
     writeUint(gpbFp, glyphSetSize);
     fwrite(&glyphArray, sizeof(Glyph), glyphSetSize, gpbFp);
     fwrite(&glyphArray, sizeof(Glyph), glyphSetSize, gpbFp);
     
     
-    // Texture.
-    unsigned int textureSize = imageWidth * imageHeight;
+    // Image dimensions
+    unsigned int imageSize = imageWidth * imageHeight;
     writeUint(gpbFp, imageWidth);
     writeUint(gpbFp, imageWidth);
     writeUint(gpbFp, imageHeight);
     writeUint(gpbFp, imageHeight);
-    writeUint(gpbFp, textureSize);
-    fwrite(imageBuffer, sizeof(unsigned char), textureSize, gpbFp);
+    writeUint(gpbFp, imageSize);
+    
+    // Flip height and width since the distance field map generator is column-wise.
+    unsigned char* distanceFieldBuffer = createDistanceFieldMap(imageBuffer, imageHeight, imageWidth);
     
     
+    // Write out the buffer
+    fwrite(distanceFieldBuffer, sizeof(unsigned char), imageSize, gpbFp);
+
+    //fwrite(imageBuffer, sizeof(unsigned char), imageSize, gpbFp);
+
     // Close file.
     // Close file.
     fclose(gpbFp);
     fclose(gpbFp);
 
 
     LOG(1, "%s.gpb created successfully. \n", getBaseName(outFilePath).c_str());
     LOG(1, "%s.gpb created successfully. \n", getBaseName(outFilePath).c_str());
 
 
+    // Save out a pgm monochome image file for preview
     if (fontpreview)
     if (fontpreview)
     {
     {
         // Write out font map to an image.
         // Write out font map to an image.
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         std::string pgmFilePath = getFilenameNoExt(outFilePath);
         pgmFilePath.append(".pgm");
         pgmFilePath.append(".pgm");
-        FILE *imageFp = fopen(pgmFilePath.c_str(), "wb");
-        fprintf(imageFp, "P5 %u %u 255\n", imageWidth, imageHeight);
-        fwrite((const char *)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, imageFp);
-        fclose(imageFp);
+        FILE* previewFp = fopen(pgmFilePath.c_str(), "wb");
+        fprintf(previewFp, "P5 %u %u 255\n", imageWidth, imageHeight);
+        
+        // Write out the preview buffer
+        fwrite((const char*)distanceFieldBuffer, sizeof(unsigned char), imageSize, previewFp);
+
+        //fwrite((const char*)imageBuffer, sizeof(unsigned char), imageWidth * imageHeight, previewFp);
+        
+        fclose(previewFp);
+
+        LOG(1, "%s.pgm preview image created successfully. \n", getBaseName(pgmFilePath).c_str());
     }
     }
 
 
     // Cleanup resources.
     // Cleanup resources.
     free(imageBuffer);
     free(imageBuffer);
-    
+    free(distanceFieldBuffer);
+
     FT_Done_Face(face);
     FT_Done_Face(face);
     FT_Done_FreeType(library);
     FT_Done_FreeType(library);
     return 0;
     return 0;