remove a bunch of cruft from Model

This commit is contained in:
ZappoMan 2015-06-09 12:57:14 -07:00
parent e0adb8e38a
commit 2c6ebcb06a
2 changed files with 1 additions and 440 deletions

View file

@ -927,206 +927,6 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
_readyWhenAdded = false;
}
bool Model::render(RenderArgs* renderArgs, float alpha) {
return true; //
PROFILE_RANGE(__FUNCTION__);
if (_meshStates.isEmpty()) {
return false;
}
renderSetup(renderArgs);
return renderCore(renderArgs, alpha);
}
bool Model::renderCore(RenderArgs* args, float alpha) {
return true;
PROFILE_RANGE(__FUNCTION__);
if (!_viewState) {
return false;
}
auto mode = args->_renderMode;
// Let's introduce a gpu::Batch to capture all the calls to the graphics api
_renderBatch.clear();
gpu::Batch& batch = _renderBatch;
// Setup the projection matrix
if (args && args->_viewFrustum) {
glm::mat4 proj;
// If for easier debug depending on the pass
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
args->_viewFrustum->evalProjectionMatrix(proj);
} else {
args->_viewFrustum->evalProjectionMatrix(proj);
}
batch.setProjectionTransform(proj);
}
// Capture the view matrix once for the rendering of this model
if (_transforms.empty()) {
_transforms.push_back(Transform());
}
_transforms[0] = _viewState->getViewTransform();
// apply entity translation offset to the viewTransform in one go (it's a preTranslate because viewTransform goes from world to eye space)
_transforms[0].preTranslate(-_translation);
batch.setViewTransform(_transforms[0]);
/*DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(
mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE,
mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE,
mode == RenderArgs::DEFAULT_RENDER_MODE);
*/
/*if (mode != RenderArgs::SHADOW_RENDER_MODE)*/ {
GLenum buffers[3];
int bufferCount = 0;
// if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) {
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
}
// if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::NORMAL_RENDER_MODE) {
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
}
// if (mode == RenderArgs::DEFAULT_RENDER_MODE) {
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
}
GLBATCH(glDrawBuffers)(bufferCount, buffers);
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
}
const float DEFAULT_ALPHA_THRESHOLD = 0.5f;
//renderMeshes(batch, mode, translucent, alphaThreshold, hasTangents, hasSpecular, isSkinned, args, forceRenderMeshes);
int opaqueMeshPartsRendered = 0;
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, true, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, true, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, true, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, true, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, false, false, args, true);
opaqueMeshPartsRendered += renderMeshes(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, false, false, args, true);
// render translucent meshes afterwards
//DependencyManager::get<TextureCache>()->setPrimaryDrawBuffers(false, true, true);
{
GLenum buffers[2];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT1;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT2;
GLBATCH(glDrawBuffers)(bufferCount, buffers);
}
int translucentMeshPartsRendered = 0;
const float MOSTLY_OPAQUE_THRESHOLD = 0.75f;
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, true, false, args, true);
{
GLenum buffers[1];
int bufferCount = 0;
buffers[bufferCount++] = GL_COLOR_ATTACHMENT0;
GLBATCH(glDrawBuffers)(bufferCount, buffers);
}
// if (mode == RenderArgs::DEFAULT_RENDER_MODE || mode == RenderArgs::DIFFUSE_RENDER_MODE) {
if (mode != RenderArgs::SHADOW_RENDER_MODE) {
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryTransparentFramebuffer());
const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f;
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, true, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, false, false, args, true);
translucentMeshPartsRendered += renderMeshes(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, true, false, args, true);
// batch.setFramebuffer(DependencyManager::get<TextureCache>()->getPrimaryOpaqueFramebuffer());
}
GLBATCH(glDepthMask)(true);
GLBATCH(glDepthFunc)(GL_LESS);
GLBATCH(glDisable)(GL_CULL_FACE);
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
GLBATCH(glCullFace)(GL_BACK);
}
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 1);
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 2);
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
GLBATCH(glActiveTexture)(GL_TEXTURE0 + 3);
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
GLBATCH(glActiveTexture)(GL_TEXTURE0);
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
// deactivate vertex arrays after drawing
GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY);
GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY);
GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY);
GLBATCH(glDisableClientState)(GL_COLOR_ARRAY);
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT);
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX);
GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT);
// bind with 0 to switch back to normal operation
GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0);
GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0);
GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
// Back to no program
GLBATCH(glUseProgram)(0);
// Render!
{
PROFILE_RANGE("render Batch");
#if defined(ANDROID)
#else
glPushMatrix();
#endif
::gpu::GLBackend::renderBatch(batch, true); // force sync with gl state here
#if defined(ANDROID)
#else
glPopMatrix();
#endif
}
// restore all the default material settings
_viewState->setupWorldLight();
#ifdef WANT_DEBUG_MESHBOXES
renderDebugMeshBoxes();
#endif
return true;
}
void Model::renderDebugMeshBoxes() {
int colorNdx = 0;
_mutex.lock();
@ -2295,22 +2095,6 @@ void Model::segregateMeshGroups() {
_meshGroupsKnown = true;
}
QVector<int>* Model::pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe) {
PROFILE_RANGE(__FUNCTION__);
// depending on which parameters we were called with, pick the correct mesh group to render
QVector<int>* whichList = NULL;
RenderKey key(translucent, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
auto bucket = _renderBuckets.find(key.getRaw());
if (bucket != _renderBuckets.end()) {
whichList = &(*bucket).second._meshes;
}
return whichList;
}
void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
Locations*& locations) {
@ -2339,212 +2123,6 @@ void Model::pickPrograms(gpu::Batch& batch, RenderMode mode, bool translucent, f
}
}
int Model::renderMeshes(gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
bool forceRenderSomeMeshes) {
PROFILE_RANGE(__FUNCTION__);
int meshPartsRendered = 0;
//Pick the mesh list with the requested render flags
QVector<int>* whichList = pickMeshList(translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe);
if (!whichList) {
return 0;
}
QVector<int>& list = *whichList;
// If this list has nothing to render, then don't bother proceeding. This saves us on binding to programs
if (list.empty()) {
return 0;
}
Locations* locations = nullptr;
pickPrograms(batch, mode, translucent, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, isWireframe,
args, locations);
meshPartsRendered = renderMeshesFromList(list, batch, mode, translucent, alphaThreshold,
args, locations, forceRenderSomeMeshes);
return meshPartsRendered;
}
int Model::renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderMode mode, bool translucent, float alphaThreshold, RenderArgs* args,
Locations* locations, bool forceRenderMeshes) {
PROFILE_RANGE(__FUNCTION__);
auto textureCache = DependencyManager::get<TextureCache>();
QString lastMaterialID;
int meshPartsRendered = 0;
updateVisibleJointStates();
const FBXGeometry& geometry = _geometry->getFBXGeometry();
const QVector<NetworkMesh>& networkMeshes = _geometry->getMeshes();
// i is the "index" from the original networkMeshes QVector...
foreach (int i, list) {
// 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 (i < 0 || i >= networkMeshes.size() || i > 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
continue;
}
// 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);
batch.setIndexBuffer(gpu::UINT32, (networkMesh._indexBuffer), 0);
int vertexCount = mesh.vertices.size();
if (vertexCount == 0) {
// sanity check
continue;
}
// if we got here, then check to see if this mesh is in view
if (args) {
bool shouldRender = true;
if (args->_viewFrustum) {
shouldRender = forceRenderMeshes ||
args->_viewFrustum->boxInFrustum(_calculatedMeshBoxes.at(i)) != ViewFrustum::OUTSIDE;
if (shouldRender && !forceRenderMeshes) {
float distance = args->_viewFrustum->distanceToCamera(_calculatedMeshBoxes.at(i).calcCenter());
shouldRender = !_viewState ? false : _viewState->shouldRenderMesh(_calculatedMeshBoxes.at(i).getLargestDimension(),
distance);
}
}
if (!shouldRender) {
continue; // skip this mesh
}
}
const MeshState& state = _meshStates.at(i);
if (state.clusterMatrices.size() > 1) {
GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false,
(const float*)state.clusterMatrices.constData());
batch.setModelTransform(Transform());
} else {
batch.setModelTransform(Transform(state.clusterMatrices[0]));
}
if (mesh.blendshapes.isEmpty()) {
batch.setInputFormat(networkMesh._vertexFormat);
batch.setInputStream(0, *networkMesh._vertexStream);
} else {
batch.setInputFormat(networkMesh._vertexFormat);
batch.setInputBuffer(0, _blendedVertexBuffers[i], 0, sizeof(glm::vec3));
batch.setInputBuffer(1, _blendedVertexBuffers[i], vertexCount * sizeof(glm::vec3), sizeof(glm::vec3));
batch.setInputStream(2, *networkMesh._vertexStream);
}
if (mesh.colors.isEmpty()) {
GLBATCH(glColor4f)(1.0f, 1.0f, 1.0f, 1.0f);
}
qint64 offset = 0;
for (int j = 0; j < networkMesh.parts.size(); j++) {
const NetworkMeshPart& networkPart = networkMesh.parts.at(j);
const FBXMeshPart& part = mesh.parts.at(j);
model::MaterialPointer material = part._material;
if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) {
offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int);
continue;
}
// apply material properties
if (mode == RenderArgs::SHADOW_RENDER_MODE) {
/// GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0);
} else {
if (lastMaterialID != part.materialID) {
const bool wantDebug = false;
if (wantDebug) {
qCDebug(renderutils) << "Material Changed ---------------------------------------------";
qCDebug(renderutils) << "part INDEX:" << j;
qCDebug(renderutils) << "NEW part.materialID:" << part.materialID;
}
if (locations->materialBufferUnit >= 0) {
batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer());
}
Texture* diffuseMap = networkPart.diffuseTexture.data();
if (mesh.isEye && diffuseMap) {
diffuseMap = (_dilatedTextures[i][j] =
static_cast<DilatableNetworkTexture*>(diffuseMap)->getDilatedTexture(_pupilDilation)).data();
}
static bool showDiffuse = true;
if (showDiffuse && diffuseMap) {
batch.setUniformTexture(0, diffuseMap->getGPUTexture());
} else {
batch.setUniformTexture(0, textureCache->getWhiteTexture());
}
if (locations->texcoordMatrices >= 0) {
glm::mat4 texcoordTransform[2];
if (!part.diffuseTexture.transform.isIdentity()) {
part.diffuseTexture.transform.getMatrix(texcoordTransform[0]);
}
if (!part.emissiveTexture.transform.isIdentity()) {
part.emissiveTexture.transform.getMatrix(texcoordTransform[1]);
}
GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);
}
if (!mesh.tangents.isEmpty()) {
Texture* normalMap = networkPart.normalTexture.data();
batch.setUniformTexture(1, !normalMap ?
textureCache->getBlueTexture() : normalMap->getGPUTexture());
}
if (locations->specularTextureUnit >= 0) {
Texture* specularMap = networkPart.specularTexture.data();
batch.setUniformTexture(locations->specularTextureUnit, !specularMap ?
textureCache->getWhiteTexture() : specularMap->getGPUTexture());
}
}
// HACK: For unkwon reason (yet!) this code that should be assigned only if the material changes need to be called for every
// drawcall with an emissive, so let's do it for now.
if (locations->emissiveTextureUnit >= 0) {
// assert(locations->emissiveParams >= 0); // we should have the emissiveParams defined in the shader
float emissiveOffset = part.emissiveParams.x;
float emissiveScale = part.emissiveParams.y;
GLBATCH(glUniform2f)(locations->emissiveParams, emissiveOffset, emissiveScale);
Texture* emissiveMap = networkPart.emissiveTexture.data();
batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ?
textureCache->getWhiteTexture() : emissiveMap->getGPUTexture());
}
lastMaterialID = part.materialID;
}
meshPartsRendered++;
if (part.quadIndices.size() > 0) {
batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset);
offset += part.quadIndices.size() * sizeof(int);
}
if (part.triangleIndices.size() > 0) {
batch.drawIndexed(gpu::TRIANGLES, part.triangleIndices.size(), offset);
offset += part.triangleIndices.size() * sizeof(int);
}
}
}
return meshPartsRendered;
}
ModelBlender::ModelBlender() :
_pendingBlenders(0) {

View file

@ -399,18 +399,8 @@ private:
int _debugMeshBoxesID = GeometryCache::UNKNOWN_ID;
// helper functions used by render() or renderInScene()
bool renderCore(RenderArgs* args, float alpha);
int renderMeshes(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args = NULL,
bool forceRenderMeshes = false);
void setupBatchTransform(gpu::Batch& batch, RenderArgs* args);
QVector<int>* pickMeshList(bool translucent, float alphaThreshold, bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe);
int renderMeshesFromList(QVector<int>& list, gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
RenderArgs* args, Locations* locations,
bool forceRenderSomeMeshes = false);
static void pickPrograms(gpu::Batch& batch, RenderArgs::RenderMode mode, bool translucent, float alphaThreshold,
bool hasLightmap, bool hasTangents, bool hasSpecular, bool isSkinned, bool isWireframe, RenderArgs* args,
Locations*& locations);
@ -543,13 +533,6 @@ private:
bool _readyWhenAdded = false;
bool _needsReload = true;
private:
// FIX ME - We want to get rid of this interface for rendering...
// right now the only remaining user are Avatar attachments.
// that usage has been temporarily disabled...
bool render(RenderArgs* renderArgs, float alpha = 1.0f);
};
Q_DECLARE_METATYPE(QPointer<Model>)