瀏覽代碼

easymesh : Vertex attribute name can now be customize. Vertex declaration code simplification, ASSERT is more understandable.

legacy
Benjamin ‘Touky’ Huet touky 11 年之前
父節點
當前提交
ea603d48e3
共有 3 個檔案被更改,包括 142 行新增31 行删除
  1. +83
    -31
      src/easymesh/easymesh.cpp
  2. +5
    -0
      src/easymesh/easymesh.h
  3. +54
    -0
      src/lol/gpu/vertexbuffer.h

+ 83
- 31
src/easymesh/easymesh.cpp 查看文件

@@ -141,11 +141,6 @@ void DefaultShaderData::SetupDefaultData(bool with_UV)
AddUniform("in_NormalMat");
AddUniform("in_Damage");
AddUniform("u_Lights");
AddAttribute("in_Vertex", VertexUsage::Position, 0);
AddAttribute("in_Normal", VertexUsage::Normal, 0);
AddAttribute("in_Color", VertexUsage::Color, 0);
if (with_UV)
AddAttribute("in_TexCoord", VertexUsage::TexCoord, 0);
}

//-----------------------------------------------------------------------------
@@ -193,9 +188,33 @@ GpuEasyMeshData::~GpuEasyMeshData()
delete(m_ibo);
}

#define BUILD_VFLAG(bool_value, flag_value, check_flag) \
bool bool_value = (check_flag & (1 << flag_value)) != 0; \
check_flag &= ~(1 << flag_value);
#define BUILD_VFLAG_OR(bool_value, flag_value, check_flag) \
bool_value = (bool_value || (check_flag & (1 << flag_value)) != 0); \
check_flag &= ~(1 << flag_value);
#define BUILD_VFLAG_COUNT(bool_value, flag_value, check_flag, count_value) \
BUILD_VFLAG(bool_value, flag_value, check_flag) \
count_value += (int)bool_value;

//-----------------------------------------------------------------------------
void GpuEasyMeshData::AddGpuData(GpuShaderData* gpudata, EasyMesh* src_mesh)
{
uint16_t vflags = gpudata->m_vert_decl_flags;

BUILD_VFLAG(has_position, VertexUsage::Position, vflags);
BUILD_VFLAG(has_normal, VertexUsage::Normal, vflags);
BUILD_VFLAG(has_color, VertexUsage::Color, vflags);
BUILD_VFLAG(has_texcoord, VertexUsage::TexCoord, vflags);
BUILD_VFLAG_OR(has_texcoord, VertexUsage::TexCoordExt, vflags);
ASSERT(!vflags, String("Vertex Useage setup is not implemented for : ") + VertexUsage::GetNameList(vflags) + String(", feel free to do so."));

if (has_position) gpudata->AddAttribute(gpudata->GetInVertexName(), VertexUsage::Position, 0);
if (has_normal) gpudata->AddAttribute(gpudata->GetInNormalName(), VertexUsage::Normal, 0);
if (has_color) gpudata->AddAttribute(gpudata->GetInColorName(), VertexUsage::Color, 0);
if (has_texcoord) gpudata->AddAttribute(gpudata->GetInTexCoordName(), VertexUsage::TexCoord, 0);

SetupVertexData(gpudata->m_vert_decl_flags, src_mesh);

if (!m_ibo)
@@ -226,10 +245,10 @@ void GpuEasyMeshData::AddGpuData(GpuShaderData* gpudata, EasyMesh* src_mesh)
}

//-----------------------------------------------------------------------------
void GpuEasyMeshData::SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh)
void GpuEasyMeshData::SetupVertexData(uint16_t vflags, EasyMesh* src_mesh)
{
for (int i = 0; i < m_vdatas.Count(); ++i)
if (m_vdatas[i].m1 == vdecl_flags)
if (m_vdatas[i].m1 == vflags)
return;

VertexDeclaration* new_vdecl = nullptr;
@@ -243,10 +262,17 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh)
memcpy(mesh, vbo_data, vbo_bytes); \
new_vbo->Unlock();

uint16_t baseflag = (1 << VertexUsage::Position) | (1 << VertexUsage::Normal) | (1 << VertexUsage::Color);
if (vdecl_flags == (baseflag | (1 << VertexUsage::TexCoordExt)) ||
vdecl_flags == (baseflag | (1 << VertexUsage::TexCoord) |
(1 << VertexUsage::TexCoordExt)))
//Keep a count of the flags
uint16_t saveflags = vflags;
int flagnb = 0;
BUILD_VFLAG_COUNT(has_position, VertexUsage::Position, saveflags, flagnb);
BUILD_VFLAG_COUNT(has_normal, VertexUsage::Normal, saveflags, flagnb);
BUILD_VFLAG_COUNT(has_color, VertexUsage::Color, saveflags, flagnb);
BUILD_VFLAG_COUNT(has_texcoord, VertexUsage::TexCoord, saveflags, flagnb);
BUILD_VFLAG_COUNT(has_texcoordExt,VertexUsage::TexCoordExt, saveflags, flagnb);
ASSERT(!saveflags, String("Vertex Declaration setup is not implemented for : ") + VertexUsage::GetNameList(vflags) + String(", feel free to do so."));

if (has_position && has_normal && has_color && has_texcoord && has_texcoordExt && flagnb == 5)
{
new_vdecl = new VertexDeclaration(
VertexStream<vec3,vec3,u8vec4,vec4>(
@@ -268,7 +294,35 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh)

COPY_VBO;
}
else if (vdecl_flags == (baseflag | (1 << VertexUsage::TexCoord)))
else if (has_position && has_texcoord && has_texcoordExt && flagnb == 3)
{
new_vdecl = new VertexDeclaration(VertexStream<vec3,vec4>(VertexUsage::Position, VertexUsage::TexCoord));

Array<vec3, vec4> vertexlist;
for (int i = 0; i < src_mesh->m_vert.Count(); i++)
vertexlist.Push(src_mesh->m_vert[i].m_coord, src_mesh->m_vert[i].m_texcoord);

vbo_data = &vertexlist[0];
vbo_bytes = vertexlist.Bytes();
m_vertexcount = vertexlist.Count();

COPY_VBO;
}
else if (has_position && has_texcoord && flagnb == 2)
{
new_vdecl = new VertexDeclaration(VertexStream<vec3,vec2>(VertexUsage::Position, VertexUsage::TexCoord));

Array<vec3, vec2> vertexlist;
for (int i = 0; i < src_mesh->m_vert.Count(); i++)
vertexlist.Push(src_mesh->m_vert[i].m_coord, src_mesh->m_vert[i].m_texcoord.xy);

vbo_data = &vertexlist[0];
vbo_bytes = vertexlist.Bytes();
m_vertexcount = vertexlist.Count();

COPY_VBO;
}
else if (has_position && has_normal && has_color && has_texcoord && flagnb == 4)
{
new_vdecl = new VertexDeclaration(
VertexStream<vec3,vec3,u8vec4,vec2>(
@@ -290,7 +344,7 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh)

COPY_VBO;
}
else if (vdecl_flags == baseflag)
else if (has_position && has_normal && has_color && flagnb == 3)
{
new_vdecl = new VertexDeclaration(
VertexStream<vec3,vec3,u8vec4>(
@@ -311,7 +365,7 @@ void GpuEasyMeshData::SetupVertexData(uint16_t vdecl_flags, EasyMesh* src_mesh)
COPY_VBO;
}

m_vdatas.Push(vdecl_flags, new_vdecl, new_vbo);
m_vdatas.Push(vflags, new_vdecl, new_vbo);
}

//-----------------------------------------------------------------------------
@@ -337,24 +391,22 @@ void GpuEasyMeshData::RenderMeshData(mat4 const &model)

vdecl->Bind();

uint16_t baseflag = (1 << VertexUsage::Position) | (1 << VertexUsage::Normal) | (1 << VertexUsage::Color);
if (vflags == (baseflag | (1 << VertexUsage::TexCoord)) ||
vflags == (baseflag | (1 << VertexUsage::TexCoordExt)) ||
vflags == (baseflag | (1 << VertexUsage::TexCoord) |
(1 << VertexUsage::TexCoordExt)))
BUILD_VFLAG(has_position, VertexUsage::Position, vflags);
BUILD_VFLAG(has_normal, VertexUsage::Normal, vflags);
BUILD_VFLAG(has_color, VertexUsage::Color, vflags);
BUILD_VFLAG(has_texcoord, VertexUsage::TexCoord, vflags);
BUILD_VFLAG_OR(has_texcoord,VertexUsage::TexCoordExt, vflags);
ASSERT(!vflags, String("Vertex Stream setup is not implemented for : ") + VertexUsage::GetNameList(vflags) + String(", feel free to do so."));

{
vdecl->SetStream(vbo, *gpu_sd.GetAttribute(lol::String("in_Vertex")),
*gpu_sd.GetAttribute(lol::String("in_Normal")),
*gpu_sd.GetAttribute(lol::String("in_Color")),
*gpu_sd.GetAttribute(lol::String("in_TexCoord")));
}
else if (vflags == baseflag)
{
vdecl->SetStream(vbo, *gpu_sd.GetAttribute(lol::String("in_Vertex")),
*gpu_sd.GetAttribute(lol::String("in_Normal")),
*gpu_sd.GetAttribute(lol::String("in_Color")));
}
int idx = 0;
ShaderAttrib Attribs[4] = { lol::ShaderAttrib(), lol::ShaderAttrib(), lol::ShaderAttrib(), lol::ShaderAttrib() };

if (has_position) Attribs[idx++] = *gpu_sd.GetAttribute(gpu_sd.GetInVertexName());
if (has_normal) Attribs[idx++] = *gpu_sd.GetAttribute(gpu_sd.GetInNormalName());
if (has_color) Attribs[idx++] = *gpu_sd.GetAttribute(gpu_sd.GetInColorName());
if (has_texcoord) Attribs[idx++] = *gpu_sd.GetAttribute(gpu_sd.GetInTexCoordName());

vdecl->SetStream(vbo, Attribs[0], Attribs[1], Attribs[2], Attribs[3]);

m_ibo->Bind();
vdecl->DrawIndexedElements(MeshPrimitive::Triangles, 0, 0, m_vertexcount, 0, m_indexcount);


+ 5
- 0
src/easymesh/easymesh.h 查看文件

@@ -82,6 +82,11 @@ public:
ShaderAttrib const *GetAttribute(const lol::String &attribute);
//--
virtual void SetupShaderDatas(mat4 const &model) { UNUSED(model); }
//--
virtual lol::String GetInVertexName() { return lol::String("in_Vertex"); }
virtual lol::String GetInNormalName() { return lol::String("in_Normal"); }
virtual lol::String GetInColorName() { return lol::String("in_Color"); }
virtual lol::String GetInTexCoordName() { return lol::String("in_TexCoord"); }

protected:
uint16_t m_vert_decl_flags;


+ 54
- 0
src/lol/gpu/vertexbuffer.h 查看文件

@@ -59,10 +59,64 @@ struct VertexUsage
Fog,
Depth,
Sample,

Max
}
m_value;

private:
static String GetName(Value v, bool use_simple)
{
String tmp = String("");
if (!use_simple) tmp += "<";
switch (v)
{
case Position: { tmp += "Position"; break; }
case BlendWeight: { tmp += "BlendWeight"; break; }
case BlendIndices: { tmp += "BlendIndices";break; }
case Normal: { tmp += "Normal"; break; }
case PointSize: { tmp += "PointSize"; break; }
case TexCoord: { tmp += "TexCoord"; break; }
case TexCoordExt: { tmp += "TexCoordExt"; break; }
case Tangent: { tmp += "Tangent"; break; }
case Binormal: { tmp += "Binormal"; break; }
case TessFactor: { tmp += "TessFactor"; break; }
case PositionT: { tmp += "PositionT"; break; }
case Color: { tmp += "Color"; break; }
case Fog: { tmp += "Fog"; break; }
case Depth: { tmp += "Depth"; break; }
case Sample: { tmp += "Sample"; break; }
default: { tmp += "UNDEFINED"; break; }
}
if (!use_simple) tmp += ">";
return tmp;
}

public:
static String GetName(Value v)
{
return GetName(v, false);
}

static String GetNameList(uint32_t v)
{
String tmp = String("<");
int nb = 0;
for (int i = 0; i < Max; ++i)
{
if (v & (1<<i))
{
if (nb != 0)
tmp += ", ";
tmp += GetName(Value(i), true);
++nb;
}
}
return tmp + ">";
}

inline VertexUsage(Value v) : m_value(v) {}
inline VertexUsage(int v) : m_value((Value)v) {}
inline operator Value() { return m_value; }
};



Loading…
取消
儲存