From 7ba3c74bc0c6840af70ce72e467c8afbd5bef1e0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 14:47:02 -0800 Subject: [PATCH 1/3] more work on render model scenes --- interface/src/renderer/Model.cpp | 260 ++++++++++++++----------------- interface/src/renderer/Model.h | 12 ++ 2 files changed, 125 insertions(+), 147 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8b3c656ae7..d10ce80126 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1553,46 +1553,18 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { int opaqueMeshPartsRendered = 0; // now, for each model in the scene, render the mesh portions - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - opaqueMeshPartsRendered += model->renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } + //bool pickProgramsNeeded = true; + //SkinLocations* skinLocations; + //GLenum specularTextureUnit; + + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args); // render translucent meshes afterwards //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); @@ -1606,46 +1578,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { int translucentParts = 0; const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args); GLBATCH(glDisable)(GL_ALPHA_TEST); GLBATCH(glEnable)(GL_BLEND); @@ -1662,46 +1602,14 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); - GLBATCH(glPopMatrix)(); - } - foreach(Model* model, _modelsInScene) { - model->setupBatchTransform(batch); - translucentParts += model->renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); - GLBATCH(glPopMatrix)(); - } + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args); } GLBATCH(glDepthMask)(true); @@ -1981,19 +1889,8 @@ void Model::segregateMeshGroups() { _meshGroupsKnown = true; } -int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, - bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { - +QVector* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned) { PROFILE_RANGE(__FUNCTION__); - bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); - bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts); - bool dontReduceMaterialSwitches = Menu::getInstance()->isOptionChecked(MenuOption::DontReduceMaterialSwitches); - - QString lastMaterialID; - int meshPartsRendered = 0; - updateVisibleJointStates(); - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - const QVector& networkMeshes = _geometry->getMeshes(); // depending on which parameters we were called with, pick the correct mesh group to render QVector* whichList = NULL; @@ -2032,23 +1929,18 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl } else { qDebug() << "unexpected!!! this mesh didn't fall into any or our groups???"; } - - if (!whichList) { - qDebug() << "unexpected!!! we don't know which list of meshes to render..."; - return 0; - } - QVector& list = *whichList; - - // If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs - if (list.size() == 0) { - return 0; - } + return whichList; +} +void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, + SkinLocations*& skinLocations, GLenum& specularTextureUnit) { + ProgramObject* program = &_program; Locations* locations = &_locations; ProgramObject* skinProgram = &_skinProgram; - SkinLocations* skinLocations = &_skinLocations; - GLenum specularTextureUnit = 0; + skinLocations = &_skinLocations; + specularTextureUnit = 0; if (mode == SHADOW_RENDER_MODE) { program = &_shadowProgram; skinProgram = &_skinShadowProgram; @@ -2091,8 +1983,84 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl if (!activeProgram->isLinked()) { activeProgram->link(); } + GLBATCH(glUseProgram)(activeProgram->programId()); GLBATCH(glUniform1f)(activeLocations->alphaThreshold, alphaThreshold); +} + +int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { + + PROFILE_RANGE(__FUNCTION__); + int meshPartsRendered = 0; + + bool pickProgramsNeeded = true; + SkinLocations* skinLocations; + GLenum specularTextureUnit; + + foreach(Model* model, _modelsInScene) { + QVector* whichList = model->pickMeshList(translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned); + if (whichList) { + QVector& list = *whichList; + if (list.size() > 0) { + //if (pickProgramsNeeded) { + pickPrograms(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, skinLocations, specularTextureUnit); + pickProgramsNeeded = false; + //} + model->setupBatchTransform(batch); + meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, skinLocations, specularTextureUnit); + GLBATCH(glPopMatrix)(); + } + } + } + // if we selected a program, then unselect it + if (!pickProgramsNeeded) { + //GLBATCH(glUseProgram)(0); + } + return meshPartsRendered; +} + +int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) { + + PROFILE_RANGE(__FUNCTION__); + int meshPartsRendered = 0; + + QVector* whichList = pickMeshList(translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned); + + if (!whichList) { + qDebug() << "unexpected!!! we don't know which list of meshes to render..."; + return 0; + } + QVector& list = *whichList; + + // If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs + if (list.size() == 0) { + return 0; + } + + SkinLocations* skinLocations; + GLenum specularTextureUnit; + pickPrograms(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, skinLocations, specularTextureUnit); + meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, skinLocations, specularTextureUnit); + GLBATCH(glUseProgram)(0); + + return meshPartsRendered; +} + + +int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args, + SkinLocations* skinLocations, GLenum specularTextureUnit) { + PROFILE_RANGE(__FUNCTION__); + bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts); + bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts); + bool dontReduceMaterialSwitches = Menu::getInstance()->isOptionChecked(MenuOption::DontReduceMaterialSwitches); + + QString lastMaterialID; + int meshPartsRendered = 0; + updateVisibleJointStates(); + const FBXGeometry& geometry = _geometry->getFBXGeometry(); + const QVector& networkMeshes = _geometry->getMeshes(); // i is the "index" from the original networkMeshes QVector... foreach (int i, list) { @@ -2268,7 +2236,5 @@ int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, fl } - GLBATCH(glUseProgram)(0); - return meshPartsRendered; } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 8c74b1a222..ab6b990eb2 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -409,6 +409,18 @@ private: int renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args = NULL); void setupBatchTransform(gpu::Batch& batch); + QVector* pickMeshList(bool translucent, float alphaThreshold, bool hasTangents, bool hasSpecular, bool isSkinned); + + int renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + RenderArgs* args, SkinLocations* skinLocations, GLenum specularTextureUnit); + + static void pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args, + SkinLocations*& skinLocations, GLenum& specularTextureUnit); + + static int renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, + bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args); + }; From 3ff89be3fdb6fe05fee801c29508ca55c1f6521a Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 14:51:47 -0800 Subject: [PATCH 2/3] actually only pick programs once --- interface/src/renderer/Model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index d9e29dba7c..997322637c 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -2003,10 +2003,10 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool if (whichList) { QVector& list = *whichList; if (list.size() > 0) { - //if (pickProgramsNeeded) { + if (pickProgramsNeeded) { pickPrograms(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, skinLocations, specularTextureUnit); pickProgramsNeeded = false; - //} + } model->setupBatchTransform(batch); meshPartsRendered += model->renderMeshesFromList(list, batch, mode, translucent, alphaThreshold, args, skinLocations, specularTextureUnit); GLBATCH(glPopMatrix)(); From 49ef6f8be087f85b146d219b3081a351d9168110 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 13 Nov 2014 14:53:37 -0800 Subject: [PATCH 3/3] some cleanup --- interface/src/renderer/Model.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 997322637c..c007f44f2e 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1553,10 +1553,6 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { int opaqueMeshPartsRendered = 0; // now, for each model in the scene, render the mesh portions - //bool pickProgramsNeeded = true; - //SkinLocations* skinLocations; - //GLenum specularTextureUnit; - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); @@ -2015,7 +2011,7 @@ int Model::renderMeshesForModelsInScene(gpu::Batch& batch, RenderMode mode, bool } // if we selected a program, then unselect it if (!pickProgramsNeeded) { - //GLBATCH(glUseProgram)(0); + GLBATCH(glUseProgram)(0); } return meshPartsRendered; }