Files
Seele/src/Engine/Graphics/StaticMeshVertexData.cpp
T

337 lines
11 KiB
C++
Raw Normal View History

2023-10-07 19:29:53 +02:00
#include "StaticMeshVertexData.h"
2023-10-31 16:16:23 +01:00
#include "Graphics.h"
2023-10-31 17:55:30 +01:00
#include "Graphics/Enums.h"
#include "Mesh.h"
2023-10-07 19:29:53 +02:00
using namespace Seele;
2023-10-26 18:37:29 +02:00
extern List<VertexData*> vertexDataList;
2023-10-31 16:16:23 +01:00
StaticMeshVertexData::StaticMeshVertexData()
2023-10-26 18:37:29 +02:00
{
vertexDataList.add(this);
}
2023-10-07 19:29:53 +02:00
StaticMeshVertexData::~StaticMeshVertexData()
{}
2023-10-31 17:55:30 +01:00
StaticMeshVertexData* StaticMeshVertexData::getInstance()
2023-10-31 16:16:23 +01:00
{
2023-10-31 17:55:30 +01:00
static StaticMeshVertexData instance;
return &instance;
2023-10-29 09:20:23 +01:00
}
2023-10-31 16:16:23 +01:00
void StaticMeshVertexData::loadPositions(MeshId id, const Array<Vector>& data)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-05 11:47:22 +01:00
assert(offset + data.size() <= head);
2023-10-31 16:16:23 +01:00
std::memcpy(positionData.data() + offset, data.data(), data.size() * sizeof(Vector));
dirty = true;
}
2024-05-06 18:36:16 +02:00
void StaticMeshVertexData::loadTexCoords(MeshId id, uint64 index, const Array<Vector2>& data)
2023-10-31 16:16:23 +01:00
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-05 11:47:22 +01:00
assert(offset + data.size() <= head);
2024-05-06 18:36:16 +02:00
std::memcpy(texCoordsData[index].data() + offset, data.data(), data.size() * sizeof(Vector2));
2023-10-31 16:16:23 +01:00
dirty = true;
}
void StaticMeshVertexData::loadNormals(MeshId id, const Array<Vector>& data)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-05 11:47:22 +01:00
assert(offset + data.size() <= head);
2023-10-31 16:16:23 +01:00
std::memcpy(normalData.data() + offset, data.data(), data.size() * sizeof(Vector));
dirty = true;
}
void StaticMeshVertexData::loadTangents(MeshId id, const Array<Vector>& data)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-05 11:47:22 +01:00
assert(offset + data.size() <= head);
2023-10-31 16:16:23 +01:00
std::memcpy(tangentData.data() + offset, data.data(), data.size() * sizeof(Vector));
dirty = true;
}
void StaticMeshVertexData::loadBiTangents(MeshId id, const Array<Vector>& data)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-05 11:47:22 +01:00
assert(offset + data.size() <= head);
2023-10-31 16:16:23 +01:00
std::memcpy(biTangentData.data() + offset, data.data(), data.size() * sizeof(Vector));
dirty = true;
}
2023-11-11 22:39:17 +01:00
void Seele::StaticMeshVertexData::loadColors(MeshId id, const Array<Vector>& data)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-11 22:39:17 +01:00
assert(offset + data.size() <= head);
std::memcpy(colorData.data() + offset, data.data(), data.size() * sizeof(Vector));
dirty = true;
}
2023-11-01 13:38:49 +01:00
void StaticMeshVertexData::serializeMesh(MeshId id, uint64 numVertices, ArchiveBuffer& buffer)
{
2024-05-01 14:10:52 +02:00
uint64 offset;
{
std::unique_lock l(mutex);
offset = meshOffsets[id];
}
2023-11-01 13:38:49 +01:00
Array<Vector> pos(numVertices);
2024-05-06 18:36:16 +02:00
Array<Vector2> tex[MAX_TEXCOORDS];
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
tex[i].resize(numVertices);
std::memcpy(tex[i].data(), texCoordsData[i].data() + offset, numVertices * sizeof(Vector2));
Serialization::save(buffer, tex[i]);
}
2023-11-01 13:38:49 +01:00
Array<Vector> nor(numVertices);
Array<Vector> tan(numVertices);
Array<Vector> bit(numVertices);
2023-11-11 22:39:17 +01:00
Array<Vector> col(numVertices);
2024-05-01 19:05:48 +02:00
std::memcpy(pos.data(), positionData.data() + offset, numVertices * sizeof(Vector));
std::memcpy(nor.data(), normalData.data() + offset, numVertices * sizeof(Vector));
std::memcpy(tan.data(), tangentData.data() + offset, numVertices * sizeof(Vector));
std::memcpy(bit.data(), biTangentData.data() + offset, numVertices * sizeof(Vector));
std::memcpy(col.data(), colorData.data() + offset, numVertices * sizeof(Vector));
2023-11-01 13:38:49 +01:00
Serialization::save(buffer, pos);
Serialization::save(buffer, nor);
Serialization::save(buffer, tan);
Serialization::save(buffer, bit);
2023-11-11 22:39:17 +01:00
Serialization::save(buffer, col);
2023-11-01 13:38:49 +01:00
}
void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer)
{
Array<Vector> pos;
2024-05-06 18:36:16 +02:00
Array<Vector2> tex[MAX_TEXCOORDS];
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
Serialization::load(buffer, tex[i]);
loadTexCoords(id, i, tex[i]);
}
2023-11-01 13:38:49 +01:00
Array<Vector> nor;
Array<Vector> tan;
Array<Vector> bit;
2023-11-11 22:39:17 +01:00
Array<Vector> col;
2023-11-01 13:38:49 +01:00
Serialization::load(buffer, pos);
Serialization::load(buffer, nor);
Serialization::load(buffer, tan);
Serialization::load(buffer, bit);
2023-11-11 22:39:17 +01:00
Serialization::load(buffer, col);
2023-11-01 13:38:49 +01:00
loadPositions(id, pos);
loadNormals(id, nor);
loadTangents(id, tan);
loadBiTangents(id, bit);
2023-11-22 13:18:54 +01:00
loadColors(id, col);
2023-11-01 13:38:49 +01:00
}
2023-12-22 19:46:07 +01:00
void StaticMeshVertexData::init(Gfx::PGraphics _graphics)
2023-10-31 16:16:23 +01:00
{
2023-12-22 19:46:07 +01:00
VertexData::init(_graphics);
2024-04-19 18:23:36 +02:00
descriptorLayout = _graphics->createDescriptorLayout("pVertexData");
2024-05-09 08:41:46 +02:00
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 0, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 1, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 2, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 3, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 4, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER });
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{ .binding = 5, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .descriptorCount = MAX_TEXCOORDS });
2023-10-31 17:55:30 +01:00
descriptorLayout->create();
descriptorSet = descriptorLayout->allocateDescriptorSet();
}
2023-12-12 11:37:00 +01:00
void StaticMeshVertexData::destroy()
{
VertexData::destroy();
positions = nullptr;
2024-05-06 18:36:16 +02:00
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
texCoords[i] = nullptr;
}
2023-12-12 11:37:00 +01:00
normals = nullptr;
tangents = nullptr;
biTangents = nullptr;
colors = nullptr;
descriptorLayout = nullptr;
}
2023-10-31 17:55:30 +01:00
void StaticMeshVertexData::bindBuffers(Gfx::PRenderCommand)
{
// TODO: for legacy vertex buffer binding
}
Gfx::PDescriptorLayout StaticMeshVertexData::getVertexDataLayout()
{
return descriptorLayout;
}
Gfx::PDescriptorSet StaticMeshVertexData::getVertexDataSet()
{
return descriptorSet;
}
2024-05-09 08:41:46 +02:00
void StaticMeshVertexData::registerStaticMesh(const Array<OMesh>& meshes, const Component::Transform& transform)
{
for (auto& mesh : meshes)
{
uint64 numVertices = meshVertexCounts[mesh->id];
uint64 offset = meshOffsets[mesh->id];
2024-05-09 08:41:46 +02:00
// Create new mesh where transform is "embedded"
MeshId mapped = VertexData::allocateVertexData(numVertices);
Array<Vector> pos(numVertices);
Matrix4 matrix = transform.toMatrix();
for (uint64 i = 0; i < numVertices; ++i)
{
pos[i] = matrix * Vector4(positionData[offset + i], 1);
}
loadPositions(mapped, pos);
Array<Vector2> tex(numVertices);
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
std::memcpy(tex.data(), texCoordsData[i].data() + offset, numVertices * sizeof(Vector2));
loadTexCoords(mapped, i, tex);
}
Array<Vector> aux(numVertices);
std::memcpy(aux.data(), normalData.data() + offset, numVertices * sizeof(Vector));
loadNormals(mapped, aux);
std::memcpy(aux.data(), biTangentData.data() + offset, numVertices * sizeof(Vector));
loadBiTangents(mapped, aux);
std::memcpy(aux.data(), colorData.data() + offset, numVertices * sizeof(Vector));
loadColors(mapped, aux);
2024-05-09 08:41:46 +02:00
// Load meshlets again
VertexData::loadMesh(mapped, mesh->indices, mesh->meshlets);
Array<uint32> ids;
// Get references to loaded meshlets
const auto& meshData = VertexData::getMeshData(mapped);
2024-05-12 19:36:32 +02:00
for (size_t i = 0; i < meshData.numMeshlets; ++i)
2024-05-09 08:41:46 +02:00
{
2024-05-12 19:36:32 +02:00
ids.add(meshData.meshletOffset + i);
2024-05-09 08:41:46 +02:00
}
2024-05-12 19:36:32 +02:00
2024-05-09 08:41:46 +02:00
// Get Static instance array
PMaterialInstance instance = mesh->referencedMaterial->getHandle();
PMaterial baseMat = instance->getBaseMaterial();
Array<StaticMatInstance> instances;
instances.add(StaticMatInstance{
.instance = mesh->referencedMaterial->getHandle(),
.meshletIds = ids,
.culledMeshletBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
.sourceData = {
.size = ids.size() * sizeof(uint32),
.data = (uint8*)ids.data(),
},
.numElements = ids.size(),
.dynamic = true,
}),
});
staticData.add(StaticMatData{
.material = baseMat,
.staticInstance = std::move(instances),
});
}
}
2023-10-31 17:55:30 +01:00
void StaticMeshVertexData::resizeBuffers()
{
2023-10-31 16:16:23 +01:00
ShaderBufferCreateInfo createInfo = {
2023-11-01 23:12:30 +01:00
.sourceData = {
2023-10-31 17:55:30 +01:00
.size = verticesAllocated * sizeof(Vector),
2023-10-31 16:16:23 +01:00
},
2023-11-15 17:42:57 +01:00
.numElements = verticesAllocated * 3,
2023-11-05 10:36:01 +01:00
.dynamic = true,
2024-04-20 21:35:43 +02:00
.name = "Positions",
2023-10-31 16:16:23 +01:00
};
positions = graphics->createShaderBuffer(createInfo);
2024-04-20 21:35:43 +02:00
createInfo.name = "Normals";
2023-10-31 16:16:23 +01:00
normals = graphics->createShaderBuffer(createInfo);
2024-04-20 21:35:43 +02:00
createInfo.name = "Tangents";
2023-10-31 16:16:23 +01:00
tangents = graphics->createShaderBuffer(createInfo);
2024-04-20 21:35:43 +02:00
createInfo.name = "BiTangents";
2023-10-31 16:16:23 +01:00
biTangents = graphics->createShaderBuffer(createInfo);
2024-04-20 21:35:43 +02:00
createInfo.name = "Colors";
2023-11-11 22:39:17 +01:00
colors = graphics->createShaderBuffer(createInfo);
2023-11-01 23:12:30 +01:00
createInfo.sourceData.size = verticesAllocated * sizeof(Vector2);
2024-04-20 21:35:43 +02:00
createInfo.name = "TexCoords";
2023-11-15 17:42:57 +01:00
createInfo.numElements = verticesAllocated * 2;
2024-05-06 18:36:16 +02:00
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
texCoords[i] = graphics->createShaderBuffer(createInfo);
texCoordsData[i].resize(verticesAllocated);
}
2024-05-09 08:41:46 +02:00
2023-10-31 17:55:30 +01:00
positionData.resize(verticesAllocated);
normalData.resize(verticesAllocated);
tangentData.resize(verticesAllocated);
biTangentData.resize(verticesAllocated);
2023-11-11 22:39:17 +01:00
colorData.resize(verticesAllocated);
2023-10-31 16:16:23 +01:00
}
void StaticMeshVertexData::updateBuffers()
{
2023-11-01 23:12:30 +01:00
positions->updateContents(DataSource{
2023-10-31 16:16:23 +01:00
.size = positionData.size() * sizeof(Vector),
.data = (uint8*)positionData.data(),
});
2024-05-06 18:36:16 +02:00
for (size_t i = 0; i < MAX_TEXCOORDS; ++i)
{
texCoords[i]->updateContents(DataSource{
.size = texCoordsData[i].size() * sizeof(Vector2),
.data = (uint8*)texCoordsData[i].data(),
});
}
2023-11-01 23:12:30 +01:00
normals->updateContents(DataSource{
2023-10-31 16:16:23 +01:00
.size = normalData.size() * sizeof(Vector),
.data = (uint8*)normalData.data(),
});
2023-11-01 23:12:30 +01:00
tangents->updateContents(DataSource{
2023-10-31 16:16:23 +01:00
.size = tangentData.size() * sizeof(Vector),
.data = (uint8*)tangentData.data(),
});
2023-11-01 23:12:30 +01:00
biTangents->updateContents(DataSource{
2023-10-31 16:16:23 +01:00
.size = biTangentData.size() * sizeof(Vector),
.data = (uint8*)biTangentData.data(),
});
2023-11-11 22:39:17 +01:00
colors->updateContents(DataSource{
.size = colorData.size() * sizeof(Vector),
.data = (uint8*)colorData.data()
});
2023-11-05 10:36:01 +01:00
descriptorLayout->reset();
2023-10-31 17:55:30 +01:00
descriptorSet = descriptorLayout->allocateDescriptorSet();
descriptorSet->updateBuffer(0, positions);
2024-05-06 18:36:16 +02:00
descriptorSet->updateBuffer(1, normals);
descriptorSet->updateBuffer(2, tangents);
descriptorSet->updateBuffer(3, biTangents);
descriptorSet->updateBuffer(4, colors);
for (size_t i = 0; i < MAX_TEXCOORDS; ++i) {
descriptorSet->updateBuffer(5, i, texCoords[i]);
}
2023-10-31 17:55:30 +01:00
descriptorSet->writeChanges();
2023-10-31 16:16:23 +01:00
}