mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Updated Mesh to support map and forEach operations on colors in RGBA8 format and normals in XYZ10W2 format
This commit is contained in:
parent
29485b65e5
commit
1d5f65b082
3 changed files with 82 additions and 24 deletions
|
@ -92,6 +92,15 @@ bool Stream::Format::setAttribute(Slot slot, Slot channel, Frequency frequency)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream::Attribute Stream::Format::getAttribute(Slot slot) const {
|
||||||
|
auto attribIt = _attributes.find(slot);
|
||||||
|
if (attribIt != _attributes.end()) {
|
||||||
|
return attribIt->second;
|
||||||
|
} else {
|
||||||
|
return Attribute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
void BufferStream::addBuffer(const BufferPointer& buffer, Offset offset, Offset stride) {
|
||||||
_buffers.push_back(buffer);
|
_buffers.push_back(buffer);
|
||||||
_offsets.push_back(offset);
|
_offsets.push_back(offset);
|
||||||
|
|
|
@ -112,6 +112,7 @@ public:
|
||||||
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
bool setAttribute(Slot slot, Slot channel, Frequency frequency = PER_VERTEX);
|
||||||
|
|
||||||
bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); }
|
bool hasAttribute(Slot slot) const { return (_attributes.find(slot) != _attributes.end()); }
|
||||||
|
Attribute getAttribute(Slot slot) const;
|
||||||
|
|
||||||
const std::string& getKey() const { return _key; }
|
const std::string& getKey() const { return _key; }
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include "Geometry.h"
|
#include "Geometry.h"
|
||||||
|
|
||||||
|
#include <glm/gtc/packing.hpp>
|
||||||
|
|
||||||
using namespace model;
|
using namespace model;
|
||||||
|
|
||||||
Mesh::Mesh() :
|
Mesh::Mesh() :
|
||||||
|
@ -139,13 +141,15 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||||
std::function<glm::vec3(glm::vec3)> colorFunc,
|
std::function<glm::vec3(glm::vec3)> colorFunc,
|
||||||
std::function<glm::vec3(glm::vec3)> normalFunc,
|
std::function<glm::vec3(glm::vec3)> normalFunc,
|
||||||
std::function<uint32_t(uint32_t)> indexFunc) const {
|
std::function<uint32_t(uint32_t)> indexFunc) const {
|
||||||
|
const auto vertexFormat = getVertexFormat();
|
||||||
|
|
||||||
// vertex data
|
// vertex data
|
||||||
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
||||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
||||||
|
|
||||||
gpu::Resource::Size vertexSize = numVertices * sizeof(glm::vec3);
|
gpu::Resource::Size vertexSize = numVertices * sizeof(glm::vec3);
|
||||||
unsigned char* resultVertexData = new unsigned char[vertexSize];
|
std::unique_ptr<unsigned char> resultVertexData{ new unsigned char[vertexSize] };
|
||||||
unsigned char* vertexDataCursor = resultVertexData;
|
unsigned char* vertexDataCursor = resultVertexData.get();
|
||||||
|
|
||||||
for (gpu::BufferView::Index i = 0; i < numVertices; i++) {
|
for (gpu::BufferView::Index i = 0; i < numVertices; i++) {
|
||||||
glm::vec3 pos = vertexFunc(vertexBufferView.get<glm::vec3>(i));
|
glm::vec3 pos = vertexFunc(vertexBufferView.get<glm::vec3>(i));
|
||||||
|
@ -159,13 +163,24 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||||
gpu::BufferView::Index numColors = (gpu::BufferView::Index)colorsBufferView.getNumElements();
|
gpu::BufferView::Index numColors = (gpu::BufferView::Index)colorsBufferView.getNumElements();
|
||||||
|
|
||||||
gpu::Resource::Size colorSize = numColors * sizeof(glm::vec3);
|
gpu::Resource::Size colorSize = numColors * sizeof(glm::vec3);
|
||||||
unsigned char* resultColorData = new unsigned char[colorSize];
|
std::unique_ptr<unsigned char> resultColorData{ new unsigned char[colorSize] };
|
||||||
unsigned char* colorDataCursor = resultColorData;
|
unsigned char* colorDataCursor = resultColorData.get();
|
||||||
|
auto colorAttribute = vertexFormat->getAttribute(attributeTypeColor);
|
||||||
|
|
||||||
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
if (colorAttribute._element == gpu::Element::VEC3F_XYZ) {
|
||||||
glm::vec3 color = colorFunc(colorsBufferView.get<glm::vec3>(i));
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
memcpy(colorDataCursor, &color, sizeof(color));
|
glm::vec3 color = colorFunc(colorsBufferView.get<glm::vec3>(i));
|
||||||
colorDataCursor += sizeof(color);
|
memcpy(colorDataCursor, &color, sizeof(color));
|
||||||
|
colorDataCursor += sizeof(color);
|
||||||
|
}
|
||||||
|
} else if (colorAttribute._element == gpu::Element::COLOR_RGBA_32) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
|
auto rawColor = colorsBufferView.get<glm::uint32>(i);
|
||||||
|
auto color = glm::vec3(glm::unpackUnorm4x8(rawColor));
|
||||||
|
color = colorFunc(color);
|
||||||
|
memcpy(colorDataCursor, &color, sizeof(color));
|
||||||
|
colorDataCursor += sizeof(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal data
|
// normal data
|
||||||
|
@ -173,22 +188,34 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||||
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
||||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
||||||
gpu::Resource::Size normalSize = numNormals * sizeof(glm::vec3);
|
gpu::Resource::Size normalSize = numNormals * sizeof(glm::vec3);
|
||||||
unsigned char* resultNormalData = new unsigned char[normalSize];
|
std::unique_ptr<unsigned char> resultNormalData{ new unsigned char[normalSize] };
|
||||||
unsigned char* normalDataCursor = resultNormalData;
|
unsigned char* normalDataCursor = resultNormalData.get();
|
||||||
|
auto normalAttribute = vertexFormat->getAttribute(attributeTypeNormal);
|
||||||
|
|
||||||
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
if (normalAttribute._element == gpu::Element::VEC3F_XYZ) {
|
||||||
glm::vec3 normal = normalFunc(normalsBufferView.get<glm::vec3>(i));
|
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
||||||
memcpy(normalDataCursor, &normal, sizeof(normal));
|
glm::vec3 normal = normalFunc(normalsBufferView.get<glm::vec3>(i));
|
||||||
normalDataCursor += sizeof(normal);
|
memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||||
|
normalDataCursor += sizeof(normal);
|
||||||
|
}
|
||||||
|
} else if (normalAttribute._element == gpu::Element::VEC4F_NORMALIZED_XYZ10W2) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
|
auto packedNormal = normalsBufferView.get<glm::uint32>(i);
|
||||||
|
auto normal = glm::vec3(glm::unpackSnorm3x10_1x2(packedNormal));
|
||||||
|
normal = normalFunc(normal);
|
||||||
|
memcpy(normalDataCursor, &normal, sizeof(normal));
|
||||||
|
normalDataCursor += sizeof(normal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO -- other attributes
|
// TODO -- other attributes
|
||||||
|
|
||||||
// face data
|
// face data
|
||||||
const gpu::BufferView& indexBufferView = getIndexBuffer();
|
const gpu::BufferView& indexBufferView = getIndexBuffer();
|
||||||
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)getNumIndices();
|
gpu::BufferView::Index numIndexes = (gpu::BufferView::Index)getNumIndices();
|
||||||
gpu::Resource::Size indexSize = numIndexes * sizeof(uint32_t);
|
gpu::Resource::Size indexSize = numIndexes * sizeof(uint32_t);
|
||||||
unsigned char* resultIndexData = new unsigned char[indexSize];
|
std::unique_ptr<unsigned char> resultIndexData{ new unsigned char[indexSize] };
|
||||||
unsigned char* indexDataCursor = resultIndexData;
|
unsigned char* indexDataCursor = resultIndexData.get();
|
||||||
|
|
||||||
for (gpu::BufferView::Index i = 0; i < numIndexes; i++) {
|
for (gpu::BufferView::Index i = 0; i < numIndexes; i++) {
|
||||||
uint32_t index = indexFunc(indexBufferView.get<uint32_t>(i));
|
uint32_t index = indexFunc(indexBufferView.get<uint32_t>(i));
|
||||||
|
@ -199,25 +226,25 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
|
||||||
model::MeshPointer result(new model::Mesh());
|
model::MeshPointer result(new model::Mesh());
|
||||||
|
|
||||||
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||||
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData);
|
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData.get());
|
||||||
gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
gpu::BufferPointer resultVertexBufferPointer(resultVertexBuffer);
|
||||||
gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
gpu::BufferView resultVertexBufferView(resultVertexBufferPointer, vertexElement);
|
||||||
result->setVertexBuffer(resultVertexBufferView);
|
result->setVertexBuffer(resultVertexBufferView);
|
||||||
|
|
||||||
gpu::Element colorElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
gpu::Element colorElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||||
gpu::Buffer* resultColorsBuffer = new gpu::Buffer(colorSize, resultColorData);
|
gpu::Buffer* resultColorsBuffer = new gpu::Buffer(colorSize, resultColorData.get());
|
||||||
gpu::BufferPointer resultColorsBufferPointer(resultColorsBuffer);
|
gpu::BufferPointer resultColorsBufferPointer(resultColorsBuffer);
|
||||||
gpu::BufferView resultColorsBufferView(resultColorsBufferPointer, colorElement);
|
gpu::BufferView resultColorsBufferView(resultColorsBufferPointer, colorElement);
|
||||||
result->addAttribute(attributeTypeColor, resultColorsBufferView);
|
result->addAttribute(attributeTypeColor, resultColorsBufferView);
|
||||||
|
|
||||||
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
gpu::Element normalElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
|
||||||
gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData);
|
gpu::Buffer* resultNormalsBuffer = new gpu::Buffer(normalSize, resultNormalData.get());
|
||||||
gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
gpu::BufferPointer resultNormalsBufferPointer(resultNormalsBuffer);
|
||||||
gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
gpu::BufferView resultNormalsBufferView(resultNormalsBufferPointer, normalElement);
|
||||||
result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
result->addAttribute(attributeTypeNormal, resultNormalsBufferView);
|
||||||
|
|
||||||
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
gpu::Element indexElement = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::RAW);
|
||||||
gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData);
|
gpu::Buffer* resultIndexesBuffer = new gpu::Buffer(indexSize, resultIndexData.get());
|
||||||
gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
gpu::BufferPointer resultIndexesBufferPointer(resultIndexesBuffer);
|
||||||
gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
gpu::BufferView resultIndexesBufferView(resultIndexesBufferPointer, indexElement);
|
||||||
result->setIndexBuffer(resultIndexesBufferView);
|
result->setIndexBuffer(resultIndexesBufferView);
|
||||||
|
@ -241,6 +268,8 @@ void Mesh::forEach(std::function<void(glm::vec3)> vertexFunc,
|
||||||
std::function<void(glm::vec3)> colorFunc,
|
std::function<void(glm::vec3)> colorFunc,
|
||||||
std::function<void(glm::vec3)> normalFunc,
|
std::function<void(glm::vec3)> normalFunc,
|
||||||
std::function<void(uint32_t)> indexFunc) {
|
std::function<void(uint32_t)> indexFunc) {
|
||||||
|
const auto vertexFormat = getVertexFormat();
|
||||||
|
|
||||||
// vertex data
|
// vertex data
|
||||||
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
const gpu::BufferView& vertexBufferView = getVertexBuffer();
|
||||||
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
gpu::BufferView::Index numVertices = (gpu::BufferView::Index)getNumVertices();
|
||||||
|
@ -252,17 +281,36 @@ void Mesh::forEach(std::function<void(glm::vec3)> vertexFunc,
|
||||||
int attributeTypeColor = gpu::Stream::InputSlot::COLOR; // libraries/gpu/src/gpu/Stream.h
|
int attributeTypeColor = gpu::Stream::InputSlot::COLOR; // libraries/gpu/src/gpu/Stream.h
|
||||||
const gpu::BufferView& colorsBufferView = getAttributeBuffer(attributeTypeColor);
|
const gpu::BufferView& colorsBufferView = getAttributeBuffer(attributeTypeColor);
|
||||||
gpu::BufferView::Index numColors = (gpu::BufferView::Index)colorsBufferView.getNumElements();
|
gpu::BufferView::Index numColors = (gpu::BufferView::Index)colorsBufferView.getNumElements();
|
||||||
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
auto colorAttribute = vertexFormat->getAttribute(attributeTypeColor);
|
||||||
colorFunc(colorsBufferView.get<glm::vec3>(i));
|
if (colorAttribute._element == gpu::Element::VEC3F_XYZ) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
|
colorFunc(colorsBufferView.get<glm::vec3>(i));
|
||||||
|
}
|
||||||
|
} else if (colorAttribute._element == gpu::Element::COLOR_RGBA_32) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
|
auto rawColor = colorsBufferView.get<glm::uint32>(i);
|
||||||
|
auto color = glm::unpackUnorm4x8(rawColor);
|
||||||
|
colorFunc(color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal data
|
// normal data
|
||||||
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
int attributeTypeNormal = gpu::Stream::InputSlot::NORMAL; // libraries/gpu/src/gpu/Stream.h
|
||||||
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
const gpu::BufferView& normalsBufferView = getAttributeBuffer(attributeTypeNormal);
|
||||||
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
gpu::BufferView::Index numNormals = (gpu::BufferView::Index)normalsBufferView.getNumElements();
|
||||||
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
auto normalAttribute = vertexFormat->getAttribute(attributeTypeNormal);
|
||||||
normalFunc(normalsBufferView.get<glm::vec3>(i));
|
if (normalAttribute._element == gpu::Element::VEC3F_XYZ) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numNormals; i++) {
|
||||||
|
normalFunc(normalsBufferView.get<glm::vec3>(i));
|
||||||
|
}
|
||||||
|
} else if (normalAttribute._element == gpu::Element::VEC4F_NORMALIZED_XYZ10W2) {
|
||||||
|
for (gpu::BufferView::Index i = 0; i < numColors; i++) {
|
||||||
|
auto packedNormal = normalsBufferView.get<glm::uint32>(i);
|
||||||
|
auto normal = glm::unpackSnorm3x10_1x2(packedNormal);
|
||||||
|
normalFunc(normal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO -- other attributes
|
// TODO -- other attributes
|
||||||
|
|
||||||
// face data
|
// face data
|
||||||
|
|
Loading…
Reference in a new issue