Handle byte stride on vertex buffers

Vertex buffers (and only vertex buffers) may have a byte stride
specified.
This commit is contained in:
JosiahWI 2023-11-29 19:57:58 -06:00 committed by Josiah VanderZee
parent 86026f9205
commit 95a4030b50
4 changed files with 93 additions and 3 deletions

View File

@ -224,10 +224,11 @@ void CGLTFMeshFileLoader::MeshExtractor::copyPositions(
const auto& buffer = getBuffer(accessorIdx); const auto& buffer = getBuffer(accessorIdx);
const auto count = getElemCount(accessorIdx); const auto count = getElemCount(accessorIdx);
const auto byteStride = getByteStride(accessorIdx);
for (std::size_t i = 0; i < count; i++) { for (std::size_t i = 0; i < count; i++) {
const auto v = readVec3DF(BufferOffset(buffer, const auto v = readVec3DF(BufferOffset(buffer,
3 * sizeof(float) * i), getScale()); (byteStride * i)), getScale());
vertices[i].Pos = v; vertices[i].Pos = v;
} }
} }
@ -275,6 +276,14 @@ std::size_t CGLTFMeshFileLoader::MeshExtractor::getElemCount(
return m_model.accessors[accessorIdx].count; return m_model.accessors[accessorIdx].count;
} }
std::size_t CGLTFMeshFileLoader::MeshExtractor::getByteStride(
const std::size_t accessorIdx) const
{
const auto& accessor = m_model.accessors[accessorIdx];
const auto& view = m_model.bufferViews[accessor.bufferView];
return accessor.ByteStride(view);
}
CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer( CGLTFMeshFileLoader::BufferOffset CGLTFMeshFileLoader::MeshExtractor::getBuffer(
const std::size_t accessorIdx) const const std::size_t accessorIdx) const
{ {

View File

@ -104,6 +104,8 @@ private:
std::size_t getElemCount(const std::size_t accessorIdx) const; std::size_t getElemCount(const std::size_t accessorIdx) const;
std::size_t getByteStride(const std::size_t accessorIdx) const;
BufferOffset getBuffer(const std::size_t accessorIdx) const; BufferOffset getBuffer(const std::size_t accessorIdx) const;
std::size_t getIndicesAccessorIdx(const std::size_t meshIdx, std::size_t getIndicesAccessorIdx(const std::size_t meshIdx,

View File

@ -0,0 +1,71 @@
{
"scene": 0,
"scenes" : [
{
"nodes" : [ 0 ]
}
],
"nodes" : [
{
"mesh" : 0
}
],
"meshes" : [
{
"primitives" : [ {
"attributes" : {
"POSITION" : 1
},
"indices" : 0
} ]
}
],
"buffers" : [
{
"uri" : "data:application/octet-stream;base64,AAABAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAAAA=",
"byteLength" : 80
}
],
"bufferViews" : [
{
"buffer" : 0,
"byteOffset" : 0,
"byteLength" : 6,
"target" : 34963
},
{
"buffer" : 0,
"byteOffset" : 8,
"byteLength" : 36,
"byteStride" : 24,
"target" : 34962
}
],
"accessors" : [
{
"bufferView" : 0,
"byteOffset" : 0,
"componentType" : 5123,
"count" : 3,
"type" : "SCALAR",
"max" : [ 2 ],
"min" : [ 0 ]
},
{
"bufferView" : 1,
"byteOffset" : 0,
"componentType" : 5126,
"count" : 3,
"type" : "VEC3",
"max" : [ 1.0, 1.0, 0.0 ],
"min" : [ 0.0, 0.0, 0.0 ]
}
],
"asset" : {
"version" : "2.0"
}
}

View File

@ -1,8 +1,12 @@
#include "CReadFile.h" #include "CReadFile.h"
#include <irrlicht.h>
// Catch needs to be included after Irrlicht so that it sees operator<<
// declarations.
#define CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN
#include <catch.hpp> #include <catch.hpp>
#include <irrlicht.h>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@ -49,7 +53,11 @@ TEST_CASE("load empty gltf file") {
} }
TEST_CASE("minimal triangle") { TEST_CASE("minimal triangle") {
ScopedMesh sm("source/Irrlicht/tests/assets/minimal_triangle.gltf"); auto path = GENERATE(
"source/Irrlicht/tests/assets/minimal_triangle.gltf",
"source/Irrlicht/tests/assets/triangle_with_vertex_stride.gltf");
INFO(path);
ScopedMesh sm(path);
REQUIRE(sm.getMesh() != nullptr); REQUIRE(sm.getMesh() != nullptr);
REQUIRE(sm.getMesh()->getMeshBufferCount() == 1); REQUIRE(sm.getMesh()->getMeshBufferCount() == 1);