فهرست منبع

Merge branch 'world' of https://github.com/taylor001/crown into world

Daniele Bartolini 12 سال پیش
والد
کامیت
669a832d11
5فایلهای تغییر یافته به همراه165 افزوده شده و 77 حذف شده
  1. 3 2
      engine/gui/Gui.cpp
  2. 128 53
      engine/gui/GuiText.h
  3. 3 1
      engine/resource/FontResource.cpp
  4. 11 4
      engine/resource/FontResource.h
  5. 20 17
      tools/gui/fontgen/main.cpp

+ 3 - 2
engine/gui/Gui.cpp

@@ -98,7 +98,6 @@ static const char* sdf_vertex =
 
 	"attribute vec4		a_position;"
 	"attribute vec2		a_tex_coord0;"
-	"attribute vec4		a_color;"
 
 	"varying vec2		v_tex_coord;"
 	"varying vec4		v_color;"
@@ -169,6 +168,7 @@ Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
 		create_rect(pos, size, color);	
 	}
 
+	// Gui's triangles creation
 	for (uint32_t i = 0; i < m_resource->num_triangles(); i++)
 	{
 		GuiTriangleData data = m_resource->get_triangle(i);
@@ -180,6 +180,7 @@ Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
 		create_triangle(p1, p2, p3, color);
 	}
 
+	// Gui's images creation
 	for (uint32_t i = 0; i < m_resource->num_images(); i++)
 	{
 		GuiImageData data = m_resource->get_image(i);
@@ -190,7 +191,7 @@ Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
 		create_image(mat, pos, size);
 	}
 
-	// Manage texts creation
+	// Gui's texts creation
 
 /*	FontResource* res = (FontResource*) device()->resource_manager()->lookup("font", "fonts/veramobi");
 	create_text("ciaO mAngOZOide", res, 30, Vector3(300, 400, 0));*/

+ 128 - 53
engine/gui/GuiText.h

@@ -27,6 +27,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 
 #include "Matrix4x4.h"
+#include "Quaternion.h"
 #include "RendererTypes.h"
 #include "StringUtils.h"
 #include "Log.h"
@@ -39,6 +40,7 @@ struct Vector3;
 struct Vector2;
 struct Color4;
 
+//-------------------------------------------------------------------------
 struct VertexData
 {
 	float x;
@@ -47,12 +49,51 @@ struct VertexData
 	float v;
 };
 
+//-------------------------------------------------------------------------
 struct IndexData
 {
 	uint16_t a;
 	uint16_t b;
 };
 
+#define UTF8_ACCEPT 0
+
+//-------------------------------------------------------------------------
+static const uint8_t s_utf8d[364] =
+{
+	// The first part of the table maps bytes to character classes that
+	// to reduce the size of the transition table and create bitmasks.
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+	8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+	10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+
+	// The second part is a transition table that maps a combination
+	// of a state of the automaton and a character class to a state.
+	 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
+	12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
+	12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
+	12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
+	12,36,12,12,12,12,12,12,12,12,12,12
+};
+
+//-------------------------------------------------------------------------
+uint32_t utf8_decode(uint32_t* state, uint32_t* code_point, uint8_t character)
+{
+	uint32_t byte = character;
+	uint32_t type = s_utf8d[byte];
+
+	*code_point = (*state != UTF8_ACCEPT) ? (byte & 0x3fu) | (*code_point << 6) : (0xff >> type) & (byte);
+	*state = s_utf8d[256 + *state + type];
+
+	return *state;
+}
+
+//-------------------------------------------------------------------------
 struct GuiText
 {
 	//-------------------------------------------------------------------------
@@ -89,6 +130,7 @@ struct GuiText
 		material->bind(m_r, uniform);
 
 		const char* str = m_str.c_str();
+		const float scale = ((float)m_font_size / (float)m_resource->font_size());
 
 		TransientVertexBuffer vb;
 		TransientIndexBuffer ib;
@@ -97,61 +139,91 @@ struct GuiText
 		m_r.reserve_transient_index_buffer(&ib, 6 * string::strlen(str));
 
 		uint16_t index = 0;
-		float advance = 0.0f;
+		float x_pen_advance = 0.0f;
+		float y_pen_advance = 0.0f;
+
+		uint32_t state = 0;
+		uint32_t code_point = 0;
 		for (uint32_t i = 0; i < string::strlen(str); i++)
 		{
-			FontGlyphData g = m_resource->get_glyph(str[i]);
-
-			const float x		= (float) g.x / m_resource->size();
-			const float y		= (float) g.y / m_resource->size();
-			const float width	= (float) g.width / m_resource->size();
-			const float height	= (float) g.height / m_resource->size();
-
-			const float u0 = x;
-			const float v0 = y;
-			const float u1 = x + width;
-			const float v1 = y - height;
-
-			(*(VertexData*)(vb.data)).x		= m_pos.x + advance;
-			(*(VertexData*)(vb.data)).y		= m_pos.y;
-			(*(VertexData*)(vb.data)).u		= u0;
-			(*(VertexData*)(vb.data)).v		= v1;
-			vb.data += sizeof(VertexData);
-
-			(*(VertexData*)(vb.data)).x		= m_pos.x + m_font_size + advance;
-			(*(VertexData*)(vb.data)).y		= m_pos.y;
-			(*(VertexData*)(vb.data)).u		= u1; 
-			(*(VertexData*)(vb.data)).v		= v1;
-			vb.data += sizeof(VertexData);
-
-			(*(VertexData*)(vb.data)).x		= m_pos.x + m_font_size + advance;
-			(*(VertexData*)(vb.data)).y		= m_pos.y - m_font_size;
-			(*(VertexData*)(vb.data)).u		= u1;
-			(*(VertexData*)(vb.data)).v		= v0;
-			vb.data += sizeof(VertexData);
-
-			(*(VertexData*)(vb.data)).x		= m_pos.x + advance;
-			(*(VertexData*)(vb.data)).y		= m_pos.y - m_font_size;
-			(*(VertexData*)(vb.data)).u		= u0;
-			(*(VertexData*)(vb.data)).v		= v0;
-			vb.data += sizeof(VertexData);
-
-
-			(*(IndexData*)(ib.data)).a		= index;
-			(*(IndexData*)(ib.data)).b		= index + 1;
-			ib.data += sizeof(IndexData);
-
-			(*(IndexData*)(ib.data)).a		= index + 2;
-			(*(IndexData*)(ib.data)).b		= index;
-			ib.data += sizeof(IndexData);
-
-			(*(IndexData*)(ib.data)).a		= index + 2;
-			(*(IndexData*)(ib.data)).b		= index + 3;
-			ib.data += sizeof(IndexData);
-
-			index += 4;
-
-			advance += g.x_advance;
+			switch (str[i])
+			{
+				case '\n':
+				{
+					x_pen_advance = 0.0f;
+					y_pen_advance += m_resource->font_size();
+					continue;
+				}
+				case '\t':
+				{
+					x_pen_advance += m_font_size * 4;
+					continue;
+				}
+			}
+			
+			if (utf8_decode(&state, &code_point, str[i]) == UTF8_ACCEPT)
+			{
+				FontGlyphData g = m_resource->get_glyph(code_point);
+
+				// Set pen position
+				m_pen.x = m_pos.x + g.x_offset;
+				m_pen.y = m_pos.y + (g.height - g.y_offset);
+
+				// Position coords
+				const float x0 = (m_pen.x + x_pen_advance) * scale;
+				const float y0 = (m_pen.y + y_pen_advance) * scale;
+				const float x1 = (m_pen.x + g.width + x_pen_advance) * scale;
+				const float y1 = (m_pen.y - g.height + y_pen_advance) * scale;
+
+				// Texture coords
+				const float u0 = (float) g.x / m_resource->texture_size();
+				const float v0 = (float) g.y / m_resource->texture_size();
+				const float u1 = u0 + ((float) g.width) / m_resource->texture_size();
+				const float v1 = v0 - ((float) g.height) / m_resource->texture_size();
+
+				// Fill vertex buffer
+				(*(VertexData*)(vb.data)).x		= x0;
+				(*(VertexData*)(vb.data)).y		= y0;
+				(*(VertexData*)(vb.data)).u		= u0;
+				(*(VertexData*)(vb.data)).v		= v1;
+				vb.data += sizeof(VertexData);
+
+				(*(VertexData*)(vb.data)).x		= x1;
+				(*(VertexData*)(vb.data)).y		= y0;
+				(*(VertexData*)(vb.data)).u		= u1; 
+				(*(VertexData*)(vb.data)).v		= v1;
+				vb.data += sizeof(VertexData);
+
+				(*(VertexData*)(vb.data)).x		= x1;
+				(*(VertexData*)(vb.data)).y		= y1;
+				(*(VertexData*)(vb.data)).u		= u1;
+				(*(VertexData*)(vb.data)).v		= v0;
+				vb.data += sizeof(VertexData);
+
+				(*(VertexData*)(vb.data)).x		= x0;
+				(*(VertexData*)(vb.data)).y		= y1;
+				(*(VertexData*)(vb.data)).u		= u0;
+				(*(VertexData*)(vb.data)).v		= v0;
+				vb.data += sizeof(VertexData);
+
+				// Fill index buffer
+				(*(IndexData*)(ib.data)).a		= index;
+				(*(IndexData*)(ib.data)).b		= index + 1;
+				ib.data += sizeof(IndexData);
+
+				(*(IndexData*)(ib.data)).a		= index + 2;
+				(*(IndexData*)(ib.data)).b		= index;
+				ib.data += sizeof(IndexData);
+
+				(*(IndexData*)(ib.data)).a		= index + 2;
+				(*(IndexData*)(ib.data)).b		= index + 3;
+				ib.data += sizeof(IndexData);
+
+				// Advance pen position
+				x_pen_advance += g.x_advance;
+
+				index += 4;
+			}
 		}
 
 		m_r.set_vertex_buffer(vb);
@@ -167,7 +239,10 @@ public:
 
 	DynamicString		m_str;
 	uint32_t			m_font_size;
+
+	// position states
 	Vector3				m_pos;
+	Vector2				m_pen;
 
 	MaterialId 			m_material;
 };

+ 3 - 1
engine/resource/FontResource.cpp

@@ -77,6 +77,7 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 	JSONElement mat = root.key("material");
 	JSONElement count = root.key("count");
 	JSONElement size = root.key("size");
+	JSONElement font_size = root.key("font_size");
 	JSONElement glyphs = root.key("glyphs");
 
 	DynamicString material_name;
@@ -97,7 +98,8 @@ void compile(Filesystem& fs, const char* resource_path, File* out_file)
 
 	h.material.id = hash::murmur2_64(material_name.c_str(), string::strlen(material_name.c_str()), 0);
 	h.num_glyphs = m_glyphs.size();
-	h.size = size.to_int();
+	h.texture_size = size.to_int();
+	h.font_size = font_size.to_int();
 
 	out_file->write((char*) &h, sizeof(FontHeader));
 

+ 11 - 4
engine/resource/FontResource.h

@@ -72,7 +72,8 @@ struct FontHeader
 {
 	ResourceId material;
 	uint32_t num_glyphs;
-	uint32_t size;			// Font texture size -- pow of 2
+	uint32_t texture_size;			// Font texture size -- pow of 2
+	uint32_t font_size;
 };
 
 //-----------------------------------------------------------------------------
@@ -140,13 +141,19 @@ public:
 	}
 
 	//-----------------------------------------------------------------------------
-	uint32_t size() const
+	uint32_t texture_size() const
 	{
-		return ((FontHeader*)this)->size;
+		return ((FontHeader*)this)->texture_size;
 	}
 
 	//-----------------------------------------------------------------------------
-	FontGlyphData get_glyph(const uint8_t index) const
+	uint32_t font_size() const
+	{
+		return ((FontHeader*)this)->font_size;
+	}
+
+	//-----------------------------------------------------------------------------
+	FontGlyphData get_glyph(const uint32_t index) const
 	{
 		CE_ASSERT(index < num_glyphs(), "Index out of bounds");
 

+ 20 - 17
tools/gui/fontgen/main.cpp

@@ -60,6 +60,8 @@ int save_c_header_SDFont(
 		const std::vector< unsigned char > &img_data,
 		const std::vector< sdf_glyph > &packed_glyphs );
 
+static int font_size = 4;
+
 //	number of rendered pixels per SDF pixel
 const int scaler = 16;
 //	(larger value means higher quality, up to a point)
@@ -314,37 +316,37 @@ bool render_signed_distance_font(
 		printf( "\nDetermining ideal font pixel size: " );
 		std::vector< sdf_glyph > all_glyphs;
 		//	initial guess for the size of the Signed Distance Field font
-		//	(intentionally low, the first trial will be at sz*2, so 8x8)
-		int sz = 4;
+		//	(intentionally low, the first trial will be at font_size*2, so 8x8)
+
 		bool keep_going = true;
 		while( keep_going )
 		{
-			sz <<= 1;
-			printf( " %i", sz );
-			keep_going = gen_pack_list( ft_face, sz, texture_size, render_list, all_glyphs );
+			font_size <<= 1;
+			printf( " %i", font_size );
+			keep_going = gen_pack_list( ft_face, font_size, texture_size, render_list, all_glyphs );
 		}
-		int sz_step = sz >> 2;
-		while( sz_step )
+		int font_size_step = font_size >> 2;
+		while( font_size_step )
 		{
 			if( keep_going )
 			{
-				sz += sz_step;
+				font_size += font_size_step;
 			} else
 			{
-				sz -= sz_step;
+				font_size -= font_size_step;
 			}
-			printf( " %i", sz );
-			sz_step >>= 1;
-			keep_going = gen_pack_list( ft_face, sz, texture_size, render_list, all_glyphs );
+			printf( " %i", font_size );
+			font_size_step >>= 1;
+			keep_going = gen_pack_list( ft_face, font_size, texture_size, render_list, all_glyphs );
 		}
 		//	just in case
-		while( (!keep_going) && (sz > 1) )
+		while( (!keep_going) && (font_size > 1) )
 		{
-			--sz;
-			printf( " %i", sz );
-			keep_going = gen_pack_list( ft_face, sz, texture_size, render_list, all_glyphs );
+			--font_size;
+			printf( " %i", font_size );
+			keep_going = gen_pack_list( ft_face, font_size, texture_size, render_list, all_glyphs );
 		}
-		printf( "\nResult = %i pixels\n", sz );
+		printf( "\nResult = %i pixels\n", font_size );
 
 		if( !keep_going )
 		{
@@ -484,6 +486,7 @@ int save_png_SDFont(
 		fprintf(fp, "\"material\": \"%s\",\n", font_name);
 		fprintf(fp, "\"count\":%i,\n", packed_glyphs.size());
 		fprintf(fp, "\"size\":%i,\n", img_width);
+		fprintf(fp, "\"font_size\": %i, \n", font_size);
 		fprintf(fp, "\"glyphs\" : [\n");
 		for(unsigned int i = 0; i < packed_glyphs.size()-1; ++i)
 		{