2019-05-08 00:25:40 +08:00
|
|
|
|
#pragma once
|
2019-04-30 16:42:59 +08:00
|
|
|
|
#include<hgl/platform/Window.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKInstance.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKPhysicalDevice.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKDevice.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKBuffer.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKShaderModule.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKShaderModuleManage.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKImageView.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKRenderable.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKDescriptorSets.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKRenderPass.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKPipeline.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKCommandBuffer.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKFormat.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKFramebuffer.h>
|
|
|
|
|
#include<hgl/graph/vulkan/VKMaterial.h>
|
2019-06-11 23:14:13 +08:00
|
|
|
|
#include<hgl/graph/SceneDB.h>
|
|
|
|
|
#include<hgl/graph/RenderList.h>
|
2019-04-30 16:42:59 +08:00
|
|
|
|
|
|
|
|
|
using namespace hgl;
|
|
|
|
|
using namespace hgl::graph;
|
|
|
|
|
|
|
|
|
|
class VulkanApplicationFramework
|
|
|
|
|
{
|
2019-06-11 16:18:49 +08:00
|
|
|
|
private:
|
2019-04-30 16:42:59 +08:00
|
|
|
|
|
|
|
|
|
Window * win =nullptr;
|
|
|
|
|
vulkan::Instance * inst =nullptr;
|
|
|
|
|
|
2019-06-14 17:13:30 +08:00
|
|
|
|
void OnResize(int w,int h)
|
|
|
|
|
{
|
|
|
|
|
InitCommandBuffer();
|
|
|
|
|
Resize(w,h);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 19:56:21 +08:00
|
|
|
|
void OnKeyDown (KeyboardButton kb){key_status[kb]=true;}
|
|
|
|
|
void OnKeyUp (KeyboardButton kb){key_status[kb]=false;}
|
|
|
|
|
void OnKeyPress (KeyboardButton kb){KeyPress(kb);}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
uint mouse_key=0;
|
|
|
|
|
Vector2f mouse_pos;
|
|
|
|
|
|
|
|
|
|
void OnMouseDown(int,int,uint mk){mouse_key=mk;MouseDown(mk);}
|
|
|
|
|
void OnMouseUp (int,int,uint mk){mouse_key=0;MouseUp(mk);}
|
|
|
|
|
void OnMouseMove(int x,int y){mouse_pos.Set(x,y);MouseMove();}
|
2019-06-14 17:13:30 +08:00
|
|
|
|
|
2019-04-30 16:42:59 +08:00
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
vulkan::Device * device =nullptr;
|
|
|
|
|
vulkan::ShaderModuleManage *shader_manage =nullptr;
|
|
|
|
|
|
2019-06-11 23:14:13 +08:00
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
uint32_t swap_chain_count=0;
|
|
|
|
|
|
|
|
|
|
vulkan::CommandBuffer ** cmd_buf =nullptr;
|
2019-06-14 17:13:30 +08:00
|
|
|
|
|
2019-06-11 23:14:13 +08:00
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
SceneDB * db =nullptr;
|
|
|
|
|
|
2019-06-14 17:13:30 +08:00
|
|
|
|
bool key_status[kbRangeSize];
|
|
|
|
|
|
2019-04-30 16:42:59 +08:00
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
virtual ~VulkanApplicationFramework()
|
2019-06-11 23:14:13 +08:00
|
|
|
|
{
|
|
|
|
|
SAFE_CLEAR(db);
|
|
|
|
|
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
|
|
|
|
|
|
2019-04-30 16:42:59 +08:00
|
|
|
|
SAFE_CLEAR(shader_manage);
|
2019-05-08 00:25:40 +08:00
|
|
|
|
SAFE_CLEAR(win); //win中会删除device,所以必须放在instance前删除
|
2019-04-30 16:42:59 +08:00
|
|
|
|
SAFE_CLEAR(inst);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 17:13:30 +08:00
|
|
|
|
virtual bool Init(int w,int h)
|
2019-04-30 16:42:59 +08:00
|
|
|
|
{
|
2019-06-14 17:13:30 +08:00
|
|
|
|
hgl_zero(key_status);
|
|
|
|
|
|
2019-05-06 11:41:05 +08:00
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
if(!vulkan::CheckStrideBytesByFormat())
|
|
|
|
|
return(false);
|
|
|
|
|
#endif//
|
|
|
|
|
|
2019-04-30 19:01:44 +08:00
|
|
|
|
InitNativeWindowSystem();
|
|
|
|
|
|
2019-04-30 16:42:59 +08:00
|
|
|
|
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);
|
|
|
|
|
|
2019-05-07 12:46:25 +08:00
|
|
|
|
device=win->CreateRenderDevice(inst);
|
2019-04-30 16:42:59 +08:00
|
|
|
|
|
|
|
|
|
if(!device)
|
|
|
|
|
return(false);
|
|
|
|
|
|
|
|
|
|
shader_manage=device->CreateShaderModuleManage();
|
2019-06-13 20:36:12 +08:00
|
|
|
|
db=new SceneDB(device);
|
|
|
|
|
|
|
|
|
|
InitCommandBuffer();
|
|
|
|
|
|
2019-06-14 17:13:30 +08:00
|
|
|
|
SetEventCall(win->OnResize, this,VulkanApplicationFramework,OnResize );
|
|
|
|
|
SetEventCall(win->OnKeyDown, this,VulkanApplicationFramework,OnKeyDown );
|
|
|
|
|
SetEventCall(win->OnKeyUp, this,VulkanApplicationFramework,OnKeyUp );
|
|
|
|
|
SetEventCall(win->OnKeyPress, this,VulkanApplicationFramework,OnKeyPress );
|
2019-06-13 23:12:11 +08:00
|
|
|
|
|
2019-06-14 19:56:21 +08:00
|
|
|
|
SetEventCall(win->OnMouseDown, this,VulkanApplicationFramework,OnMouseDown );
|
|
|
|
|
SetEventCall(win->OnMouseUp, this,VulkanApplicationFramework,OnMouseUp );
|
|
|
|
|
SetEventCall(win->OnMouseMove, this,VulkanApplicationFramework,OnMouseMove );
|
|
|
|
|
|
2019-06-13 20:36:12 +08:00
|
|
|
|
return(true);
|
|
|
|
|
}
|
2019-06-11 23:14:13 +08:00
|
|
|
|
|
2019-06-13 23:12:11 +08:00
|
|
|
|
virtual void Resize(int,int)=0;
|
2019-06-14 17:13:30 +08:00
|
|
|
|
virtual void KeyPress(KeyboardButton){}
|
2019-06-14 19:56:21 +08:00
|
|
|
|
virtual void MouseDown(uint){}
|
|
|
|
|
virtual void MouseUp(uint){}
|
|
|
|
|
virtual void MouseMove(){}
|
2019-06-13 23:12:11 +08:00
|
|
|
|
|
2019-06-13 20:36:12 +08:00
|
|
|
|
void InitCommandBuffer()
|
|
|
|
|
{
|
|
|
|
|
if(cmd_buf)
|
2019-06-11 23:14:13 +08:00
|
|
|
|
{
|
2019-06-13 20:36:12 +08:00
|
|
|
|
for(uint i=0;i<swap_chain_count;i++)
|
|
|
|
|
delete cmd_buf[i];
|
2019-06-11 23:14:13 +08:00
|
|
|
|
|
2019-06-13 20:36:12 +08:00
|
|
|
|
delete[] cmd_buf;
|
2019-06-11 23:14:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-13 20:36:12 +08:00
|
|
|
|
swap_chain_count=device->GetSwapChainImageCount();
|
|
|
|
|
{
|
|
|
|
|
cmd_buf=hgl_zero_new<vulkan::CommandBuffer *>(swap_chain_count);
|
2019-06-11 23:14:13 +08:00
|
|
|
|
|
2019-06-13 20:36:12 +08:00
|
|
|
|
for(uint i=0;i<swap_chain_count;i++)
|
|
|
|
|
cmd_buf[i]=device->CreateCommandBuffer();
|
|
|
|
|
}
|
2019-04-30 16:42:59 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 23:14:13 +08:00
|
|
|
|
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;i<swap_chain_count;i++)
|
|
|
|
|
{
|
|
|
|
|
cmd_buf[i]->Begin();
|
|
|
|
|
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;i<swap_chain_count;i++)
|
|
|
|
|
{
|
|
|
|
|
cmd_buf[i]->Begin();
|
|
|
|
|
cmd_buf[i]->BeginRenderPass(device->GetRenderPass(),device->GetFramebuffer(i));
|
|
|
|
|
rl->Render(cmd_buf[i]);
|
|
|
|
|
cmd_buf[i]->EndRenderPass();
|
|
|
|
|
cmd_buf[i]->End();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
2019-04-30 16:42:59 +08:00
|
|
|
|
void AcquireNextFrame()
|
|
|
|
|
{
|
|
|
|
|
device->AcquireNextImage();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-05 11:54:49 +08:00
|
|
|
|
void Submit(const VkCommandBuffer cmd_buf)
|
2019-04-30 16:42:59 +08:00
|
|
|
|
{
|
2019-05-20 13:50:11 +08:00
|
|
|
|
device->SubmitDraw(&cmd_buf);
|
2019-04-30 16:42:59 +08:00
|
|
|
|
device->Wait();
|
|
|
|
|
device->QueuePresent();
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 23:14:13 +08:00
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
virtual void Draw()
|
|
|
|
|
{
|
|
|
|
|
const vulkan::CommandBuffer *cb=cmd_buf[device->GetCurrentFrameIndices()];
|
|
|
|
|
|
|
|
|
|
Submit(*cb);
|
|
|
|
|
}
|
2019-05-04 16:52:44 +08:00
|
|
|
|
|
2019-04-30 19:01:44 +08:00
|
|
|
|
bool Run()
|
2019-04-30 16:42:59 +08:00
|
|
|
|
{
|
2019-05-04 16:52:44 +08:00
|
|
|
|
if(!win->Update())return(false);
|
|
|
|
|
|
|
|
|
|
if(win->IsVisible())
|
|
|
|
|
{
|
|
|
|
|
AcquireNextFrame();
|
|
|
|
|
Draw();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(true);
|
2019-04-30 16:42:59 +08:00
|
|
|
|
}
|
|
|
|
|
};//class VulkanApplicationFramework
|
2019-06-14 17:13:30 +08:00
|
|
|
|
|
|
|
|
|
class WalkerCameraAppFramework:public VulkanApplicationFramework
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
vulkan::Buffer * ubo_world_matrix =nullptr;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
WalkerCamera camera;
|
2019-06-14 17:28:40 +08:00
|
|
|
|
float move_speed=1;
|
2019-06-14 17:13:30 +08:00
|
|
|
|
|
2019-06-14 19:56:21 +08:00
|
|
|
|
Vector2f mouse_last_pos;
|
|
|
|
|
|
2019-06-14 17:13:30 +08:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 20:01:46 +08:00
|
|
|
|
virtual void Draw()override
|
2019-06-14 17:13:30 +08:00
|
|
|
|
{
|
|
|
|
|
camera.Refresh(); //更新相机矩阵
|
|
|
|
|
ubo_world_matrix->Write(&camera.matrix); //写入缓冲区
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
2019-06-14 17:28:40 +08:00
|
|
|
|
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
|
2019-06-14 17:13:30 +08:00
|
|
|
|
|
2019-06-14 19:41:14 +08:00
|
|
|
|
if(key_status[kbHome ])camera.ForwardRotate (move_speed);else
|
|
|
|
|
if(key_status[kbEnd ])camera.BackwardRotate (move_speed);else
|
2019-06-14 17:28:40 +08:00
|
|
|
|
if(key_status[kbDelete ])camera.LeftRotate (move_speed);else
|
|
|
|
|
if(key_status[kbPageDown])camera.RightRotate (move_speed);else
|
2019-06-14 17:13:30 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-14 19:56:21 +08:00
|
|
|
|
virtual void KeyPress(KeyboardButton kb)override
|
2019-06-14 17:13:30 +08:00
|
|
|
|
{
|
2019-06-14 17:28:40 +08:00
|
|
|
|
if(kb==kbMinus)move_speed*=0.9f;else
|
|
|
|
|
if(kb==kbEquals)move_speed*=1.1f;else
|
2019-06-14 17:13:30 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
2019-06-14 19:56:21 +08:00
|
|
|
|
|
|
|
|
|
virtual void MouseDown(uint) override
|
|
|
|
|
{
|
|
|
|
|
mouse_last_pos=mouse_pos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void MouseMove() override
|
|
|
|
|
{
|
|
|
|
|
if(!(mouse_key&mbLeft))return;
|
|
|
|
|
|
|
|
|
|
Vector2f gap=mouse_pos-mouse_last_pos;
|
|
|
|
|
|
|
|
|
|
bool update=false;
|
|
|
|
|
if(gap.x!=0){update=true;camera.LeftRotate(gap.x);}
|
|
|
|
|
if(gap.y!=0){update=true;camera.ForwardRotate(gap.y);}
|
|
|
|
|
|
|
|
|
|
mouse_last_pos=mouse_pos;
|
|
|
|
|
}
|
2019-06-14 17:13:30 +08:00
|
|
|
|
};//class WalkerCameraAppFramework
|