diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 3027eb52cc..01c3785086 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -181,7 +181,7 @@ public: unsigned int meshIndex; // the order the meshes appeared in the object file # if USE_MODEL_MESH - model::Mesh _mesh; + model::MeshPointer _mesh; # endif }; diff --git a/libraries/fbx/src/FBXReader_Mesh.cpp b/libraries/fbx/src/FBXReader_Mesh.cpp index c0cf57df58..f3bf3f433d 100644 --- a/libraries/fbx/src/FBXReader_Mesh.cpp +++ b/libraries/fbx/src/FBXReader_Mesh.cpp @@ -370,19 +370,19 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex("buildModelMesh failed -- .*"); if (extracted.mesh.vertices.size() == 0) { - extracted.mesh._mesh = model::Mesh(); + extracted.mesh._mesh; qCDebug(modelformat) << "buildModelMesh failed -- no vertices, url = " << url; return; } FBXMesh& fbxMesh = extracted.mesh; - model::Mesh mesh; + model::MeshPointer mesh(new model::Mesh()); // Grab the vertices in a buffer auto vb = std::make_shared(); vb->setData(extracted.mesh.vertices.size() * sizeof(glm::vec3), (const gpu::Byte*) extracted.mesh.vertices.data()); gpu::BufferView vbv(vb, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)); - mesh.setVertexBuffer(vbv); + mesh->setVertexBuffer(vbv); // evaluate all attribute channels sizes int normalsSize = fbxMesh.normals.size() * sizeof(glm::vec3); @@ -414,37 +414,37 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { attribBuffer->setSubData(clusterWeightsOffset, clusterWeightsSize, (gpu::Byte*) fbxMesh.clusterWeights.constData()); if (normalsSize) { - mesh.addAttribute(gpu::Stream::NORMAL, + mesh->addAttribute(gpu::Stream::NORMAL, model::BufferView(attribBuffer, normalsOffset, normalsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (tangentsSize) { - mesh.addAttribute(gpu::Stream::TANGENT, + mesh->addAttribute(gpu::Stream::TANGENT, model::BufferView(attribBuffer, tangentsOffset, tangentsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); } if (colorsSize) { - mesh.addAttribute(gpu::Stream::COLOR, + mesh->addAttribute(gpu::Stream::COLOR, model::BufferView(attribBuffer, colorsOffset, colorsSize, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::RGB))); } if (texCoordsSize) { - mesh.addAttribute(gpu::Stream::TEXCOORD, + mesh->addAttribute(gpu::Stream::TEXCOORD, model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } if (texCoords1Size) { - mesh.addAttribute(gpu::Stream::TEXCOORD1, + mesh->addAttribute(gpu::Stream::TEXCOORD1, model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV))); } if (clusterIndicesSize) { - mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); } if (clusterWeightsSize) { - mesh.addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, + mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, gpu::Element(gpu::VEC4, gpu::FLOAT, gpu::XYZW))); } @@ -457,7 +457,6 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } if (! totalIndices) { - extracted.mesh._mesh = model::Mesh(); qCDebug(modelformat) << "buildModelMesh failed -- no indices, url = " << url; return; } @@ -489,21 +488,20 @@ void FBXReader::buildModelMesh(ExtractedMesh& extracted, const QString& url) { } gpu::BufferView ibv(ib, gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::XYZ)); - mesh.setIndexBuffer(ibv); + mesh->setIndexBuffer(ibv); if (parts.size()) { auto pb = std::make_shared(); pb->setData(parts.size() * sizeof(model::Mesh::Part), (const gpu::Byte*) parts.data()); gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW)); - mesh.setPartBuffer(pbv); + mesh->setPartBuffer(pbv); } else { - extracted.mesh._mesh = model::Mesh(); qCDebug(modelformat) << "buildModelMesh failed -- no parts, url = " << url; return; } // model::Box box = - mesh.evalPartBound(0); + mesh->evalPartBound(0); extracted.mesh._mesh = mesh; } diff --git a/libraries/model-networking/src/model-networking/ModelCache.cpp b/libraries/model-networking/src/model-networking/ModelCache.cpp index a66fda624d..71d225a43a 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.cpp +++ b/libraries/model-networking/src/model-networking/ModelCache.cpp @@ -269,6 +269,7 @@ static NetworkMesh* buildNetworkMesh(const FBXMesh& mesh, const QUrl& textureBas auto textureCache = DependencyManager::get(); NetworkMesh* networkMesh = new NetworkMesh(); + networkMesh->_mesh = mesh._mesh; int totalIndices = 0; bool checkForTexcoordLightmap = false; diff --git a/libraries/model-networking/src/model-networking/ModelCache.h b/libraries/model-networking/src/model-networking/ModelCache.h index 1110d36e3e..4067bed122 100644 --- a/libraries/model-networking/src/model-networking/ModelCache.h +++ b/libraries/model-networking/src/model-networking/ModelCache.h @@ -191,15 +191,14 @@ public: /// The state associated with a single mesh. class NetworkMesh { public: + model::MeshPointer _mesh; + gpu::BufferPointer _indexBuffer; gpu::BufferPointer _vertexBuffer; gpu::BufferStreamPointer _vertexStream; gpu::Stream::FormatPointer _vertexFormat; - - int getTranslucentPartCount(const FBXMesh& fbxMesh) const; - bool isPartTranslucent(const FBXMesh& fbxMesh, int partIndex) const; }; #endif // hifi_GeometryCache_h diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 7cf965951b..a374f9acb8 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -754,6 +754,16 @@ public: int meshIndex; int partIndex; int _shapeID; + + render::Item::Bound getBound() const { + if (_isBoundInvalid) { + model->getPartBounds(meshIndex, partIndex); + _isBoundInvalid = false; + } + return _bound; + } + mutable render::Item::Bound _bound; + mutable bool _isBoundInvalid = true; }; namespace render { @@ -780,7 +790,7 @@ namespace render { template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) { if (payload) { - return payload->model->getPartBounds(payload->meshIndex, payload->partIndex); + return payload->getBound(); // model->getPartBounds(payload->meshIndex, payload->partIndex); } return render::Item::Bound(); } @@ -1486,6 +1496,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape const FBXMesh& mesh = geometry.meshes.at(meshIndex); const MeshState& state = _meshStates.at(meshIndex); + auto drawMesh = networkMesh._mesh; + + auto drawMaterialKey = material->getKey(); bool translucentMesh = drawMaterialKey.isTransparent() || drawMaterialKey.isTransparentMap(); @@ -1541,7 +1554,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape return; // FIXME! } - batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); + // Assign index buffer: + batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0); + // batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { // sanity check @@ -1574,10 +1589,21 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape batch.setModelTransform(_transforms[0]); if (mesh.blendshapes.isEmpty()) { - batch.setInputFormat(networkMesh._vertexFormat); - batch.setInputStream(0, *networkMesh._vertexStream); + batch.setInputFormat((drawMesh->getVertexFormat())); + auto inputStream = drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + + // batch.setInputFormat(networkMesh._vertexFormat); + // batch.setInputStream(0, *networkMesh._vertexStream); } else { + /* batch.setInputFormat((drawMesh->getVertexFormat())); + auto inputStream = drawMesh->makeBufferStream(); + + batch.setInputStream(0, inputStream); + */ batch.setInputFormat(networkMesh._vertexFormat); + batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3)); batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3)); batch.setInputStream(2, *networkMesh._vertexStream); @@ -1702,9 +1728,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape } } - batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); - batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + auto& drawPart = drawMesh->getPartBuffer().get(); + batch.drawIndexed(model::Mesh::topologyToPrimitive(drawPart._topology), drawPart._numIndices, drawPart._startIndex); +/* batch.setIndexBuffer(gpu::UINT32, part.getMergedTriangles(), 0); + batch.drawIndexed(gpu::TRIANGLES, part.mergedTrianglesIndicesCount, 0); + */ if (args) { const int INDICES_PER_TRIANGLE = 3; args->_details._trianglesRendered += part.mergedTrianglesIndicesCount / INDICES_PER_TRIANGLE; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 137294c5b6..0094a3c3a1 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -189,8 +189,12 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems); - args->_context->render((*args->_batch)); - args->_batch = nullptr; + { + PerformanceTimer perfTimer("DrawOpaqueDeferred::run::renderBatch"); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } } void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {