ULRE/example/Vulkan/ViewModelFramework.h
2019-06-16 17:18:10 +08:00

150 lines
4.0 KiB
C++

#pragma once
#include"VulkanAppFramework.h"
using namespace hgl;
using namespace hgl::graph;
class ViewModelFramework:public VulkanApplicationFramework
{
private:
vulkan::Buffer * ubo_world_matrix =nullptr;
protected:
AABB bounding_box;
Matrix4f view_model_matrix;
ControlCamera camera;
float move_speed=1;
Vector2f mouse_last_pos;
protected:
SceneNode render_root;
RenderList render_list;
public:
virtual ~ViewModelFramework()=default;
virtual bool Init(int w,int h,const AABB &aabb)
{
if(!VulkanApplicationFramework::Init(w,h))
return(false);
bounding_box=aabb;
view_model_matrix=identity();
InitCamera(w,h);
return(true);
}
virtual void InitCamera(int w,int h)
{
math::vec center_point=bounding_box.CenterPoint();
math::vec max_point=bounding_box.maxPoint;
max_point.x*=5.0f;
max_point.y=center_point.y;
max_point.z=center_point.z;
camera.type=CameraType::Perspective;
camera.width=w;
camera.height=h;
camera.center=center_point;
camera.eye=max_point;
camera.Refresh(); //更新矩阵计算
move_speed=length(max_point,center_point)/100.0f;
}
bool InitCameraUBO(vulkan::DescriptorSets *desc_set,uint world_matrix_bindpoint)
{
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 Resize(int w,int h)override
{
camera.width=w;
camera.height=h;
}
virtual void Draw()override
{
camera.Refresh(); //更新相机矩阵
ubo_world_matrix->Write(&camera.matrix); //写入缓冲区
render_root.RefreshMatrix(&view_model_matrix);
render_list.Clear();
render_root.ExpendToList(&render_list);
BuildCommandBuffer(&render_list);
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[kbR])camera.Up (move_speed);else
if(key_status[kbF])camera.Down (move_speed);else
if(key_status[kbLeft ])view_model_matrix=rotate(hgl_ang2rad(move_speed*100),normalized(camera.center-camera.eye))*view_model_matrix;else
if(key_status[kbRight])view_model_matrix=rotate(hgl_ang2rad(-move_speed*100),normalized(camera.center-camera.eye))*view_model_matrix;else
return;
}
virtual void KeyPress(KeyboardButton kb)override
{
if(kb==kbMinus)move_speed*=0.9f;else
if(kb==kbEquals)move_speed*=1.1f;else
return;
}
virtual void MouseDown(uint) override
{
mouse_last_pos=mouse_pos;
}
virtual void MouseMove() override
{
if(!mouse_key)return;
Vector2f gap=mouse_pos-mouse_last_pos;
if(mouse_key&mbLeft)
{
if(gap.x!=0)camera.HorzRotate(-gap.x/10.0f);
if(gap.y!=0)camera.VertRotate(-gap.y/10.0f);
}
else if(mouse_key&mbRight)
{
if(gap.x!=0)view_model_matrix=rotate(hgl_ang2rad(gap.x),camera.up_vector)*view_model_matrix;
if(gap.y!=0)view_model_matrix=rotate(hgl_ang2rad(gap.y),camera.right_vector)*view_model_matrix;
}
else if(mouse_key&mbMid)
{
if(gap.x!=0)camera.Left(gap.x*move_speed/10.0f);
if(gap.y!=0)camera.Up(gap.y*move_speed/10.0f);
}
mouse_last_pos=mouse_pos;
}
virtual void MouseWheel(int v,int h,uint)
{
camera.Distance(1+(v/1000.0f));
}
};//class CameraAppFramework