group materials together when rendering models

This commit is contained in:
ZappoMan 2014-10-16 14:05:35 -07:00
parent ffb7bcf9d3
commit d1f263ecc5
9 changed files with 256 additions and 101 deletions

View file

@ -430,6 +430,7 @@ Menu::Menu() :
QMenu* modelCullingMenu = modelDebugMenu->addMenu("Culling");
addCheckableActionToQMenuAndActionHash(modelCullingMenu, MenuOption::DontCullOutOfViewMeshParts, 0, false);
addCheckableActionToQMenuAndActionHash(modelCullingMenu, MenuOption::DontCullTooSmallMeshParts, 0, false);
addCheckableActionToQMenuAndActionHash(modelCullingMenu, MenuOption::DontReduceMaterialSwitches, 0, false);
QMenu* voxelOptionsMenu = developerMenu->addMenu("Voxels");
addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures);

View file

@ -374,6 +374,7 @@ namespace MenuOption {
const QString ControlWithSpeech = "Control With Speech";
const QString DontCullOutOfViewMeshParts = "Don't Cull Out Of View Mesh Parts";
const QString DontCullTooSmallMeshParts = "Don't Cull Too Small Mesh Parts";
const QString DontReduceMaterialSwitches = "Don't Attempt to Reduce Material Switches";
const QString DecreaseAvatarSize = "Decrease Avatar Size";
const QString DecreaseVoxelSize = "Decrease Voxel Size";
const QString DisableActivityLogger = "Disable Activity Logger";

View file

@ -1299,10 +1299,32 @@ void Model::segregateMeshGroups() {
_meshesOpaqueSkinned.clear();
_meshesOpaqueTangentsSpecularSkinned.clear();
_meshesOpaqueSpecularSkinned.clear();
_unsortedMeshesTranslucentTangents.clear();
_unsortedMeshesTranslucent.clear();
_unsortedMeshesTranslucentTangentsSpecular.clear();
_unsortedMeshesTranslucentSpecular.clear();
_unsortedMeshesTranslucentTangentsSkinned.clear();
_unsortedMeshesTranslucentSkinned.clear();
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
_unsortedMeshesTranslucentSpecularSkinned.clear();
_unsortedMeshesOpaqueTangents.clear();
_unsortedMeshesOpaque.clear();
_unsortedMeshesOpaqueTangentsSpecular.clear();
_unsortedMeshesOpaqueSpecular.clear();
_unsortedMeshesOpaqueTangentsSkinned.clear();
_unsortedMeshesOpaqueSkinned.clear();
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
_unsortedMeshesOpaqueSpecularSkinned.clear();
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
// Run through all of the meshes, and place them into their segregated, but unsorted buckets
for (int i = 0; i < networkMeshes.size(); i++) {
const NetworkMesh& networkMesh = networkMeshes.at(i);
const FBXMesh& mesh = geometry.meshes.at(i);
@ -1312,79 +1334,171 @@ void Model::segregateMeshGroups() {
bool hasTangents = !mesh.tangents.isEmpty();
bool hasSpecular = mesh.hasSpecularTexture();
bool isSkinned = state.clusterMatrices.size() > 1;
QString materialID = mesh.parts.at(0).materialID;
if (translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
_meshesTranslucent.append(i);
_unsortedMeshesTranslucent.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
_meshesTranslucentTangents.append(i);
_unsortedMeshesTranslucentTangents.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && hasSpecular && !isSkinned) {
_meshesTranslucentTangentsSpecular.append(i);
_unsortedMeshesTranslucentTangentsSpecular.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
_meshesTranslucentSpecular.append(i);
_unsortedMeshesTranslucentSpecular.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && !hasSpecular && isSkinned) {
_meshesTranslucentTangentsSkinned.append(i);
_unsortedMeshesTranslucentTangentsSkinned.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
_meshesTranslucentSkinned.append(i);
_unsortedMeshesTranslucentSkinned.insertMulti(materialID, i);
} else if (translucentMesh && hasTangents && hasSpecular && isSkinned) {
_meshesTranslucentTangentsSpecularSkinned.append(i);
_unsortedMeshesTranslucentTangentsSpecularSkinned.insertMulti(materialID, i);
} else if (translucentMesh && !hasTangents && hasSpecular && isSkinned) {
_meshesTranslucentSpecularSkinned.append(i);
_unsortedMeshesTranslucentSpecularSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && !hasSpecular && !isSkinned) {
_meshesOpaque.append(i);
_unsortedMeshesOpaque.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && !hasSpecular && !isSkinned) {
_meshesOpaqueTangents.append(i);
_unsortedMeshesOpaqueTangents.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && hasSpecular && !isSkinned) {
_meshesOpaqueTangentsSpecular.append(i);
_unsortedMeshesOpaqueTangentsSpecular.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && hasSpecular && !isSkinned) {
_meshesOpaqueSpecular.append(i);
_unsortedMeshesOpaqueSpecular.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && !hasSpecular && isSkinned) {
_meshesOpaqueTangentsSkinned.append(i);
_unsortedMeshesOpaqueTangentsSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && !hasSpecular && isSkinned) {
_meshesOpaqueSkinned.append(i);
_unsortedMeshesOpaqueSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && hasTangents && hasSpecular && isSkinned) {
_meshesOpaqueTangentsSpecularSkinned.append(i);
_unsortedMeshesOpaqueTangentsSpecularSkinned.insertMulti(materialID, i);
} else if (!translucentMesh && !hasTangents && hasSpecular && isSkinned) {
_meshesOpaqueSpecularSkinned.append(i);
_unsortedMeshesOpaqueSpecularSkinned.insertMulti(materialID, i);
} else {
qDebug() << "unexpected!!! this mesh didn't fall into any or our groups???";
}
}
foreach(int i, _unsortedMeshesTranslucent) {
_meshesTranslucent.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangents) {
_meshesTranslucentTangents.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSpecular) {
_meshesTranslucentTangentsSpecular.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSpecular) {
_meshesTranslucentSpecular.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSkinned) {
_meshesTranslucentSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSkinned) {
_meshesTranslucentTangentsSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentTangentsSpecularSkinned) {
_meshesTranslucentTangentsSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesTranslucentSpecularSkinned) {
_meshesTranslucentSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaque) {
_meshesOpaque.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangents) {
_meshesOpaqueTangents.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSpecular) {
_meshesOpaqueTangentsSpecular.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSpecular) {
_meshesOpaqueSpecular.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSkinned) {
_meshesOpaqueSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSkinned) {
_meshesOpaqueTangentsSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueTangentsSpecularSkinned) {
_meshesOpaqueTangentsSpecularSkinned.append(i);
}
foreach(int i, _unsortedMeshesOpaqueSpecularSkinned) {
_meshesOpaqueSpecularSkinned.append(i);
}
_unsortedMeshesTranslucentTangents.clear();
_unsortedMeshesTranslucent.clear();
_unsortedMeshesTranslucentTangentsSpecular.clear();
_unsortedMeshesTranslucentSpecular.clear();
_unsortedMeshesTranslucentTangentsSkinned.clear();
_unsortedMeshesTranslucentSkinned.clear();
_unsortedMeshesTranslucentTangentsSpecularSkinned.clear();
_unsortedMeshesTranslucentSpecularSkinned.clear();
_unsortedMeshesOpaqueTangents.clear();
_unsortedMeshesOpaque.clear();
_unsortedMeshesOpaqueTangentsSpecular.clear();
_unsortedMeshesOpaqueSpecular.clear();
_unsortedMeshesOpaqueTangentsSkinned.clear();
_unsortedMeshesOpaqueSkinned.clear();
_unsortedMeshesOpaqueTangentsSpecularSkinned.clear();
_unsortedMeshesOpaqueSpecularSkinned.clear();
_meshGroupsKnown = true;
}
int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
bool hasTangents, bool hasSpecular, bool isSkinned, RenderArgs* args) {
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();
@ -1507,9 +1621,6 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
// if we got here, then check to see if this mesh is in view
if (args) {
bool dontCullOutOfViewMeshParts = Menu::getInstance()->isOptionChecked(MenuOption::DontCullOutOfViewMeshParts);
bool cullTooSmallMeshParts = !Menu::getInstance()->isOptionChecked(MenuOption::DontCullTooSmallMeshParts);
bool shouldRender = true;
args->_meshesConsidered++;
@ -1600,39 +1711,49 @@ int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold,
glBindTexture(GL_TEXTURE_2D, 0);
} else {
glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity);
if (!(translucent && alphaThreshold == 0.0f)) {
glAlphaFunc(GL_EQUAL, diffuse.a = Application::getInstance()->getGlowEffect()->getIntensity());
}
glm::vec4 specular = glm::vec4(part.specularColor, 1.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse);
glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular);
glMaterialf(GL_FRONT, GL_SHININESS, part.shininess);
if (dontReduceMaterialSwitches || lastMaterialID != part.materialID) {
//qDebug() << "Material Changed ---------------------------------------------";
//qDebug() << "NEW part.materialID:" << part.materialID;
glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity);
if (!(translucent && alphaThreshold == 0.0f)) {
glAlphaFunc(GL_EQUAL, diffuse.a = Application::getInstance()->getGlowEffect()->getIntensity());
}
glm::vec4 specular = glm::vec4(part.specularColor, 1.0f);
glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse);
glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular);
glMaterialf(GL_FRONT, GL_SHININESS, part.shininess);
Texture* diffuseMap = networkPart.diffuseTexture.data();
if (mesh.isEye && diffuseMap) {
diffuseMap = (_dilatedTextures[i][j] =
static_cast<DilatableNetworkTexture*>(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
}
glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
Texture* diffuseMap = networkPart.diffuseTexture.data();
if (mesh.isEye && diffuseMap) {
diffuseMap = (_dilatedTextures[i][j] =
static_cast<DilatableNetworkTexture*>(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
}
glBindTexture(GL_TEXTURE_2D, !diffuseMap ?
Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID());
if (!mesh.tangents.isEmpty()) {
glActiveTexture(GL_TEXTURE1);
Texture* normalMap = networkPart.normalTexture.data();
glBindTexture(GL_TEXTURE_2D, !normalMap ?
Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
glActiveTexture(GL_TEXTURE0);
}
if (!mesh.tangents.isEmpty()) {
glActiveTexture(GL_TEXTURE1);
Texture* normalMap = networkPart.normalTexture.data();
glBindTexture(GL_TEXTURE_2D, !normalMap ?
Application::getInstance()->getTextureCache()->getBlueTextureID() : normalMap->getID());
glActiveTexture(GL_TEXTURE0);
}
if (specularTextureUnit) {
glActiveTexture(specularTextureUnit);
Texture* specularMap = networkPart.specularTexture.data();
glBindTexture(GL_TEXTURE_2D, !specularMap ?
Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID());
glActiveTexture(GL_TEXTURE0);
if (specularTextureUnit) {
glActiveTexture(specularTextureUnit);
Texture* specularMap = networkPart.specularTexture.data();
glBindTexture(GL_TEXTURE_2D, !specularMap ?
Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID());
glActiveTexture(GL_TEXTURE0);
}
if (args) {
args->_materialSwitches++;
}
}
lastMaterialID = part.materialID;
}
meshPartsRendered++;

View file

@ -338,6 +338,26 @@ private:
bool _meshGroupsKnown;
QMap<QString, int> _unsortedMeshesTranslucent;
QMap<QString, int> _unsortedMeshesTranslucentTangents;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecular;
QMap<QString, int> _unsortedMeshesTranslucentSpecular;
QMap<QString, int> _unsortedMeshesTranslucentSkinned;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSkinned;
QMap<QString, int> _unsortedMeshesTranslucentTangentsSpecularSkinned;
QMap<QString, int> _unsortedMeshesTranslucentSpecularSkinned;
QMap<QString, int> _unsortedMeshesOpaque;
QMap<QString, int> _unsortedMeshesOpaqueTangents;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecular;
QMap<QString, int> _unsortedMeshesOpaqueSpecular;
QMap<QString, int> _unsortedMeshesOpaqueSkinned;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSkinned;
QMap<QString, int> _unsortedMeshesOpaqueTangentsSpecularSkinned;
QMap<QString, int> _unsortedMeshesOpaqueSpecularSkinned;
QVector<int> _meshesTranslucent;
QVector<int> _meshesTranslucentTangents;
QVector<int> _meshesTranslucentTangentsSpecular;

View file

@ -459,7 +459,7 @@ void Stats::display(
VoxelSystem* voxels = Application::getInstance()->getVoxels();
lines = _expanded ? 15 : 3;
lines = _expanded ? 14 : 3;
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing)) {
lines += 10; // spatial audio processing adds 1 spacing line and 8 extra lines of info
}
@ -468,44 +468,54 @@ void Stats::display(
lines * STATS_PELS_PER_LINE + 10);
horizontalOffset += 5;
// Model/Entity render details
EntityTreeRenderer* entities = Application::getInstance()->getEntities();
voxelStats.str("");
voxelStats << "Entity Items rendered: " << entities->getItemsRendered()
<< " / Out of view:" << entities->getItemsOutOfView()
<< " / Too small:" << entities->getItemsTooSmall();
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
if (_expanded) {
// Model/Entity render details
EntityTreeRenderer* entities = Application::getInstance()->getEntities();
voxelStats.str("");
voxelStats << "Entity Items rendered: " << entities->getItemsRendered()
<< " Out of view:" << entities->getItemsOutOfView()
<< " Too small:" << entities->getItemsTooSmall();
voxelStats << " Meshes rendered: " << entities->getMeshesRendered()
<< " / Out of view:" << entities->getMeshesOutOfView()
<< " / Too small:" << entities->getMeshesTooSmall();
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
voxelStats.str("");
voxelStats << "Meshes rendered: " << entities->getMeshesRendered()
<< " Out of view:" << entities->getMeshesOutOfView()
<< " Too small:" << entities->getMeshesTooSmall();
voxelStats << " Triangles: " << entities->getTrianglesRendered()
<< " / Quads:" << entities->getQuadsRendered()
<< " / Material Switches:" << entities->getMaterialSwitches();
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
voxelStats.str("");
voxelStats << "Triangles: " << entities->getTrianglesRendered() << " Quads:" << entities->getQuadsRendered();
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
voxelStats.str("");
voxelStats << "Mesh Parts Rendered Opaque: " << entities->getOpaqueMeshPartsRendered()
<< " Translucent:" << entities->getTranslucentMeshPartsRendered();
voxelStats << " Mesh Parts Rendered Opaque: " << entities->getOpaqueMeshPartsRendered()
<< " / Translucent:" << entities->getTranslucentMeshPartsRendered();
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
}
voxelStats.str("");
voxelStats.precision(4);
voxelStats << "Voxels Drawn: " << voxels->getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << voxels->getAbandonedVoxels() / 1000.f << "K ";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
if (_expanded) {
// Local Voxel Memory Usage
voxelStats.str("");
voxelStats << "Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
voxelStats << " Voxels Memory Nodes: " << VoxelTreeElement::getTotalMemoryUsage() / 1000000.f << "MB";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
voxelStats.str("");
voxelStats <<
"Geometry RAM: " << voxels->getVoxelMemoryUsageRAM() / 1000000.f << "MB / " <<
" Geometry RAM: " << voxels->getVoxelMemoryUsageRAM() / 1000000.f << "MB / " <<
"VBO: " << voxels->getVoxelMemoryUsageVBO() / 1000000.f << "MB";
if (voxels->hasVoxelMemoryUsageGPU()) {
voxelStats << " / GPU: " << voxels->getVoxelMemoryUsageGPU() / 1000000.f << "MB";
@ -516,18 +526,11 @@ void Stats::display(
// Voxel Rendering
voxelStats.str("");
voxelStats.precision(4);
voxelStats << "Voxel Rendering Slots Max: " << voxels->getMaxVoxels() / 1000.f << "K";
voxelStats << " Voxel Rendering Slots Max: " << voxels->getMaxVoxels() / 1000.f << "K";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
}
voxelStats.str("");
voxelStats.precision(4);
voxelStats << "Drawn: " << voxels->getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << voxels->getAbandonedVoxels() / 1000.f << "K ";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
std::stringstream sendingMode("");
sendingMode << "Octree Sending Mode: [";
@ -598,44 +601,44 @@ void Stats::display(
}
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
unsigned long localTotal = VoxelTreeElement::getNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
// Server Voxels
voxelStats.str("");
voxelStats << "Server voxels: " << qPrintable(serversTotalString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
if (_expanded) {
QString serversInternalString = locale.toString((uint)totalInternal);
QString serversLeavesString = locale.toString((uint)totalLeaves);
// Server Octree Elements
if (!_expanded) {
voxelStats.str("");
voxelStats <<
"Internal: " << qPrintable(serversInternalString) << " " <<
"Leaves: " << qPrintable(serversLeavesString) << "";
voxelStats << "Octree Elements Server: " << qPrintable(serversTotalString)
<< " Local:" << qPrintable(localTotalString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
}
unsigned long localTotal = VoxelTreeElement::getNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
// Local Voxels
voxelStats.str("");
voxelStats << "Local voxels: " << qPrintable(localTotalString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
if (_expanded) {
voxelStats.str("");
voxelStats << "Octree Elements -";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
QString serversInternalString = locale.toString((uint)totalInternal);
QString serversLeavesString = locale.toString((uint)totalLeaves);
voxelStats.str("");
voxelStats << " Server: " << qPrintable(serversTotalString) <<
" Internal: " << qPrintable(serversInternalString) <<
" Leaves: " << qPrintable(serversLeavesString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
// Local Voxels
unsigned long localInternal = VoxelTreeElement::getInternalNodeCount();
unsigned long localLeaves = VoxelTreeElement::getLeafNodeCount();
QString localInternalString = locale.toString((uint)localInternal);
QString localLeavesString = locale.toString((uint)localLeaves);
voxelStats.str("");
voxelStats <<
"Internal: " << qPrintable(localInternalString) << " " <<
"Leaves: " << qPrintable(localLeavesString) << "";
voxelStats << " Local: " << qPrintable(serversTotalString) <<
" Internal: " << qPrintable(localInternalString) <<
" Leaves: " << qPrintable(localLeavesString) << "";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
}

View file

@ -659,6 +659,7 @@ public:
glm::vec3 emissive;
float shininess;
float opacity;
QString id;
};
class Cluster {
@ -1319,7 +1320,8 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
}
}
}
materials.insert(getID(object.properties), material);
material.id = getID(object.properties);
materials.insert(material.id, material);
} else if (object.name == "Deformer") {
if (object.properties.last() == "Cluster") {
@ -1621,6 +1623,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping)
if (!specularTexture.filename.isNull()) {
part.specularTexture = specularTexture;
}
part.materialID = material.id;
}
}
materialIndex++;

View file

@ -115,6 +115,8 @@ public:
FBXTexture diffuseTexture;
FBXTexture normalTexture;
FBXTexture specularTexture;
QString materialID;
};
/// A single mesh (with optional blendshapes) extracted from an FBX document.

View file

@ -163,7 +163,7 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) {
void OctreeRenderer::render(RenderMode renderMode) {
RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
if (_tree) {
_tree->lockForRead();
_tree->recurseTreeWithOperation(renderOperation, &args);
@ -179,6 +179,7 @@ void OctreeRenderer::render(RenderMode renderMode) {
_itemsOutOfView = args._itemsOutOfView;
_itemsTooSmall = args._itemsTooSmall;
_materialSwitches = args._materialSwitches;
_trianglesRendered = args._trianglesRendered;
_quadsRendered = args._quadsRendered;

View file

@ -74,6 +74,7 @@ public:
int getMeshesOutOfView() const { return _meshesOutOfView; }
int getMeshesTooSmall() const { return _meshesTooSmall; }
int getMaterialSwitches() const { return _materialSwitches; }
int getTrianglesRendered() const { return _trianglesRendered; }
int getQuadsRendered() const { return _quadsRendered; }
@ -95,6 +96,7 @@ protected:
int _meshesOutOfView;
int _meshesTooSmall;
int _materialSwitches;
int _trianglesRendered;
int _quadsRendered;
@ -120,6 +122,7 @@ public:
int _meshesOutOfView;
int _meshesTooSmall;
int _materialSwitches;
int _trianglesRendered;
int _quadsRendered;