1188 lines
37 KiB
C++
1188 lines
37 KiB
C++
#ifndef HGL_GRAPH_VERTEX_ATTRIB_DATA_ACCESS_INCLUDE
|
||
#define HGL_GRAPH_VERTEX_ATTRIB_DATA_ACCESS_INCLUDE
|
||
|
||
#include<hgl/type/Color3f.h>
|
||
#include<hgl/type/Color4f.h>
|
||
#include<hgl/type/RectScope.h>
|
||
#include<hgl/type/BaseString.h>
|
||
#include<hgl/graph/VertexAttribData.h>
|
||
#include<hgl/log/LogInfo.h>
|
||
namespace hgl
|
||
{
|
||
namespace graph
|
||
{
|
||
/**
|
||
* 顶点属性数据访问模板
|
||
*/
|
||
template<typename T,int C> class VertexAttribDataAccess
|
||
{
|
||
protected:
|
||
|
||
T *mem_type; ///<符合当前类型的地址
|
||
T *access; ///<当前访问地址
|
||
|
||
T *start; ///<访问起始地址
|
||
|
||
public:
|
||
|
||
VertexAttribDataAccess(uint32_t _size,const T *_data=nullptr)
|
||
{
|
||
mem_type=(T *)GetData();
|
||
access=0;
|
||
start=0;
|
||
|
||
if(_data)
|
||
memcpy(mem_type,_data,total_bytes);
|
||
}
|
||
|
||
virtual ~VertexAttribDataAccess()=default;
|
||
|
||
void BufferData(const T *ptr)
|
||
{
|
||
if(!ptr)return;
|
||
|
||
memcpy(mem_type,ptr,total_bytes);
|
||
}
|
||
|
||
/**
|
||
* 取得数据区地址
|
||
* @param offset 从第几个数据开始访问
|
||
* @return 访问地址
|
||
*/
|
||
T *Get(uint32_t offset=0)
|
||
{
|
||
if(!mem_type||offset>=count)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribBuffer::Get() out,offset:")+OSString::valueOf(offset));
|
||
return(nullptr);
|
||
}
|
||
|
||
return mem_type+offset*C;
|
||
}
|
||
|
||
/**
|
||
* 开始访问数据区
|
||
* @param offset 从第几个数据开始访问
|
||
* @return 访问地址
|
||
*/
|
||
void *Begin(uint32_t offset=0)
|
||
{
|
||
if(access)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribBuffer::Begin() access!=0,offset:")+OSString::valueOf(offset));
|
||
return(nullptr);
|
||
}
|
||
|
||
access=Get(offset);
|
||
|
||
if(access)
|
||
start=access;
|
||
|
||
return access;
|
||
}
|
||
|
||
/**
|
||
* 结束访问
|
||
*/
|
||
void End()
|
||
{
|
||
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("VertexAttribBuffer::Write(const T *,number) out,number:")+OSString::valueOf(number));
|
||
return(false);
|
||
}
|
||
|
||
memcpy(access,vp,C*number*sizeof(T));
|
||
|
||
access+=C*number;
|
||
|
||
return(true);
|
||
}
|
||
};//class VertexAttribBuffer
|
||
|
||
/**
|
||
* 一元数据缓冲区
|
||
*/
|
||
template<typename T,VkFormat VKFMT> class VertexAttribDataAccess1:public VertexAttribDataAccess<T,1>
|
||
{
|
||
public:
|
||
|
||
using VertexAttribDataAccess<T,1>::VertexAttribDataAccess;
|
||
virtual ~VertexAttribDataAccess1()=default;
|
||
|
||
static VertexAttribDataAccess1<T,VKFMT> * Create(VertexAttribData *vad)
|
||
{
|
||
if(!vad)return(nullptr);
|
||
|
||
if(vad->GetComponent()!=1)
|
||
return(nullptr);
|
||
|
||
if(vad->GetDataType()!=VKFMT)
|
||
return(nullptr);
|
||
|
||
return(new VertexAttribDataAccess1<T,VKFMT>(vad->GetCount(),vad->GetData()));
|
||
}
|
||
|
||
/**
|
||
* 计算绑定盒
|
||
* @param min_vertex 最小值坐标
|
||
* @param max_vertex 最大值坐标
|
||
*/
|
||
template<typename V>
|
||
void GetBoundingBox(V &min_vertex,V &max_vertex) const
|
||
{
|
||
T *p=this->mem_type;
|
||
|
||
//先以corner为最小值,length为最大值,求取最小最大值
|
||
min_vertex.x=*p++;
|
||
|
||
max_vertex=min_vertex;
|
||
|
||
for(uint32_t i=1;i<this->count;i++)
|
||
{
|
||
if(*p<min_vertex.x)min_vertex.x=*p;
|
||
if(*p>max_vertex.x)max_vertex.x=*p;
|
||
++p;
|
||
}
|
||
}
|
||
|
||
AABB GetAABB()const
|
||
{
|
||
vec min_point,max_point;
|
||
|
||
GetBoundingBox(min_point,max_point);
|
||
|
||
min_point.y=0;
|
||
min_point.z=0;
|
||
min_point.w=0;
|
||
|
||
max_point.y=0;
|
||
max_point.z=0;
|
||
max_point.w=0;
|
||
|
||
return AABB(min_point,max_point);
|
||
}
|
||
|
||
bool Write(const T v1)
|
||
{
|
||
if(!this->access||this->access+1>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess1::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("VertexAttribDataAccess1::Write(const T,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
hgl_set(this->access,v,count);
|
||
this->access+=count;
|
||
return(true);
|
||
}
|
||
};//class VertexAttribDataAccess1
|
||
|
||
/**
|
||
* 二元数据缓冲区
|
||
*/
|
||
template<typename T,VkFormat VKFMT> class VertexAttribDataAccess2:public VertexAttribDataAccess<T,2>
|
||
{
|
||
public:
|
||
|
||
using VertexAttribDataAccess<T,2>::VertexAttribDataAccess;
|
||
virtual ~VertexAttribDataAccess2()=default;
|
||
|
||
static VertexAttribDataAccess2<T,VKFMT> * Create(VertexAttribData *vad)
|
||
{
|
||
if(!vad)return(nullptr);
|
||
|
||
if(vad->GetComponent()!=2)
|
||
return(nullptr);
|
||
|
||
if(vad->GetDataType()!=VKFMT)
|
||
return(nullptr);
|
||
|
||
return(new VertexAttribDataAccess2<T,VKFMT>(vad->GetCount(),vad->GetData()));
|
||
}
|
||
|
||
/**
|
||
* 计算绑定盒
|
||
* @param min_vertex 最小值坐标
|
||
* @param max_vertex 最大值坐标
|
||
*/
|
||
template<typename V>
|
||
void GetBoundingBox(V &min_vertex,V &max_vertex) const
|
||
{
|
||
T *p=this->mem_type;
|
||
|
||
//先以corner为最小值,length为最大值,求取最小最大值
|
||
min_vertex.x=*p++;
|
||
min_vertex.y=*p++;
|
||
|
||
max_vertex=min_vertex;
|
||
|
||
for(uint32_t i=1;i<this->count;i++)
|
||
{
|
||
if(*p<min_vertex.x)min_vertex.x=*p;
|
||
if(*p>max_vertex.x)max_vertex.x=*p;
|
||
++p;
|
||
|
||
if(*p<min_vertex.y)min_vertex.y=*p;
|
||
if(*p>max_vertex.y)max_vertex.y=*p;
|
||
++p;
|
||
}
|
||
}
|
||
|
||
AABB GetAABB()const
|
||
{
|
||
vec min_point,max_point;
|
||
|
||
GetBoundingBox(min_point,max_point);
|
||
|
||
min_point.z=0;
|
||
min_point.w=0;
|
||
max_point.z=0;
|
||
max_point.w=0;
|
||
|
||
return AABB(min_point,max_point);
|
||
}
|
||
|
||
bool Write(const T v1,const T v2)
|
||
{
|
||
if(!this->access||this->access+2>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::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("VertexAttribDataAccess2::Write(T *) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=*v++;
|
||
*this->access++=*v;
|
||
|
||
return(true);
|
||
}
|
||
|
||
template<typename V2>
|
||
bool Write(const V2 &v)
|
||
{
|
||
if(!this->access||this->access+2>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::Write(vec2 &) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=v.x;
|
||
*this->access++=v.y;
|
||
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
* 将一个值重复多次写入缓冲区
|
||
* @param v 值
|
||
* @param count 写入数量
|
||
*/
|
||
template<typename V2>
|
||
bool Fill(const V2 &v,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(count<<1)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess1::Write(const Vector2f &,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=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("VertexAttribDataAccess2::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<typename V2>
|
||
bool WriteLine(const V2 &start,const V2 &end)
|
||
{
|
||
if(!this->access||this->access+4>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::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<typename V2>
|
||
bool WriteTriangle(const V2 &v1,const V2 &v2,const V2 &v3)
|
||
{
|
||
if(!this->access||this->access+6>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::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<typename V2>
|
||
bool WriteTriangle(const V2 *v)
|
||
{
|
||
if(!this->access||this->access+6>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::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<typename V2>
|
||
bool WriteQuad(const V2 <,const V2 &rt,const V2 &rb,const V2 &lb)
|
||
{
|
||
if(WriteTriangle(lt,lb,rb))
|
||
if(WriteTriangle(lt,rb,rt))
|
||
return(true);
|
||
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::WriteQuad(vec2 &,vec2 &,vec2 &,vec2 &) error"));
|
||
return(false);
|
||
}
|
||
|
||
/**
|
||
* 写入2D矩形(两个三角形)坐标数据
|
||
*/
|
||
template<typename V>
|
||
bool WriteRect(const T left,const T top,const T width,const T height)
|
||
{
|
||
const vec2<V> lt(left ,top);
|
||
const vec2<V> rt(left+width,top);
|
||
const vec2<V> rb(left+width,top+height);
|
||
const vec2<V> lb(left ,top+height);
|
||
|
||
return WriteQuad(lt,rt,rb,lb);
|
||
}
|
||
|
||
template<typename V>
|
||
bool WriteRect(const RectScope2<V> &scope)
|
||
{
|
||
return WriteQuad( scope.GetLeftTop(),
|
||
scope.GetRightTop(),
|
||
scope.GetRightBottom(),
|
||
scope.GetLeftBottom());
|
||
}
|
||
|
||
template<typename V>
|
||
bool WriteRectFan(const RectScope2<V> &scope)
|
||
{
|
||
if(!this->access||this->access+8>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::WriteRectFan(RectScope2 *) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=scope.GetLeft();
|
||
*this->access++=scope.GetBottom();
|
||
|
||
*this->access++=scope.GetRight();
|
||
*this->access++=scope.GetBottom();
|
||
|
||
*this->access++=scope.GetRight();
|
||
*this->access++=scope.GetTop();
|
||
|
||
*this->access++=scope.GetLeft();
|
||
*this->access++=scope.GetTop();
|
||
|
||
return(true);
|
||
}
|
||
|
||
template<typename V>
|
||
bool WriteRectTriangleStrip(const RectScope2<V> &scope)
|
||
{
|
||
if(!this->access||this->access+8>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess2::WriteRectTriangleStrip(RectScope2 *) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=scope.GetLeft();
|
||
*this->access++=scope.GetTop();
|
||
|
||
*this->access++=scope.GetLeft();
|
||
*this->access++=scope.GetBottom();
|
||
|
||
*this->access++=scope.GetRight();
|
||
*this->access++=scope.GetTop();
|
||
|
||
*this->access++=scope.GetRight();
|
||
*this->access++=scope.GetBottom();
|
||
|
||
return(true);
|
||
}
|
||
};//class VertexAttribDataAccess2
|
||
|
||
/**
|
||
* 三元数据缓冲区
|
||
*/
|
||
template<typename T,VkFormat VKFMT> class VertexAttribDataAccess3:public VertexAttribDataAccess<T,3>
|
||
{
|
||
public:
|
||
|
||
using VertexAttribDataAccess<T,3>::VertexAttribDataAccess;
|
||
virtual ~VertexAttribDataAccess3()=default;
|
||
|
||
static VertexAttribDataAccess3<T,VKFMT> * Create(VertexAttribData *vad)
|
||
{
|
||
if(!vad)return(nullptr);
|
||
|
||
if(vad->GetComponent()!=3)
|
||
return(nullptr);
|
||
|
||
if(vad->GetDataType()!=VMFKT)
|
||
return(nullptr);
|
||
|
||
return(new VertexAttribDataAccess3<T,VKFMT>(vad->GetCount(),vad->GetData()));
|
||
}
|
||
|
||
/**
|
||
* 计算绑定盒
|
||
* @param min_vertex 最小值坐标
|
||
* @param max_vertex 最大值坐标
|
||
*/
|
||
template<typename V>
|
||
void GetBoundingBox(V &min_vertex,V &max_vertex) const
|
||
{
|
||
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;i<this->count;i++)
|
||
{
|
||
if(*p<min_vertex.x)min_vertex.x=*p;
|
||
if(*p>max_vertex.x)max_vertex.x=*p;
|
||
++p;
|
||
|
||
if(*p<min_vertex.y)min_vertex.y=*p;
|
||
if(*p>max_vertex.y)max_vertex.y=*p;
|
||
++p;
|
||
|
||
if(*p<min_vertex.z)min_vertex.z=*p;
|
||
if(*p>max_vertex.z)max_vertex.z=*p;
|
||
++p;
|
||
}
|
||
}
|
||
|
||
AABB GetAABB()const
|
||
{
|
||
vec min_point,max_point;
|
||
|
||
GetBoundingBox(min_point,max_point);
|
||
|
||
min_point.w=0;
|
||
max_point.w=0;
|
||
|
||
return AABB(min_point,max_point);
|
||
}
|
||
|
||
bool Write(const T v1,const T v2,const T v3)
|
||
{
|
||
if(!this->access||this->access+3>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::Write(T,T,T) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=v1;
|
||
*this->access++=v2;
|
||
*this->access++=v3;
|
||
|
||
return(true);
|
||
}
|
||
|
||
bool Write3(const T *v)
|
||
{
|
||
if(!this->access||this->access+3>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::Write(T *) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=*v++;
|
||
*this->access++=*v++;
|
||
*this->access++=*v;
|
||
|
||
return(true);
|
||
}
|
||
|
||
template<typename V3>
|
||
bool Write(const V3 &v)
|
||
{
|
||
if(!this->access||this->access+3>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::Write(vec3 &) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=v.x;
|
||
*this->access++=v.y;
|
||
*this->access++=v.z;
|
||
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
* 将一个值重复多次写入缓冲区
|
||
* @param v 值
|
||
* @param count 写入数量
|
||
*/
|
||
template<typename V3>
|
||
bool Fill(const V3 &v,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(count*3)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::Write(const Vector3f,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=v.x;
|
||
*this->access++=v.y;
|
||
*this->access++=v.z;
|
||
}
|
||
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
* 写入多个值到缓冲区
|
||
* @param v 值
|
||
* @param count 写入数量
|
||
*/
|
||
template<typename V3>
|
||
bool Write(const V3 *v,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(count*3)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::Write(const Vector3f,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=v->x;
|
||
*this->access++=v->y;
|
||
*this->access++=v->z;
|
||
|
||
++v;
|
||
}
|
||
|
||
return(true);
|
||
}
|
||
|
||
bool Write(const Color3f &v)
|
||
{
|
||
if(!this->access||this->access+3>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::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("VertexAttribDataAccess3::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<typename V3>
|
||
bool WriteLine(const V3 &start,const V3 &end)
|
||
{
|
||
if(!this->access||this->access+6>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::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<typename V3>
|
||
bool WriteTriangle(const V3 &v1,const V3 &v2,const V3 &v3)
|
||
{
|
||
if(!this->access||this->access+9>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::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<typename V3>
|
||
bool WriteTriangle(const V3 *v)
|
||
{
|
||
if(!this->access||this->access+9>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess3::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 VertexAttribDataAccess3
|
||
|
||
/**
|
||
* 四元数据缓冲区
|
||
*/
|
||
template<typename T,VkFormat VKFMT> class VertexAttribDataAccess4:public VertexAttribDataAccess<T,4>
|
||
{
|
||
public:
|
||
|
||
using VertexAttribDataAccess<T,4>::VertexAttribDataAccess;
|
||
virtual ~VertexAttribDataAccess4()=default;
|
||
|
||
static VertexAttribDataAccess4<T,VKFMT> * Create(VertexAttribData *vad)
|
||
{
|
||
if(!vad)return(nullptr);
|
||
|
||
if(vad->GetComponent()!=4)
|
||
return(nullptr);
|
||
|
||
if(vad->GetDataType()!=VMFMT)
|
||
return(nullptr);
|
||
|
||
return(new VertexAttribDataAccess4<T,VKFMT>(vad->GetCount(),vad->GetData()));
|
||
}
|
||
|
||
/**
|
||
* 计算绑定盒
|
||
* @param min_vertex 最小值坐标
|
||
* @param max_vertex 最大值坐标
|
||
*/
|
||
template<typename V>
|
||
void GetBoundingBox(V &min_vertex,V &max_vertex) const
|
||
{
|
||
T *p=this->mem_type;
|
||
|
||
//先以corner为最小值,length为最大值,求取最小最大值
|
||
min_vertex.x=*p++;
|
||
min_vertex.y=*p++;
|
||
min_vertex.z=*p++;
|
||
++p;
|
||
|
||
max_vertex=min_vertex;
|
||
|
||
for(uint32_t i=1;i<this->count;i++)
|
||
{
|
||
if(*p<min_vertex.x)min_vertex.x=*p;
|
||
if(*p>max_vertex.x)max_vertex.x=*p;
|
||
++p;
|
||
|
||
if(*p<min_vertex.y)min_vertex.y=*p;
|
||
if(*p>max_vertex.y)max_vertex.y=*p;
|
||
++p;
|
||
|
||
if(*p<min_vertex.z)min_vertex.z=*p;
|
||
if(*p>max_vertex.z)max_vertex.z=*p;
|
||
++p;
|
||
|
||
++p;
|
||
}
|
||
}
|
||
|
||
AABB GetAABB()const
|
||
{
|
||
vec min_point,max_point;
|
||
|
||
GetBoundingBox(min_point,max_point);
|
||
|
||
min_point.w=0;
|
||
max_point.w=0;
|
||
|
||
return AABB(min_point,max_point);
|
||
}
|
||
|
||
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("VertexAttribDataAccess4::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("VertexAttribDataAccess4::Write(T *) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=*v++;
|
||
*this->access++=*v++;
|
||
*this->access++=*v++;
|
||
*this->access++=*v;
|
||
|
||
return(true);
|
||
}
|
||
|
||
template<typename V4>
|
||
bool Write(const V4 &v)
|
||
{
|
||
if(!this->access||this->access+4>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::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("VertexAttribDataAccess4::Write(color4 &) out"));
|
||
return(false);
|
||
}
|
||
|
||
*this->access++=v.r;
|
||
*this->access++=v.g;
|
||
*this->access++=v.b;
|
||
*this->access++=v.a;
|
||
|
||
return(true);
|
||
}
|
||
|
||
bool Fill(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("VertexAttribDataAccess4::Write(color4 &,count) out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=v.r;
|
||
*this->access++=v.g;
|
||
*this->access++=v.b;
|
||
*this->access++=v.a;
|
||
}
|
||
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
* 将一个值重复多次写入缓冲区
|
||
* @param v 值
|
||
* @param count 写入数量
|
||
*/
|
||
template<typename V4>
|
||
bool Fill(const V4 &v,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(count<<2)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::Write(const Vector4f,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=v.x;
|
||
*this->access++=v.y;
|
||
*this->access++=v.z;
|
||
*this->access++=v.w;
|
||
}
|
||
|
||
return(true);
|
||
}
|
||
|
||
/**
|
||
* 将多个值写入缓冲区
|
||
* @param v 值
|
||
* @param count 写入数量
|
||
*/
|
||
template<typename V4>
|
||
bool Write(const V4 *v,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(count<<2)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::Write(const Vector4f,")+OSString::valueOf(count)+OS_TEXT(") out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=v->x;
|
||
*this->access++=v->y;
|
||
*this->access++=v->z;
|
||
*this->access++=v->w;
|
||
|
||
++v;
|
||
}
|
||
|
||
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("VertexAttribDataAccess4::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<typename V4>
|
||
bool WriteLine(const V4 &start,const V4 &end)
|
||
{
|
||
if(!this->access||this->access+8>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::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<typename V4>
|
||
bool WriteTriangle(const V4 &v1,const V4 &v2,const V4 &v3)
|
||
{
|
||
if(!this->access||this->access+12>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::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<typename V4>
|
||
bool WriteTriangle(const V4 *v)
|
||
{
|
||
if(!this->access||this->access+12>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::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<typename V>
|
||
bool WriteRectangle2D(const RectScope2<V> &rect)
|
||
{
|
||
if(!this->access||this->access+4>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::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<typename V>
|
||
bool WriteRectangle2D(const RectScope2<V> *rect,const uint32_t count)
|
||
{
|
||
if(!this->access||this->access+(4*count)>this->mem_end)
|
||
{
|
||
LOG_HINT(OS_TEXT("VertexAttribDataAccess4::WriteRectangle2D(RectScope2 *,count) out"));
|
||
return(false);
|
||
}
|
||
|
||
for(uint32_t i=0;i<count;i++)
|
||
{
|
||
*this->access++=rect->Left;
|
||
*this->access++=rect->Top;
|
||
*this->access++=rect->Width;
|
||
*this->access++=rect->Height;
|
||
|
||
++rect;
|
||
}
|
||
|
||
return(true);
|
||
}
|
||
};//class VertexAttribDataAccess4
|
||
|
||
//缓冲区具体数据类型定义
|
||
typedef VertexAttribDataAccess1<int8 ,FMT_R8I > VB1i8 ,VB1b;
|
||
typedef VertexAttribDataAccess1<int16 ,FMT_R16I > VB1i16 ,VB1s;
|
||
typedef VertexAttribDataAccess1<int32 ,FMT_R32I > VB1i32 ,VB1i;
|
||
typedef VertexAttribDataAccess1<uint8 ,FMT_R8U > VB1u8 ,VB1ub;
|
||
typedef VertexAttribDataAccess1<uint16,FMT_R16U > VB1u16 ,VB1us;
|
||
typedef VertexAttribDataAccess1<uint32,FMT_R32U > VB1u32 ,VB1ui;
|
||
typedef VertexAttribDataAccess1<float ,FMT_R32F > VB1f;
|
||
typedef VertexAttribDataAccess1<double,FMT_R64F > VB1d;
|
||
|
||
typedef VertexAttribDataAccess2<int8 ,FMT_RG8I > VB2i8 ,VB2b;
|
||
typedef VertexAttribDataAccess2<int16 ,FMT_RG16I > VB2i16 ,VB2s;
|
||
typedef VertexAttribDataAccess2<int32 ,FMT_RG32I > VB2i32 ,VB2i;
|
||
typedef VertexAttribDataAccess2<uint8 ,FMT_RG8U > VB2u8 ,VB2ub;
|
||
typedef VertexAttribDataAccess2<uint16,FMT_RG16U > VB2u16 ,VB2us;
|
||
typedef VertexAttribDataAccess2<uint32,FMT_RG32U > VB2u32 ,VB2ui;
|
||
typedef VertexAttribDataAccess2<float ,FMT_RG32F > VB2f;
|
||
typedef VertexAttribDataAccess2<double,FMT_RG64F > VB2d;
|
||
|
||
// typedef VertexAttribDataAccess3<int8 ,FMT_RGB8I > VB3i8 ,VB3b;
|
||
// typedef VertexAttribDataAccess3<int16 ,FMT_RGB16I > VB3i16 ,VB3s;
|
||
typedef VertexAttribDataAccess3<int32 ,FMT_RGB32I > VB3i32 ,VB3i;
|
||
// typedef VertexAttribDataAccess3<uint8 ,FMT_RGB8U > VB3u8 ,VB3ub;
|
||
// typedef VertexAttribDataAccess3<uint16,FMT_RGB16U > VB3u16 ,VB3us;
|
||
typedef VertexAttribDataAccess3<uint32,FMT_RGB32U > VB3u32 ,VB3ui;
|
||
typedef VertexAttribDataAccess3<float ,FMT_RGB32F > VB3f;
|
||
typedef VertexAttribDataAccess3<double,FMT_RGB64F > VB3d;
|
||
|
||
typedef VertexAttribDataAccess4<int8 ,FMT_RGBA8I > VB4i8 ,VB4b;
|
||
typedef VertexAttribDataAccess4<int16 ,FMT_RGBA16I> VB4i16 ,VB4s;
|
||
typedef VertexAttribDataAccess4<int32 ,FMT_RGBA32I> VB4i32 ,VB4i;
|
||
typedef VertexAttribDataAccess4<uint8 ,FMT_RGBA8U > VB4u8 ,VB4ub;
|
||
typedef VertexAttribDataAccess4<uint16,FMT_RGBA16U> VB4u16 ,VB4us;
|
||
typedef VertexAttribDataAccess4<uint32,FMT_RGBA32U> VB4u32 ,VB4ui;
|
||
typedef VertexAttribDataAccess4<float ,FMT_RGBA32F> VB4f;
|
||
typedef VertexAttribDataAccess4<double,FMT_RGBA64F> VB4d;
|
||
|
||
/**
|
||
* 根据格式要求,创建对应的顶点属性数据区(VAD)
|
||
* @param base_type 基础格式,参见spirv_cross/spirv_common.hpp中的spirv_cross::SPIRType
|
||
* @param vecsize vec数量
|
||
* @param vertex_count 顶点数量
|
||
*/
|
||
VertexAttribData *CreateVertexAttribData(const uint32_t base_type,const uint32_t vecsize,const uint32_t vertex_count);
|
||
|
||
|
||
}//namespace graph
|
||
}//namespace hgl
|
||
#endif//HGL_GRAPH_VERTEX_ATTRIB_DATA_ACCESS_INCLUDE
|