#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace hgl; using namespace hgl::graph; class VulkanApplicationFramework { private: Window * win =nullptr; vulkan::Instance * inst =nullptr; void OnResize(int w,int h) { InitCommandBuffer(); Resize(w,h); } void OnKeyDown(KeyboardButton kb){key_status[kb]=true;} void OnKeyUp(KeyboardButton kb){key_status[kb]=false;} void OnKeyPress(KeyboardButton kb){KeyPress(kb);} protected: vulkan::Device * device =nullptr; vulkan::ShaderModuleManage *shader_manage =nullptr; private: uint32_t swap_chain_count=0; vulkan::CommandBuffer ** cmd_buf =nullptr; protected: SceneDB * db =nullptr; bool key_status[kbRangeSize]; public: virtual ~VulkanApplicationFramework() { SAFE_CLEAR(db); SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count); SAFE_CLEAR(shader_manage); SAFE_CLEAR(win); //win中会删除device,所以必须放在instance前删除 SAFE_CLEAR(inst); } virtual bool Init(int w,int h) { hgl_zero(key_status); #ifdef _DEBUG if(!vulkan::CheckStrideBytesByFormat()) return(false); #endif// InitNativeWindowSystem(); win=CreateRenderWindow(OS_TEXT("VulkanTest")); if(!win) return(false); if(!win->Create(w,h)) return(false); inst=vulkan::CreateInstance(U8_TEXT("VulkanTest")); if(!inst) return(false); device=win->CreateRenderDevice(inst); if(!device) return(false); shader_manage=device->CreateShaderModuleManage(); db=new SceneDB(device); InitCommandBuffer(); SetEventCall(win->OnResize, this,VulkanApplicationFramework,OnResize ); SetEventCall(win->OnKeyDown, this,VulkanApplicationFramework,OnKeyDown ); SetEventCall(win->OnKeyUp, this,VulkanApplicationFramework,OnKeyUp ); SetEventCall(win->OnKeyPress, this,VulkanApplicationFramework,OnKeyPress ); return(true); } virtual void Resize(int,int)=0; virtual void KeyPress(KeyboardButton){} void InitCommandBuffer() { if(cmd_buf) { for(uint i=0;iGetSwapChainImageCount(); { cmd_buf=hgl_zero_new(swap_chain_count); for(uint i=0;iCreateCommandBuffer(); } } void BuildCommandBuffer(vulkan::Pipeline *p,vulkan::DescriptorSets *ds,vulkan::Renderable *r) { if(!p||!ds||!r) return; const vulkan::IndexBuffer *ib=r->GetIndexBuffer(); for(uint i=0;iBegin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); cmd_buf[i]->Bind(p); cmd_buf[i]->Bind(ds); cmd_buf[i]->Bind(r); if (ib) cmd_buf[i]->DrawIndexed(ib->GetCount()); else cmd_buf[i]->Draw(r->GetDrawCount()); cmd_buf[i]->EndRenderPass(); cmd_buf[i]->End(); } } void BuildCommandBuffer(RenderList *rl) { if(!rl)return; for(uint i=0;iBegin(); cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i)); rl->Render(cmd_buf[i]); cmd_buf[i]->EndRenderPass(); cmd_buf[i]->End(); } } private: void AcquireNextFrame() { device->AcquireNextImage(); } void Submit(const VkCommandBuffer cmd_buf) { device->SubmitDraw(&cmd_buf); device->Wait(); device->QueuePresent(); } public: virtual void Draw() { const vulkan::CommandBuffer *cb=cmd_buf[device->GetCurrentFrameIndices()]; Submit(*cb); } bool Run() { if(!win->Update())return(false); if(win->IsVisible()) { AcquireNextFrame(); Draw(); } return(true); } };//class VulkanApplicationFramework class WalkerCameraAppFramework:public VulkanApplicationFramework { private: vulkan::Buffer * ubo_world_matrix =nullptr; protected: WalkerCamera camera; float move_speed=1; public: virtual ~WalkerCameraAppFramework()=default; virtual bool Init(int w,int h) { if(!VulkanApplicationFramework::Init(w,h)) return(false); InitCamera(); return(true); } virtual void InitCamera() { camera.type=CameraType::Perspective; camera.center.Set(0,0,0,1); camera.eye.Set(100,100,100,1); camera.Refresh(); //更新矩阵计算 } bool InitCameraUBO(vulkan::DescriptorSets *desc_set,uint world_matrix_bindpoint) { InitCamera(); const VkExtent2D extent=device->GetExtent(); camera.width=extent.width; camera.height=extent.height; ubo_world_matrix=db->CreateUBO(sizeof(WorldMatrix),&camera.matrix); if(!ubo_world_matrix) return(false); return desc_set->BindUBO(world_matrix_bindpoint,*ubo_world_matrix); } void RefreshCameraUBO() { camera.Refresh(); //更新相机矩阵 ubo_world_matrix->Write(&camera.matrix); //写入缓冲区 } void Draw()override { VulkanApplicationFramework::Draw(); if(key_status[kbW])camera.Forward (move_speed);else if(key_status[kbS])camera.Backward (move_speed);else if(key_status[kbA])camera.Left (move_speed);else if(key_status[kbD])camera.Right (move_speed);else if(key_status[kbLeft ])camera.WrapLeftRotate (move_speed);else if(key_status[kbRight ])camera.WrapRightRotate(move_speed);else if(key_status[kbUp ])camera.WrapUpRotate (move_speed);else if(key_status[kbDown ])camera.WrapDownRotate (move_speed);else if(key_status[kbHome ])camera.ForwardRotate (move_speed);else if(key_status[kbEnd ])camera.BackwardRotate (move_speed);else if(key_status[kbDelete ])camera.LeftRotate (move_speed);else if(key_status[kbPageDown])camera.RightRotate (move_speed);else return; RefreshCameraUBO(); } void KeyPress(KeyboardButton kb)override { if(kb==kbMinus)move_speed*=0.9f;else if(kb==kbEquals)move_speed*=1.1f;else return; RefreshCameraUBO(); } };//class WalkerCameraAppFramework