// DrawTile // 该示例使用TileData,演示多个tile图片在一张纹理上 #include #include #include #include"VulkanAppFramework.h" #include #include #include using namespace hgl; using namespace hgl::graph; constexpr uint32_t SCREEN_WIDTH =1024; constexpr uint32_t SCREEN_HEIGHT=512; constexpr float BORDER=2; struct TileBitmap { BitmapData *bmp; TileObject *to; }; class TestApp:public VulkanApplicationFramework { Camera cam; ObjectList tile_list; TileData *tile_data; float *vertex_data=nullptr; float *tex_coord_data=nullptr; private: vulkan::Material * material =nullptr; vulkan::Sampler * sampler =nullptr; vulkan::MaterialInstance * material_instance =nullptr; vulkan::Renderable * render_obj =nullptr; vulkan::Buffer * ubo_world_matrix =nullptr; vulkan::Pipeline * pipeline =nullptr; vulkan::VertexAttribBuffer *vertex_buffer =nullptr; vulkan::VertexAttribBuffer *tex_coord_buffer =nullptr; public: ~TestApp() { SAFE_CLEAR_ARRAY(vertex_data); SAFE_CLEAR_ARRAY(tex_coord_data); SAFE_CLEAR(tile_data); } private: int LoadIcons() { const OSString icon_path=OS_TEXT("res/image/icon/freepik/"); UTF8StringList sl; const int count=LoadStringListFromTextFile(sl,icon_path+OS_TEXT("list.txt")); Bitmap2DLoader loader; int result=0; for(int i=0;ibmp =loader.GetBitmap(); tb->to =nullptr; tile_list.Add(tb); ++result; } } return result; } bool InitTileTexture() { tile_data=device->CreateTileData(FMT_A1RGB5,512,512,tile_list.GetCount()); if(!tile_data) return(false); const int count=tile_list.GetCount(); TileBitmap **tb=tile_list.GetData(); vertex_data=new float[count*4]; tex_coord_data=new float[count*4]; float *vp=vertex_data; float *tp=tex_coord_data; int col=0; int row=0; float size=SCREEN_WIDTH/10; for(int i=0;ito=tile_data->Add((*tb)->bmp); *vp++=float(col)*size+BORDER; *vp++=float(row)*size+BORDER; *vp++=float(col+1)*size-BORDER*2; *vp++=float(row+1)*size-BORDER*2; *tp++=(*tb)->to->uv_float.GetLeft(); *tp++=(*tb)->to->uv_float.GetTop(); *tp++=(*tb)->to->uv_float.GetRight(); *tp++=(*tb)->to->uv_float.GetBottom(); ++col; if(col==10) { ++row; col=0; } ++tb; } return(true); } bool InitMaterial() { material=shader_manage->CreateMaterial( OS_TEXT("res/shader/DrawRect2D.vert"), OS_TEXT("res/shader/DrawRect2D.geom"), OS_TEXT("res/shader/FlatTexture.frag")); if(!material) return(false); material_instance=material->CreateInstance(); sampler=db->CreateSampler(); 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); return(true); } bool InitUBO() { const VkExtent2D extent=sc_render_target->GetExtent(); cam.width=extent.width; cam.height=extent.height; cam.Refresh(); ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&cam.matrix); if(!ubo_world_matrix) return(false); return(true); } void InitVBO() { 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() { AutoDelete pipeline_creater=new vulkan::PipelineCreater(device,material,sc_render_target); pipeline_creater->CloseCullFace(); pipeline_creater->Set(PRIM_2D_RECTANGLES); pipeline=pipeline_creater->Create(); db->Add(pipeline); return pipeline; } public: bool Init() { if(LoadIcons()<=0) return(false); if(!VulkanApplicationFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) return(false); if(!InitTileTexture()) return(false); if(!InitUBO()) return(false); if(!InitMaterial()) return(false); InitVBO(); if(!InitPipeline()) return(false); BuildCommandBuffer(pipeline,material_instance,render_obj); return(true); } void Resize(int w,int h)override { cam.width=w; cam.height=h; cam.Refresh(); ubo_world_matrix->Write(&cam.matrix); BuildCommandBuffer(pipeline,material_instance,render_obj); } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { TestApp app; if(!app.Init()) return(-1); while(app.Run()); return 0; }