mirror of
https://github.com/lubosz/overte.git
synced 2025-04-24 03:53:52 +02:00
first cut at separating opaque from transparent meshes
This commit is contained in:
parent
c8db8855cc
commit
8a83511942
3 changed files with 76 additions and 17 deletions
|
@ -46,7 +46,8 @@ Model::Model(QObject* parent) :
|
|||
_url("http://invalid.com"),
|
||||
_blendNumber(0),
|
||||
_appliedBlendNumber(0),
|
||||
_calculatedMeshBoxesValid(false) {
|
||||
_calculatedMeshBoxesValid(false),
|
||||
_translucentMeshesKnown(false) {
|
||||
|
||||
// we may have been created in the network thread, but we live in the main thread
|
||||
moveToThread(Application::getInstance()->thread());
|
||||
|
@ -271,6 +272,8 @@ void Model::reset() {
|
|||
for (int i = 0; i < _jointStates.size(); i++) {
|
||||
_jointStates[i].setRotationInConstrainedFrame(geometry.joints.at(i).rotation, 0.0f);
|
||||
}
|
||||
|
||||
_translucentMeshesKnown = false;
|
||||
}
|
||||
|
||||
bool Model::updateGeometry() {
|
||||
|
@ -421,6 +424,10 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
_dilatedTextures.append(dilated);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_translucentMeshesKnown) {
|
||||
calculateTranslucentMeshes();
|
||||
}
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
@ -451,11 +458,11 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
mode == DEFAULT_RENDER_MODE);
|
||||
|
||||
const float DEFAULT_ALPHA_THRESHOLD = 0.5f;
|
||||
renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, args);
|
||||
int opaqueMeshPartsRendered = renderMeshes(mode, false, DEFAULT_ALPHA_THRESHOLD, args);
|
||||
|
||||
// render translucent meshes afterwards
|
||||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true);
|
||||
renderMeshes(mode, true, 0.75f, args);
|
||||
int translucentMeshPartsRendered = renderMeshes(mode, true, 0.75f, args);
|
||||
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
|
@ -465,7 +472,7 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true);
|
||||
|
||||
if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) {
|
||||
renderMeshes(mode, true, 0.0f, args);
|
||||
translucentMeshPartsRendered += renderMeshes(mode, true, 0.0f, args);
|
||||
}
|
||||
|
||||
glDepthMask(true);
|
||||
|
@ -488,6 +495,11 @@ bool Model::render(float alpha, RenderMode mode, RenderArgs* args) {
|
|||
|
||||
// restore all the default material settings
|
||||
Application::getInstance()->setupWorldLight();
|
||||
|
||||
if (args) {
|
||||
args->_translucentMeshPartsRendered = translucentMeshPartsRendered;
|
||||
args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1238,21 +1250,45 @@ void Model::deleteGeometry() {
|
|||
_blendedBlendshapeCoefficients.clear();
|
||||
}
|
||||
|
||||
void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args) {
|
||||
void Model::calculateTranslucentMeshes() {
|
||||
_translucentMeshes.clear();
|
||||
_opaqueMeshes.clear();
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||
|
||||
for (int i = 0; i < networkMeshes.size(); i++) {
|
||||
const NetworkMesh& networkMesh = networkMeshes.at(i);
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
|
||||
bool translucentMesh = networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size();
|
||||
if (translucentMesh) {
|
||||
_translucentMeshes.append(i);
|
||||
} else {
|
||||
_opaqueMeshes.append(i);
|
||||
}
|
||||
}
|
||||
_translucentMeshesKnown = true;
|
||||
}
|
||||
|
||||
int Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args) {
|
||||
int meshPartsRendered = 0;
|
||||
updateVisibleJointStates();
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
|
||||
|
||||
bool cullMeshParts = args && !Menu::getInstance()->isOptionChecked(MenuOption::DontCullMeshParts);
|
||||
|
||||
for (int i = 0; i < networkMeshes.size(); i++) {
|
||||
// if we're called in translucent mode, then use our translucent list vs opaque list
|
||||
QList<int>& list = translucent ? _translucentMeshes : _opaqueMeshes;
|
||||
|
||||
|
||||
// i is the "index" from the original networkMeshes QVector...
|
||||
foreach (int i, list) {
|
||||
|
||||
// exit early if the translucency doesn't match what we're drawing
|
||||
const NetworkMesh& networkMesh = networkMeshes.at(i);
|
||||
const FBXMesh& mesh = geometry.meshes.at(i);
|
||||
if (translucent ? (networkMesh.getTranslucentPartCount(mesh) == 0) :
|
||||
(networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const_cast<QOpenGLBuffer&>(networkMesh.indexBuffer).bind();
|
||||
|
||||
int vertexCount = mesh.vertices.size();
|
||||
|
@ -1424,11 +1460,19 @@ void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold
|
|||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
}
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, part.triangleIndices.size(),
|
||||
GL_UNSIGNED_INT, (void*)offset);
|
||||
offset += part.triangleIndices.size() * sizeof(int);
|
||||
|
||||
meshPartsRendered++;
|
||||
|
||||
if (part.quadIndices.size() > 0) {
|
||||
glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset);
|
||||
offset += part.quadIndices.size() * sizeof(int);
|
||||
}
|
||||
|
||||
if (part.triangleIndices.size() > 0) {
|
||||
glDrawRangeElementsEXT(GL_TRIANGLES, 0, vertexCount - 1, part.triangleIndices.size(),
|
||||
GL_UNSIGNED_INT, (void*)offset);
|
||||
offset += part.triangleIndices.size() * sizeof(int);
|
||||
}
|
||||
|
||||
if (args) {
|
||||
const int INDICES_PER_TRIANGLE = 3;
|
||||
|
@ -1467,6 +1511,8 @@ void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold
|
|||
|
||||
activeProgram->release();
|
||||
}
|
||||
|
||||
return meshPartsRendered;
|
||||
}
|
||||
|
||||
void AnimationHandle::setURL(const QUrl& url) {
|
||||
|
|
|
@ -251,7 +251,7 @@ private:
|
|||
|
||||
void applyNextGeometry();
|
||||
void deleteGeometry();
|
||||
void renderMeshes(RenderMode mode, bool translucent, float alphaThreshold = 0.5f, RenderArgs* args = NULL);
|
||||
int renderMeshes(RenderMode mode, bool translucent, float alphaThreshold = 0.5f, RenderArgs* args = NULL);
|
||||
QVector<JointState> createJointStates(const FBXGeometry& geometry);
|
||||
void initJointTransforms();
|
||||
|
||||
|
@ -332,6 +332,13 @@ private:
|
|||
|
||||
QVector<AABox> _calculatedMeshBoxes;
|
||||
bool _calculatedMeshBoxesValid;
|
||||
|
||||
void calculateTranslucentMeshes(); // used to calculate our list of translucent vs opaque meshes
|
||||
|
||||
bool _translucentMeshesKnown;
|
||||
QList<int> _translucentMeshes; // indices of the meshes that are translucent
|
||||
QList<int> _opaqueMeshes; // indices of the meshes that are opaque
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(QPointer<Model>)
|
||||
|
|
|
@ -461,7 +461,7 @@ void Stats::display(
|
|||
|
||||
lines = _expanded ? 14 : 3;
|
||||
if (_expanded && Menu::getInstance()->isOptionChecked(MenuOption::AudioSpatialProcessing)) {
|
||||
lines += 9; // spatial audio processing adds 1 spacing line and 8 extra lines of info
|
||||
lines += 10; // spatial audio processing adds 1 spacing line and 8 extra lines of info
|
||||
}
|
||||
|
||||
drawBackground(backgroundColor, horizontalOffset, 0, glWidget->width() - horizontalOffset,
|
||||
|
@ -486,6 +486,12 @@ void Stats::display(
|
|||
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();
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)voxelStats.str().c_str(), color);
|
||||
|
||||
|
||||
// Local Voxel Memory Usage
|
||||
voxelStats.str("");
|
||||
|
|
Loading…
Reference in a new issue