diff --git a/example/Vulkan/DrawText.cpp b/example/Vulkan/DrawText.cpp index 409304ed..ca0c5a1f 100644 --- a/example/Vulkan/DrawText.cpp +++ b/example/Vulkan/DrawText.cpp @@ -1,13 +1,6 @@ #include -#include -#include -#include -#include -#include - +#include #include"VulkanAppFramework.h" -#include -#include #include using namespace hgl; @@ -16,192 +9,6 @@ using namespace hgl::graph; constexpr uint32_t SCREEN_WIDTH =1280; constexpr uint32_t SCREEN_HEIGHT=SCREEN_WIDTH/16*9; -constexpr uint CHAR_BITMAP_SIZE=16; //字符尺寸 - -class TextRender -{ - GPUDevice * device =nullptr; - RenderResource * db =nullptr; - - Material * material =nullptr; - MaterialInstance * material_instance =nullptr; - - Sampler * sampler =nullptr; - - Pipeline * pipeline =nullptr; - - FontSource * eng_fs =nullptr; - FontSource * chs_fs =nullptr; - FontSourceMulti * font_source =nullptr; - - TileFont * tile_font =nullptr; - TextLayout tl_engine; ///<文本排版引擎 - - Color4f color; - GPUBuffer * ubo_color =nullptr; - -public: - - TextRender(GPUDevice *dev) - { - device=dev; - db=new RenderResource(device); - } - - ~TextRender() - { - SAFE_CLEAR(tile_font); - SAFE_CLEAR(db); - } - -private: - - bool InitTileFont() - { - Font eng_fnt(OS_TEXT("Source Code Pro"),0,CHAR_BITMAP_SIZE); - Font chs_fnt(OS_TEXT("微软雅黑"),0,CHAR_BITMAP_SIZE); - - eng_fs=AcquireFontSource(eng_fnt); - chs_fs=AcquireFontSource(chs_fnt); - - font_source=new FontSourceMulti(eng_fs); - font_source->AddCJK(chs_fs); - - tile_font=device->CreateTileFont(font_source); - return(true); - } - - bool InitTextLayoutEngine() - { - CharLayoutAttr cla; - TextLayoutAttributes tla; - - cla.CharColor=Color4f(COLOR::White); - cla.BackgroundColor=Color4f(COLOR::Black); - - tla.char_layout_attr=&cla; - tla.line_gap=0.1f; - - tl_engine.SetFont(tile_font->GetFontSource()); - tl_engine.Set(&tla); - tl_engine.SetTextDirection(0); - tl_engine.SetAlign(TextAlign::Left); - tl_engine.SetMaxWidth(0); - tl_engine.SetMaxHeight(0); - - return tl_engine.Init(); - } - - bool InitUBO() - { - color.One(); - - ubo_color=db->CreateUBO(sizeof(Color4f),&color); - - if(!ubo_color) - return(false); - - return(true); - } - - bool InitMaterial(RenderPass *rp,GPUBuffer *ubo_camera_info) - { - material=db->CreateMaterial(OS_TEXT("res/material/LumTextureRect2D")); - - //文本渲染Position坐标全部是使用整数,这里强制要求Position输入流使用RGBA16I格式 - { - VABConfigInfo vab_config; - VAConfig va_cfg; - - va_cfg.format=VF_V4I16; - va_cfg.instance=false; - - vab_config.Add("Position",va_cfg); - - material_instance=db->CreateMaterialInstance(material,&vab_config); - if(!material_instance)return(false); - } - - pipeline=rp->CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles); - if(!pipeline)return(false); - - sampler=db->CreateSampler(); - - { - MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); - - if(!mp_global) - return(false); - - if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); - - mp_global->Update(); - } - - { - MaterialParameters *mp=material_instance->GetMP(DescriptorSetsType::Value); - - if(!mp) - return(false); - - if(!mp->BindSampler("lum_texture",tile_font->GetTexture(),sampler))return(false); - if(!mp->BindUBO("color_material",ubo_color))return(false); - - mp->Update(); - } - - return(true); - } - -public: - - bool Init(RenderPass *rp,GPUBuffer *ubo_camera_info) - { - if(!InitTileFont()) - return(false); - - if(!InitTextLayoutEngine()) - return(false); - - if(!InitUBO()) - return(false); - - if(!InitMaterial(rp,ubo_camera_info)) - return(false); - - return(true); - } - - TextRenderable *CreateRenderable() - { - return db->CreateTextRenderable(material); - } - - RenderableInstance *CreateRenderableInstance(TextRenderable *text_render_obj,const UTF16String &str) - { - if(tl_engine.SimpleLayout(text_render_obj,tile_font,str)<=0) - return(nullptr); - - return db->CreateRenderableInstance(text_render_obj,material_instance,pipeline); - } -};//class TextRender - -TextRender *CreateTextRender(GPUDevice *dev,RenderPass *rp,GPUBuffer *ubo_camera_info) -{ - if(!dev||!rp||!ubo_camera_info) - return(nullptr); - - TextRender *text_render=new TextRender(dev); - - if(!text_render->Init(rp,ubo_camera_info)) - { - delete text_render; - return(nullptr); - } - - return text_render; -} - class TestApp:public VulkanApplicationFramework { Camera cam; diff --git a/inc/hgl/graph/font/TextRender.h b/inc/hgl/graph/font/TextRender.h new file mode 100644 index 00000000..8dfee41c --- /dev/null +++ b/inc/hgl/graph/font/TextRender.h @@ -0,0 +1,66 @@ +#ifndef HGL_GRAPH_TEXT_RENDER_INCLUDE +#define HGL_GRAPH_TEXT_RENDER_INCLUDE + +#include +#include + +namespace hgl +{ + namespace graph + { + class FontSource; + class FontSourceMulti; + class TileFont; + class TextLayout; + class TextRenderable; + + class TextRender + { + GPUDevice * device =nullptr; + RenderResource * db =nullptr; + + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + + Sampler * sampler =nullptr; + + Pipeline * pipeline =nullptr; + + FontSource * eng_fs =nullptr; + FontSource * chs_fs =nullptr; + FontSourceMulti * font_source =nullptr; + + TileFont * tile_font =nullptr; + TextLayout * tl_engine =nullptr; + + Color4f color; + GPUBuffer * ubo_color =nullptr; + + private: + + friend TextRender *CreateTextRender(GPUDevice *,RenderPass *,GPUBuffer *); + TextRender(GPUDevice *dev); + + public: + + ~TextRender(); + + private: + + bool InitTileFont(); + bool InitTextLayoutEngine(); + bool InitUBO(); + bool InitMaterial(RenderPass *,GPUBuffer *); + + public: + + bool Init(RenderPass *rp,GPUBuffer *ubo_camera_info); + + TextRenderable *CreateRenderable(); + RenderableInstance *CreateRenderableInstance(TextRenderable *text_render_obj,const UTF16String &str); + };//class TextRender + + TextRender *CreateTextRender(GPUDevice *,RenderPass *,GPUBuffer *); + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_TEXT_RENDER_INCLUDE diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 598aadcd..49a6ab9d 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -62,12 +62,15 @@ SET(FONT_LAYOUT_SOURCE ${SG_INCLUDE_PATH}/font/TextLayout.h font/TextLayout.cpp) SET(TEXT_RENDERABLE_SOURCE ${SG_INCLUDE_PATH}/font/TextRenderable.h + ${SG_INCLUDE_PATH}/font/TextRender.h + font/TextRender.cpp font/TextRenderable.cpp) SOURCE_GROUP("Font" FILES ${FONT_MANAGE_SOURCE}) SOURCE_GROUP("Font\\Source" FILES ${FONT_SOURCE}) SOURCE_GROUP("Font\\TileFont" FILES ${TILE_FONT_SOURCE}) -SOURCE_GROUP("Font\\Layout" FILES ${FONT_LAYOUT_SOURCE} ${TEXT_RENDERABLE_SOURCE}) +SOURCE_GROUP("Font\\Layout" FILES ${FONT_LAYOUT_SOURCE}) +SOURCE_GROUP("Font\\Render" FILES ${TEXT_RENDERABLE_SOURCE}) IF(WIN32) SET(FONT_SOURCE_OS font/FontSourceWin.cpp diff --git a/src/SceneGraph/font/TextRender.cpp b/src/SceneGraph/font/TextRender.cpp new file mode 100644 index 00000000..e4878986 --- /dev/null +++ b/src/SceneGraph/font/TextRender.cpp @@ -0,0 +1,172 @@ +#include +#include +#include +#include +#include +#include + +constexpr uint CHAR_BITMAP_SIZE=16; //字符尺寸 + +namespace hgl +{ + namespace graph + { + TextRender::TextRender(GPUDevice *dev) + { + device=dev; + db=new RenderResource(device); + tl_engine=new TextLayout(); + } + + TextRender::~TextRender() + { + SAFE_CLEAR(tl_engine); + SAFE_CLEAR(tile_font); + SAFE_CLEAR(db); + } + + bool TextRender::InitTileFont() + { + Font eng_fnt(OS_TEXT("Source Code Pro"),0,CHAR_BITMAP_SIZE); + Font chs_fnt(OS_TEXT("微软雅黑"),0,CHAR_BITMAP_SIZE); + + eng_fs=AcquireFontSource(eng_fnt); + chs_fs=AcquireFontSource(chs_fnt); + + font_source=new FontSourceMulti(eng_fs); + font_source->AddCJK(chs_fs); + + tile_font=device->CreateTileFont(font_source); + return(true); + } + + bool TextRender::InitTextLayoutEngine() + { + CharLayoutAttr cla; + TextLayoutAttributes tla; + + cla.CharColor=Color4f(COLOR::White); + cla.BackgroundColor=Color4f(COLOR::Black); + + tla.char_layout_attr=&cla; + tla.line_gap=0.1f; + + tl_engine->SetFont(tile_font->GetFontSource()); + tl_engine->Set(&tla); + tl_engine->SetTextDirection(0); + tl_engine->SetAlign(TextAlign::Left); + tl_engine->SetMaxWidth(0); + tl_engine->SetMaxHeight(0); + + return tl_engine->Init(); + } + + bool TextRender::InitUBO() + { + color.One(); + + ubo_color=db->CreateUBO(sizeof(Color4f),&color); + + if(!ubo_color) + return(false); + + return(true); + } + + bool TextRender::InitMaterial(RenderPass *rp,GPUBuffer *ubo_camera_info) + { + material=db->CreateMaterial(OS_TEXT("res/material/LumTextureRect2D")); + + //文本渲染Position坐标全部是使用整数,这里强制要求Position输入流使用RGBA16I格式 + { + VABConfigInfo vab_config; + VAConfig va_cfg; + + va_cfg.format=VF_V4I16; + va_cfg.instance=false; + + vab_config.Add("Position",va_cfg); + + material_instance=db->CreateMaterialInstance(material,&vab_config); + if(!material_instance)return(false); + } + + pipeline=rp->CreatePipeline(material_instance,InlinePipeline::Solid2D,Prim::SolidRectangles); + if(!pipeline)return(false); + + sampler=db->CreateSampler(); + + { + MaterialParameters *mp_global=material_instance->GetMP(DescriptorSetsType::Global); + + if(!mp_global) + return(false); + + if(!mp_global->BindUBO("g_camera",ubo_camera_info))return(false); + + mp_global->Update(); + } + + { + MaterialParameters *mp=material_instance->GetMP(DescriptorSetsType::Value); + + if(!mp) + return(false); + + if(!mp->BindSampler("lum_texture",tile_font->GetTexture(),sampler))return(false); + if(!mp->BindUBO("color_material",ubo_color))return(false); + + mp->Update(); + } + + return(true); + } + + bool TextRender::Init(RenderPass *rp,GPUBuffer *ubo_camera_info) + { + if(!InitTileFont()) + return(false); + + if(!InitTextLayoutEngine()) + return(false); + + if(!InitUBO()) + return(false); + + if(!InitMaterial(rp,ubo_camera_info)) + return(false); + + return(true); + } + + TextRenderable *TextRender::CreateRenderable() + { + return db->CreateTextRenderable(material); + } + + RenderableInstance *TextRender::CreateRenderableInstance(TextRenderable *text_render_obj,const UTF16String &str) + { + if(tl_engine->SimpleLayout(text_render_obj,tile_font,str)<=0) + return(nullptr); + + return db->CreateRenderableInstance(text_render_obj,material_instance,pipeline); + } + + TextRender *CreateTextRender(GPUDevice *dev,RenderPass *rp,GPUBuffer *ubo_camera_info) + { + if(!dev||!rp||!ubo_camera_info) + return(nullptr); + + TextRender *text_render=new TextRender(dev); + + if(!text_render->Init(rp,ubo_camera_info)) + { + delete text_render; + return(nullptr); + } + + return text_render; + } + }//namespace graph +}//namespace hgl +