From 1f80f793ac01a9dbbd6ba693b580380695f1f4b2 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Fri, 31 Jul 2020 18:01:28 +0800 Subject: [PATCH] update TileFont.... --- CMCore | 2 +- example/Vulkan/DrawText.cpp | 112 ++++++++++++---- inc/hgl/graph/TileData.h | 4 +- inc/hgl/graph/VertexAttribDataAccess.h | 70 +++++----- inc/hgl/graph/font/Font.h | 2 +- inc/hgl/graph/font/FontSource.h | 168 ++++++++++++++---------- inc/hgl/graph/font/TextLayout.h | 34 +---- inc/hgl/graph/font/TileFont.h | 29 ++++- inc/hgl/graph/vulkan/VKDevice.h | 6 +- res | 2 +- src/RenderDevice/Vulkan/CMakeLists.txt | 3 +- src/RenderDevice/Vulkan/VKTileData.cpp | 122 +++++++++--------- src/RenderDevice/Vulkan/VKTileFont.cpp | 44 +++++++ src/SceneGraph/CMakeLists.txt | 11 +- src/SceneGraph/font/FontSource.cpp | 58 +++++++++ src/SceneGraph/font/FontSourceWin.cpp | 2 +- src/SceneGraph/font/TextLayout.cpp | 171 +++++++------------------ src/SceneGraph/font/TileFont.cpp | 52 ++++---- 18 files changed, 512 insertions(+), 380 deletions(-) create mode 100644 src/RenderDevice/Vulkan/VKTileFont.cpp diff --git a/CMCore b/CMCore index c2d6f456..5866f923 160000 --- a/CMCore +++ b/CMCore @@ -1 +1 @@ -Subproject commit c2d6f456f7c17fe2ab7905a7c4f5b2222b5b611b +Subproject commit 5866f9238750b11ddd925d51201da788cb234d7e diff --git a/example/Vulkan/DrawText.cpp b/example/Vulkan/DrawText.cpp index db10ab53..0001e989 100644 --- a/example/Vulkan/DrawText.cpp +++ b/example/Vulkan/DrawText.cpp @@ -1,30 +1,40 @@ +// DrawTile +// 该示例使用TileData,演示多个tile图片在一张纹理上 + +#include +#include +#include +#include +#include + #include"VulkanAppFramework.h" #include #include #include -#include using namespace hgl; using namespace hgl::graph; -VK_NAMESPACE_BEGIN -Texture2D *CreateTextureFromFile(Device *device,const OSString &filename); -VK_NAMESPACE_END +/** + * 文本绘制技术流程: + * + * 1.由TextLayout模块排版所有的字符,并向FontSource获取所有字符的Bitmap。生成文本可渲染对象的vertex position数据 + * 2.由TextLayout向TileData提交需要渲染的所有字符的Bitmap,并得到每个Bitmap对应的UV数据。生成文本可渲染对象的uv数据 + */ -constexpr uint32_t SCREEN_SIZE=512; +constexpr uint32_t SCREEN_WIDTH =1280; +constexpr uint32_t SCREEN_HEIGHT=960; + +constexpr uint CHAR_BITMAP_SIZE=16; //字符尺寸 +constexpr uint CHAR_BITMAP_BORDER=1; //边界象素尺寸 class TestApp:public VulkanApplicationFramework { Camera cam; - -private: - - TextLayout text_layout; - + private: vulkan::Material * material =nullptr; - vulkan::Texture2D * texture =nullptr; vulkan::Sampler * sampler =nullptr; vulkan::MaterialInstance * material_instance =nullptr; vulkan::Renderable * render_obj =nullptr; @@ -32,11 +42,60 @@ private: vulkan::Pipeline * pipeline =nullptr; - vulkan::VertexAttribBuffer *vertex_buffer =nullptr; - vulkan::VertexAttribBuffer *tex_coord_buffer =nullptr; +private: + + TileFont * tile_font; + TextLayout tl_engine; ///<文本排版引擎 + + RenderableCreater * text_rc =nullptr; + Renderable * text_renderable =nullptr; ///<文本渲染对象列表 + +public: + + ~TestApp() + { + SAFE_CLEAR(text_renderable); + SAFE_CLEAR(text_rc); + SAFE_CLEAR(tile_font); + } private: + bool InitTileFont() + { + Font fnt(OS_TEXT("Consolas"),0,CHAR_BITMAP_SIZE); + + tile_font=device->CreateTileFont(fnt); + return(true); + } + + bool InitTextRenderable() + { + CharAttributes ca; + TextLayoutAttributes tla; + + ca.CharColor=Color4f(COLOR::White); + ca.BackgroundColor=Color4f(COLOR::Black); + + tla.char_attributes=&ca; + + text_rc=new RenderableCreater(db,material); + + tl_engine.Set(text_rc); + tl_engine.Set(&tla); + tl_engine.SetTextDirection(0); + tl_engine.Set(TextAlign::Left); + tl_engine.SetMaxWidth(0); + tl_engine.SetMaxHeight(0); + + if(!tl_engine.Init()) + return(false); + + UTF16String str=U16_TEXT("道可道,非常道。名可名,非常名。无名天地之始。有名万物之母。故常无欲以观其妙。常有欲以观其徼。此两者同出而异名,同谓之玄。玄之又玄,众妙之门。"); + + tl_engine.PlaneLayout(tile_font,0,str); + } + bool InitMaterial() { material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"), @@ -45,21 +104,16 @@ private: if(!material) return(false); - render_obj=material->CreateRenderable(VERTEX_COUNT); material_instance=material->CreateInstance(); - texture=vulkan::CreateTextureFromFile(device,OS_TEXT("res/image/lena.Tex2D")); - sampler=db->CreateSampler(); - material_instance->BindSampler("tex",texture,sampler); + material_instance->BindSampler("tex",tile_data->GetTexture(),sampler); material_instance->BindUBO("world",ubo_world_matrix); material_instance->Update(); db->Add(material); db->Add(material_instance); - db->Add(texture); - db->Add(render_obj); return(true); } @@ -82,11 +136,17 @@ private: void InitVBO() { - vertex_buffer =db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,vertex_data); - tex_coord_buffer=db->CreateVAB(FMT_RGBA32F,VERTEX_COUNT,tex_coord_data); + const int tile_count=tile_list.GetCount(); + + render_obj=material->CreateRenderable(tile_count); + + vertex_buffer =db->CreateVAB(VAF_VEC4,tile_count,vertex_data); + tex_coord_buffer=db->CreateVAB(VAF_VEC4,tile_count,tex_coord_data); render_obj->Set("Vertex",vertex_buffer); render_obj->Set("TexCoord",tex_coord_buffer); + + db->Add(render_obj); } bool InitPipeline() @@ -106,7 +166,13 @@ public: bool Init() { - if(!VulkanApplicationFramework::Init(SCREEN_SIZE,SCREEN_SIZE)) + if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + if(!InitTileData()) + return(false); + + if(!InitTileFont()) return(false); if(!InitUBO()) @@ -138,7 +204,7 @@ public: } };//class TestApp:public VulkanApplicationFramework -int os_main(int,os_char **) +int main(int,char **) { TestApp app; diff --git a/inc/hgl/graph/TileData.h b/inc/hgl/graph/TileData.h index f1161733..c41da1f1 100644 --- a/inc/hgl/graph/TileData.h +++ b/inc/hgl/graph/TileData.h @@ -42,14 +42,14 @@ namespace hgl uint tile_rows,tile_cols; ///<贴图中可用的Tile行数和列数 protected: - + vulkan::Buffer *tile_buffer; /// commit_list; uint8 *commit_ptr; bool CommitTile(TileObject *,const void *,const uint,const int,const int); ///<提交一个Tile数据 - + public: int GetWidth ()const{return tile_width;} ///<取得Tile宽 diff --git a/inc/hgl/graph/VertexAttribDataAccess.h b/inc/hgl/graph/VertexAttribDataAccess.h index 6c453bc0..199d868d 100644 --- a/inc/hgl/graph/VertexAttribDataAccess.h +++ b/inc/hgl/graph/VertexAttribDataAccess.h @@ -34,7 +34,7 @@ namespace hgl data =_data; count =_size; data_end=_data+_size*C; - + total_bytes =_size*C*sizeof(T); access =nullptr; @@ -469,10 +469,10 @@ namespace hgl LOG_HINT(OS_TEXT("VertexAttribDataAccess2::WriteRectFan(RectScope2 *) out")); return(false); } - + *this->access++=scope.GetLeft(); *this->access++=scope.GetBottom(); - + *this->access++=scope.GetRight(); *this->access++=scope.GetBottom(); @@ -1140,41 +1140,41 @@ namespace hgl };//class VertexAttribDataAccess4 //缓冲区具体数据类型定义 - typedef VertexAttribDataAccess1 VB1i8 ,VB1b; - typedef VertexAttribDataAccess1 VB1i16 ,VB1s; - typedef VertexAttribDataAccess1 VB1i32 ,VB1i; - typedef VertexAttribDataAccess1 VB1u8 ,VB1ub; - typedef VertexAttribDataAccess1 VB1u16 ,VB1us; - typedef VertexAttribDataAccess1 VB1u32 ,VB1ui; - typedef VertexAttribDataAccess1 VB1f; - typedef VertexAttribDataAccess1 VB1d; + typedef VertexAttribDataAccess1 VB1i8 ,VB1b; + typedef VertexAttribDataAccess1 VB1i16 ,VB1s; + typedef VertexAttribDataAccess1 VB1i32 ,VB1i; + typedef VertexAttribDataAccess1 VB1u8 ,VB1ub; + typedef VertexAttribDataAccess1 VB1u16 ,VB1us; + typedef VertexAttribDataAccess1 VB1u32 ,VB1ui; + typedef VertexAttribDataAccess1 VB1f; + typedef VertexAttribDataAccess1 VB1d; - typedef VertexAttribDataAccess2 VB2i8 ,VB2b; - typedef VertexAttribDataAccess2 VB2i16 ,VB2s; - typedef VertexAttribDataAccess2 VB2i32 ,VB2i; - typedef VertexAttribDataAccess2 VB2u8 ,VB2ub; - typedef VertexAttribDataAccess2 VB2u16 ,VB2us; - typedef VertexAttribDataAccess2 VB2u32 ,VB2ui; - typedef VertexAttribDataAccess2 VB2f; - typedef VertexAttribDataAccess2 VB2d; + typedef VertexAttribDataAccess2 VB2i8 ,VB2b; + typedef VertexAttribDataAccess2 VB2i16 ,VB2s; + typedef VertexAttribDataAccess2 VB2i32 ,VB2i; + typedef VertexAttribDataAccess2 VB2u8 ,VB2ub; + typedef VertexAttribDataAccess2 VB2u16 ,VB2us; + typedef VertexAttribDataAccess2 VB2u32 ,VB2ui; + typedef VertexAttribDataAccess2 VB2f; + typedef VertexAttribDataAccess2 VB2d; -// typedef VertexAttribDataAccess3 VB3i8 ,VB3b; -// typedef VertexAttribDataAccess3 VB3i16 ,VB3s; - typedef VertexAttribDataAccess3 VB3i32 ,VB3i; -// typedef VertexAttribDataAccess3 VB3u8 ,VB3ub; -// typedef VertexAttribDataAccess3 VB3u16 ,VB3us; - typedef VertexAttribDataAccess3 VB3u32 ,VB3ui; - typedef VertexAttribDataAccess3 VB3f; - typedef VertexAttribDataAccess3 VB3d; +// typedef VertexAttribDataAccess3 VB3i8 ,VB3b; +// typedef VertexAttribDataAccess3 VB3i16 ,VB3s; + typedef VertexAttribDataAccess3 VB3i32 ,VB3i; +// typedef VertexAttribDataAccess3 VB3u8 ,VB3ub; +// typedef VertexAttribDataAccess3 VB3u16 ,VB3us; + typedef VertexAttribDataAccess3 VB3u32 ,VB3ui; + typedef VertexAttribDataAccess3 VB3f; + typedef VertexAttribDataAccess3 VB3d; - typedef VertexAttribDataAccess4 VB4i8 ,VB4b; - typedef VertexAttribDataAccess4 VB4i16 ,VB4s; - typedef VertexAttribDataAccess4 VB4i32 ,VB4i; - typedef VertexAttribDataAccess4 VB4u8 ,VB4ub; - typedef VertexAttribDataAccess4 VB4u16 ,VB4us; - typedef VertexAttribDataAccess4 VB4u32 ,VB4ui; - typedef VertexAttribDataAccess4 VB4f; - typedef VertexAttribDataAccess4 VB4d; + typedef VertexAttribDataAccess4 VB4i8 ,VB4b; + typedef VertexAttribDataAccess4 VB4i16 ,VB4s; + typedef VertexAttribDataAccess4 VB4i32 ,VB4i; + typedef VertexAttribDataAccess4 VB4u8 ,VB4ub; + typedef VertexAttribDataAccess4 VB4u16 ,VB4us; + typedef VertexAttribDataAccess4 VB4u32 ,VB4ui; + typedef VertexAttribDataAccess4 VB4f; + typedef VertexAttribDataAccess4 VB4d; }//namespace graph }//namespace hgl #endif//HGL_GRAPH_VERTEX_ATTRIB_DATA_ACCESS_INCLUDE diff --git a/inc/hgl/graph/font/Font.h b/inc/hgl/graph/font/Font.h index 6b9aa7cd..c630996b 100644 --- a/inc/hgl/graph/font/Font.h +++ b/inc/hgl/graph/font/Font.h @@ -27,7 +27,7 @@ namespace hgl public: Font(); - Font(const os_char *,int,int,bool,bool,bool=true); + Font(const os_char *,int,int,bool b=false,bool i=false,bool=true); CompOperatorMemcmp(const Font &); ///<比较操作符重载 };//struct Font diff --git a/inc/hgl/graph/font/FontSource.h b/inc/hgl/graph/font/FontSource.h index 81748e70..4731d73c 100644 --- a/inc/hgl/graph/font/FontSource.h +++ b/inc/hgl/graph/font/FontSource.h @@ -11,111 +11,141 @@ using namespace hgl; namespace hgl { - namespace graph - { - struct CharMetricsInfo - { - int x,y; //图像显示偏移 - int w,h; //图像尺寸 + namespace graph + { + struct CharMetricsInfo + { + int x,y; //图像显示偏移 + int w,h; //图像尺寸 - int adv_x,adv_y;//字符尺寸 - };//struct CharMetricsInfo + int adv_x,adv_y;//字符尺寸 + };//struct CharMetricsInfo - /** - * 字体位图数据 - */ - struct FontBitmap - { - int count; //使用次数 + /** + * 字体位图数据 + */ + struct FontBitmap + { + int count; //使用次数 - CharMetricsInfo metrics_info; + CharMetricsInfo metrics_info; - uint8 *data; - };//struct FontBitmap + uint8 *data; + };//struct FontBitmap + + /** + * 字符排版属性 + */ + struct CharLayoutAttributes + { + u32char ch; ///<字符 - /** - * 文字位图数据源 - */ - class FontSource - { - protected: + bool visible; ///<是否可显示字符 + + int size; ///<字符排版尺寸(一般为宽) - Set ref_object; + bool is_cjk; ///<是否是中日韩文字 + bool is_emoji; ///<是否是表情符号 - public: + bool is_punctuation; ///<是否是标点符号 - virtual ~FontSource()=default; + bool begin_disable; ///<是否行首禁用符号 + bool end_disable; ///<是否行尾禁用符号 + bool vrotate; ///<竖排时是否需要旋转 - virtual FontBitmap *GetCharBitmap (const u32char &)=0; ///<取得字符位图数据 - virtual const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 - virtual int GetCharHeight ()const=0; ///<取得字符高度 + CharMetricsInfo adv_info; ///<字符绘制信息 + };//struct CharLayoutAttributes - void RefAcquire(void *); ///<引用请求 - void RefRelease(void *); ///<引用释放 - int RefCount()const{return ref_object.GetCount();} ///<获取引用对象数量 - };//class FontSource + using CLA=CharLayoutAttributes; + + /** + * 文字位图数据源 + */ + class FontSource + { + protected: - /** - * 文字位图单一数据源 - */ - class FontSourceSingle:public FontSource - { - protected: + Set ref_object; - Font fnt; + MapObject cla_cache; - MapObject chars_bitmap; ///<字符位图 + public: - protected: + virtual ~FontSource()=default; - virtual bool MakeCharBitmap(FontBitmap *,u32char)=0; ///<产生字符位图数据 + virtual FontBitmap *GetCharBitmap (const u32char &)=0; ///<取得字符位图数据 + virtual const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 + const CLA * GetCLA (const u32char &); ///<取得字符排版信息 + virtual int GetCharHeight ()const=0; ///<取得字符高度 - public: + void RefAcquire(void *); ///<引用请求 + void RefRelease(void *); ///<引用释放 + int RefCount()const{return ref_object.GetCount();} ///<获取引用对象数量 + };//class FontSource - FontSourceSingle(const Font &f){fnt=f;} - virtual ~FontSourceSingle()=default; + /** + * 文字位图单一数据源 + */ + class FontSourceSingle:public FontSource + { + protected: - FontBitmap *GetCharBitmap (const u32char &ch) override; ///<取得字符位图数据 - const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 - virtual int GetCharHeight ()const override{return fnt.height;} ///<取得字符高度 - };//class FontSourceSingle:public FontSource + Font fnt; - /** - * 文字位图多重数据源 - */ + MapObject chars_bitmap; ///<字符位图 + + protected: + + virtual bool MakeCharBitmap(FontBitmap *,u32char)=0; ///<产生字符位图数据 + + public: + + FontSourceSingle(const Font &f){fnt=f;} + virtual ~FontSourceSingle()=default; + + FontBitmap *GetCharBitmap (const u32char &ch) override; ///<取得字符位图数据 + const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 + virtual int GetCharHeight ()const override{return fnt.height;} ///<取得字符高度 + };//class FontSourceSingle:public FontSource + + FontSourceSingle *CreateFontSource(const Font &f); + + /** + * 文字位图多重数据源 + */ class FontSourceMulti:public FontSource { using FontSourcePointer=FontSource *; - FontSource *default_source; - Map source_map; + FontSource *default_source; + Map source_map; - int max_char_height; + int max_char_height; - void RefreshMaxCharHeight(); + void RefreshMaxCharHeight(); - protected: + protected: - FontSource *GetFontSource(const u32char &ch); + FontSource *GetFontSource(const u32char &ch); public: - /** - * @param dfs 缺省字符数据源 - */ + /** + * @param dfs 缺省字符数据源 + */ FontSourceMulti(FontSource *dfs); virtual ~FontSourceMulti(); void Add(UnicodeBlock,FontSource *); - void Remove(UnicodeBlock); - void Remove(FontSource *); + void Remove(UnicodeBlock); + void Remove(FontSource *); - public: + public: - FontBitmap *GetCharBitmap (const u32char &ch) override; - const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 - int GetCharHeight ()const override; ///<取得字符高度 + FontBitmap *GetCharBitmap (const u32char &ch) override; + const bool GetCharMetrics (CharMetricsInfo &,const u32char &); ///<取得字符绘制信息 + int GetCharHeight ()const override; ///<取得字符高度 };//class FontSourceMulti:public FontSource - }//namespace graph + }//namespace graph }//namespace hgl #endif//HGL_GRAPH_FONT_SOURCE_INCLUDE diff --git a/inc/hgl/graph/font/TextLayout.h b/inc/hgl/graph/font/TextLayout.h index 7ad4c730..3cc0ad44 100644 --- a/inc/hgl/graph/font/TextLayout.h +++ b/inc/hgl/graph/font/TextLayout.h @@ -82,30 +82,6 @@ namespace hgl class TextLayout { - protected: - - struct CharLayoutAttributes - { - u32char ch; ///<字符 - - int size; ///<字符排版尺寸(一般为宽) - - bool visible; ///<是否可显示字符 - - bool is_cjk; ///<是否是中日韩文字 - bool is_emoji; ///<是否是表情符号 - - bool is_punctuation; ///<是否是标点符号 - - bool begin_disable; ///<是否行首禁用符号 - bool end_disable; ///<是否行尾禁用符号 - bool vrotate; ///<竖排时是否需要旋转 - - CharMetricsInfo adv_info; ///<字符绘制信息 - };//struct CharLayoutAttributes - - using CLA=CharLayoutAttributes; - protected: RenderableCreater *rc; @@ -119,14 +95,15 @@ namespace hgl float splite_line_max_limit; int max_chars; ///<总字符数量 - int draw_chars_count; ///<可绘制字符数量 - List chars_attributes; + Set alone_chars; ///<不重复字符统计缓冲区 + + List cla_list; ///<所有字符属性列表 protected: - template int preprocess(const BaseString &origin_string); - template int plane_preprocess(const BaseString &origin_string); + template int stat_chars(const T *,const int); + template int preprocess(const T *,const int); bool h_splite_to_lines(float view_limit); bool v_splite_to_lines(float view_limit); @@ -162,7 +139,6 @@ namespace hgl direction.text_direction=0; max_chars =0; - draw_chars_count =0; vertex =nullptr; tex_coord =nullptr; diff --git a/inc/hgl/graph/font/TileFont.h b/inc/hgl/graph/font/TileFont.h index 5637b233..b886b296 100644 --- a/inc/hgl/graph/font/TileFont.h +++ b/inc/hgl/graph/font/TileFont.h @@ -3,12 +3,28 @@ #include #include -#include +#include namespace hgl { namespace graph { + class TileObjectPool + { + TileData *tile_data; + + public: + + TileObject *Acquire(); + void Release(TileObject *); + + public: + + TileObjectPool(TileData *td):tile_data(td); + }; + + using TileObjectManage=_ResPoolManage; + /** * Tile字符管理
* 本模块允许有多个字符数据来源,每个来源也可以对应多个unicode块, 但一个unicode块只能对应一个字体数据来源 @@ -18,10 +34,21 @@ namespace hgl FontSource *source; TileData *tile_data; + TileObjectPool *tile_pool; + TileObjectManage *ch_tile_pool; + + public: + + FontSource *GetFontSource (){return source;} + TileData * GetTileData (){return tile_data;} + public: TileFont(TileData *td,FontSource *fs); virtual ~TileFont(); + + bool Registry(List &,const List &); ///<注册要使用的字符 + void Unregistry(const List &); ///<注销要使用的字符 };//class TileFont }//namespace graph }//namespace hgl diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h index 633877c2..733e3333 100644 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ b/inc/hgl/graph/vulkan/VKDevice.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ namespace hgl namespace graph { class TileData; + class TileFont; }//namespace graph }//namespace hgl @@ -261,7 +263,9 @@ public: RenderTarget *CreateRenderTarget(Framebuffer *); - TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集 + TileData *CreateTileData(const VkFormat video_format,const uint width,const uint height,const uint count); ///<创建一个Tile数据集 + + TileFont *CreateTileFont(const Font &f,int limit_count=-1); ///<创建一个Tile字体 };//class Device Device *CreateRenderDevice(Instance *inst,Window *win,const PhysicalDevice *physical_device=nullptr); diff --git a/res b/res index c6eafccb..8e31af94 160000 --- a/res +++ b/res @@ -1 +1 @@ -Subproject commit c6eafccb4e3db9336cbfeef610c3a7f114016213 +Subproject commit 8e31af94c83e4114673e19db2ea7593522bae16e diff --git a/src/RenderDevice/Vulkan/CMakeLists.txt b/src/RenderDevice/Vulkan/CMakeLists.txt index 79638f2e..085562d4 100644 --- a/src/RenderDevice/Vulkan/CMakeLists.txt +++ b/src/RenderDevice/Vulkan/CMakeLists.txt @@ -85,7 +85,8 @@ SET(VK_RENDERABLE_SOURCE ${RD_INCLUDE_PATH}/VKVertexAttributeBinding.h ${RD_INCLUDE_PATH}/VKRenderable.h VKVertexAttributeBinding.cpp VKRenderable.cpp - VKTileData.cpp) + VKTileData.cpp + VKTileFont.cpp) SOURCE_GROUP("Renderable" FILES ${VK_RENDERABLE_SOURCE}) diff --git a/src/RenderDevice/Vulkan/VKTileData.cpp b/src/RenderDevice/Vulkan/VKTileData.cpp index f0fcefce..24a85966 100644 --- a/src/RenderDevice/Vulkan/VKTileData.cpp +++ b/src/RenderDevice/Vulkan/VKTileData.cpp @@ -4,60 +4,60 @@ namespace { - using namespace hgl; + using namespace hgl; void AnalyseSize(uint &fw,uint &fh,const uint w,const uint h,const uint count,const uint32_t max_texture_size) - { - int total,tw,th,t; + { + int total,tw,th,t; - fw=fh=0; + fw=fh=0; - tw=max_texture_size; - while(tw>=w) - { - th=max_texture_size; - while(th>=h) - { - t=(tw/w)*(th/h); + tw=max_texture_size; + while(tw>=w) + { + th=max_texture_size; + while(th>=h) + { + t=(tw/w)*(th/h); - if(!fw) - { - fw=tw; - fh=th; + if(!fw) + { + fw=tw; + fh=th; - total=t; - } - else - { - if(t==count) - { - //正好,就要这么大的 + total=t; + } + else + { + if(t==count) + { + //正好,就要这么大的 - fw=tw; - fh=th; + fw=tw; + fh=th; - return; - } - else - if(t>count) //要比要求的最大值大 - { - if(tcount) //要比要求的最大值大 + { + if(t>=1; - } + th>>=1; + } - tw>>=1; - } - }//void AnalyseSize + tw>>=1; + } + }//void AnalyseSize }//namespace VK_NAMESPACE_BEGIN @@ -73,28 +73,28 @@ TileData *Device::CreateTileData(const VkFormat format,const uint width,const ui uint tex_width,tex_height; - AnalyseSize(tex_width,tex_height,width,height,count,max_2d_texture); + AnalyseSize(tex_width,tex_height,width,height,count,max_2d_texture); - const VulkanFormat *vf=GetVulkanFormat(format); + const VulkanFormat *vf=GetVulkanFormat(format); - if(!vf)return(nullptr); + if(!vf)return(nullptr); - Texture2D *tex=nullptr; + Texture2D *tex=nullptr; - if(vf->color>VulkanDataType::NONE - &&vf->colordepth>VulkanDataType::NONE - &&vf->depthcolor>VulkanDataType::NONE + &&vf->colordepth>VulkanDataType::NONE + &&vf->depth +#include + +namespace hgl +{ + namespace graph + { + FontSource *AcquireFontSource(const Font &f); + }//namespace graph +}//namespace hgl + +VK_NAMESPACE_BEGIN +/** + * 创建只使用一种字符的Tile字符管理对象 + * @param f 字体需求信息 + * @param limit_count 缓冲字符数量上限 + */ +TileFont *Device::CreateTileFont(const Font &f,int limit_count) +{ + int height=(f.height+3)>>2; + + height<<=2; //保证可以被4整除 + height+=2; //上下左右各空一个象素 + + if(limit_count<=0) + { + const VkExtent2D &ext=GetSwapchainSize(); + + limit_count=(ext.width/height)*(ext.height/height); //按全屏幕放满不一样的字符为上限 + } + + FontSource *fs=AcquireFontSource(f); + + if(!fs) + return(nullptr); + + TileData *td=CreateTileData(UFMT_R8,height,height,limit_count); + + if(!td) + return nullptr; + + return(new TileFont(td,fs)); +} +VK_NAMESPACE_END diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 188eedd1..1eb1597c 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -19,7 +19,12 @@ SET(SG_VAD_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribData.h ${ROOT_INCLUDE_PATH}/hgl/graph/VertexAttribDataAccess.h VertexAttribData.cpp) -SOURCE_GROUP("VertexAttribData" FILES ${SG_VAD_SOURCE}) +SOURCE_GROUP("VertexAttribData" FILES ${SG_VAD_SOURCE}) + +SET(TILE_SOURCE ${ROOT_INCLUDE_PATH}/hgl/graph/TileData.h + TileData.cpp) + +SOURCE_GROUP("Tile" FILES ${TILE_SOURCE}) SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneDB.h @@ -28,7 +33,6 @@ SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/RenderableInstance.h ${ROOT_INCLUDE_PATH}/hgl/graph/RenderList.h ${ROOT_INCLUDE_PATH}/hgl/graph/InlineGeometry.h - ${ROOT_INCLUDE_PATH}/hgl/graph/TileData.h #${ROOT_INCLUDE_PATH}/hgl/graph/Mesh.h #${ROOT_INCLUDE_PATH}/hgl/graph/Material.h #${ROOT_INCLUDE_PATH}/hgl/graph/Spline.h @@ -39,7 +43,6 @@ SET(SCENE_GRAPH_SOURCE RenderList.cpp SceneNode.cpp SceneOrient.cpp InlineGeometry.cpp - TileData.cpp #InlinePipeline.cpp #Material.cpp #Mesh.cpp @@ -90,7 +93,7 @@ add_cm_library(ULRE.SceneGraph "ULRE" ${SCENE_GRAPH_HEADER} ${SG_TEXTURE_SOURCE} ${SG_MATERIAL_HEADER} ${SG_MATERIAL_SOURCE} - + ${TILE_SOURCE} ${SG_VAD_SOURCE} ${RENDERABLE_FILES} diff --git a/src/SceneGraph/font/FontSource.cpp b/src/SceneGraph/font/FontSource.cpp index dfdc618d..826b92c2 100644 --- a/src/SceneGraph/font/FontSource.cpp +++ b/src/SceneGraph/font/FontSource.cpp @@ -19,5 +19,63 @@ namespace hgl ref_object.Delete(ptr); } + + namespace + { + constexpr u16char BeginSymbols []=U16_TEXT("!),❟.:;?]}¨·ˇˉ―‖’❜”„❞…∶、。〃々❯〉》」』】〕〗!"'),.:;?]`|}~»›"); //行首禁用符号 + constexpr u16char EndSymbols []=U16_TEXT("([{·❛‘“‟❝❮〈《「『【〔〖(.[{«‹"); //行尾禁用符号 + constexpr u16char CurrencySymbols []=U16_TEXT("₳฿₿¢₡¢₢₵₫€££₤₣ƒ₲₭Ł₥₦₽₱$$₮ℳ₶₩₩¥¥₴₸¤₰៛₪₯₠₧﷼㍐원৳₹₨৲௹"); //货币符号 + constexpr u16char VRotateSymbols []=U16_TEXT("()[]{}〈〉《》「」『』【】〔〕〖〗()[]{}―‖…∶|~"); //竖排必须旋转的符号 + + constexpr int BeginSymbolsCount =(sizeof(BeginSymbols) /sizeof(u16char))-1; + constexpr int EndSymbolsCount =(sizeof(EndSymbols) /sizeof(u16char))-1; + constexpr int CurrencySymbolsCount=(sizeof(CurrencySymbols)/sizeof(u16char))-1; + constexpr int VRotateSymbolsCount =(sizeof(VRotateSymbols) /sizeof(u16char))-1; + }//namespace + + const CLA *FontSource::GetCLA(const u32char &ch) + { + CLA *cla; + + if(cla_cache.Get(ch,cla)) + return cla; + + cla=new CLA; + + cla->ch=ch; + + if(hgl::isspace(ch)) + { + cla->visible=false; + } + else + { + cla->visible=true; + + cla->begin_disable =hgl::strchr(BeginSymbols, ch,BeginSymbolsCount ); + cla->end_disable =hgl::strchr(EndSymbols, ch,EndSymbolsCount ); + + if(!cla->end_disable) //货币符号同样行尾禁用 + cla->end_disable =hgl::strchr(CurrencySymbols, ch,CurrencySymbolsCount ); + + cla->vrotate =hgl::strchr(VRotateSymbols, ch,VRotateSymbolsCount ); + + cla->is_cjk =isCJK(ch); + cla->is_emoji =isEmoji(ch); + + cla->is_punctuation =isPunctuation(ch); + + if(!GetCharMetrics(cla->adv_info,ch)) + hgl_zero(cla->adv_info); + else + if(cla->adv_info.w>0&&cla->adv_info.h>0) + { + cla->size=ceil(cla->adv_info.adv_x); + } + } + + cla_cache.Add(ch,cla); + return cla; + } }//namespace graph }//namespace hgl diff --git a/src/SceneGraph/font/FontSourceWin.cpp b/src/SceneGraph/font/FontSourceWin.cpp index f68d0ef7..9fa675ef 100644 --- a/src/SceneGraph/font/FontSourceWin.cpp +++ b/src/SceneGraph/font/FontSourceWin.cpp @@ -139,7 +139,7 @@ namespace hgl return(true); } - FontSource *CreateFontSource(const Font &f) + FontSourceSingle *CreateFontSource(const Font &f) { return(new WinBitmapFont(f)); } diff --git a/src/SceneGraph/font/TextLayout.cpp b/src/SceneGraph/font/TextLayout.cpp index f6007cd1..085d5d43 100644 --- a/src/SceneGraph/font/TextLayout.cpp +++ b/src/SceneGraph/font/TextLayout.cpp @@ -6,27 +6,6 @@ namespace hgl { namespace graph { - namespace - { - constexpr u16char BeginSymbols []=U16_TEXT("!),❟.:;?]}¨·ˇˉ―‖’❜”„❞…∶、。〃々❯〉》」』】〕〗!"'),.:;?]`|}~»›"); //行首禁用符号 - constexpr u16char EndSymbols []=U16_TEXT("([{·❛‘“‟❝❮〈《「『【〔〖(.[{«‹"); //行尾禁用符号 - constexpr u16char CurrencySymbols []=U16_TEXT("₳฿₿¢₡¢₢₵₫€££₤₣ƒ₲₭Ł₥₦₽₱$$₮ℳ₶₩₩¥¥₴₸¤₰៛₪₯₠₧﷼㍐원৳₹₨৲௹"); //货币符号 - constexpr u16char VRotateSymbols []=U16_TEXT("()[]{}〈〉《》「」『』【】〔〕〖〗()[]{}―‖…∶|~"); //竖排必须旋转的符号 - - constexpr int BeginSymbolsCount =(sizeof(BeginSymbols) /sizeof(u16char))-1; - constexpr int EndSymbolsCount =(sizeof(EndSymbols) /sizeof(u16char))-1; - constexpr int CurrencySymbolsCount=(sizeof(CurrencySymbols)/sizeof(u16char))-1; - constexpr int VRotateSymbolsCount =(sizeof(VRotateSymbols) /sizeof(u16char))-1; - - /** - * 4舍5入处理 - */ - inline TEXT_COORD_TYPE out4in5(const double value) - { - return TEXT_COORD_TYPE(floor(value+0.5)); - } - }//namespace - bool TextLayout::Init() { if(!rc @@ -50,124 +29,60 @@ namespace hgl const float origin_char_height=tla.font_source->GetCharHeight(); x=y=0; - char_height =out4in5(origin_char_height); - space_size =out4in5(origin_char_height*tla.space_size); - full_space_size =out4in5(origin_char_height*tla.full_space_size); - tab_size =out4in5(origin_char_height*tla.tab_size); - char_gap =out4in5(origin_char_height*tla.char_gap); - line_gap =out4in5(origin_char_height*tla.line_gap); - line_height =out4in5(origin_char_height+line_gap); - paragraph_gap =out4in5(origin_char_height*tla.paragraph_gap); + char_height =ceil(origin_char_height); + space_size =ceil(origin_char_height*tla.space_size); + full_space_size =ceil(origin_char_height*tla.full_space_size); + tab_size =ceil(origin_char_height*tla.tab_size); + char_gap =ceil(origin_char_height*tla.char_gap); + line_gap =ceil(origin_char_height*tla.line_gap); + line_height =ceil(origin_char_height+line_gap); + paragraph_gap =ceil(origin_char_height*tla.paragraph_gap); return(true); } + template + int TextLayout::stat_chars(const T *str,const int str_length) + { + if(!str||!*str||str_length<=0) + return 0; + + alone_chars.ClearData(); + + for(int i=0;i - int TextLayout::preprocess(const BaseString &origin_string) + int TextLayout::preprocess(const T *str,const int str_length) { - const int count=hgl_min(max_chars,origin_string.Length()); + const int count=hgl_min(max_chars,str_length); if(count<=0) return 0; - chars_attributes.SetCount(count); - draw_chars_count=0; + cla_list.ClearData(); + cla_list.SetCount(count); - CLA *cla=chars_attributes.GetData(); - const T *cp=origin_string.c_str(); + CLA **cla=cla.GetData(); + const T *cp=str; for(int i=0;ich=*cp; - - if(hgl::isspace(*cp)) - { - cla->visible=false; - - if(*cp=='\t') cla->size=tab_size; else - if(*cp==HGL_FULL_SPACE) cla->size=full_space_size; else - cla->size=space_size; - } - else - { - cla->visible=true; cla->size=out4in5(tla.font_source->GetCharAdvWidth(*cp)); - - cla->begin_disable =hgl::strchr(BeginSymbols, *cp,BeginSymbolsCount ); - cla->end_disable =hgl::strchr(EndSymbols, *cp,EndSymbolsCount ); - - if(!cla->end_disable) //货币符号同样行尾禁用 - cla->end_disable =hgl::strchr(CurrencySymbols,*cp,CurrencySymbolsCount ); - - cla->vrotate =hgl::strchr(VRotateSymbols,*cp,VRotateSymbolsCount ); - - cla->is_cjk =isCJK(*cp); - cla->is_emoji =isEmoji(*cp); - - cla->is_punctuation =isPunctuation(*cp); - - if(!tla->font_source->GetCharMetrics(cla->adv_info,*cp)) - hgl_zero(cla->adv_info); - else - if(cla->adv_info.w>0&&cla->adv_info.h>0) - ++draw_chars_count; - } + *cla=tla->font_source.GetCLA(*cp); ++cp; ++cla; } - - return count; - } - - /** - * 简易预处理所有的字符,获取所有字符的宽高,以及是否标点符号等信息 - */ - template - int TextLayout::plane_preprocess(const BaseString &origin_string) - { - const int count=hgl_min(max_chars,origin_string.Length()); - if(count<=0) - return 0; - - chars_attributes.SetCount(count); - draw_chars_count=0; - - CLA *cla=chars_attributes.GetData(); - const T *cp=origin_string.c_str(); - - for(int i=0;ich=*cp; - - if(hgl::isspace(*cp)) - { - cla->visible=false; - - if(*cp=='\t') cla->size=tab_size; else - if(*cp==HGL_FULL_SPACE) cla->size=full_space_size; else - cla->size=space_size; - } - else - { - cla->visible=true; cla->size=out4in5(tla.font_source->GetCharAdvWidth(*cp)); - - cla->vrotate =hgl::strchr(VRotateSymbols,*cp,VRotateSymbolsCount ); - - if(!tla->font_source->GetCharMetrics(cla->adv_info,*cp)) - hgl_zero(cla->adv_info); - else - if(cla->adv_info.w>0&&cla->adv_info.h>0) - ++draw_chars_count; - } - - ++cp; - ++cla; - } - return count; } @@ -176,8 +91,8 @@ namespace hgl */ bool TextLayout::h_splite_to_lines(float view_limit) { - const int count=chars_attributes.GetCount(); - const CLA *cla=chars_attributes.GetData(); + const int count=cla_list.GetCount(); + const CLA **cla=cla_list.GetData(); int cur_size=0; @@ -232,17 +147,24 @@ namespace hgl int TextLayout::pl_h_l2r() { - const int count=chars_attributes.GetCount(); - const CLA *cla=chars_attributes.GetData(); + const int count=cla_list.GetCount(); + const CLA **cla=cla_list.GetData(); int cur_size=0; int left=0,top=0; + float *tp=vertex->Begin(); + for(int i=0;iWrite( + *tp=left; ++tp; + *tp=top; ++tp; + *tp=left+(*cla)->adv_info.w;++tp; + *tp=top +(*cla)->adv_info.h;++tp; } + vertex->End(); + return 0; } @@ -262,7 +184,10 @@ namespace hgl max_chars=hgl_min(mc,str.Length()); - if(plane_preprocess(str)<=0) + if(stat_chars(str.c_str(),str.Length())<=0) + return(-2); + + if(preprocess(str.c_str(),str.Length())<=0) return(-3); if(!rc->Init(draw_chars_count)) diff --git a/src/SceneGraph/font/TileFont.cpp b/src/SceneGraph/font/TileFont.cpp index 328a6f8c..4361789d 100644 --- a/src/SceneGraph/font/TileFont.cpp +++ b/src/SceneGraph/font/TileFont.cpp @@ -6,8 +6,14 @@ namespace hgl { namespace graph { - FontSource *AcquireFontSource(const Font &f); - + TileObject *TileObjectPool::Acquire() + { + } + + void TileObjectPool::Release(TileObject *) + { + } + TileFont::TileFont(TileData *td,FontSource *fs) { tile_data=td; @@ -17,10 +23,16 @@ namespace hgl source=fs; source->RefAcquire(this); } + + tile_pool=new TileObjectPool(tile_data); + ch_tile_pool=new TileObjectManage(tile_pool); } TileFont::~TileFont() { + delete ch_tile_pool; + delete tile_pool; + if(source) source->RefRelease(this); @@ -28,35 +40,21 @@ namespace hgl } /** - * 创建只使用一种字符的Tile字符管理对象 - * @param f 字体需求信息 - * @param limit_count 缓冲字符数量上限 + * 注册要使用的字符 + * @param rs 每个字符在纹理中的UV坐标 + * @param ch_list 要注册的字符列表 */ - TileFont *CreateTileFont(VK_NAMESPACE::Device *device,const Font &f,int limit_count=-1) + bool TileFont::Registry(List &rs,const List &ch_list) { - int height=(f.height+3)>>2; - height<<=2; //保证可以被4整除 - height+=2; //上下左右各空一个象素 + } - if(limit_count<=0) - { - const VkExtent2D &ext=device->GetSwapchainSize(); - - limit_count=(ext.width/height)*(ext.height/height); //按全屏幕放满不一样的字符为上限 - } - - FontSource *fs=AcquireFontSource(f); - - if(!fs) - return(nullptr); - - TileData *td=device->CreateTileData(UFMT_R8,height,height,limit_count); - - if(!td) - return nullptr; - - return(new TileFont(td,fs)); + /** + * 注销要使用的字符 + * @param ch_list 要注销的字符列表 + */ + void TileFont::Unregistry(const List &ch_list) + { } }//namespace graph }//namespace hgl