| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #include "anki/resource/Mesh.h"
- #include "anki/resource/Material.h"
- #include "anki/resource/MeshLoader.h"
- #include "anki/gl/Vbo.h"
- #include "anki/util/Functions.h"
- namespace anki {
- //==============================================================================
- void Mesh::load(const char* filename)
- {
- MeshLoader loader(filename);
- // Set the non-VBO members
- vertsCount = loader.getPositions().size();
- ANKI_ASSERT(vertsCount > 0);
- indicesCount.push_back(loader.getLodsCount());
- for(U lod = 0; lod < indicesCount.size(); lod++)
- {
- indicesCount[lod] = loader.getIndices(lod).size();
- ANKI_ASSERT(indicesCount[lod] > 0);
- ANKI_ASSERT(indicesCount[lod] % 3 == 0 && "Expecting triangles");
- }
- weights = loader.getWeights().size() > 1;
- texChannelsCount = loader.getTextureChannelsCount();
- try
- {
- createVbos(loader);
- visibilityShape.set(loader.getPositions());
- }
- catch(std::exception& e)
- {
- throw ANKI_EXCEPTION("Mesh loading failed: " + filename) << e;
- }
- }
- //==============================================================================
- U32 Mesh::calcVertexSize() const
- {
- U32 a = sizeof(Vec3) + sizeof(Vec3) + sizeof(Vec4)
- + texChannelsCount * sizeof(Vec2);
- if(weights)
- {
- a += sizeof(MeshLoader::VertexWeight);
- }
- return a;
- }
- //==============================================================================
- void Mesh::createVbos(const MeshLoader& loader)
- {
- // Calculate VBO size
- U32 vertexsize = calcVertexSize();
- U32 vbosize = vertexsize * vertsCount;
- // Create a temp buffer and populate it
- Vector<U8> buff(vbosize, 0);
- U8* ptr = &buff[0];
- for(U i = 0; i < vertsCount; i++)
- {
- ANKI_ASSERT(ptr + vertexsize <= &buff[0] + vbosize);
- memcpy(ptr, &loader.getPositions()[i], sizeof(Vec3));
- ptr += sizeof(Vec3);
- memcpy(ptr, &loader.getNormals()[i], sizeof(Vec3));
- ptr += sizeof(Vec3);
- memcpy(ptr, &loader.getTangents()[i], sizeof(Vec4));
- ptr += sizeof(Vec4);
- for(U j = 0; j < texChannelsCount; j++)
- {
- memcpy(ptr, &loader.getTexureCoordinates(j)[i], sizeof(Vec2));
- ptr += sizeof(Vec2);
- }
- if(weights)
- {
- memcpy(ptr, &loader.getWeights()[i],
- sizeof(MeshLoader::VertexWeight));
- ptr += sizeof(MeshLoader::VertexWeight);
- }
- }
- // Create VBO
- vbo.create(
- GL_ARRAY_BUFFER,
- vbosize,
- &buff[0],
- GL_STATIC_DRAW);
- /// Create the indices VBOs
- indicesVbos.resize(loader.getLodsCount());
- U lod = 0;
- for(Vbo& v : indicesVbos)
- {
- v.create(
- GL_ELEMENT_ARRAY_BUFFER,
- getVectorSizeInBytes(loader.getIndices(lod)),
- &loader.getIndices(lod)[0],
- GL_STATIC_DRAW);
- ++lod;
- }
- }
- //==============================================================================
- void Mesh::getVboInfo(
- const VertexAttribute attrib, const U32 lod, const Vbo*& v, U32& size,
- GLenum& type, U32& stride, U32& offset) const
- {
- stride = calcVertexSize();
- // Set all to zero
- v = nullptr;
- size = 0;
- type = GL_NONE;
- offset = 0;
- switch(attrib)
- {
- case VA_POSITION:
- v = &vbo;
- size = 3;
- type = GL_FLOAT;
- offset = 0;
- break;
- case VA_NORMAL:
- v = &vbo;
- size = 3;
- type = GL_FLOAT;
- offset = sizeof(Vec3);
- break;
- case VA_TANGENT:
- v = &vbo;
- size = 4;
- type = GL_FLOAT;
- offset = sizeof(Vec3) * 2;
- break;
- case VA_TEXTURE_COORDS:
- if(texChannelsCount > 0)
- {
- v = &vbo;
- size = 2;
- type = GL_FLOAT;
- offset = sizeof(Vec3) * 2 + sizeof(Vec4);
- }
- break;
- case VA_TEXTURE_COORDS_1:
- if(texChannelsCount > 1)
- {
- v = &vbo;
- size = 2;
- type = GL_FLOAT;
- offset = sizeof(Vec3) * 2 + sizeof(Vec4) + sizeof(Vec2);
- }
- break;
- case VA_BONE_COUNT:
- if(weights)
- {
- v = &vbo;
- size = 1;
- type = GL_UNSIGNED_INT;
- offset = sizeof(Vec3) * 2 + sizeof(Vec4)
- + texChannelsCount * sizeof(Vec2);
- }
- break;
- case VA_BONE_IDS:
- if(weights)
- {
- v = &vbo;
- size = 4;
- type = GL_UNSIGNED_INT;
- offset = sizeof(Vec3) * 2 + sizeof(Vec4)
- + texChannelsCount * sizeof(Vec2) + sizeof(U32);
- }
- break;
- case VA_BONE_WEIGHTS:
- if(weights)
- {
- v = &vbo;
- size = 4;
- type = GL_FLOAT;
- offset = sizeof(Vec3) * 2 + sizeof(Vec4)
- + texChannelsCount * sizeof(Vec2) + sizeof(U32)
- + sizeof(U32) * 4;
- }
- case VA_INDICES:
- if(lod < indicesVbos.size())
- {
- v = &indicesVbos[lod];
- }
- break;
- default:
- ANKI_ASSERT(0);
- break;
- }
- }
- } // end namespace anki
|