ULRE/example/common/VulkanAppFramework.h

535 lines
12 KiB
C
Raw Normal View History

2019-05-08 00:25:40 +08:00
#pragma once
#include<hgl/platform/Window.h>
#include<hgl/graph/VKInstance.h>
#include<hgl/graph/VKPhysicalDevice.h>
2023-05-11 21:17:06 +08:00
#include<hgl/graph/VKDeviceCreater.h>
#include<hgl/graph/VKSemaphore.h>
#include<hgl/graph/VKBuffer.h>
#include<hgl/graph/VKShaderModule.h>
#include<hgl/graph/VKImageView.h>
2022-06-24 17:51:05 +08:00
#include<hgl/graph/VKPrimitive.h>
#include<hgl/graph/VKDescriptorSet.h>
#include<hgl/graph/VKRenderPass.h>
#include<hgl/graph/VKPipeline.h>
#include<hgl/graph/VKCommandBuffer.h>
#include<hgl/graph/VKFormat.h>
#include<hgl/graph/VKFramebuffer.h>
#include<hgl/graph/VKMaterial.h>
#include<hgl/graph/VKMaterialParameters.h>
2021-06-16 20:29:25 +08:00
#include<hgl/graph/VKMaterialInstance.h>
#include<hgl/graph/VKRenderTarget.h>
2020-10-21 12:39:22 +08:00
#include<hgl/graph/VKRenderResource.h>
2023-05-07 01:07:26 +08:00
#include<hgl/graph/RenderList.h>
#include<hgl/graph/mtl/UBOCommon.h>
#include<hgl/color/Color.h>
2022-01-24 19:36:54 +08:00
#include<hgl/Time.h>
2023-07-28 20:17:46 +08:00
#include<hgl/log/LogInfo.h>
2022-01-24 19:36:54 +08:00
//#include<hgl/graph/LookAtCameraControl.h>
#include<hgl/graph/FirstPersonCameraControl.h>
2022-01-24 19:36:54 +08:00
#include<hgl/io/event/KeyboardEvent.h>
#include<hgl/io/event/MouseEvent.h>
using namespace hgl;
2022-01-24 19:36:54 +08:00
using namespace hgl::io;
using namespace hgl::graph;
2023-03-21 18:05:48 +08:00
namespace hgl{namespace graph
{
2023-03-21 18:05:48 +08:00
bool InitShaderCompiler();
void CloseShaderCompiler();
}}//namespace hgl::graph
2022-01-24 19:36:54 +08:00
class VulkanApplicationFramework:WindowEvent
{
2022-01-24 19:36:54 +08:00
protected:
2020-10-21 12:47:06 +08:00
Window * win =nullptr;
VulkanInstance * inst =nullptr;
protected:
2020-10-21 12:52:32 +08:00
GPUDevice * device =nullptr;
RenderPass * device_render_pass =nullptr;
2020-10-21 12:47:06 +08:00
SwapchainRenderTarget * sc_render_target =nullptr;
2020-01-23 21:00:35 +08:00
2019-07-17 04:49:16 +08:00
protected:
2020-10-21 12:52:32 +08:00
int32_t swap_chain_count =0;
RenderCmdBuffer ** cmd_buf =nullptr;
2020-10-21 12:52:32 +08:00
Color4f clear_color;
protected:
2020-10-21 12:52:32 +08:00
RenderResource * db =nullptr;
protected:
ViewportInfo vp_info;
DeviceBuffer * ubo_vp_info =nullptr;
public:
virtual ~VulkanApplicationFramework()
{
2023-03-21 18:05:48 +08:00
CloseShaderCompiler();
2022-01-24 19:36:54 +08:00
win->Unjoin(this);
SAFE_CLEAR(db);
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
SAFE_CLEAR(device);
2020-01-23 21:00:35 +08:00
SAFE_CLEAR(win);
SAFE_CLEAR(inst);
}
virtual bool Init(int w,int h)
{
logger::InitLogger(OS_TEXT("VulkanTest"));
2023-03-21 18:05:48 +08:00
if(!InitShaderCompiler())
return(false);
clear_color.Set(0,0,0,1);
#ifdef _DEBUG
2020-10-21 12:47:06 +08:00
if(!CheckStrideBytesByFormat())
return(false);
#endif//
2019-04-30 19:01:44 +08:00
InitNativeWindowSystem();
2020-10-28 17:28:07 +08:00
InitVulkanInstanceProperties();
2019-11-14 17:57:46 +08:00
win=CreateRenderWindow(OS_TEXT("VulkanTest"));
if(!win)
return(false);
if(!win->Create(w,h))
return(false);
2019-11-14 17:57:46 +08:00
{
2020-10-21 12:52:32 +08:00
CreateInstanceLayerInfo cili;
2020-09-28 11:16:45 +08:00
hgl_zero(cili);
2019-11-14 17:57:46 +08:00
cili.lunarg.standard_validation = true;
cili.khronos.validation = true;
2020-10-21 12:47:06 +08:00
inst=CreateInstance("VulkanTest",nullptr,&cili);
2019-11-14 17:57:46 +08:00
if(!inst)
return(false);
}
device=CreateRenderDevice(inst,win);
if(!device)
return(false);
device_render_pass=device->GetRenderPass();
2020-10-21 12:47:06 +08:00
db=new RenderResource(device);
InitCommandBuffer();
2022-01-24 19:36:54 +08:00
win->Join(this);
2019-06-14 19:56:21 +08:00
{
vp_info.Set(w,h);
ubo_vp_info=db->CreateUBO(sizeof(ViewportInfo),&vp_info);
db->global_descriptor.AddUBO(mtl::SBS_ViewportInfo.name,ubo_vp_info);
}
return(true);
}
virtual void Resize(int w,int h)
{
vp_info.Set(w,h);
ubo_vp_info->Write(&vp_info);
}
2020-01-23 21:00:35 +08:00
2022-03-11 17:38:21 +08:00
void SetClearColor(const Color4f &cc)
{
2022-03-11 17:38:21 +08:00
clear_color=cc;
}
2022-03-11 17:58:53 +08:00
void SetClearColor(const enum class COLOR &ce)
{
clear_color=GetColor4f(ce,1.0f);
}
2022-01-24 19:36:54 +08:00
void OnResize(uint w,uint h) override
2019-07-17 04:49:16 +08:00
{
if(w>0&&h>0)
device->Resize(w,h);
2019-07-17 04:49:16 +08:00
InitCommandBuffer();
Resize(w,h);
}
void InitCommandBuffer()
{
if(cmd_buf)
2019-06-28 20:46:32 +08:00
SAFE_CLEAR_OBJECT_ARRAY(cmd_buf,swap_chain_count);
2020-01-23 21:00:35 +08:00
2019-07-17 04:49:16 +08:00
sc_render_target=device->GetSwapchainRT();
swap_chain_count=sc_render_target->GetImageCount();
{
const VkExtent2D extent=sc_render_target->GetExtent();
cmd_buf=hgl_zero_new<RenderCmdBuffer *>(swap_chain_count);
for(int32_t i=0;i<swap_chain_count;i++)
cmd_buf[i]=device->CreateRenderCommandBuffer();
}
}
bool BuildCommandBuffer(RenderCmdBuffer *cb,RenderPass *rp,Framebuffer *fb,Renderable *ri)
{
if(!ri)return(false);
const VertexInputData *vid=ri->GetVertexInputData();
cb->Begin();
cb->BindFramebuffer(rp,fb);
cb->SetClearColor(0,clear_color);
cb->BeginRenderPass();
cb->BindPipeline(ri->GetPipeline());
2021-06-16 20:29:25 +08:00
cb->BindDescriptorSets(ri);
2021-12-15 14:24:35 +08:00
cb->BindVBO(ri);
if (vid->index_buffer->buffer)
cb->DrawIndexed(vid->index_buffer->buffer->GetCount());
else
cb->Draw(vid->vertex_count);
cb->EndRenderPass();
cb->End();
return(true);
}
void BuildCommandBuffer(RenderCmdBuffer *cb,RenderTarget *rt,Renderable *ri)
{
if(!cb||!rt||!ri)
return;
BuildCommandBuffer(cb,rt->GetRenderPass(),rt->GetFramebuffer(),ri);
}
bool BuildCommandBuffer(uint32_t index,Renderable *ri)
2020-10-24 19:11:54 +08:00
{
if(!ri)return(false);
return BuildCommandBuffer(cmd_buf[index],sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index),ri);
2019-06-18 00:48:05 +08:00
}
2020-01-23 21:00:35 +08:00
bool BuildCommandBuffer(Renderable *ri)
2019-06-18 00:48:05 +08:00
{
2020-10-24 19:11:54 +08:00
if(!ri)return(false);
for(int32_t i=0;i<swap_chain_count;i++)
BuildCommandBuffer(i,ri);
2020-10-24 19:11:54 +08:00
return(true);
}
bool BuildCurrentCommandBuffer(Renderable *ri)
{
2020-10-24 19:11:54 +08:00
if(!ri)return(false);
return BuildCommandBuffer(sc_render_target->GetCurrentFrameIndices(),ri);
2019-06-18 00:48:05 +08:00
}
2023-05-07 01:07:26 +08:00
void BuildCommandBuffer(uint32_t index,RenderList *rl)
{
if(!rl)return;
RenderCmdBuffer *cb=cmd_buf[index];
cb->Begin();
cb->BindFramebuffer(sc_render_target->GetRenderPass(),sc_render_target->GetFramebuffer(index));
cb->SetClearColor(0,clear_color);
cb->BeginRenderPass();
rl->Render(cb);
cb->EndRenderPass();
cb->End();
}
2023-05-07 01:07:26 +08:00
void BuildCommandBuffer(RenderList *rl)
{
for(int32_t i=0;i<swap_chain_count;i++)
BuildCommandBuffer(i,rl);
}
2023-05-07 01:07:26 +08:00
void BuildCurrentCommandBuffer(RenderList *rl)
{
BuildCommandBuffer(sc_render_target->GetCurrentFrameIndices(),rl);
}
template<typename ...ARGS>
Pipeline *CreatePipeline(ARGS...args){return device_render_pass->CreatePipeline(args...);}
public:
2019-06-18 00:48:05 +08:00
int AcquireNextImage()
{
return sc_render_target->AcquireNextImage();
2019-06-18 00:48:05 +08:00
}
virtual void SubmitDraw(int index)
2019-06-18 00:48:05 +08:00
{
VkCommandBuffer cb=*cmd_buf[index];
2020-01-23 21:00:35 +08:00
sc_render_target->Submit(cb);
sc_render_target->PresentBackbuffer();
sc_render_target->WaitQueue();
sc_render_target->WaitFence();
}
2019-06-18 00:48:05 +08:00
virtual void Draw()
{
int index=AcquireNextImage();
2019-07-01 17:04:02 +08:00
if(index<0||index>=swap_chain_count)return;
2019-06-18 00:48:05 +08:00
SubmitDraw(index);
}
2019-04-30 19:01:44 +08:00
bool Run()
{
if(!win->Update())return(false);
if(win->IsVisible())
Draw();
2022-03-11 18:27:04 +08:00
device->WaitIdle();
return(true);
}
};//class VulkanApplicationFramework
2022-01-24 19:36:54 +08:00
class CameraKeyboardControl:public KeyboardStateEvent
{
FirstPersonCameraControl *camera;
2022-01-24 19:36:54 +08:00
float move_speed;
public:
CameraKeyboardControl(FirstPersonCameraControl *wc)
2022-01-24 19:36:54 +08:00
{
camera=wc;
move_speed=1.0f;
}
bool OnPressed(const KeyboardButton &kb)override
{
if(!KeyboardStateEvent::OnPressed(kb))
return(false);
if(kb==KeyboardButton::Minus )move_speed*=0.9f;else
if(kb==KeyboardButton::Equals )move_speed*=1.1f;
return(true);
}
void Update()
{
if(HasPressed(KeyboardButton::W ))camera->Forward (move_speed);else
if(HasPressed(KeyboardButton::S ))camera->Backward (move_speed);else
if(HasPressed(KeyboardButton::A ))camera->Left (move_speed);else
if(HasPressed(KeyboardButton::D ))camera->Right (move_speed);else
//if(HasPressed(KeyboardButton::R ))camera->Up (move_speed);else
//if(HasPressed(KeyboardButton::F ))camera->Down (move_speed);else
2022-01-24 19:36:54 +08:00
//if(HasPressed(KeyboardButton::Left ))camera->HoriRotate( move_speed);else
//if(HasPressed(KeyboardButton::Right ))camera->HoriRotate(-move_speed);else
//if(HasPressed(KeyboardButton::Up ))camera->VertRotate( move_speed);else
//if(HasPressed(KeyboardButton::Down ))camera->VertRotate(-move_speed);else
2022-01-24 19:36:54 +08:00
return;
}
};
class CameraMouseControl:public MouseEvent
{
FirstPersonCameraControl *camera;
2022-01-24 19:36:54 +08:00
double cur_time;
double last_time;
2022-01-24 19:36:54 +08:00
2022-02-10 18:56:00 +08:00
Vector2f mouse_pos;
2022-01-24 19:36:54 +08:00
Vector2f mouse_last_pos;
2022-02-10 18:56:00 +08:00
protected:
2022-01-24 19:36:54 +08:00
bool OnPressed(int x,int y,MouseButton) override
{
mouse_last_pos.x=x;
mouse_last_pos.y=y;
last_time=cur_time;
2022-01-24 19:36:54 +08:00
return(true);
}
2022-03-11 19:13:20 +08:00
bool OnWheel(int,int y) override
{
if(y==0)return(false);
camera->Forward(float(y)/10.0f);
return(true);
}
2022-01-24 19:36:54 +08:00
bool OnMove(int x,int y) override
{
2022-02-10 18:56:00 +08:00
mouse_pos.x=x;
mouse_pos.y=y;
2022-01-24 19:36:54 +08:00
bool left=HasPressed(MouseButton::Left);
bool right=HasPressed(MouseButton::Right);
2022-03-11 19:13:20 +08:00
Vector2f pos(x,y);
Vector2f gap=pos-mouse_last_pos;
if(left)
2022-01-24 19:36:54 +08:00
{
2022-03-11 19:13:20 +08:00
gap/=-5.0f;
2022-01-24 19:36:54 +08:00
2022-03-09 18:40:31 +08:00
camera->Rotate(gap);
2022-03-11 19:13:20 +08:00
}
else
if(right)
{
gap/=10.0f;
2022-03-11 19:13:20 +08:00
camera->Move(Vector3f(gap.x,0,gap.y));
2022-01-24 19:36:54 +08:00
}
2022-03-11 19:13:20 +08:00
last_time=cur_time;
mouse_last_pos=Vector2f(x,y);
2022-01-24 19:36:54 +08:00
return(true);
}
public:
CameraMouseControl(FirstPersonCameraControl *wc)
2022-01-24 19:36:54 +08:00
{
camera=wc;
cur_time=0;
}
2022-02-10 18:56:00 +08:00
const Vector2f &GetMouseCoord()const{return mouse_pos;}
2022-01-24 19:36:54 +08:00
void Update()
{
cur_time=GetDoubleTime();
}
};
class CameraAppFramework:public VulkanApplicationFramework
{
protected:
Camera * camera =nullptr;
DeviceBuffer * ubo_camera_info =nullptr;
FirstPersonCameraControl *camera_control=nullptr;
2022-01-24 19:36:54 +08:00
CameraKeyboardControl * ckc=nullptr;
CameraMouseControl * cmc=nullptr;
2019-06-14 19:56:21 +08:00
2022-02-10 18:56:00 +08:00
const Vector2f &GetMouseCoord()const{return cmc->GetMouseCoord();}
public:
2020-11-17 17:20:59 +08:00
virtual ~CameraAppFramework()
{
2022-01-24 19:36:54 +08:00
SAFE_CLEAR(ckc);
SAFE_CLEAR(cmc);
SAFE_CLEAR(camera);
2020-11-17 17:20:59 +08:00
}
virtual bool Init(int w,int h)
{
if(!VulkanApplicationFramework::Init(w,h))
return(false);
2020-01-23 21:00:35 +08:00
InitCamera(w,h);
return(true);
}
virtual void InitCamera(int w,int h)
{
camera_control=new FirstPersonCameraControl(&vp_info,camera);
camera_control->Refresh(); //更新矩阵计算
2022-01-24 19:36:54 +08:00
ckc=new CameraKeyboardControl(camera_control);
cmc=new CameraMouseControl(camera_control);
2022-01-24 19:36:54 +08:00
win->Join(ckc);
win->Join(cmc);
camera=new Camera;
camera->pos=Vector3f(10,10,10);
RefreshCameraInfo(&camera_control->GetCameraInfo(),&vp_info,camera);
ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&camera_control->GetCameraInfo());
}
2020-01-23 21:00:35 +08:00
void Resize(int w,int h)override
{
vp_info.Set(w,h);
camera_control->Refresh();
ubo_camera_info->Write(&camera_control->GetCameraInfo());
}
const CameraInfo &GetCameraInfo()
{
return camera_control->GetCameraInfo();
}
DeviceBuffer *GetCameraInfoBuffer()
{
return ubo_camera_info;
}
bool BindCameraUBO(MaterialInstance *mi)
{
return mi->BindUBO(DescriptorSetType::Global,"g_camera",ubo_camera_info);
}
2019-06-18 00:48:05 +08:00
virtual void BuildCommandBuffer(uint32_t index)=0;
2019-06-14 20:01:46 +08:00
virtual void Draw()override
{
camera_control->Refresh(); //更新相机矩阵
ubo_camera_info->Write(&camera_control->GetCameraInfo()); //写入缓冲区
const uint32_t index=AcquireNextImage();
2019-06-18 00:48:05 +08:00
BuildCommandBuffer(index);
SubmitDraw(index);
2022-01-24 19:36:54 +08:00
ckc->Update();
cmc->Update();
}
2022-01-24 19:36:54 +08:00
};//class CameraAppFramework