From 19714f8942c5e558dfe33f51d56fae867b983d61 Mon Sep 17 00:00:00 2001 From: hyzboy Date: Wed, 22 May 2019 18:10:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AC=A1=E7=9A=84=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E5=8C=96=E5=88=9B=E5=BB=BARenderable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/Vulkan/Geometry2D.cpp | 159 +++-- inc/hgl/graph/VertexBuffer.h | 936 ++++++++++++++++++++++++++++ inc/hgl/graph/VertexBufferCreater.h | 48 ++ inc/hgl/graph/vulkan/VKDevice.h | 2 + inc/hgl/graph/vulkan/VKMaterial.h | 2 + inc/hgl/graph/vulkan/VKRenderable.h | 2 +- inc/hgl/math/Vector.h | 85 +++ inc/hgl/type/RectScope.h | 24 +- src/SceneGraph/CMakeLists.txt | 4 +- 9 files changed, 1189 insertions(+), 73 deletions(-) create mode 100644 inc/hgl/graph/VertexBuffer.h create mode 100644 inc/hgl/graph/VertexBufferCreater.h diff --git a/example/Vulkan/Geometry2D.cpp b/example/Vulkan/Geometry2D.cpp index e16e65c5..ee03b4e7 100644 --- a/example/Vulkan/Geometry2D.cpp +++ b/example/Vulkan/Geometry2D.cpp @@ -1,9 +1,12 @@ -// 0.triangle -// 该范例主要演示直接绘制一个渐变色的三角形 +// 3.Geometry2D +// 该范例有两个作用: +// 一、测试绘制2D几何体 +// 二、试验动态合并材质渲染机制、包括普通合并与Instance #include"VulkanAppFramework.h" #include #include +#include using namespace hgl; using namespace hgl::graph; @@ -11,37 +14,85 @@ using namespace hgl::graph; bool SaveToFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); bool LoadFromFile(const OSString &filename,VK_NAMESPACE::PipelineCreater *pc); -constexpr uint32_t SCREEN_WIDTH=1280; -constexpr uint32_t SCREEN_HEIGHT=720; +constexpr uint32_t SCREEN_WIDTH=128; +constexpr uint32_t SCREEN_HEIGHT=128; struct WorldConfig { Matrix4f mvp; }world; -/** - * 网格数据 - */ -class Mesh +struct RectangleCreateInfo { -public: -};//class Mesh + RectScope2f scope; + vec3 normal; + Color4f color; + RectScope2f tex_coord; +}; -/** - * 网格数据生成器 - */ -class MeshCreater +vulkan::Renderable *CreateRectangle(vulkan::Device *device,vulkan::Material *mtl,const RectangleCreateInfo *rci) { -public: + const vulkan::VertexShaderModule *vsm=mtl->GetVertexShaderModule(); - MeshCreater() + vulkan::Renderable *render_obj=mtl->CreateRenderable(); + + const int vertex_binding=vsm->GetStageInputBinding("Vertex"); + + if(vertex_binding!=-1) { - } -};// + VB2f *vertex=new VB2f(6); -Mesh *CreateRectangle(float l,float t,float w,float h) -{ - MeshCreater *creater=new MeshCreater(); + vertex->Begin(); + vertex->WriteRect(rci->scope); + vertex->End(); + + render_obj->Set(vertex_binding,device->CreateVBO(vertex)); + delete vertex; + } + + const int normal_binding=vsm->GetStageInputBinding("Normal"); + + if(normal_binding!=-1) + { + VB3f *normal=new VB3f(6); + + normal->Begin(); + normal->Write(rci->normal,6); + normal->End(); + + render_obj->Set(normal_binding,device->CreateVBO(normal)); + delete normal; + } + + const int color_binding=vsm->GetStageInputBinding("Color"); + + if(color_binding!=-1) + { + VB4f *color=new VB4f(6); + + color->Begin(); + color->Write(rci->color,6); + color->End(); + + render_obj->Set(color_binding,device->CreateVBO(color)); + delete color; + } + + const int tex_coord_binding=vsm->GetStageInputBinding("TexCoord"); + + if(tex_coord_binding!=-1) + { + VB2f *tex_coord=new VB2f(6); + + tex_coord->Begin(); + tex_coord->WriteRect(rci->tex_coord); + tex_coord->End(); + + render_obj->Set(tex_coord_binding,device->CreateVBO(tex_coord)); + delete tex_coord; + } + + return render_obj; } /** @@ -49,24 +100,9 @@ Mesh *CreateRectangle(float l,float t,float w,float h) * @param r 半径 * @param rp 半径精度 */ -Mesh *CreateRoundrectangle(float l,float t,float w,float h,float r,uint32_t rp) -{ -} - -constexpr uint32_t VERTEX_COUNT=3; - -constexpr float vertex_data[VERTEX_COUNT][2]= -{ - {SCREEN_WIDTH*0.5, SCREEN_HEIGHT*0.25}, - {SCREEN_WIDTH*0.75, SCREEN_HEIGHT*0.75}, - {SCREEN_WIDTH*0.25, SCREEN_HEIGHT*0.75} -}; - -constexpr float color_data[VERTEX_COUNT][3]= -{ {1,0,0}, - {0,1,0}, - {0,0,1} -}; +//Mesh *CreateRoundrectangle(float l,float t,float w,float h,float r,uint32_t rp) +//{ +//} class TestApp:public VulkanApplicationFramework { @@ -103,16 +139,26 @@ private: bool InitMaterial() { - material=shader_manage->CreateMaterial(OS_TEXT("FlatColor.vert.spv"), + material=shader_manage->CreateMaterial(OS_TEXT("OnlyPosition.vert.spv"), OS_TEXT("FlatColor.frag.spv")); if(!material) return(false); - render_obj=material->CreateRenderable(); desciptor_sets=material->CreateDescriptorSets(); return(true); } + bool CreateRenderObject() + { + struct RectangleCreateInfo rci; + + rci.scope.Set(10,10,10,10); + + render_obj=CreateRectangle(device,material,&rci); + + return render_obj; + } + bool InitUBO() { const VkExtent2D extent=device->GetExtent(); @@ -130,16 +176,7 @@ private: desciptor_sets->Update(); return(true); } - - void InitVBO() - { - vertex_buffer =device->CreateVBO(FMT_RG32F, VERTEX_COUNT,vertex_data); - color_buffer =device->CreateVBO(FMT_RGB32F, VERTEX_COUNT,color_data); - - render_obj->Set("Vertex", vertex_buffer); - render_obj->Set("Color", color_buffer); - } - + bool InitPipeline() { constexpr os_char PIPELINE_FILENAME[]=OS_TEXT("2DSolid.pipeline"); @@ -151,17 +188,6 @@ private: pipeline_creater->CloseCullFace(); pipeline_creater->Set(PRIM_TRIANGLES); - SaveToFile(PIPELINE_FILENAME,pipeline_creater); - - delete pipeline_creater; - } - - { - void *data; - uint size=filesystem::LoadFileToMemory(PIPELINE_FILENAME,(void **)&data); - - vulkan::PipelineCreater *pipeline_creater=new vulkan::PipelineCreater(device,material,device->GetRenderPass(),device->GetExtent(),(uchar *)data,size); - pipeline=pipeline_creater->Create(); delete pipeline_creater; @@ -186,7 +212,7 @@ private: cmd_buf[i]->Bind(pipeline); cmd_buf[i]->Bind(desciptor_sets); cmd_buf[i]->Bind(render_obj); - cmd_buf[i]->Draw(VERTEX_COUNT); + cmd_buf[i]->Draw(6); cmd_buf[i]->EndRenderPass(); cmd_buf[i]->End(); } @@ -206,11 +232,12 @@ public: if(!InitMaterial()) return(false); - if(!InitUBO()) + if(!CreateRenderObject()) return(false); - InitVBO(); - + if(!InitUBO()) + return(false); + if(!InitPipeline()) return(false); diff --git a/inc/hgl/graph/VertexBuffer.h b/inc/hgl/graph/VertexBuffer.h new file mode 100644 index 00000000..e0bf0f33 --- /dev/null +++ b/inc/hgl/graph/VertexBuffer.h @@ -0,0 +1,936 @@ +#ifndef HGL_GRAPH_VERTEX_BUFFER_INCLUDE +#define HGL_GRAPH_VERTEX_BUFFER_INCLUDE + +#include +#include +#include +#include +#include +#include +namespace hgl +{ + namespace graph + { + /** + * 顶点属性数据实际模板 + */ + template class VertexBuffer:public VertexBufferCreater + { + protected: + + T *mem_type; ///<符合当前类型的地址 + T *access; ///<当前访问地址 + + T *start; ///<访问起始地址 + + public: + + VertexBuffer(uint32_t _size,const T *_data=nullptr):VertexBufferCreater(_size,C,sizeof(T)) + { + mem_type=(T *)GetData(); + access=0; + start=0; + + if(_data) + memcpy(mem_type,_data,total_bytes); + } + + virtual ~VertexBuffer()=default; + + /** + * 取得数据区地址 + * @param offset 从第几个数据开始访问 + * @return 访问地址 + */ + T *Get(uint32_t offset=0) + { + if(!mem_type||offset>=count) + { + LOG_HINT(OS_TEXT("VertexBuffer::Get() out,offset:")+OSString(offset)); + return(nullptr); + } + + return mem_type+offset*C; + } + + /** + * 开始访问数据区 + * @param offset 从第几个数据开始访问 + * @return 访问地址 + */ + void *Begin(uint32_t offset=0) + { + if(access) + { + LOG_HINT(OS_TEXT("VertexBuffer::Begin() access!=0,offset:")+OSString(offset)); + return(nullptr); + } + + access=Get(offset); + + if(access) + start=access; + + return access; + } + + /** + * 结束访问 + */ + void End() + { + //ChangeVertexBuffer( ((char *)start )-((char *)mem_type), + // ((char *)access)-((char *)start), + // start); + + access=nullptr; + start=nullptr; + } + + /** + * 写入指定数量的数据 + * @param vp 数据指针 + * @param number 数据数量 + */ + bool WriteData(const T *vp,const uint32_t number) + { + if(!this->access||this->access+C*number>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer::Write(const T *,number) out,number:")+OSString(number)); + return(false); + } + + memcpy(access,vp,C*number*sizeof(T)); + + access+=C*number; + + return(true); + } + };//class VertexBuffer + + /** + * 一元数据缓冲区 + */ + template class VertexBuffer1:public VertexBuffer + { + public: + + using VertexBuffer::VertexBuffer; + virtual ~VertexBuffer1()=default; + + VkFormat GetDataType()const override; + + bool Write(const T v1) + { + if(!this->access||this->access+1>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer1::Write(const T) out")); + return(false); + } + + *this->access++=v1; + return(true); + } + + /** + * 将一个值重复多次写入缓冲区 + * @param v 值 + * @param count 写入数量 + */ + bool Write(const T v,const uint32_t count) + { + if(!this->access||this->access+count>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer1::Write(const T,")+OSString(count)+OS_TEXT(") out")); + return(false); + } + + hgl_set(this->access,v,count); + this->access+=count; + return(true); + } + };//class VertexBuffer1 + + /** + * 二元数据缓冲区 + */ + template class VertexBuffer2:public VertexBuffer + { + public: + + using VertexBuffer::VertexBuffer; + virtual ~VertexBuffer2()=default; + + VkFormat GetDataType()const override; + + bool Write(const T v1,const T v2) + { + if(!this->access||this->access+2>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::Write(const T ,const T) out")); + return(false); + } + + *this->access++=v1; + *this->access++=v2; + + return(true); + } + + bool Write(const T *v) + { + if(!this->access||this->access+2>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::Write(T *) out")); + return(false); + } + + *this->access++=*v++; + *this->access++=*v; + + return(true); + } + + template + bool Write(const vec2 &v) + { + if(!this->access||this->access+2>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::Write(vec2 &) out")); + return(false); + } + + *this->access++=v.x; + *this->access++=v.y; + + return(true); + } + + /** + * 将一个值重复多次写入缓冲区 + * @param v 值 + * @param count 写入数量 + */ + template + bool Write(const vec2 &v,const uint32_t count) + { + if(!this->access||this->access+(count<<1)>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer1::Write(const Vector2f &,")+OSString(count)+OS_TEXT(") out")); + return(false); + } + + for(uint32_t i=0;iaccess++=v.x; + *this->access++=v.y; + } + + return(true); + } + + bool WriteLine(const T start_x,const T start_y,const T end_x,const T end_y) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::WriteLine(T,T,T,T) out")); + return(false); + } + + *this->access++=start_x; + *this->access++=start_y; + *this->access++=end_x; + *this->access++=end_y; + + return(true); + } + + template + bool WriteLine(const vec2 &start,const vec2 &end) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::WriteLine(vec2,vec2) out")); + return(false); + } + + *this->access++=start.x; + *this->access++=start.y; + *this->access++=end.x; + *this->access++=end.y; + + return(true); + } + + /** + * 写入2D三角形 + */ + template + bool WriteTriangle(const vec2 &v1,const vec2 &v2,const vec2 &v3) + { + if(!this->access||this->access+6>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::WriteTriangle(vec2,vec2,vec2) out")); + return(false); + } + + *this->access++=v1.x; + *this->access++=v1.y; + + *this->access++=v2.x; + *this->access++=v2.y; + + *this->access++=v3.x; + *this->access++=v3.y; + + return(true); + } + + /** + * 写入2D三角形 + */ + template + bool WriteTriangle(const vec2 *v) + { + if(!this->access||this->access+6>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer2::WriteTriangle(vec2 *) out")); + return(false); + } + + *this->access++=v->x; + *this->access++=v->y; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + + return(true); + } + + /** + * 写入2D四边形坐标数据 + */ + template + bool WriteQuad(const vec2 <,const vec2 &rt,const vec2 &rb,const vec2 &lb) + { + if(WriteTriangle(lt,lb,rb)) + if(WriteTriangle(lt,rb,rt)) + return(true); + + LOG_HINT(OS_TEXT("VertexBuffer2::WriteQuad(vec2 &,vec2 &,vec2 &,vec2 &) error")); + return(false); + } + + /** + * 写入2D矩形(两个三角形)坐标数据 + */ + template + bool WriteRect(const T left,const T top,const T width,const T height) + { + const vec2 lt(left ,top); + const vec2 rt(left+width,top); + const vec2 rb(left+width,top+height); + const vec2 lb(left ,top+height); + + return WriteQuad(lt,rt,rb,lb); + } + + template + bool WriteRect(const RectScope2 &scope) + { + return WriteQuad( scope.GetLeftTop(), + scope.GetRightTop(), + scope.GetRightBottom(), + scope.GetLeftBottom()); + } + };//class VertexBuffer2 + + /** + * 三元数据缓冲区 + */ + template class VertexBuffer3:public VertexBuffer + { + public: + + using VertexBuffer::VertexBuffer; + virtual ~VertexBuffer3()=default; + + VkFormat GetDataType()const override; + + /** + * 计算绑定盒 + * @param min_vertex 最小值坐标 + * @param max_vertex 最大值坐标 + */ + template + void GetBoundingBox(V &min_vertex,V &max_vertex) + { + T *p=this->mem_type; + + //先以corner为最小值,length为最大值,求取最小最大值 + min_vertex.x=*p++; + min_vertex.y=*p++; + min_vertex.z=*p++; + + max_vertex=min_vertex; + + for(uint32_t i=1;icount;i++) + { + if(*pmax_vertex.x)max_vertex.x=*p; + ++p; + + if(*pmax_vertex.y)max_vertex.y=*p; + ++p; + + if(*pmax_vertex.z)max_vertex.z=*p; + ++p; + } + } + + bool Write(const T v1,const T v2,const T v3) + { + if(!this->access||this->access+3>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(T,T,T) out")); + return(false); + } + + *this->access++=v1; + *this->access++=v2; + *this->access++=v3; + + return(true); + } + + bool Write(const T *v) + { + if(!this->access||this->access+3>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(T *) out")); + return(false); + } + + *this->access++=*v++; + *this->access++=*v++; + *this->access++=*v; + + return(true); + } + + template + bool Write(const vec3 &v) + { + if(!this->access||this->access+3>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(vec3 &) out")); + return(false); + } + + *this->access++=v.x; + *this->access++=v.y; + *this->access++=v.z; + + return(true); + } + + template + bool Write(const vec4 &v) + { + if(!this->access||this->access+3>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(vec4 &) out")); + return(false); + } + + *this->access++=v.x; + *this->access++=v.y; + *this->access++=v.z; + + return(true); + } + + /** + * 将一个值重复多次写入缓冲区 + * @param v 值 + * @param count 写入数量 + */ + template + bool Write(const vec3 &v,const uint32_t count) + { + if(!this->access||this->access+(count*3)>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(const Vector3f,")+OSString(count)+OS_TEXT(") out")); + return(false); + } + + for(uint32_t i=0;iaccess++=v.x; + *this->access++=v.y; + *this->access++=v.z; + } + + return(true); + } + + bool Write(const Color3f &v) + { + if(!this->access||this->access+3>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::Write(color3f &) out")); + return(false); + } + + *this->access++=v.r; + *this->access++=v.g; + *this->access++=v.b; + + return(true); + } + + bool WriteLine(const T start_x,const T start_y,const T start_z,const T end_x,const T end_y,const T end_z) + { + if(!this->access||this->access+6>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::WriteLine(T,T,T,T,T,T) out")); + return(false); + } + + *this->access++=start_x; + *this->access++=start_y; + *this->access++=start_z; + *this->access++=end_x; + *this->access++=end_y; + *this->access++=end_z; + + return(true); + } + + template + bool WriteLine(const vec3 &start,const vec3 &end) + { + if(!this->access||this->access+6>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::WriteLine(vec3,vec3) out")); + return(false); + } + + *this->access++=start.x; + *this->access++=start.y; + *this->access++=start.z; + *this->access++=end.x; + *this->access++=end.y; + *this->access++=end.z; + + return(true); + } + + /** + * 写入3D三角形 + */ + template + bool WriteTriangle(const vec3 &v1,const vec3 &v2,const vec3 &v3) + { + if(!this->access||this->access+9>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::WriteTriangle(vec3,vec3,vec3) out")); + return(false); + } + + *this->access++=v1.x; + *this->access++=v1.y; + *this->access++=v1.z; + + *this->access++=v2.x; + *this->access++=v2.y; + *this->access++=v2.z; + + *this->access++=v3.x; + *this->access++=v3.y; + *this->access++=v3.z; + + return(true); + } + + /** + * 写入3D三角形 + */ + template + bool WriteTriangle(const vec3 *v) + { + if(!this->access||this->access+9>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer3::WriteTriangle(vec3 *) out")); + return(false); + } + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + + return(true); + } + };//class VertexBuffer3 + + /** + * 四元数据缓冲区 + */ + template class VertexBuffer4:public VertexBuffer + { + public: + + using VertexBuffer::VertexBuffer; + virtual ~VertexBuffer4()=default; + + VkFormat GetDataType()const override; + + /** + * 计算绑定盒 + * @param min_vertex 最小值坐标 + * @param max_vertex 最大值坐标 + */ + template + void GetBoundingBox(V &min_vertex,V &max_vertex) + { + T *p=this->mem_type; + + //先以corner为最小值,length为最大值,求取最小最大值 + min_vertex.x=*p++; + min_vertex.y=*p++; + min_vertex.z=*p++; + + max_vertex=min_vertex; + + for(uint32_t i=1;icount;i++) + { + if(*pmax_vertex.x)max_vertex.x=*p; + ++p; + + if(*pmax_vertex.y)max_vertex.y=*p; + ++p; + + if(*pmax_vertex.z)max_vertex.z=*p; + ++p; + } + } + + bool Write(const T v1,const T v2,const T v3,const T v4) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(T,T,T,T) out")); + return(false); + } + + *this->access++=v1; + *this->access++=v2; + *this->access++=v3; + *this->access++=v4; + + return(true); + } + + bool Write(const T *v) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(T *) out")); + return(false); + } + + *this->access++=*v++; + *this->access++=*v++; + *this->access++=*v++; + *this->access++=*v; + + return(true); + } + + template + bool Write(const vec4 &v) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(color4 &) out")); + return(false); + } + + *this->access++=v.x; + *this->access++=v.y; + *this->access++=v.z; + *this->access++=v.w; + + return(true); + } + + bool Write(const Color4f &v) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(color4 &) out")); + return(false); + } + + *this->access++=v.r; + *this->access++=v.g; + *this->access++=v.b; + *this->access++=v.a; + + return(true); + } + + bool Write(const Color4f &v,const uint32_t count) + { + if(count<=0)return(false); + + if(!this->access||this->access+(4*count)>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(color4 &,count) out")); + return(false); + } + + for(uint32_t i=0;iaccess++=v.r; + *this->access++=v.g; + *this->access++=v.b; + *this->access++=v.a; + } + + return(true); + } + + /** + * 将一个值重复多次写入缓冲区 + * @param v 值 + * @param count 写入数量 + */ + template + bool Write(const vec4 &v,const uint32_t count) + { + if(!this->access||this->access+(count<<2)>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::Write(const Vector4f,")+OSString(count)+OS_TEXT(") out")); + return(false); + } + + for(uint32_t i=0;iaccess++=v.x; + *this->access++=v.y; + *this->access++=v.z; + *this->access++=v.w; + } + + return(true); + } + + bool WriteLine(const T start_x,const T start_y,const T start_z,const T end_x,const T end_y,const T end_z) + { + if(!this->access||this->access+8>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteLine(T,T,T,T,T,T) out")); + return(false); + } + + *this->access++=start_x; + *this->access++=start_y; + *this->access++=start_z; + *this->access++=1.0f; + *this->access++=end_x; + *this->access++=end_y; + *this->access++=end_z; + *this->access++=1.0f; + + return(true); + } + + template + bool WriteLine(const vec3 &start,const vec3 &end) + { + if(!this->access||this->access+8>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteLine(vec3,vec3) out")); + return(false); + } + + *this->access++=start.x; + *this->access++=start.y; + *this->access++=start.z; + *this->access++=1.0f; + *this->access++=end.x; + *this->access++=end.y; + *this->access++=end.z; + *this->access++=1.0f; + + return(true); + } + + /** + * 写入3D三角形 + */ + template + bool WriteTriangle(const vec3 &v1,const vec3 &v2,const vec3 &v3) + { + if(!this->access||this->access+12>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteTriangle(vec3,vec3,vec3) out")); + return(false); + } + + *this->access++=v1.x; + *this->access++=v1.y; + *this->access++=v1.z; + *this->access++=1.0f; + + *this->access++=v2.x; + *this->access++=v2.y; + *this->access++=v2.z; + *this->access++=1.0f; + + *this->access++=v3.x; + *this->access++=v3.y; + *this->access++=v3.z; + *this->access++=1.0f; + + return(true); + } + + /** + * 写入3D三角形 + */ + template + bool WriteTriangle(const vec3 *v) + { + if(!this->access||this->access+12>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteTriangle(vec3 *) out")); + return(false); + } + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + *this->access++=1.0f; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + *this->access++=1.0f; + ++v; + + *this->access++=v->x; + *this->access++=v->y; + *this->access++=v->z; + *this->access++=1.0f; + + return(true); + } + + /** + * 写入2D矩形,注:这个函数会依次写入Left,Top,Width,Height四个值 + */ + template + bool WriteRectangle2D(const RectScope2 &rect) + { + if(!this->access||this->access+4>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteRectangle2D(RectScope2 ) out")); + return(false); + } + + *this->access++=rect.Left; + *this->access++=rect.Top; + *this->access++=rect.Width; + *this->access++=rect.Height; + + return(true); + } + + /** + * 写入2D矩形,注:这个函数会依次写入Left,Top,Width,Height四个值 + */ + template + bool WriteRectangle2D(const RectScope2 *rect,const uint32_t count) + { + if(!this->access||this->access+(4*count)>this->mem_end) + { + LOG_HINT(OS_TEXT("VertexBuffer4::WriteRectangle2D(RectScope2 *,count) out")); + return(false); + } + + for(uint32_t i=0;iaccess++=rect->Left; + *this->access++=rect->Top; + *this->access++=rect->Width; + *this->access++=rect->Height; + + ++rect; + } + + return(true); + } + };//class VertexBuffer4 + + //缓冲区具体数据类型定义 + typedef VertexBuffer1 VB1i8 ,VB1b; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R8I; } + typedef VertexBuffer1 VB1i16 ,VB1s; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R16I; } + typedef VertexBuffer1 VB1i32 ,VB1i; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R32I; } + typedef VertexBuffer1 VB1u8 ,VB1ub; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R8U; } + typedef VertexBuffer1 VB1u16 ,VB1us; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R16U; } + typedef VertexBuffer1 VB1u32 ,VB1ui; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R32U; } + typedef VertexBuffer1 VB1f; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R32F; } + typedef VertexBuffer1 VB1d; template<> inline VkFormat VertexBuffer1::GetDataType()const{return FMT_R64F; } + + typedef VertexBuffer2 VB2i8 ,VB2b; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG8I; } + typedef VertexBuffer2 VB2i16 ,VB2s; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG16I; } + typedef VertexBuffer2 VB2i32 ,VB2i; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG32I; } + typedef VertexBuffer2 VB2u8 ,VB2ub; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG8U; } + typedef VertexBuffer2 VB2u16 ,VB2us; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG16U; } + typedef VertexBuffer2 VB2u32 ,VB2ui; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG32U; } + typedef VertexBuffer2 VB2f; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG32F; } + typedef VertexBuffer2 VB2d; template<> inline VkFormat VertexBuffer2::GetDataType()const{return FMT_RG64F; } + + typedef VertexBuffer3 VB3i8 ,VB3b; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB8I; } + typedef VertexBuffer3 VB3i16 ,VB3s; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB16I; } + typedef VertexBuffer3 VB3i32 ,VB3i; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB32I; } + typedef VertexBuffer3 VB3u8 ,VB3ub; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB8U; } + typedef VertexBuffer3 VB3u16 ,VB3us; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB16U; } + typedef VertexBuffer3 VB3u32 ,VB3ui; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB32U; } + typedef VertexBuffer3 VB3f; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB32F; } + typedef VertexBuffer3 VB3d; template<> inline VkFormat VertexBuffer3::GetDataType()const{return FMT_RGB64F; } + + typedef VertexBuffer4 VB4i8 ,VB4b; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA8I; } + typedef VertexBuffer4 VB4i16 ,VB4s; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA16I; } + typedef VertexBuffer4 VB4i32 ,VB4i; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA32I; } + typedef VertexBuffer4 VB4u8 ,VB4ub; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA8U; } + typedef VertexBuffer4 VB4u16 ,VB4us; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA16U; } + typedef VertexBuffer4 VB4u32 ,VB4ui; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA32U; } + typedef VertexBuffer4 VB4f; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA32F; } + typedef VertexBuffer4 VB4d; template<> inline VkFormat VertexBuffer4::GetDataType()const{return FMT_RGBA64F; } + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_VERTEX_BUFFER_INCLUDE diff --git a/inc/hgl/graph/VertexBufferCreater.h b/inc/hgl/graph/VertexBufferCreater.h new file mode 100644 index 00000000..24b49aa2 --- /dev/null +++ b/inc/hgl/graph/VertexBufferCreater.h @@ -0,0 +1,48 @@ +#ifndef HGL_GRAPH_VERTEX_BUFFER_CREATER_INCLUDE +#define HGL_GRAPH_VERTEX_BUFFER_CREATER_INCLUDE + +#include +namespace hgl +{ + namespace graph + { + class VertexBufferCreater + { + void *mem_data; ///<内存中的数据 + + protected: + + const uint32_t dc_num; ///<每个数据成员数(比如二维坐标为2、三维坐标为3) + const uint32_t comp_stride; ///<单个成员数据字节数 + uint32_t count; ///<数据个数 + + const uint32_t stride; ///<每组数据字节数 + const uint32_t total_bytes; ///<字节数 + + void *mem_end; ///<内存数据区访问结束地址 + + public: + + VertexBufferCreater(uint32_t c,uint32_t dc,uint32_t cs):count(c),dc_num(dc),comp_stride(cs),stride(dc*cs),total_bytes(dc*cs*c) + { + mem_data = hgl_malloc(total_bytes); //在很多情况下,hgl_malloc分配的内存是对齐的,这样有效率上的提升 + mem_end = ((char *)mem_data) + total_bytes; + } + + virtual ~VertexBufferCreater() + { + if(mem_data) + hgl_free(mem_data); + } + + virtual VkFormat GetDataType ()const=0; ///<取得数据类型 +// const uint32_t GetDataBytes ()const{return comp_stride;} ///<取得每数据字节数 +// const uint32_t GetComponent ()const{return dc_num; } ///<取数缓冲区元数据数量 + const uint32_t GetCount ()const{return count; } ///<取得数据数量 + const uint32_t GetStride ()const{return stride;} ///<取得每一组数据字节数 + void * GetData ()const{return mem_data;} ///<取得数据指针 + const uint32_t GetTotalBytes ()const{return total_bytes; } ///<取得数据字节数 + };//class VertexBufferCreater + }//namespace graph +}//namespace hgl +#endif//HGL_GRAPH_VERTEX_BUFFER_CREATER_INCLUDE diff --git a/inc/hgl/graph/vulkan/VKDevice.h b/inc/hgl/graph/vulkan/VKDevice.h index ac86d53c..535c94c2 100644 --- a/inc/hgl/graph/vulkan/VKDevice.h +++ b/inc/hgl/graph/vulkan/VKDevice.h @@ -8,6 +8,7 @@ #include #include #include +#include VK_NAMESPACE_BEGIN class Device @@ -71,6 +72,7 @@ public: //Buffer相关 VertexBuffer * CreateVBO(VkFormat format,uint32_t count,const void *data,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE); VertexBuffer * CreateVBO(VkFormat format,uint32_t count,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE){return CreateVBO(format,count,nullptr,sharing_mode);} + VertexBuffer * CreateVBO(const VertexBufferCreater *vbc,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE){return CreateVBO(vbc->GetDataType(),vbc->GetCount(),vbc->GetData(),sharing_mode);} IndexBuffer * CreateIBO(VkIndexType index_type,uint32_t count,const void *data,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE); IndexBuffer * CreateIBO16(uint32_t count,const uint16 *data,VkSharingMode sharing_mode=VK_SHARING_MODE_EXCLUSIVE){return CreateIBO(VK_INDEX_TYPE_UINT16,count,(void *)data,sharing_mode);} diff --git a/inc/hgl/graph/vulkan/VKMaterial.h b/inc/hgl/graph/vulkan/VKMaterial.h index ff7fdec4..c6e7ac4d 100644 --- a/inc/hgl/graph/vulkan/VKMaterial.h +++ b/inc/hgl/graph/vulkan/VKMaterial.h @@ -28,6 +28,8 @@ public: Material(Device *dev,ShaderModuleMap *smm,List *,DescriptorSetLayoutCreater *dslc); ~Material(); + const VertexShaderModule *GetVertexShaderModule()const{return vertex_sm;} + const int GetBinding(VkDescriptorType,const UTF8String &)const; #define GET_BO_BINDING(name,vk_name) const int Get##name(const UTF8String &obj_name)const{return GetBinding(VK_DESCRIPTOR_TYPE_##vk_name,obj_name);} diff --git a/inc/hgl/graph/vulkan/VKRenderable.h b/inc/hgl/graph/vulkan/VKRenderable.h index 9104570d..61d868cb 100644 --- a/inc/hgl/graph/vulkan/VKRenderable.h +++ b/inc/hgl/graph/vulkan/VKRenderable.h @@ -8,7 +8,7 @@ VK_NAMESPACE_BEGIN * 可渲染数据对象
* 本对象包含材质实例信息和Mesh信息,可渲染数据对象中包含供最终API使用的VBO数据,可能存在多个MESH数据的集合。

* 比如有多种形状的石头,它们使用了同一种材质,这种情况下多个mesh就可以合并到一个Renderable中,渲染时不再切换VBO。 -*/ + */ class Renderable { const VertexShaderModule *vertex_sm; diff --git a/inc/hgl/math/Vector.h b/inc/hgl/math/Vector.h index 95a8ed82..e80208ec 100644 --- a/inc/hgl/math/Vector.h +++ b/inc/hgl/math/Vector.h @@ -255,5 +255,90 @@ namespace hgl result.x = center.x + ((source.x - center.x)*ac - (source.y - center.y)*as); result.y = center.y + ((source.x - center.x)*as + (source.y - center.y)*ac); } + + template union vec2 + { + struct { T x,y; }; + struct { T r,g; }; + T data[2]; + + public: + + vec2(){x=y=0;} + vec2(T v1,T v2):x(v1),y(v2){} + vec2(const vec2 &v2) + { + x=v2.x; + y=v2.y; + } + + vec2(const Vector2f &v2f) + { + x=v2f.x; + y=v2f.y; + } + + operator const Vector2f()const{return Vector2f(x,y);} + }; + + template union vec3 + { + struct { T x,y,z; }; + struct { T r,g,b; }; + T data[3]; + + public: + + vec3(){x=y=z=0;} + vec3(T v1,T v2,T v3):x(v1),y(v2),z(v3){} + vec3(const vec3 &v3) + { + x=v3.x; + y=v3.y; + z=v3.z; + } + + vec3(const Vector3f &v3f) + { + x=v3f.x; + y=v3f.y; + z=v3f.z; + + return *this; + } + + operator const Vector3f()const{return Vector3f(x,y,z);} + }; + + template union vec4 + { + struct { T x,y,z,w; }; + struct { T r,g,b,a; }; + T data[4]; + + public: + + vec4(){x=y=z=w=0;} + vec4(T v1,T v2,T v3,T v4):x(v1),y(v2),z(v3),w(v4){} + vec4(const vec4 &v4) + { + x=v4.x; + y=v4.y; + z=v4.z; + w=v4.w; + } + + vec4(const Vector4f &v4f) + { + x=v4f.x; + y=v4f.y; + z=v4f.z; + w=v4f.w; + + return *this; + } + + operator const Vector4f()const{return Vector4f(x,y,z,w);} + }; }//namespace hgl #endif//HGL_ALGORITHM_MATH_VECTOR_INCLUDE diff --git a/inc/hgl/type/RectScope.h b/inc/hgl/type/RectScope.h index 777d062a..893e1594 100644 --- a/inc/hgl/type/RectScope.h +++ b/inc/hgl/type/RectScope.h @@ -9,7 +9,7 @@ namespace hgl */ template class RectScope2 ///矩形范围类 { - public: + protected: T Left; ///<矩形左边所在的坐标 T Top; ///<矩形上边所在的坐标 @@ -18,14 +18,28 @@ namespace hgl public: - T GetBottom()const{return Height+Top;} - T GetRight()const{return Width+Left;} - void SetBottom(T v){Top=v-Height;} - void SetRight(T v){Left=v-Width;} + T GetLeft ()const{return Left;} + T GetTop ()const{return Top;} + T GetWidth ()const{return Width;} + T GetHeight ()const{return Height;} + T GetBottom ()const{return Height+Top;} + T GetRight ()const{return Width+Left;} + + void SetLeft (T v){Left=v;} + void SetTop (T v){Top=v;} + void SetWidth (T v){Width=v;} + void SetHeight (T v){Height=v;} + void SetBottom (T v){Height=v-Top;} + void SetRight (T v){Width=v-Left;} T GetCenterX()const{return Left+(Width/2);} T GetCenterY()const{return Top+(Height/2);} + const vec2 GetLeftTop ()const{return vec2(Left, Top);} + const vec2 GetLeftBottom ()const{return vec2(Left, Top+Height);} + const vec2 GetRightTop ()const{return vec2(Left+Width, Top);} + const vec2 GetRightBottom()const{return vec2(Left+Width, Top+Height);} + public: RectScope2(); diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index af9efa61..5b0413ee 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -2,7 +2,9 @@ SET(SCENE_GRAPH_HEADER ${ROOT_INCLUDE_PATH}/hgl/graph/AABox.h ${ROOT_INCLUDE_PATH}/hgl/graph/Camera.h ${ROOT_INCLUDE_PATH}/hgl/graph/Light.h ${ROOT_INCLUDE_PATH}/hgl/graph/SceneNode.h - ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h) + ${ROOT_INCLUDE_PATH}/hgl/graph/SceneOrient.h + ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBufferCreater.h + ${ROOT_INCLUDE_PATH}/hgl/graph/VertexBuffer.h) SET(SCENE_GRAPH_SOURCE AABox.cpp Camera.cpp