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