Skip to content
Snippets Groups Projects
Commit 85e623e6 authored by Trevor Hollmann's avatar Trevor Hollmann
Browse files

[#26] Use std::vector instead of void* for buffers.

parent be08961c
No related branches found
No related tags found
1 merge request!19Resolve "Asset Loading"
Pipeline #25123 passed
......@@ -47,6 +47,8 @@ namespace vkcv::asset {
enum PrimitiveMode { POINTS=0, LINES, LINELOOP, LINESTRIP, TRIANGLES, TRIANGLESTRIP, TRIANGLEFAN };
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum PrimitiveType { POSITION=1, NORMAL, TEXCOORD_0 };
/* The indices in the index buffer can be of different bit width. */
enum IndexType { UINT32=0, UINT16=1, UINT8=2 };
typedef struct {
// TODO not yet needed for the first (unlit) triangle
......@@ -64,26 +66,18 @@ typedef struct {
/* This struct represents one (possibly the only) part of a mesh. There is
* always one vertexBuffer and zero or one indexBuffer (indexed rendering is
* common but not always used). If there is no indexBuffer, this is indicated
* by indexBuffer.data being NULL.
* Each vertex buffer can have one or more vertex attributes.
* Note that the indexBuffer and vertexBuffer might be pointing to the same
* block of memory.
*
* TODO For now, the caller of loadMesh() has to free this memory when they are
* done, but since this is not generally good practice in C++, this behaviour
* will likely be changed later. */
* common but not always used). If there is no index buffer, this is indicated
* by indexBuffer.data being empty. Each vertex buffer can have one or more
* vertex attributes. */
typedef struct {
enum PrimitiveMode mode; // draw as points, lines or triangle?
size_t numIndices, numVertices;
struct {
void *data; // binary data of the index buffer
size_t byteLength; // length of the index buffer
uint32_t byteOffset; // offset into the buffer in bytes
enum IndexType type; // data type of the indices
std::vector<uint8_t> data; // binary data of the index buffer
} indexBuffer;
struct {
void *data; // the binary data of the buffer
size_t byteLength; // the length of the entire buffer in bytes
std::vector<uint8_t> data; // binary data of the vertex buffer
std::vector<VertexAttribute> attributes;
} vertexBuffer;
struct { float x, y, z; } min; // bounding box lower left
......
......@@ -146,58 +146,60 @@ namespace vkcv::asset {
const fx::gltf::Accessor &indexAccessor = object.accessors[objectPrimitive.indices];
const fx::gltf::BufferView &indexBufferView = object.bufferViews[indexAccessor.bufferView];
const fx::gltf::Buffer &indexBuffer = object.buffers[indexBufferView.buffer];
void *indexBufferData = calloc(1, indexBuffer.byteLength);
if (memcpy(indexBufferData, indexBuffer.data.data(), indexBuffer.byteLength) == NULL) {
fprintf(stderr, "ERROR copying buffer data.\n");
return 0;
std::vector<uint8_t> indexBufferData;
indexBufferData.resize(indexBufferView.byteLength);
{
const size_t off = indexBufferView.byteOffset;
const void *const ptr = ((char*)indexBuffer.data.data()) + off;
if (!memcpy(indexBufferData.data(), ptr, indexBufferView.byteLength)) {
std::cerr << "ERROR copying index buffer data.\n";
return 0;
}
}
// vertexBuffer
fx::gltf::BufferView& vertexBufferView = object.bufferViews[posAccessor.bufferView];
fx::gltf::Buffer& vertexBuffer = object.buffers[vertexBufferView.buffer];
void *vertexBufferData;
// check whether only one buffer is used
if (indexBufferView.buffer == vertexBufferView.buffer){
std::cout << "It's just one Buffer, let's be efficient!" << std::endl;
vertexBufferData = indexBufferData;
} else {
std::cout << "No luck, different Buffers :(" << std::endl;
vertexBufferData = calloc(1, vertexBuffer.byteLength);
if (memcpy(vertexBufferData, vertexBuffer.data.data(), vertexBuffer.byteLength) == NULL) {
fprintf(stderr, "ERROR copying buffer data.\n");
return 0;
}
}
std::vector<uint8_t> vertexBufferData;
vertexBufferData.resize(vertexBufferView.byteLength);
{
const size_t off = vertexBufferView.byteOffset;
const void *const ptr = ((char*)vertexBuffer.data.data()) + off;
if (!memcpy(vertexBufferData.data(), ptr, vertexBufferView.byteLength)) {
fprintf(stderr, "ERROR copying vertex buffer data.\n");
return 0;
}
}
// fill vertex groups vector
const size_t numVertexGroups = 1; // TODO get value from fx-gltf
IndexType indexType;
switch(indexAccessor.componentType) {
case fx::gltf::Accessor::ComponentType::UnsignedByte:
indexType = UINT8; break;
case fx::gltf::Accessor::ComponentType::UnsignedShort:
indexType = UINT16; break;
case fx::gltf::Accessor::ComponentType::UnsignedInt:
indexType = UINT32; break;
default:
std::cerr << "ERROR: Index type not supported: " <<
static_cast<uint16_t>(indexAccessor.componentType) <<
std::endl;
return 0;
}
const size_t numVertexGroups = objectMesh.primitives.size();
vertexGroups.resize(numVertexGroups);
vertexGroups.back() = {
static_cast<PrimitiveMode>(objectPrimitive.mode), // mode
object.accessors[objectPrimitive.indices].count, // num indices
posAccessor.count, // num vertices
{ //index buffer
indexBufferData,
indexBufferView.byteLength,
indexBufferView.byteOffset
},
{ //vertex buffer
vertexBufferData,
vertexBufferView.byteLength,
vertexAttributes
},
vertexGroups[0] = {
static_cast<PrimitiveMode>(objectPrimitive.mode),// mode
object.accessors[objectPrimitive.indices].count, // numIndices
posAccessor.count, // numVertices
{ indexType, indexBufferData },
{ vertexBufferData, vertexAttributes },
{posAccessor.min[0], posAccessor.min[1], posAccessor.min[2]}, // bounding box min
{posAccessor.max[0], posAccessor.max[1], posAccessor.max[2]}, // bounding box max
static_cast<uint8_t>(objectPrimitive.material) // material index
};
// fill mesh struct
mesh = {
object.meshes[0].name,
vertexGroups,
materials
};
mesh = { object.meshes[0].name, vertexGroups, materials };
// Finally return 1 to signal that all is fine
return 1;
......
......@@ -30,11 +30,10 @@ int main(int argc, const char** argv) {
const auto &vg = mesh.vertexGroups[i];
printf("primitive mode: %d (%s)\n", vg.mode,
primitive_modes[vg.mode]);
printf("index buffer: %lu bytes for %lu indices (offset into "
"%p is %u)\n", vg.indexBuffer.byteLength,
vg.numIndices, vg.indexBuffer.data,
vg.indexBuffer.byteOffset);
buf = (char*)vg.indexBuffer.data + vg.indexBuffer.byteOffset;
printf("index buffer: %lu bytes for %lu indices (%p)\n",
vg.indexBuffer.data.size(), vg.numIndices,
vg.indexBuffer.data.data());
buf = (char*)vg.indexBuffer.data.data();
uint16_t *indices = (uint16_t*)buf;
printf("\tindices: ");
for (size_t j = 0; j < vg.numIndices; j++) {
......@@ -43,9 +42,9 @@ int main(int argc, const char** argv) {
printf("\n");
printf("vertex buffer: %lu bytes for %lu vertices with %lu "
"attributes (starting at %p)\n",
vg.vertexBuffer.byteLength, vg.numVertices,
vg.vertexBuffer.data.size(), vg.numVertices,
vg.vertexBuffer.attributes.size(),
vg.vertexBuffer.data);
vg.vertexBuffer.data.data());
}
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment