// 画一个带纹理的矩形,2D模式专用 #include"VulkanAppFramework.h" #include #include #include #include #include #include #include using namespace hgl; using namespace hgl::graph; VK_NAMESPACE_BEGIN //Texture2D *CreateTexture2DFromFile(VulkanDevice *device,const OSString &filename); VK_NAMESPACE_END constexpr uint32_t SCREEN_WIDTH=256; constexpr uint32_t SCREEN_HEIGHT=256; float position_data[4]= { 0, //left 0, //top 1, //right 1 //bottom }; constexpr float tex_coord_data[4]= { 0,0, 1,1 }; constexpr const os_char *tex_filename[]= { OS_TEXT("001-online resume.Tex2D"), OS_TEXT("002-salary.Tex2D"), OS_TEXT("003-application.Tex2D"), OS_TEXT("004-job interview.Tex2D") }; constexpr const size_t TexCount=sizeof(tex_filename)/sizeof(os_char *); class TestApp:public VulkanApplicationFramework { private: SceneNode render_root; RenderList * render_list =nullptr; Texture2DArray * texture =nullptr; Sampler * sampler =nullptr; Material * material =nullptr; Pipeline * pipeline =nullptr; DeviceBuffer * tex_id_ubo =nullptr; Primitive * prim_rectangle =nullptr; struct { MaterialInstance * mi; Mesh * mesh; }render_obj[TexCount]{}; private: bool InitTexture() { texture=db->CreateTexture2DArray( "freepik icons", 512,512, ///<纹理尺寸 TexCount, ///<纹理层数 PF_BC1_RGBAUN, ///<纹理格式 false); ///<是否自动产生mipmaps if(!texture)return(false); OSString filename; for(uint i=0;iLoadTexture2DToArray(texture,i,filename)) return(false); } return(true); } bool InitMaterial() { mtl::Material2DCreateConfig cfg(device->GetDevAttr(),"RectTexture2DArray",PrimitiveType::SolidRectangles); cfg.coordinate_system=CoordinateSystem2D::ZeroToOne; cfg.local_to_world=true; material=db->LoadMaterial("Std2D/RectTexture2DArray",&cfg); if(!material) return(false); pipeline=CreatePipeline(material,InlinePipeline::Solid2D,PrimitiveType::SolidRectangles); //等同上一行,为Framework重载,默认使用swapchain的render target if(!pipeline) return(false); sampler=db->CreateSampler(); if(!material->BindImageSampler( DescriptorSetType::PerMaterial, ///<描述符合集 mtl::SamplerName::BaseColor, ///<采样器名称 texture, ///<纹理 sampler)) ///<采样器 return(false); for(uint32_t i=0;iCreateMaterialInstance(material); if(!render_obj[i].mi) return(false); render_obj[i].mi->WriteMIData(i); //设置MaterialInstance的数据 } return(true); } bool InitVBOAndRenderList() { PrimitiveCreater rpc(device,material->GetDefaultVIL()); rpc.Init("Rectangle",1); position_data[2]=1.0f/float(TexCount); if(!rpc.WriteVAB(VAN::Position,VF_V4F,position_data))return(false); if(!rpc.WriteVAB(VAN::TexCoord,VF_V4F,tex_coord_data))return(false); prim_rectangle=rpc.Create(); Vector3f offset(1.0f/float(TexCount),0,0); for(uint32_t i=0;iCreateMesh(prim_rectangle,render_obj[i].mi,pipeline); if(!render_obj[i].mesh) return(false); offset.x=position_data[2]*float(i); render_root.CreateSubNode(translate(offset),render_obj[i].mesh); } render_root.RefreshMatrix(); render_list->Expend(&render_root); return(true); } public: ~TestApp() { SAFE_CLEAR(prim_rectangle); SAFE_CLEAR(render_list); } bool Init() { if(!VulkanApplicationFramework::Init(SCREEN_WIDTH*TexCount,SCREEN_HEIGHT)) return(false); render_list=new RenderList(device); if(!InitTexture()) return(false); if(!InitMaterial()) return(false); if(!InitVBOAndRenderList()) return(false); BuildCommandBuffer(render_list); return(true); } void Resize(uint w,uint h)override { VulkanApplicationFramework::Resize(w,h); BuildCommandBuffer(render_list); } };//class TestApp:public VulkanApplicationFramework int main(int,char **) { #ifdef _DEBUG if(!CheckStrideBytesByFormat()) return 0xff; #endif// TestApp app; if(!app.Init()) return(-1); while(app.Run()); return 0; }