mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 15:00:36 +02:00
Interleaving the attributes and relying on just 3 input buffers
This commit is contained in:
parent
0fe13ea5ee
commit
e8d922a56c
5 changed files with 116 additions and 12 deletions
|
@ -585,13 +585,15 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||||
|
|
||||||
FBXMesh& fbxMesh = extractedMesh;
|
FBXMesh& fbxMesh = extractedMesh;
|
||||||
graphics::MeshPointer mesh(new graphics::Mesh());
|
graphics::MeshPointer mesh(new graphics::Mesh());
|
||||||
|
bool blendShapes = !fbxMesh.blendshapes.empty();
|
||||||
|
int numVerts = extractedMesh.vertices.size();
|
||||||
|
|
||||||
// Grab the vertices in a buffer
|
// Grab the vertices in a buffer
|
||||||
auto vb = std::make_shared<gpu::Buffer>();
|
auto vb = std::make_shared<gpu::Buffer>();
|
||||||
vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3),
|
vb->setData(extractedMesh.vertices.size() * sizeof(glm::vec3),
|
||||||
(const gpu::Byte*) extractedMesh.vertices.data());
|
(const gpu::Byte*) extractedMesh.vertices.data());
|
||||||
gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
mesh->setVertexBuffer(vbv);
|
// mesh->setVertexBuffer(vbv);
|
||||||
|
|
||||||
if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) {
|
if (!fbxMesh.normals.empty() && fbxMesh.tangents.empty()) {
|
||||||
// Fill with a dummy value to force tangents to be present if there are normals
|
// Fill with a dummy value to force tangents to be present if there are normals
|
||||||
|
@ -634,7 +636,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||||
// Normals and tangents are interleaved
|
// Normals and tangents are interleaved
|
||||||
const int normalsOffset = 0;
|
const int normalsOffset = 0;
|
||||||
const int tangentsOffset = normalsOffset + sizeof(NormalType);
|
const int tangentsOffset = normalsOffset + sizeof(NormalType);
|
||||||
const int colorsOffset = normalsOffset + normalsSize + tangentsSize;
|
const int totalNTSize = normalsOffset + normalsSize + tangentsSize;
|
||||||
|
//const int colorsOffset = normalsOffset + normalsSize + tangentsSize;
|
||||||
|
|
||||||
|
const int colorsOffset = 0;
|
||||||
const int texCoordsOffset = colorsOffset + colorsSize;
|
const int texCoordsOffset = colorsOffset + colorsSize;
|
||||||
const int texCoords1Offset = texCoordsOffset + texCoordsSize;
|
const int texCoords1Offset = texCoordsOffset + texCoordsSize;
|
||||||
const int clusterIndicesOffset = texCoords1Offset + texCoords1Size;
|
const int clusterIndicesOffset = texCoords1Offset + texCoords1Size;
|
||||||
|
@ -642,6 +647,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||||
const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize;
|
const int totalAttributeSize = clusterWeightsOffset + clusterWeightsSize;
|
||||||
|
|
||||||
// Copy all attribute data in a single attribute buffer
|
// Copy all attribute data in a single attribute buffer
|
||||||
|
|
||||||
|
auto attribNTBuffer = std::make_shared<gpu::Buffer>();
|
||||||
|
attribNTBuffer->resize(totalNTSize);
|
||||||
|
|
||||||
auto attribBuffer = std::make_shared<gpu::Buffer>();
|
auto attribBuffer = std::make_shared<gpu::Buffer>();
|
||||||
attribBuffer->resize(totalAttributeSize);
|
attribBuffer->resize(totalAttributeSize);
|
||||||
|
|
||||||
|
@ -665,9 +674,10 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||||
normalsAndTangents.push_back(packedNormal);
|
normalsAndTangents.push_back(packedNormal);
|
||||||
normalsAndTangents.push_back(packedTangent);
|
normalsAndTangents.push_back(packedTangent);
|
||||||
}
|
}
|
||||||
attribBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data());
|
attribNTBuffer->setSubData(normalsOffset, normalsAndTangentsSize, (const gpu::Byte*) normalsAndTangents.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (colorsSize > 0) {
|
if (colorsSize > 0) {
|
||||||
#if FBX_PACK_COLORS
|
#if FBX_PACK_COLORS
|
||||||
std::vector<ColorType> colors;
|
std::vector<ColorType> colors;
|
||||||
|
@ -723,50 +733,123 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
|
||||||
}
|
}
|
||||||
attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData());
|
attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (const gpu::Byte*) fbxMesh.clusterWeights.constData());
|
||||||
|
|
||||||
|
auto vf = std::make_shared<gpu::Stream::Format>();
|
||||||
|
auto vbs = std::make_shared<gpu::BufferStream>();
|
||||||
|
|
||||||
|
gpu::Offset buf0Offset = 12;
|
||||||
|
vf->setAttribute(gpu::Stream::POSITION, 0, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
|
vbs->addBuffer(vb, 0, buf0Offset);
|
||||||
|
|
||||||
|
gpu::Offset buf1Offset = 0;
|
||||||
if (normalsSize) {
|
if (normalsSize) {
|
||||||
mesh->addAttribute(gpu::Stream::NORMAL,
|
/* mesh->addAttribute(gpu::Stream::NORMAL,
|
||||||
graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize,
|
graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize,
|
||||||
normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
|
normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
|
||||||
mesh->addAttribute(gpu::Stream::TANGENT,
|
mesh->addAttribute(gpu::Stream::TANGENT,
|
||||||
graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize,
|
graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize,
|
||||||
normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
|
normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
|
||||||
|
*/
|
||||||
|
vf->setAttribute(gpu::Stream::NORMAL, 1, FBX_NORMAL_ELEMENT, 0);
|
||||||
|
vf->setAttribute(gpu::Stream::TANGENT, 1, FBX_NORMAL_ELEMENT, 4);
|
||||||
|
buf1Offset = 8;
|
||||||
|
vbs->addBuffer(attribNTBuffer, 0, buf1Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gpu::Offset buf2Offset = 0;
|
||||||
if (colorsSize) {
|
if (colorsSize) {
|
||||||
mesh->addAttribute(gpu::Stream::COLOR,
|
/* mesh->addAttribute(gpu::Stream::COLOR,
|
||||||
graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT));
|
graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT));
|
||||||
|
*/
|
||||||
|
vf->setAttribute(gpu::Stream::COLOR, 2, FBX_COLOR_ELEMENT, buf2Offset);
|
||||||
|
buf2Offset += 4;
|
||||||
}
|
}
|
||||||
if (texCoordsSize) {
|
if (texCoordsSize) {
|
||||||
mesh->addAttribute(gpu::Stream::TEXCOORD,
|
/* mesh->addAttribute(gpu::Stream::TEXCOORD,
|
||||||
graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize,
|
graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize,
|
||||||
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
||||||
|
*/ vf->setAttribute(gpu::Stream::TEXCOORD, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset);
|
||||||
|
buf2Offset += 4;
|
||||||
}
|
}
|
||||||
if (texCoords1Size) {
|
if (texCoords1Size) {
|
||||||
mesh->addAttribute( gpu::Stream::TEXCOORD1,
|
/* mesh->addAttribute( gpu::Stream::TEXCOORD1,
|
||||||
graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size,
|
graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size,
|
||||||
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
||||||
|
*/ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset);
|
||||||
|
buf2Offset += 4;
|
||||||
} else if (texCoordsSize) {
|
} else if (texCoordsSize) {
|
||||||
mesh->addAttribute(gpu::Stream::TEXCOORD1,
|
/* mesh->addAttribute(gpu::Stream::TEXCOORD1,
|
||||||
graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize,
|
graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize,
|
||||||
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
|
||||||
|
*/ vf->setAttribute(gpu::Stream::TEXCOORD1, 2, gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV), buf2Offset - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterIndicesSize) {
|
if (clusterIndicesSize) {
|
||||||
if (fbxMesh.clusters.size() < UINT8_MAX) {
|
if (fbxMesh.clusters.size() < UINT8_MAX) {
|
||||||
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
|
/* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
|
||||||
graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
|
graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
|
||||||
gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW)));
|
gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW)));
|
||||||
|
*/
|
||||||
|
vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW), buf2Offset);
|
||||||
|
buf2Offset += 4;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
|
/* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
|
||||||
graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
|
graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
|
||||||
gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)));
|
gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)));
|
||||||
|
*/ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, 2, gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW), buf2Offset);
|
||||||
|
buf2Offset += 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clusterWeightsSize) {
|
if (clusterWeightsSize) {
|
||||||
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT,
|
/* mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT,
|
||||||
graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize,
|
graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize,
|
||||||
gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW)));
|
gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW)));
|
||||||
|
*/ vf->setAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, 2, gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW), buf2Offset);
|
||||||
|
buf2Offset += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto vColorOffset = 0;
|
||||||
|
auto vColorSize = colorsSize / numVerts;
|
||||||
|
|
||||||
|
auto vTexcoord0Offset = vColorOffset + vColorSize;
|
||||||
|
auto vTexcoord0Size = texCoordsSize / numVerts;
|
||||||
|
|
||||||
|
auto vTexcoord1Offset = vTexcoord0Offset + vTexcoord0Size;
|
||||||
|
auto vTexcoord1Size = texCoords1Size / numVerts;
|
||||||
|
|
||||||
|
auto vClusterIndiceOffset = vTexcoord1Offset + vTexcoord1Size;
|
||||||
|
auto vClusterIndiceSize = clusterIndicesSize / numVerts;
|
||||||
|
|
||||||
|
auto vClusterWeightOffset = vClusterIndiceOffset + vClusterIndiceSize;
|
||||||
|
auto vClusterWeightSize = clusterWeightsSize / numVerts;
|
||||||
|
|
||||||
|
auto vStride = vClusterWeightOffset + vClusterWeightSize;
|
||||||
|
//int vStride = buf2Offset;
|
||||||
|
std::vector<gpu::Byte> dest;
|
||||||
|
dest.resize(totalAttributeSize);
|
||||||
|
auto vDest = dest.data();
|
||||||
|
|
||||||
|
auto source = attribBuffer->getData();
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < numVerts; i++) {
|
||||||
|
|
||||||
|
if (vColorSize) memcpy(vDest + vColorOffset, source + colorsOffset + i * vColorSize, vColorSize);
|
||||||
|
if (vTexcoord0Size) memcpy(vDest + vTexcoord0Offset, source + texCoordsOffset + i * vTexcoord0Size, vTexcoord0Size);
|
||||||
|
if (vTexcoord1Size) memcpy(vDest + vTexcoord1Offset, source + texCoords1Offset + i * vTexcoord1Size, vTexcoord1Size);
|
||||||
|
if (vClusterIndiceSize) memcpy(vDest + vClusterIndiceOffset, source + clusterIndicesOffset + i * vClusterIndiceSize, vClusterIndiceSize);
|
||||||
|
if (vClusterWeightSize) memcpy(vDest + vClusterWeightOffset, source + clusterWeightsOffset + i * vClusterWeightSize, vClusterWeightSize);
|
||||||
|
|
||||||
|
vDest += vStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
attribBuffer->setData(totalAttributeSize, dest.data());
|
||||||
|
|
||||||
|
vbs->addBuffer(attribBuffer, 0, vStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->setVertexFormatAndStream(vf, vbs);
|
||||||
|
|
||||||
unsigned int totalIndices = 0;
|
unsigned int totalIndices = 0;
|
||||||
foreach(const FBXMeshPart& part, extractedMesh.parts) {
|
foreach(const FBXMeshPart& part, extractedMesh.parts) {
|
||||||
|
|
|
@ -27,6 +27,8 @@ void GL45Backend::resetInputStage() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GL45Backend::updateInput() {
|
void GL45Backend::updateInput() {
|
||||||
|
// PROFILE_RANGE(render_gpu, __FUNCTION__);
|
||||||
|
|
||||||
bool isStereoNow = isStereo();
|
bool isStereoNow = isStereo();
|
||||||
// track stereo state change potentially happening wihtout changing the input format
|
// track stereo state change potentially happening wihtout changing the input format
|
||||||
// this is a rare case requesting to invalid the format
|
// this is a rare case requesting to invalid the format
|
||||||
|
@ -36,6 +38,7 @@ void GL45Backend::updateInput() {
|
||||||
_input._lastUpdateStereoState = isStereoNow;
|
_input._lastUpdateStereoState = isStereoNow;
|
||||||
|
|
||||||
if (_input._invalidFormat) {
|
if (_input._invalidFormat) {
|
||||||
|
PROFILE_RANGE(render_gpu, "bindInputFormat");
|
||||||
InputStageState::ActivationCache newActivation;
|
InputStageState::ActivationCache newActivation;
|
||||||
|
|
||||||
// Assign the vertex format required
|
// Assign the vertex format required
|
||||||
|
@ -128,16 +131,22 @@ void GL45Backend::updateInput() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_input._invalidBuffers.any()) {
|
if (_input._invalidBuffers.any()) {
|
||||||
|
// PROFILE_RANGE(render_gpu, "bindInputBuffers");
|
||||||
auto vbo = _input._bufferVBOs.data();
|
auto vbo = _input._bufferVBOs.data();
|
||||||
auto offset = _input._bufferOffsets.data();
|
auto offset = _input._bufferOffsets.data();
|
||||||
auto stride = _input._bufferStrides.data();
|
auto stride = _input._bufferStrides.data();
|
||||||
|
|
||||||
for (GLuint buffer = 0; buffer < _input._buffers.size(); buffer++, vbo++, offset++, stride++) {
|
int numSet = 0;
|
||||||
|
auto numBuffers = _input._buffers.size();
|
||||||
|
for (GLuint buffer = 0; buffer < numBuffers; buffer++, vbo++, offset++, stride++) {
|
||||||
if (_input._invalidBuffers.test(buffer)) {
|
if (_input._invalidBuffers.test(buffer)) {
|
||||||
glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride));
|
glBindVertexBuffer(buffer, (*vbo), (*offset), (GLsizei)(*stride));
|
||||||
|
numSet++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILE_COUNTER_IF_CHANGED(render_gpu, "numVBSbound", int, numSet);
|
||||||
|
|
||||||
_input._invalidBuffers.reset();
|
_input._invalidBuffers.reset();
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,6 +152,8 @@ public:
|
||||||
|
|
||||||
BufferStream makeRangedStream(uint32 offset, uint32 count = -1) const;
|
BufferStream makeRangedStream(uint32 offset, uint32 count = -1) const;
|
||||||
|
|
||||||
|
BufferStream& operator = (const BufferStream& src) = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Buffers _buffers;
|
Buffers _buffers;
|
||||||
Offsets _offsets;
|
Offsets _offsets;
|
||||||
|
|
|
@ -32,6 +32,13 @@ Mesh::Mesh(const Mesh& mesh) :
|
||||||
Mesh::~Mesh() {
|
Mesh::~Mesh() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mesh::setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs) {
|
||||||
|
_vertexFormat = vf;
|
||||||
|
_vertexStream = (*vbs);
|
||||||
|
|
||||||
|
_vertexBuffer = BufferView(vbs->getBuffers()[0], vbs->getOffsets()[0], vbs->getBuffers()[0]->getSize(), vbs->getStrides()[0], gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ));
|
||||||
|
}
|
||||||
|
|
||||||
void Mesh::setVertexBuffer(const BufferView& buffer) {
|
void Mesh::setVertexBuffer(const BufferView& buffer) {
|
||||||
_vertexBuffer = buffer;
|
_vertexBuffer = buffer;
|
||||||
evalVertexFormat();
|
evalVertexFormat();
|
||||||
|
|
|
@ -59,6 +59,9 @@ public:
|
||||||
void removeAttribute(Slot slot);
|
void removeAttribute(Slot slot);
|
||||||
const BufferView getAttributeBuffer(int attrib) const;
|
const BufferView getAttributeBuffer(int attrib) const;
|
||||||
|
|
||||||
|
// Force vertex stream and Vertex format
|
||||||
|
void setVertexFormatAndStream(const gpu::Stream::FormatPointer& vf, const gpu::BufferStreamPointer& vbs);
|
||||||
|
|
||||||
// Stream format
|
// Stream format
|
||||||
const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; }
|
const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue