From 9acfa5edd0b4350aea3a8e2c825a69afea6d6754 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Thu, 10 Feb 2022 18:56:00 +0800 Subject: [PATCH] added RayPicking example --- CMSceneGraph | 2 +- example/Vulkan/CMakeLists.txt | 3 +- example/Vulkan/Geometry3D.cpp | 8 +- example/Vulkan/RayPicking.cpp | 189 +++++++++++++++++++++++++++ example/Vulkan/first_triangle.cpp | 4 +- example/common/VulkanAppFramework.h | 10 +- inc/hgl/graph/VKVertexAttribBuffer.h | 5 - src/SceneGraph/Vulkan/VKMemory.cpp | 2 +- 8 files changed, 208 insertions(+), 15 deletions(-) create mode 100644 example/Vulkan/RayPicking.cpp diff --git a/CMSceneGraph b/CMSceneGraph index 2fa35362..647c2a55 160000 --- a/CMSceneGraph +++ b/CMSceneGraph @@ -1 +1 @@ -Subproject commit 2fa353629a68d193d5f053332ff75ac18579dec0 +Subproject commit 647c2a557c96301eed8860bb933c84b289f32de3 diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index bc30bd2f..d9ba6577 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -50,4 +50,5 @@ CreateProject(15.OffscreenRender OffscreenRender.cpp) CreateProject(16.DeferredRenderMultiCmdBuffer DeferredRenderMultiCmdBuffer.cpp) #CreateProject(14.AutoMaterial auto_material.cpp) -CreateProject(17.Cubemap Cubemap.cpp) \ No newline at end of file +CreateProject(17.Cubemap Cubemap.cpp) +CreateProject(18.RayPicking RayPicking.cpp) \ No newline at end of file diff --git a/example/Vulkan/Geometry3D.cpp b/example/Vulkan/Geometry3D.cpp index 4491578f..4cbe187f 100644 --- a/example/Vulkan/Geometry3D.cpp +++ b/example/Vulkan/Geometry3D.cpp @@ -65,11 +65,11 @@ private: pgci.coord[2]=Vector3f( 100, 100,0); pgci.coord[3]=Vector3f(-100, 100,0); - pgci.step.x=20; - pgci.step.y=20; + pgci.step.x=32; + pgci.step.y=32; - pgci.side_step.x=10; - pgci.side_step.y=10; + pgci.side_step.x=8; + pgci.side_step.y=8; pgci.color.Set(0.5,0,0,1); pgci.side_color.Set(1,0,0,1); diff --git a/example/Vulkan/RayPicking.cpp b/example/Vulkan/RayPicking.cpp new file mode 100644 index 00000000..17391420 --- /dev/null +++ b/example/Vulkan/RayPicking.cpp @@ -0,0 +1,189 @@ +// 18.RayPicking + +#include"VulkanAppFramework.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace hgl; +using namespace hgl::graph; + +constexpr uint32_t SCREEN_WIDTH=1280; +constexpr uint32_t SCREEN_HEIGHT=720; + +static float position_data[2][3]= +{ + {100,100,100}, + {0,0,0} +}; + +static float color_data[2][4]= +{ + {1,1,0,1}, + {1,1,0,1} +}; + +class TestApp:public CameraAppFramework +{ + Color4f color; + + GPUBuffer *ubo_color=nullptr; + +private: + + SceneNode render_root; + RenderList * render_list =nullptr; + + Material * material =nullptr; + MaterialInstance * material_instance =nullptr; + Pipeline * pipeline =nullptr; + + Renderable * ro_plane_grid =nullptr; + + Renderable * ro_line =nullptr; + + VBO * vbo_pos =nullptr; + + Ray ray; + +private: + + bool InitMDP() + { + material=db->CreateMaterial(OS_TEXT("res/material/VertexColor3D")); + if(!material)return(false); + + material_instance=db->CreateMaterialInstance(material); + if(!material_instance)return(false); + + pipeline=CreatePipeline(material_instance,InlinePipeline::Solid3D,Prim::Lines); + if(!pipeline) + return(false); + + return(true); + } + + RenderableInstance *Add(Renderable *r,const Matrix4f &mat) + { + RenderableInstance *ri=db->CreateRenderableInstance(r,material_instance,pipeline); + + render_root.CreateSubNode(mat,ri); + + return ri; + } + + bool CreateRenderObject() + { + { + struct PlaneGridCreateInfo pgci; + + pgci.coord[0]=Vector3f(-100,-100,0); + pgci.coord[1]=Vector3f( 100,-100,0); + pgci.coord[2]=Vector3f( 100, 100,0); + pgci.coord[3]=Vector3f(-100, 100,0); + + pgci.step.x=32; + pgci.step.y=32; + + pgci.side_step.x=8; + pgci.side_step.y=8; + + pgci.color.Set(0.25,0,0,1); + pgci.side_color.Set(1,0,0,1); + + const VAB *vab=material_instance->GetVAB(); + + ro_plane_grid=CreateRenderablePlaneGrid(db,vab,&pgci); + } + + { + ro_line=db->CreateRenderable(2); + if(!ro_line)return(false); + + if(!ro_line->Set(VAN::Position, vbo_pos=db->CreateVBO(VF_V3F,2,position_data)))return(false); + if(!ro_line->Set(VAN::Color, db->CreateVBO(VF_V4F,2,color_data)))return(false); + } + + return(true); + } + + bool InitScene() + { + Add(ro_plane_grid,Matrix4f(1.0f)); + Add(ro_line,Matrix4f(1.0f)); + + camera->pos=Vector3f(100,100,50); + camera_control->SetTarget(Vector3f(0,0,0)); + camera_control->Refresh(); + + render_root.RefreshMatrix(); + render_list->Expend(camera->info,&render_root); + + return(true); + } + +public: + + ~TestApp() + { + SAFE_CLEAR(render_list); + } + + bool Init() + { + if(!CameraAppFramework::Init(SCREEN_WIDTH,SCREEN_HEIGHT)) + return(false); + + render_list=new RenderList(device); + + if(!InitMDP()) + return(false); + + if(!CreateRenderObject()) + return(false); + + if(!InitScene()) + return(false); + + return(true); + } + + void BuildCommandBuffer(uint32 index) + { + const CameraInfo &ci=GetCameraInfo(); + + ray.Set(GetMouseCoord(),&ci); //设置射线查询的屏幕坐标点 + + const Vector3f pos=ray.ClosestPoint(Vector3f(0,0,0)); //求射线上与点(0,0,0)最近的点的坐标 + + vbo_pos->Write(&pos,3*sizeof(float)); //更新VBO上这个点的位置 + + render_root.RefreshMatrix(); + render_list->Expend(ci,&render_root); + + VulkanApplicationFramework::BuildCommandBuffer(index,render_list); + } + + void Resize(int w,int h)override + { + CameraAppFramework::Resize(w,h); + + VulkanApplicationFramework::BuildCommandBuffer(render_list); + } +};//class TestApp:public CameraAppFramework + +int main(int,char **) +{ + TestApp app; + + if(!app.Init()) + return(-1); + + while(app.Run()); + + return 0; +} diff --git a/example/Vulkan/first_triangle.cpp b/example/Vulkan/first_triangle.cpp index 9676a72d..7479cc58 100644 --- a/example/Vulkan/first_triangle.cpp +++ b/example/Vulkan/first_triangle.cpp @@ -61,7 +61,7 @@ private: cam.width=extent.width; cam.height=extent.height; - cam.Refresh(); + cam.RefreshCameraInfo(); ubo_camera_info=db->CreateUBO(sizeof(CameraInfo),&cam.info); @@ -119,7 +119,7 @@ public: cam.width=w; cam.height=h; - cam.Refresh(); + cam.RefreshCameraInfo(); ubo_camera_info->Write(&cam.info); diff --git a/example/common/VulkanAppFramework.h b/example/common/VulkanAppFramework.h index ccd3261f..dc46a908 100644 --- a/example/common/VulkanAppFramework.h +++ b/example/common/VulkanAppFramework.h @@ -326,9 +326,10 @@ class CameraMouseControl:public MouseEvent double cur_time; double last_time; + Vector2f mouse_pos; Vector2f mouse_last_pos; -protected: +protected: bool OnPressed(int x,int y,MouseButton) override { @@ -342,6 +343,9 @@ protected: bool OnMove(int x,int y) override { + mouse_pos.x=x; + mouse_pos.y=y; + bool left=HasPressed(MouseButton::Left); bool right=HasPressed(MouseButton::Right); @@ -367,6 +371,8 @@ public: cur_time=0; } + const Vector2f &GetMouseCoord()const{return mouse_pos;} + void Update() { cur_time=GetDoubleTime(); @@ -387,6 +393,8 @@ protected: CameraKeyboardControl * ckc=nullptr; CameraMouseControl * cmc=nullptr; + const Vector2f &GetMouseCoord()const{return cmc->GetMouseCoord();} + public: virtual ~CameraAppFramework() diff --git a/inc/hgl/graph/VKVertexAttribBuffer.h b/inc/hgl/graph/VKVertexAttribBuffer.h index 59f4ced6..24b9b807 100644 --- a/inc/hgl/graph/VKVertexAttribBuffer.h +++ b/inc/hgl/graph/VKVertexAttribBuffer.h @@ -31,11 +31,6 @@ namespace hgl const VkFormat GetFormat()const { return format; } const uint32_t GetStride()const { return stride; } const uint32_t GetCount ()const { return count; } - - void *Map(VkDeviceSize start=0,VkDeviceSize size=0) override - { - return GPUBuffer::Map(start*stride,size*stride); - } };//class VertexAttribBuffer:public GPUBuffer using VBO=VertexAttribBuffer; diff --git a/src/SceneGraph/Vulkan/VKMemory.cpp b/src/SceneGraph/Vulkan/VKMemory.cpp index aedc7ca9..0d7aee34 100644 --- a/src/SceneGraph/Vulkan/VKMemory.cpp +++ b/src/SceneGraph/Vulkan/VKMemory.cpp @@ -54,7 +54,7 @@ void *GPUMemory::Map(const VkDeviceSize offset,const VkDeviceSize size) void *result; - if(vkMapMemory(device,memory,0,size,0,&result)==VK_SUCCESS) + if(vkMapMemory(device,memory,offset,size,0,&result)==VK_SUCCESS) return result; return(nullptr);