diff --git a/src/easymesh/easymesh.cpp b/src/easymesh/easymesh.cpp index a41b9081..a3441c35 100644 --- a/src/easymesh/easymesh.cpp +++ b/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( @@ -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(VertexUsage::Position, VertexUsage::TexCoord)); + + Array 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(VertexUsage::Position, VertexUsage::TexCoord)); + + Array 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( @@ -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( @@ -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); diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h index 4e52158e..d0a641c3 100644 --- a/src/easymesh/easymesh.h +++ b/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; diff --git a/src/lol/gpu/vertexbuffer.h b/src/lol/gpu/vertexbuffer.h index 7d0881ab..32df52a3 100644 --- a/src/lol/gpu/vertexbuffer.h +++ b/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<"; + } + inline VertexUsage(Value v) : m_value(v) {} + inline VertexUsage(int v) : m_value((Value)v) {} inline operator Value() { return m_value; } };