mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 15:09:34 +02:00
MOving rednering code of Model into ModelRenderPayload.h/cpp
This commit is contained in:
parent
fd232b7d32
commit
9e393ced46
4 changed files with 364 additions and 32 deletions
|
@ -1373,7 +1373,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) {
|
||||||
return AABox();
|
return AABox();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) {
|
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload) {
|
||||||
// PROFILE_RANGE(__FUNCTION__);
|
// PROFILE_RANGE(__FUNCTION__);
|
||||||
PerformanceTimer perfTimer("Model::renderPart");
|
PerformanceTimer perfTimer("Model::renderPart");
|
||||||
if (!_readyWhenAdded) {
|
if (!_readyWhenAdded) {
|
||||||
|
@ -1505,6 +1505,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape
|
||||||
|
|
||||||
auto drawPart = drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
auto drawPart = drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
||||||
|
|
||||||
|
/*
|
||||||
if (mesh.blendshapes.isEmpty()) {
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0);
|
batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
|
||||||
|
@ -1527,7 +1528,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape
|
||||||
if (mesh.colors.isEmpty()) {
|
if (mesh.colors.isEmpty()) {
|
||||||
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
payload->bindMesh(batch);
|
||||||
|
|
||||||
// guard against partially loaded meshes
|
// guard against partially loaded meshes
|
||||||
if (partIndex >= mesh.parts.size()) {
|
if (partIndex >= mesh.parts.size()) {
|
||||||
return;
|
return;
|
||||||
|
@ -1644,9 +1647,9 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shape
|
||||||
|
|
||||||
{
|
{
|
||||||
PerformanceTimer perfTimer("batch.drawIndexed()");
|
PerformanceTimer perfTimer("batch.drawIndexed()");
|
||||||
batch.drawIndexed(gpu::TRIANGLES, drawPart._numIndices, drawPart._startIndex);
|
payload->drawCall(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args) {
|
if (args) {
|
||||||
const int INDICES_PER_TRIANGLE = 3;
|
const int INDICES_PER_TRIANGLE = 3;
|
||||||
args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE;
|
args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE;
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
bool isVisible() const { return _isVisible; }
|
bool isVisible() const { return _isVisible; }
|
||||||
|
|
||||||
AABox getPartBounds(int meshIndex, int partIndex);
|
AABox getPartBounds(int meshIndex, int partIndex);
|
||||||
void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID);
|
void renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID, const MeshPartPayload* payload);
|
||||||
|
|
||||||
bool maybeStartBlender();
|
bool maybeStartBlender();
|
||||||
|
|
||||||
|
@ -494,6 +494,7 @@ private:
|
||||||
bool _needsReload = true;
|
bool _needsReload = true;
|
||||||
bool _needsUpdateClusterMatrices = true;
|
bool _needsUpdateClusterMatrices = true;
|
||||||
|
|
||||||
|
friend class MeshPartPayload;
|
||||||
protected:
|
protected:
|
||||||
RigPointer _rig;
|
RigPointer _rig;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,13 +13,44 @@
|
||||||
|
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
|
||||||
|
namespace render {
|
||||||
|
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) {
|
||||||
|
if (payload) {
|
||||||
|
return payload->getKey();
|
||||||
|
}
|
||||||
|
// Return opaque for lack of a better idea
|
||||||
|
return ItemKey::Builder::opaqueShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
|
||||||
|
if (payload) {
|
||||||
|
return payload->getBound();
|
||||||
|
}
|
||||||
|
return render::Item::Bound();
|
||||||
|
}
|
||||||
|
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) {
|
||||||
|
return payload->render(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) {
|
||||||
|
return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) :
|
MeshPartPayload::MeshPartPayload(Model* model, int meshIndex, int partIndex, int shapeIndex) :
|
||||||
model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex)
|
model(model), url(model->getURL()), meshIndex(meshIndex), partIndex(partIndex), _shapeID(shapeIndex)
|
||||||
{
|
{
|
||||||
|
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = model->_geometry->getMeshes();
|
||||||
|
const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get());
|
||||||
|
_drawMesh = networkMesh._mesh;
|
||||||
|
|
||||||
|
_drawPart = _drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
render::ItemKey MeshPartPayload::getKey() const {
|
render::ItemKey MeshPartPayload::getKey() const {
|
||||||
if (!model->isVisible()) {
|
if (!model->isVisible()) {
|
||||||
return ItemKey::Builder().withInvisible().build();
|
return ItemKey::Builder().withInvisible().build();
|
||||||
|
@ -50,6 +81,316 @@ render::Item::Bound MeshPartPayload::getBound() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MeshPartPayload::render(RenderArgs* args) const {
|
void MeshPartPayload::render(RenderArgs* args) const {
|
||||||
return model->renderPart(args, meshIndex, partIndex, _shapeID);
|
return model->renderPart(args, meshIndex, partIndex, _shapeID, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MeshPartPayload::bindMesh(gpu::Batch& batch) const {
|
||||||
|
const FBXGeometry& geometry = model->_geometry->getFBXGeometry();
|
||||||
|
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = model->_geometry->getMeshes();
|
||||||
|
const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get());
|
||||||
|
const FBXMesh& mesh = geometry.meshes.at(meshIndex);
|
||||||
|
// auto drawMesh = networkMesh._mesh;
|
||||||
|
|
||||||
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
|
||||||
|
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||||
|
auto inputStream = _drawMesh->makeBufferStream();
|
||||||
|
|
||||||
|
batch.setInputStream(0, inputStream);
|
||||||
|
} else {
|
||||||
|
batch.setIndexBuffer(gpu::UINT32, (_drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
batch.setInputFormat((_drawMesh->getVertexFormat()));
|
||||||
|
|
||||||
|
batch.setInputBuffer(0, model->_blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3));
|
||||||
|
batch.setInputBuffer(1, model->_blendedVertexBuffers[meshIndex], _drawMesh->getNumVertices() * sizeof(glm::vec3), sizeof(glm::vec3));
|
||||||
|
|
||||||
|
auto inputStream = _drawMesh->makeBufferStream().makeRangedStream(2);
|
||||||
|
|
||||||
|
batch.setInputStream(2, inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.colors.isEmpty()) {
|
||||||
|
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MeshPartPayload::drawCall(gpu::Batch& batch) const {
|
||||||
|
batch.drawIndexed(gpu::TRIANGLES, _drawPart._numIndices, _drawPart._startIndex);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, int shapeID) {
|
||||||
|
// PROFILE_RANGE(__FUNCTION__);
|
||||||
|
PerformanceTimer perfTimer("Model::renderPart");
|
||||||
|
if (!_readyWhenAdded) {
|
||||||
|
return; // bail asap
|
||||||
|
}
|
||||||
|
|
||||||
|
auto textureCache = DependencyManager::get<TextureCache>();
|
||||||
|
|
||||||
|
gpu::Batch& batch = *(args->_batch);
|
||||||
|
auto mode = args->_renderMode;
|
||||||
|
|
||||||
|
|
||||||
|
// Capture the view matrix once for the rendering of this model
|
||||||
|
if (_transforms.empty()) {
|
||||||
|
_transforms.push_back(Transform());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME
|
||||||
|
|
||||||
|
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||||
|
const std::vector<std::unique_ptr<NetworkMesh>>& networkMeshes = _geometry->getMeshes();
|
||||||
|
|
||||||
|
auto networkMaterial = _geometry->getShapeMaterial(shapeID);
|
||||||
|
if (!networkMaterial) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
auto material = networkMaterial->_material;
|
||||||
|
if (!material) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Not yet
|
||||||
|
// auto drawMesh = _geometry->getShapeMesh(shapeID);
|
||||||
|
// auto drawPart = _geometry->getShapePart(shapeID);
|
||||||
|
|
||||||
|
// guard against partially loaded meshes
|
||||||
|
if (meshIndex >= (int)networkMeshes.size() || meshIndex >= (int)geometry.meshes.size() || meshIndex >= (int)_meshStates.size() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateClusterMatrices();
|
||||||
|
|
||||||
|
const NetworkMesh& networkMesh = *(networkMeshes.at(meshIndex).get());
|
||||||
|
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();
|
||||||
|
|
||||||
|
bool hasTangents = drawMaterialKey.isNormalMap() && !mesh.tangents.isEmpty();
|
||||||
|
bool hasSpecular = drawMaterialKey.isGlossMap(); // !drawMaterial->specularTextureName.isEmpty(); //mesh.hasSpecularTexture();
|
||||||
|
bool hasLightmap = drawMaterialKey.isLightmapMap(); // !drawMaterial->emissiveTextureName.isEmpty(); //mesh.hasEmissiveTexture();
|
||||||
|
bool isSkinned = state.clusterMatrices.size() > 1;
|
||||||
|
bool wireframe = isWireframe();
|
||||||
|
|
||||||
|
// render the part bounding box
|
||||||
|
#ifdef DEBUG_BOUNDING_PARTS
|
||||||
|
{
|
||||||
|
AABox partBounds = getPartBounds(meshIndex, partIndex);
|
||||||
|
bool inView = args->_viewFrustum->boxInFrustum(partBounds) != ViewFrustum::OUTSIDE;
|
||||||
|
|
||||||
|
glm::vec4 cubeColor;
|
||||||
|
if (isSkinned) {
|
||||||
|
cubeColor = glm::vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
} else if (inView) {
|
||||||
|
cubeColor = glm::vec4(1.0f, 0.0f, 1.0f, 1.0f);
|
||||||
|
} else {
|
||||||
|
cubeColor = glm::vec4(1.0f, 1.0f, 0.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform transform;
|
||||||
|
transform.setTranslation(partBounds.calcCenter());
|
||||||
|
transform.setScale(partBounds.getDimensions());
|
||||||
|
batch.setModelTransform(transform);
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->renderWireCube(batch, 1.0f, cubeColor);
|
||||||
|
}
|
||||||
|
#endif //def DEBUG_BOUNDING_PARTS
|
||||||
|
|
||||||
|
if (wireframe) {
|
||||||
|
translucentMesh = hasTangents = hasSpecular = hasLightmap = isSkinned = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Locations* locations = nullptr;
|
||||||
|
pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
|
||||||
|
args, locations);
|
||||||
|
|
||||||
|
// if our index is ever out of range for either meshes or networkMeshes, then skip it, and set our _meshGroupsKnown
|
||||||
|
// to false to rebuild out mesh groups.
|
||||||
|
if (meshIndex < 0 || meshIndex >= (int)networkMeshes.size() || meshIndex > geometry.meshes.size()) {
|
||||||
|
_meshGroupsKnown = false; // regenerate these lists next time around.
|
||||||
|
_readyWhenAdded = false; // in case any of our users are using scenes
|
||||||
|
invalidCalculatedMeshBoxes(); // if we have to reload, we need to assume our mesh boxes are all invalid
|
||||||
|
return; // FIXME!
|
||||||
|
}
|
||||||
|
|
||||||
|
int vertexCount = mesh.vertices.size();
|
||||||
|
if (vertexCount == 0) {
|
||||||
|
// sanity check
|
||||||
|
return; // FIXME!
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform stage
|
||||||
|
if (_transforms.empty()) {
|
||||||
|
_transforms.push_back(Transform());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSkinned) {
|
||||||
|
const float* bones;
|
||||||
|
if (_cauterizeBones) {
|
||||||
|
bones = (const float*)state.cauterizedClusterMatrices.constData();
|
||||||
|
} else {
|
||||||
|
bones = (const float*)state.clusterMatrices.constData();
|
||||||
|
}
|
||||||
|
batch._glUniformMatrix4fv(locations->clusterMatrices, state.clusterMatrices.size(), false, bones);
|
||||||
|
_transforms[0] = Transform();
|
||||||
|
_transforms[0].preTranslate(_translation);
|
||||||
|
} else {
|
||||||
|
if (_cauterizeBones) {
|
||||||
|
_transforms[0] = Transform(state.cauterizedClusterMatrices[0]);
|
||||||
|
} else {
|
||||||
|
_transforms[0] = Transform(state.clusterMatrices[0]);
|
||||||
|
}
|
||||||
|
_transforms[0].preTranslate(_translation);
|
||||||
|
}
|
||||||
|
batch.setModelTransform(_transforms[0]);
|
||||||
|
|
||||||
|
auto drawPart = drawMesh->getPartBuffer().get<model::Mesh::Part>(partIndex);
|
||||||
|
|
||||||
|
if (mesh.blendshapes.isEmpty()) {
|
||||||
|
batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
|
||||||
|
batch.setInputFormat((drawMesh->getVertexFormat()));
|
||||||
|
auto inputStream = drawMesh->makeBufferStream();
|
||||||
|
|
||||||
|
batch.setInputStream(0, inputStream);
|
||||||
|
} else {
|
||||||
|
batch.setIndexBuffer(gpu::UINT32, (drawMesh->getIndexBuffer()._buffer), 0);
|
||||||
|
batch.setInputFormat((drawMesh->getVertexFormat()));
|
||||||
|
|
||||||
|
batch.setInputBuffer(0, _blendedVertexBuffers[meshIndex], 0, sizeof(glm::vec3));
|
||||||
|
batch.setInputBuffer(1, _blendedVertexBuffers[meshIndex], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3));
|
||||||
|
|
||||||
|
auto inputStream = drawMesh->makeBufferStream().makeRangedStream(2);
|
||||||
|
|
||||||
|
batch.setInputStream(2, inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh.colors.isEmpty()) {
|
||||||
|
batch._glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// guard against partially loaded meshes
|
||||||
|
if (partIndex >= mesh.parts.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WANT_DEBUG
|
||||||
|
if (material == nullptr) {
|
||||||
|
qCDebug(renderutils) << "WARNING: material == nullptr!!!";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
// apply material properties
|
||||||
|
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
|
||||||
|
#ifdef WANT_DEBUG
|
||||||
|
qCDebug(renderutils) << "Material Changed ---------------------------------------------";
|
||||||
|
qCDebug(renderutils) << "part INDEX:" << partIndex;
|
||||||
|
qCDebug(renderutils) << "NEW part.materialID:" << part.materialID;
|
||||||
|
#endif //def WANT_DEBUG
|
||||||
|
|
||||||
|
if (locations->materialBufferUnit >= 0) {
|
||||||
|
batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto materialKey = material->getKey();
|
||||||
|
auto textureMaps = material->getTextureMaps();
|
||||||
|
glm::mat4 texcoordTransform[2];
|
||||||
|
|
||||||
|
// Diffuse
|
||||||
|
if (materialKey.isDiffuseMap()) {
|
||||||
|
auto diffuseMap = textureMaps[model::MaterialKey::DIFFUSE_MAP];
|
||||||
|
if (diffuseMap && diffuseMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(DIFFUSE_MAP_SLOT, diffuseMap->getTextureView());
|
||||||
|
|
||||||
|
if (!diffuseMap->getTextureTransform().isIdentity()) {
|
||||||
|
diffuseMap->getTextureTransform().getMatrix(texcoordTransform[0]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(DIFFUSE_MAP_SLOT, textureCache->getGrayTexture());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal map
|
||||||
|
if ((locations->normalTextureUnit >= 0) && hasTangents) {
|
||||||
|
auto normalMap = textureMaps[model::MaterialKey::NORMAL_MAP];
|
||||||
|
if (normalMap && normalMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(NORMAL_MAP_SLOT, normalMap->getTextureView());
|
||||||
|
|
||||||
|
// texcoord are assumed to be the same has diffuse
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(NORMAL_MAP_SLOT, textureCache->getBlueTexture());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(NORMAL_MAP_SLOT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: For now gloss map is used as the "specular map in the shading, we ll need to fix that
|
||||||
|
if ((locations->specularTextureUnit >= 0) && materialKey.isGlossMap()) {
|
||||||
|
auto specularMap = textureMaps[model::MaterialKey::GLOSS_MAP];
|
||||||
|
if (specularMap && specularMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(SPECULAR_MAP_SLOT, specularMap->getTextureView());
|
||||||
|
|
||||||
|
// texcoord are assumed to be the same has diffuse
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(SPECULAR_MAP_SLOT, textureCache->getBlackTexture());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(SPECULAR_MAP_SLOT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: For now lightmaop is piped into the emissive map unit, we need to fix that and support for real emissive too
|
||||||
|
if ((locations->emissiveTextureUnit >= 0) && materialKey.isLightmapMap()) {
|
||||||
|
auto lightmapMap = textureMaps[model::MaterialKey::LIGHTMAP_MAP];
|
||||||
|
|
||||||
|
if (lightmapMap && lightmapMap->isDefined()) {
|
||||||
|
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, lightmapMap->getTextureView());
|
||||||
|
|
||||||
|
auto lightmapOffsetScale = lightmapMap->getLightmapOffsetScale();
|
||||||
|
batch._glUniform2f(locations->emissiveParams, lightmapOffsetScale.x, lightmapOffsetScale.y);
|
||||||
|
|
||||||
|
if (!lightmapMap->getTextureTransform().isIdentity()) {
|
||||||
|
lightmapMap->getTextureTransform().getMatrix(texcoordTransform[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, textureCache->getGrayTexture());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
batch.setResourceTexture(LIGHTMAP_MAP_SLOT, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texcoord transforms ?
|
||||||
|
if (locations->texcoordMatrices >= 0) {
|
||||||
|
batch._glUniformMatrix4fv(locations->texcoordMatrices, 2, false, (const float*)&texcoordTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: We should be able to do that just in the renderTransparentJob
|
||||||
|
if (translucentMesh && locations->lightBufferUnit >= 0) {
|
||||||
|
PerformanceTimer perfTimer("DLE->setupTransparent()");
|
||||||
|
|
||||||
|
DependencyManager::get<DeferredLightingEffect>()->setupTransparent(args, locations->lightBufferUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
args->_details._materialSwitches++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args) {
|
||||||
|
const int INDICES_PER_TRIANGLE = 3;
|
||||||
|
args->_details._trianglesRendered += drawPart._numIndices / INDICES_PER_TRIANGLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -12,9 +12,14 @@
|
||||||
#ifndef hifi_ModelRenderPayload_h
|
#ifndef hifi_ModelRenderPayload_h
|
||||||
#define hifi_ModelRenderPayload_h
|
#define hifi_ModelRenderPayload_h
|
||||||
|
|
||||||
#include <render/Scene.h>
|
#include <QUrl>
|
||||||
|
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
|
|
||||||
|
#include <render/Scene.h>
|
||||||
|
|
||||||
|
#include <model/Geometry.h>
|
||||||
|
|
||||||
class Model;
|
class Model;
|
||||||
|
|
||||||
class MeshPartPayload {
|
class MeshPartPayload {
|
||||||
|
@ -35,34 +40,16 @@ public:
|
||||||
render::Item::Bound getBound() const;
|
render::Item::Bound getBound() const;
|
||||||
void render(RenderArgs* args) const;
|
void render(RenderArgs* args) const;
|
||||||
|
|
||||||
|
// MeshPartPayload functions to perform render
|
||||||
|
void bindMesh(gpu::Batch& batch) const;
|
||||||
|
void drawCall(gpu::Batch& batch) const;
|
||||||
|
|
||||||
|
model::MeshPointer _drawMesh;
|
||||||
|
model::Mesh::Part _drawPart;
|
||||||
|
model::MaterialPointer _drawMaterial;
|
||||||
|
|
||||||
mutable render::Item::Bound _bound;
|
mutable render::Item::Bound _bound;
|
||||||
mutable bool _isBoundInvalid = true;
|
mutable bool _isBoundInvalid = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
|
||||||
template <> const ItemKey payloadGetKey(const MeshPartPayload::Pointer& payload) {
|
|
||||||
if (payload) {
|
|
||||||
return payload->getKey();
|
|
||||||
}
|
|
||||||
// Return opaque for lack of a better idea
|
|
||||||
return ItemKey::Builder::opaqueShape();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const MeshPartPayload::Pointer& payload) {
|
|
||||||
if (payload) {
|
|
||||||
return payload->getBound();
|
|
||||||
}
|
|
||||||
return render::Item::Bound();
|
|
||||||
}
|
|
||||||
template <> void payloadRender(const MeshPartPayload::Pointer& payload, RenderArgs* args) {
|
|
||||||
return payload->render(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* template <> const model::MaterialKey& shapeGetMaterialKey(const MeshPartPayload::Pointer& payload) {
|
|
||||||
return payload->model->getPartMaterial(payload->meshIndex, payload->partIndex);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // hifi_ModelRenderPayload_h
|
#endif // hifi_ModelRenderPayload_h
|
Loading…
Reference in a new issue