From 4c817547b771bf6373e8cb2729db9b25b80ceadc Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 31 May 2015 14:02:20 -0700 Subject: [PATCH 01/10] Merging with Brad's branch and trying to get the rendering working --- interface/src/Application.cpp | 2 +- .../src/EntityTreeRenderer.cpp | 2 +- libraries/gpu/src/gpu/Context.cpp | 8 +- libraries/gpu/src/gpu/Context.h | 12 +- libraries/gpu/src/gpu/GLBackend.cpp | 17 ++ libraries/gpu/src/gpu/GLBackend.h | 4 +- .../src/DeferredLightingEffect.cpp | 4 +- libraries/render-utils/src/Model.cpp | 167 +++++++------- libraries/render/src/render/DrawTask.cpp | 216 ++++++++++++------ 9 files changed, 267 insertions(+), 165 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index da386cf696..e8e7606862 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -842,7 +842,7 @@ void Application::paintGL() { _glWidget->makeCurrent(); auto lodManager = DependencyManager::get(); - gpu::Context context; + gpu::Context context(new gpu::GLBackend()); RenderArgs renderArgs(&context, nullptr, getViewFrustum(), lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 5f20e55298..af73c1cc02 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -524,7 +524,7 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) { _tree->unlock(); glPushMatrix(); - renderArgs->_context->enqueueBatch(batch); + renderArgs->_context->render(batch); glPopMatrix(); renderArgs->_batch = nullptr; diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 78a6a6f607..c888003b29 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -15,7 +15,8 @@ using namespace gpu; -Context::Context() { +Context::Context(Backend* backend) : + _backend(backend) { } Context::Context(const Context& context) { @@ -31,6 +32,7 @@ bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) { return false; } -void Context::enqueueBatch(Batch& batch) { - GLBackend::renderBatch(batch, true); +void Context::render(Batch& batch) { + _backend->render(batch); + // GLBackend::renderBatch(batch, true); } diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 7ffb22f1c8..97ecf6b846 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -31,6 +31,9 @@ class Batch; class Backend { public: + virtual~ Backend() {}; + virtual void render(Batch& batch) = 0; + class TransformObject { public: Mat4 _model; @@ -107,15 +110,14 @@ protected: class Context { public: - Context(); - Context(const Context& context); + Context(Backend* backend); ~Context(); - void enqueueBatch(Batch& batch); - + void render(Batch& batch); protected: + Context(const Context& context); // This function can only be called by "static Shader::makeProgram()" // makeProgramShader(...) make a program shader ready to be used in a Batch. @@ -123,6 +125,8 @@ protected: // If the shader passed is not a program, nothing happens. static bool makeProgram(Shader& shader, const Shader::BindingSet& bindings = Shader::BindingSet()); + std::unique_ptr _backend; + friend class Shader; }; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 0dde9699f2..c26564a338 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -442,6 +442,8 @@ void Batch::_glUniform1f(GLint location, GLfloat v0) { } void GLBackend::do_glUniform1f(Batch& batch, uint32 paramOffset) { if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect return; } glUniform1f( @@ -460,6 +462,11 @@ void Batch::_glUniform2f(GLint location, GLfloat v0, GLfloat v1) { DO_IT_NOW(_glUniform2f, 1); } void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } glUniform2f( batch._params[paramOffset + 2]._int, batch._params[paramOffset + 1]._float, @@ -478,6 +485,11 @@ void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) { DO_IT_NOW(_glUniform4fv, 3); } void GLBackend::do_glUniform4fv(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } glUniform4fv( batch._params[paramOffset + 2]._int, batch._params[paramOffset + 1]._uint, @@ -498,6 +510,11 @@ void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpo DO_IT_NOW(_glUniformMatrix4fv, 4); } void GLBackend::do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } glUniformMatrix4fv( batch._params[paramOffset + 3]._int, batch._params[paramOffset + 2]._uint, diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 6c70502458..da0fe77b24 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -26,9 +26,9 @@ public: explicit GLBackend(bool syncCache); GLBackend(); - ~GLBackend(); + virtual ~GLBackend(); - void render(Batch& batch); + virtual void render(Batch& batch); // Render Batch create a local Context and execute the batch with it // WARNING: diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 202c6c6a02..4398c1c3cc 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -107,7 +107,7 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { } void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured) { - DependencyManager::get()->setPrimaryDrawBuffers(batch, true, true, true); + // DependencyManager::get()->setPrimaryDrawBuffers(batch, true, true, true); if (textured) { batch.setPipeline(_simpleProgramTextured); @@ -117,7 +117,7 @@ void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch, bool textured) } void DeferredLightingEffect::releaseSimpleProgram(gpu::Batch& batch) { - DependencyManager::get()->setPrimaryDrawBuffers(batch, true, false, false); + // DependencyManager::get()->setPrimaryDrawBuffers(batch, true, false, false); } void DeferredLightingEffect::renderSolidSphere(gpu::Batch& batch, float radius, int slices, int stacks, const glm::vec4& color) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 1f397b40e8..894e929897 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -783,7 +783,7 @@ namespace render { } template <> const Item::Bound payloadGetBound(const TransparentMeshPart::Pointer& payload) { - qDebug() << "payloadGetBound(TransparentMeshPart) url:" << payload->model->getURL(); + //qDebug() << "payloadGetBound(TransparentMeshPart) url:" << payload->model->getURL(); if (payload) { //return payload->model->getPartBounds(payload->meshIndex, payload->partIndex); } @@ -791,7 +791,7 @@ namespace render { } template <> void payloadRender(const TransparentMeshPart::Pointer& payload, RenderArgs* args) { if (args) { - qDebug() << "payloadRender(TransparentMeshPart) url:" << payload->model->getURL(); + // qDebug() << "payloadRender(TransparentMeshPart) url:" << payload->model->getURL(); args->_elementsTouched++; return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, true); } @@ -815,7 +815,7 @@ namespace render { } template <> const Item::Bound payloadGetBound(const OpaqueMeshPart::Pointer& payload) { - qDebug() << "payloadGetBound(OpaqueMeshPart) url:" << payload->model->getURL(); + // qDebug() << "payloadGetBound(OpaqueMeshPart) url:" << payload->model->getURL(); if (payload) { //return payload->model->getPartBounds(payload->meshIndex, payload->partIndex); } @@ -823,7 +823,7 @@ namespace render { } template <> void payloadRender(const OpaqueMeshPart::Pointer& payload, RenderArgs* args) { if (args) { - qDebug() << "payloadRender(OpaqueMeshPart) url:" << payload->model->getURL(); + // qDebug() << "payloadRender(OpaqueMeshPart) url:" << payload->model->getURL(); args->_elementsTouched++; return payload->model->renderPart(args, payload->meshIndex, payload->partIndex, false); } @@ -1957,9 +1957,12 @@ void Model::setupBatchTransform(gpu::Batch& batch, RenderArgs* args) { } void Model::endScene(RenderArgs* args) { + // Now that we migrated everything to the new RENDER/SCENE no more work to do! + return; PROFILE_RANGE(__FUNCTION__); + #if (GPU_TRANSFORM_PROFILE == GPU_LEGACY) // with legacy transform profile, we still to protect that transform stack... glPushMatrix(); @@ -1972,6 +1975,7 @@ void Model::endScene(RenderArgs* args) { renderSide = args->_renderSide; } + gpu::GLBackend backend; backend.syncCache(); // force sync with gl state here @@ -2191,7 +2195,7 @@ AABox Model::getPartBounds(int meshIndex, int partIndex) { void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool translucent) { //renderCore(args, 1.0f); //return; -qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; +//qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; renderSetup(args); auto textureCache = DependencyManager::get(); @@ -2229,7 +2233,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << // FIXME: Do I need this? it doesn't seem to do anything. - { + /* { GLenum buffers[3]; int bufferCount = 0; @@ -2243,7 +2247,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; } GLBATCH(glDrawBuffers)(bufferCount, buffers); - } + }*/ const float DEFAULT_ALPHA_THRESHOLD = 0.5f; // auto alphaThreshold = DEFAULT_ALPHA_THRESHOLD; // FIX ME @@ -2285,7 +2289,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << if (i < 0 || i >= networkMeshes.size() || i > geometry.meshes.size()) { _meshGroupsKnown = false; // regenerate these lists next time around. - qDebug() << "if (i < 0 || i >= networkMeshes.size() || i > geometry.meshes.size()) {.... BAIL!!!"; + // qDebug() << "if (i < 0 || i >= networkMeshes.size() || i > geometry.meshes.size()) {.... BAIL!!!"; return; // FIXME! } @@ -2297,7 +2301,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { // sanity check - qDebug() << "if (vertexCount == 0) {.... BAIL!!!"; + // qDebug() << "if (vertexCount == 0) {.... BAIL!!!"; return; // FIXME! } @@ -2321,10 +2325,10 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << } if (mesh.colors.isEmpty()) { - qDebug() << " colors empty ... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; + // qDebug() << " colors empty ... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; GLBATCH(glColor4f)(1.0f, 1.0f, 1.0f, 1.0f); } else { - qDebug() << " colors size:" << mesh.colors.size() << " ... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; + // qDebug() << " colors size:" << mesh.colors.size() << " ... meshIndex:" << meshIndex << "partIndex:" << partIndex << "url:" << _url; } qint64 offset = 0; @@ -2333,6 +2337,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << const FBXMeshPart& part = mesh.parts.at(j); model::MaterialPointer material = part._material; + if (material != nullptr) { /* if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); @@ -2340,86 +2345,88 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << } */ - // apply material properties - if (mode == RenderArgs::SHADOW_RENDER_MODE) { - /// GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + // apply material properties + if (mode == RenderArgs::SHADOW_RENDER_MODE) { + /// GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - } else { - if (true) { //lastMaterialID != part.materialID) { - const bool wantDebug = true; - if (wantDebug) { - qCDebug(renderutils) << "Material Changed ---------------------------------------------"; - qCDebug(renderutils) << "part INDEX:" << j; - qCDebug(renderutils) << "NEW part.materialID:" << part.materialID; - } + } else { + if (true) { //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()); - } + 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(diffuseMap)->getDilatedTexture(_pupilDilation)).data(); - } - static bool showDiffuse = true; - if (showDiffuse && diffuseMap) { - qCDebug(renderutils) << " batch.setUniformTexture(0, diffuseMap->getGPUTexture());"; - batch.setUniformTexture(0, diffuseMap->getGPUTexture()); + Texture* diffuseMap = networkPart.diffuseTexture.data(); + if (mesh.isEye && diffuseMap) { + diffuseMap = (_dilatedTextures[i][j] = + static_cast(diffuseMap)->getDilatedTexture(_pupilDilation)).data(); + } + static bool showDiffuse = true; + if (showDiffuse && diffuseMap) { + // qCDebug(renderutils) << " batch.setUniformTexture(0, diffuseMap->getGPUTexture());"; + batch.setUniformTexture(0, diffuseMap->getGPUTexture()); - } else { - qCDebug(renderutils) << " batch.setUniformTexture(0, textureCache->getWhiteTexture());"; - batch.setUniformTexture(0, textureCache->getWhiteTexture()); - } - - if (locations->texcoordMatrices >= 0) { - glm::mat4 texcoordTransform[2]; - if (!part.diffuseTexture.transform.isIdentity()) { - qCDebug(renderutils) << " part.diffuseTexture.transform.getMatrix(texcoordTransform[0]);"; - part.diffuseTexture.transform.getMatrix(texcoordTransform[0]); + } else { + // qCDebug(renderutils) << " batch.setUniformTexture(0, textureCache->getWhiteTexture());"; + batch.setUniformTexture(0, textureCache->getWhiteTexture()); } - if (!part.emissiveTexture.transform.isIdentity()) { - qCDebug(renderutils) << " part.emissiveTexture.transform.getMatrix(texcoordTransform[1]);"; - part.emissiveTexture.transform.getMatrix(texcoordTransform[1]); + + if (locations->texcoordMatrices >= 0) { + glm::mat4 texcoordTransform[2]; + if (!part.diffuseTexture.transform.isIdentity()) { + // qCDebug(renderutils) << " part.diffuseTexture.transform.getMatrix(texcoordTransform[0]);"; + part.diffuseTexture.transform.getMatrix(texcoordTransform[0]); + } + if (!part.emissiveTexture.transform.isIdentity()) { + // qCDebug(renderutils) << " part.emissiveTexture.transform.getMatrix(texcoordTransform[1]);"; + part.emissiveTexture.transform.getMatrix(texcoordTransform[1]); + } + // qCDebug(renderutils) << " GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);"; + GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform); } - qCDebug(renderutils) << " GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform);"; - GLBATCH(glUniformMatrix4fv)(locations->texcoordMatrices, 2, false, (const float*) &texcoordTransform); - } - if (!mesh.tangents.isEmpty()) { - Texture* normalMap = networkPart.normalTexture.data(); - qCDebug(renderutils) << " batch.setUniformTexture(1, !normalMap ? textureCache->getBlueTexture() : normalMap->getGPUTexture());"; - batch.setUniformTexture(1, !normalMap ? - textureCache->getBlueTexture() : normalMap->getGPUTexture()); + if (!mesh.tangents.isEmpty()) { + Texture* normalMap = networkPart.normalTexture.data(); + // qCDebug(renderutils) << " batch.setUniformTexture(1, !normalMap ? textureCache->getBlueTexture() : normalMap->getGPUTexture());"; + batch.setUniformTexture(1, !normalMap ? + textureCache->getBlueTexture() : normalMap->getGPUTexture()); - } + } - if (locations->specularTextureUnit >= 0) { - Texture* specularMap = networkPart.specularTexture.data(); - qCDebug(renderutils) << " batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? textureCache->getWhiteTexture() : specularMap->getGPUTexture());"; - batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? - textureCache->getWhiteTexture() : specularMap->getGPUTexture()); + if (locations->specularTextureUnit >= 0) { + Texture* specularMap = networkPart.specularTexture.data(); + // qCDebug(renderutils) << " batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? textureCache->getWhiteTexture() : specularMap->getGPUTexture());"; + batch.setUniformTexture(locations->specularTextureUnit, !specularMap ? + textureCache->getWhiteTexture() : specularMap->getGPUTexture()); + } + + if (args) { + args->_materialSwitches++; + } + } - if (args) { - args->_materialSwitches++; + // 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(); + // qCDebug(renderutils) << " batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? textureCache->getWhiteTexture() : emissiveMap->getGPUTexture());"; + batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? + textureCache->getWhiteTexture() : emissiveMap->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(); - qCDebug(renderutils) << " batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? textureCache->getWhiteTexture() : emissiveMap->getGPUTexture());"; - batch.setUniformTexture(locations->emissiveTextureUnit, !emissiveMap ? - textureCache->getWhiteTexture() : emissiveMap->getGPUTexture()); - } lastMaterialID = part.materialID; } @@ -2427,13 +2434,13 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << meshPartsRendered++; if (part.quadIndices.size() > 0) { - qDebug() << "batch.drawIndexed(gpu::QUADS) size:" << part.quadIndices.size(); + // qDebug() << "batch.drawIndexed(gpu::QUADS) size:" << part.quadIndices.size(); batch.drawIndexed(gpu::QUADS, part.quadIndices.size(), offset); offset += part.quadIndices.size() * sizeof(int); } if (part.triangleIndices.size() > 0) { - qDebug() << "batch.drawIndexed(gpu::TRIANGLES) size:" << part.triangleIndices.size(); + // qDebug() << "batch.drawIndexed(gpu::TRIANGLES) size:" << part.triangleIndices.size(); batch.drawIndexed(gpu::TRIANGLES, part.triangleIndices.size(), offset); offset += part.triangleIndices.size() * sizeof(int); } @@ -2483,7 +2490,7 @@ qDebug() << "Model::renderPart()... meshIndex:" << meshIndex << "partIndex:" << */ // Back to no program - GLBATCH(glUseProgram)(0); // NOTE: We need this or else the avatar will end up with the texture of the last entity + // GLBATCH(glUseProgram)(0); // NOTE: We need this or else the avatar will end up with the texture of the last entity } void Model::segregateMeshGroups() { diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index d8d3a14390..9e66ec0938 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -55,73 +55,6 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon Job::~Job() { } -template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render opaques - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape()); - - ItemIDs inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.push_back(id); - } - - ItemIDs culledItems; - cullItems(sceneContext, renderContext, inItems, culledItems); - - ItemIDs sortedItems; - depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items! - - renderItems(sceneContext, renderContext, sortedItems); -} - - -template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render transparents - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape()); - - ItemIDs inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.push_back(id); - } - - ItemIDs culledItems; - cullItems(sceneContext, renderContext, inItems, culledItems); - - ItemIDs sortedItems; - depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items! - - renderItems(sceneContext, renderContext, sortedItems); -} - -template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - assert(renderContext->args); - assert(renderContext->args->_viewFrustum); - - // render lights - auto& scene = sceneContext->_scene; - auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light()); - - - ItemIDs inItems; - inItems.reserve(items.size()); - for (auto id : items) { - inItems.push_back(id); - } - - ItemIDs culledItems; - cullItems(sceneContext, renderContext, inItems, culledItems); - renderItems(sceneContext, renderContext, culledItems); -} - /* bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera) { const float octreeToMeshRatio = 4.0f; // must be this many times closer to a mesh than a voxel to see it. @@ -263,16 +196,155 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems) { auto& scene = sceneContext->_scene; RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - args->_batch = &theBatch; - // render for (auto id : inItems) { auto item = scene->getItem(id); item.render(args); } +} - args->_context->enqueueBatch((*args->_batch)); +void addClearStateCommands(gpu::Batch& batch) { + batch._glDepthMask(true); + batch._glDepthFunc(GL_LESS); + batch._glDisable(GL_CULL_FACE); + + batch._glActiveTexture(GL_TEXTURE0 + 1); + batch._glBindTexture(GL_TEXTURE_2D, 0); + batch._glActiveTexture(GL_TEXTURE0 + 2); + batch._glBindTexture(GL_TEXTURE_2D, 0); + batch._glActiveTexture(GL_TEXTURE0 + 3); + batch._glBindTexture(GL_TEXTURE_2D, 0); + batch._glActiveTexture(GL_TEXTURE0); + batch._glBindTexture(GL_TEXTURE_2D, 0); + + + // deactivate vertex arrays after drawing + batch._glDisableClientState(GL_NORMAL_ARRAY); + batch._glDisableClientState(GL_VERTEX_ARRAY); + batch._glDisableClientState(GL_TEXTURE_COORD_ARRAY); + batch._glDisableClientState(GL_COLOR_ARRAY); + batch._glDisableVertexAttribArray(gpu::Stream::TANGENT); + batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_INDEX); + batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_WEIGHT); + + // bind with 0 to switch back to normal operation + batch._glBindBuffer(GL_ARRAY_BUFFER, 0); + batch._glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + batch._glBindTexture(GL_TEXTURE_2D, 0); + + // Back to no program + batch._glUseProgram(0); +} + + +template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render opaques + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape()); + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + + ItemIDs culledItems; + cullItems(sceneContext, renderContext, inItems, culledItems); + + ItemIDs sortedItems; + depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items! + + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + + glm::mat4 proj; + args->_viewFrustum->evalProjectionMatrix(proj); + theBatch.setProjectionTransform(proj); + + renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + theBatch._glDrawBuffers(bufferCount, buffers); + } + + renderItems(sceneContext, renderContext, sortedItems); + + addClearStateCommands((*args->_batch)); + args->_context->render((*args->_batch)); args->_batch = nullptr; -} \ No newline at end of file +} + + +template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render transparents + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::transparentShape()); + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + + ItemIDs culledItems; + cullItems(sceneContext, renderContext, inItems, culledItems); + + ItemIDs sortedItems; + depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items! + + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + + renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + theBatch._glDrawBuffers(bufferCount, buffers); + } + + renderItems(sceneContext, renderContext, sortedItems); + + addClearStateCommands((*args->_batch)); + args->_context->render((*args->_batch)); + args->_batch = nullptr; +} + +template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render lights + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::light()); + + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + + ItemIDs culledItems; + cullItems(sceneContext, renderContext, inItems, culledItems); + + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + renderItems(sceneContext, renderContext, culledItems); + args->_context->render((*args->_batch)); + args->_batch = nullptr; +} From c8e30ef39eebd22124d95a458645025ec3769772 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 1 Jun 2015 12:35:54 -0700 Subject: [PATCH 02/10] On to a full rendered pipeline --- libraries/gpu/src/gpu/Context.cpp | 5 ++++- libraries/gpu/src/gpu/Context.h | 2 ++ libraries/gpu/src/gpu/GLBackend.h | 12 ++++++------ libraries/render-utils/src/RenderDeferredTask.cpp | 4 ++++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index c888003b29..9cc6bb3cd7 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -34,5 +34,8 @@ bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) { void Context::render(Batch& batch) { _backend->render(batch); - // GLBackend::renderBatch(batch, true); } + +void Context::syncCache() { + _backend->syncCache(); +} \ No newline at end of file diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 97ecf6b846..99021d2731 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -33,6 +33,7 @@ public: virtual~ Backend() {}; virtual void render(Batch& batch) = 0; + virtual void syncCache() = 0; class TransformObject { public: @@ -115,6 +116,7 @@ public: void render(Batch& batch); + void syncCache(); protected: Context(const Context& context); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index da0fe77b24..d1ba7714e9 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -30,6 +30,12 @@ public: virtual void render(Batch& batch); + // This call synchronize the Full Backend cache with the current GLState + // THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync + // the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls + // Let's try to avoid to do that as much as possible! + virtual void syncCache(); + // Render Batch create a local Context and execute the batch with it // WARNING: // if syncCache is true, then the gpu::GLBackend will synchornize @@ -195,12 +201,6 @@ public: void do_setStateColorWriteMask(uint32 mask); - // This call synchronize the Full Backend cache with the current GLState - // THis is only intended to be used when mixing raw gl calls with the gpu api usage in order to sync - // the gpu::Backend state with the true gl state which has probably been messed up by these ugly naked gl calls - // Let's try to avoid to do that as much as possible! - void syncCache(); - protected: // Draw Stage diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 8ab5faace1..821a93f567 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -10,6 +10,8 @@ // #include "RenderDeferredTask.h" +#include "gpu/Context.h" + using namespace render; RenderDeferredTask::RenderDeferredTask() : Task() { @@ -34,6 +36,8 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend return; } + renderContext->args->_context->syncCache(); + for (auto job : _jobs) { job.run(sceneContext, renderContext); } From bd7c22e715d5db93cac04f928ec29d97bb08a7a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 1 Jun 2015 17:31:00 -0700 Subject: [PATCH 03/10] Trying to transfer the rnedering from displaySide to RenderDeferredTask --- interface/src/Application.cpp | 213 +++++++++++------- interface/src/Application.h | 4 +- interface/src/Environment.cpp | 4 +- interface/src/Environment.h | 6 +- libraries/render-utils/src/Model.cpp | 7 +- .../render-utils/src/RenderDeferredTask.cpp | 18 ++ .../render-utils/src/RenderDeferredTask.h | 12 + libraries/render/src/render/DrawTask.cpp | 60 ++++- libraries/render/src/render/DrawTask.h | 5 + libraries/render/src/render/Scene.cpp | 4 +- libraries/render/src/render/Scene.h | 5 + libraries/shared/src/RenderArgs.h | 2 + 12 files changed, 241 insertions(+), 99 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9f5a7ae43b..2b3029bfed 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3192,6 +3192,113 @@ namespace render { } } +// Background Render Data & rendering functions +class BackgroundRenderData { +public: + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + Stars _stars; + Environment* _environment; + + BackgroundRenderData(Environment* environment) : _environment(environment) { + } + + static render::ItemID _item; // unique WorldBoxRenderData +}; + +render::ItemID BackgroundRenderData::_item = 0; + +namespace render { + template <> const ItemKey payloadGetKey(const BackgroundRenderData::Pointer& stuff) { return ItemKey::Builder::background(); } + template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); } + template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) { + + // Background rendering decision + auto skyStage = DependencyManager::get()->getSkyStage(); + auto skybox = model::SkyboxPointer(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) { + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) { + if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { + PerformanceTimer perfTimer("stars"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::payloadRender() ... stars..."); + if (!background->_stars.isStarsLoaded()) { + background->_stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); + } + // should be the first rendering pass - w/o depth buffer / lighting + + // compute starfield alpha based on distance from atmosphere + float alpha = 1.0f; + bool hasStars = true; + + if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + // TODO: handle this correctly for zones + const EnvironmentData& closestData = background->_environment->getClosestData(args->_viewFrustum->getPosition()); // was theCamera instead of _viewFrustum + + if (closestData.getHasStars()) { + const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f; + const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f; + + glm::vec3 sunDirection = (args->_viewFrustum->getPosition()/*getAvatarPosition()*/ - closestData.getSunLocation()) + / closestData.getAtmosphereOuterRadius(); + float height = glm::distance(args->_viewFrustum->getPosition()/*theCamera.getPosition()*/, closestData.getAtmosphereCenter()); + if (height < closestData.getAtmosphereInnerRadius()) { + // If we're inside the atmosphere, then determine if our keyLight is below the horizon + alpha = 0.0f; + + if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { + float directionY = glm::clamp(sunDirection.y, + -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) + + APPROXIMATE_DISTANCE_FROM_HORIZON; + alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); + } + + + } else if (height < closestData.getAtmosphereOuterRadius()) { + alpha = (height - closestData.getAtmosphereInnerRadius()) / + (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); + + if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { + float directionY = glm::clamp(sunDirection.y, + -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) + + APPROXIMATE_DISTANCE_FROM_HORIZON; + alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); + } + } + } else { + hasStars = false; + } + } + + // finally render the starfield + if (hasStars) { + background->_stars.render(args->_viewFrustum->getFieldOfView(), args->_viewFrustum->getAspectRatio(), args->_viewFrustum->getNearClip(), alpha); + } + + // draw the sky dome + if (/*!selfAvatarOnly &&*/ Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { + PerformanceTimer perfTimer("atmosphere"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... atmosphere..."); + background->_environment->renderAtmospheres(*(args->_viewFrustum)); + } + + } + } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + PerformanceTimer perfTimer("skybox"); + + skybox = skyStage->getSkybox(); + if (skybox) { + gpu::Batch batch; + model::Skybox::render(batch, *(args->_viewFrustum), *skybox); + + gpu::GLBackend::renderBatch(batch, true); + glUseProgram(0); + } + } + } +} void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { @@ -3264,86 +3371,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se glTexGenfv(GL_R, GL_EYE_PLANE, (const GLfloat*)&_shadowMatrices[i][2]); } + // THe pending changes collecting the changes here + render::PendingChanges pendingChanges; + // Background rendering decision - auto skyStage = DependencyManager::get()->getSkyStage(); - auto skybox = model::SkyboxPointer(); - if (skyStage->getBackgroundMode() == model::SunSkyStage::NO_BACKGROUND) { - } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_DOME) { - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { - PerformanceTimer perfTimer("stars"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... stars..."); - if (!_stars.isStarsLoaded()) { - _stars.generate(STARFIELD_NUM_STARS, STARFIELD_SEED); - } - // should be the first rendering pass - w/o depth buffer / lighting + if (BackgroundRenderData::_item == 0) { + auto backgroundRenderData = BackgroundRenderData::Pointer(new BackgroundRenderData(&_environment)); + auto backgroundRenderPayload = render::PayloadPointer(new BackgroundRenderData::Payload(backgroundRenderData)); - // compute starfield alpha based on distance from atmosphere - float alpha = 1.0f; - bool hasStars = true; + BackgroundRenderData::_item = _main3DScene->allocateID(); - if (Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - // TODO: handle this correctly for zones - const EnvironmentData& closestData = _environment.getClosestData(theCamera.getPosition()); + pendingChanges.resetItem(WorldBoxRenderData::_item, backgroundRenderPayload); + } else { - if (closestData.getHasStars()) { - const float APPROXIMATE_DISTANCE_FROM_HORIZON = 0.1f; - const float DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON = 0.2f; - - glm::vec3 sunDirection = (getAvatarPosition() - closestData.getSunLocation()) - / closestData.getAtmosphereOuterRadius(); - float height = glm::distance(theCamera.getPosition(), closestData.getAtmosphereCenter()); - if (height < closestData.getAtmosphereInnerRadius()) { - // If we're inside the atmosphere, then determine if our keyLight is below the horizon - alpha = 0.0f; - - if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { - float directionY = glm::clamp(sunDirection.y, - -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) - + APPROXIMATE_DISTANCE_FROM_HORIZON; - alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); - } - - - } else if (height < closestData.getAtmosphereOuterRadius()) { - alpha = (height - closestData.getAtmosphereInnerRadius()) / - (closestData.getAtmosphereOuterRadius() - closestData.getAtmosphereInnerRadius()); - - if (sunDirection.y > -APPROXIMATE_DISTANCE_FROM_HORIZON) { - float directionY = glm::clamp(sunDirection.y, - -APPROXIMATE_DISTANCE_FROM_HORIZON, APPROXIMATE_DISTANCE_FROM_HORIZON) - + APPROXIMATE_DISTANCE_FROM_HORIZON; - alpha = (directionY / DOUBLE_APPROXIMATE_DISTANCE_FROM_HORIZON); - } - } - } else { - hasStars = false; - } - } - - // finally render the starfield - if (hasStars) { - _stars.render(_displayViewFrustum.getFieldOfView(), _displayViewFrustum.getAspectRatio(), _displayViewFrustum.getNearClip(), alpha); - } - - // draw the sky dome - if (!selfAvatarOnly && Menu::getInstance()->isOptionChecked(MenuOption::Atmosphere)) { - PerformanceTimer perfTimer("atmosphere"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... atmosphere..."); - _environment.renderAtmospheres(theCamera); - } - - } - } else if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { - skybox = skyStage->getSkybox(); - if (skybox) { - gpu::Batch batch; - model::Skybox::render(batch, _viewFrustum, *skybox); - - gpu::GLBackend::renderBatch(batch, true); - glUseProgram(0); - } } if (Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { @@ -3353,7 +3393,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); - DependencyManager::get()->prepare(); + // Assuming nothing get's rendered through that + // DependencyManager::get()->prepare(); if (!selfAvatarOnly) { @@ -3380,10 +3421,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se renderArgs->_debugFlags = renderDebugFlags; _entities.render(renderArgs); - if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { + // This shouldn't matter anymore + /* if (!Menu::getInstance()->isOptionChecked(MenuOption::Wireframe)) { // Restaure polygon mode glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } + }*/ } // render the ambient occlusion effect if enabled @@ -3395,7 +3437,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } } - render::PendingChanges pendingChanges; // Make sure the WorldBox is in the scene if (WorldBoxRenderData::_item == 0) { @@ -3445,11 +3486,19 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se auto skyStage = DependencyManager::get()->getSkyStage(); DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); + + auto skybox = model::SkyboxPointer(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + skybox = skyStage->getSkybox(); + } DependencyManager::get()->setGlobalSkybox(skybox); + // Not needed anymore here, taken care off by the Engine + /* PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); - DependencyManager::get()->render(); + DependencyManager::get()->render();*/ + } //Render the sixense lasers @@ -3700,7 +3749,7 @@ void Application::updateWindowTitle(){ void Application::clearDomainOctreeDetails() { qCDebug(interfaceapp) << "Clearing domain octree details..."; // reset the environment so that we don't erroneously end up with multiple - _environment.resetToDefault(); + // _environment.resetToDefault(); // reset our node to stats and node to jurisdiction maps... since these must be changing... _entityServerJurisdictions.lockForWrite(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 56cfb87674..aaf831a511 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -210,7 +210,7 @@ public: ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; } const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } EntityTreeRenderer* getEntities() { return &_entities; } - Environment* getEnvironment() { return &_environment; } + // Environment* getEnvironment() { return &_environment; } QUndoStack* getUndoStack() { return &_undoStack; } MainWindow* getWindow() { return _window; } OctreeQuery& getOctreeQuery() { return _octreeQuery; } @@ -535,7 +535,7 @@ private: QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; bool _justStarted; - Stars _stars; + // Stars _stars; ShapeManager _shapeManager; PhysicalEntitySimulation _entitySimulation; diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index a2b78c2ff5..9f197920d9 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -68,7 +68,7 @@ void Environment::resetToDefault() { _data[HifiSockAddr()][0]; } -void Environment::renderAtmospheres(Camera& camera) { +void Environment::renderAtmospheres(ViewFrustum& camera) { // get the lock for the duration of the call QMutexLocker locker(&_mutex); @@ -228,7 +228,7 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { return program; } -void Environment::renderAtmosphere(Camera& camera, const EnvironmentData& data) { +void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) { glm::vec3 center = data.getAtmosphereCenter(); glPushMatrix(); diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 1a46a10175..c1b4171947 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -19,7 +19,7 @@ #include "EnvironmentData.h" -class Camera; +class ViewFrustum; class ProgramObject; class Environment { @@ -29,7 +29,7 @@ public: void init(); void resetToDefault(); - void renderAtmospheres(Camera& camera); + void renderAtmospheres(ViewFrustum& camera); void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; } void endOverride() { _environmentIsOverridden = false; } @@ -46,7 +46,7 @@ private: ProgramObject* createSkyProgram(const char* from, int* locations); - void renderAtmosphere(Camera& camera, const EnvironmentData& data); + void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data); bool _initialized; ProgramObject* _skyFromAtmosphereProgram; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9a82d4acfe..72857476cb 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2239,9 +2239,10 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran batch.setViewTransform(_transforms[0]); - const float OPAQUE_ALPHA_THRESHOLD = 0.5f; - const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; - auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + // const float OPAQUE_ALPHA_THRESHOLD = 0.5f; + // const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + // auto alphaThreshold = translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME + auto alphaThreshold = args->_alphaThreshold; //translucent ? TRANSPARENT_ALPHA_THRESHOLD : OPAQUE_ALPHA_THRESHOLD; // FIX ME const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 821a93f567..4483fedfb2 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -12,12 +12,30 @@ #include "gpu/Context.h" +#include + using namespace render; + +template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("PrepareDeferred"); + DependencyManager::get()->prepare(); +} + +template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("ResolveDeferred"); + DependencyManager::get()->render(); +} + + RenderDeferredTask::RenderDeferredTask() : Task() { + _jobs.push_back(Job(PrepareDeferred())); + _jobs.push_back(Job(DrawBackground())); _jobs.push_back(Job(DrawOpaque())); _jobs.push_back(Job(DrawLight())); _jobs.push_back(Job(DrawTransparent())); + _jobs.push_back(Job(ResolveDeferred())); + } RenderDeferredTask::~RenderDeferredTask() { diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 574dc651b1..010fa80d3d 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -14,6 +14,18 @@ #include "render/DrawTask.h" +#include "DeferredLightingEffect.h" + +class PrepareDeferred { +public: +}; +template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + +class ResolveDeferred { +public: +}; +template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); + class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 9e66ec0938..37180ff0aa 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -239,6 +239,7 @@ void addClearStateCommands(gpu::Batch& batch) { template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOpaque"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -251,12 +252,16 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer for (auto id : items) { inItems.push_back(id); } + ItemIDs& renderedItems = inItems; ItemIDs culledItems; cullItems(sceneContext, renderContext, inItems, culledItems); - + renderedItems = culledItems; + ItemIDs sortedItems; depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items! + renderedItems = sortedItems; + RenderArgs* args = renderContext->args; gpu::Batch theBatch; @@ -276,15 +281,15 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer theBatch._glDrawBuffers(bufferCount, buffers); } - renderItems(sceneContext, renderContext, sortedItems); + renderItems(sceneContext, renderContext, renderedItems); - addClearStateCommands((*args->_batch)); args->_context->render((*args->_batch)); args->_batch = nullptr; } template <> void render::jobRun(const DrawTransparent& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawTransparent"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -297,26 +302,47 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo for (auto id : items) { inItems.push_back(id); } + ItemIDs& renderedItems = inItems; ItemIDs culledItems; cullItems(sceneContext, renderContext, inItems, culledItems); + renderedItems = culledItems; ItemIDs sortedItems; depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items! + renderedItems = sortedItems; RenderArgs* args = renderContext->args; gpu::Batch theBatch; args->_batch = &theBatch; - renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + + // render translucent meshes afterwards + { + GLenum buffers[2]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + theBatch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; + } + + renderItems(sceneContext, renderContext, renderedItems); + { GLenum buffers[3]; int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; theBatch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; } - renderItems(sceneContext, renderContext, sortedItems); + + renderItems(sceneContext, renderContext, renderedItems); addClearStateCommands((*args->_batch)); args->_context->render((*args->_batch)); @@ -324,6 +350,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo } template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawLight"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -348,3 +375,26 @@ template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& args->_context->render((*args->_batch)); args->_batch = nullptr; } + +template <> void render::jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawBackground"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::background()); + + + ItemIDs inItems; + inItems.reserve(items.size()); + for (auto id : items) { + inItems.push_back(id); + } + RenderArgs* args = renderContext->args; + gpu::Batch theBatch; + args->_batch = &theBatch; + renderItems(sceneContext, renderContext, inItems); + args->_context->render((*args->_batch)); + args->_batch = nullptr; +} diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 78d4d1bd8b..d9213aca4a 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -78,6 +78,11 @@ public: }; template <> void jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +class DrawBackground { +public: +}; +template <> void jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + class DrawSceneTask : public Task { public: diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index 93b8b4d7ef..8615f7cf7a 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -47,8 +47,8 @@ void ItemBucketMap::reset(const ItemID& id, const ItemKey& oldKey, const ItemKey void ItemBucketMap::allocateStandardOpaqueTranparentBuckets() { (*this)[ItemFilter::Builder::opaqueShape()]; (*this)[ItemFilter::Builder::transparentShape()]; - auto lightFilter = ItemFilter::Builder().withTypeLight().build(); - (*this)[lightFilter]; + (*this)[ItemFilter::Builder::light()]; + (*this)[ItemFilter::Builder::background()]; } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index afacb25067..88ba2b478c 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -34,6 +34,7 @@ public: enum FlagBit { TYPE_SHAPE = 0, // Item is a Shape TYPE_LIGHT, // Item is a Light + TYPE_BACKGROUND, // Item is a Background TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work... VIEW_SPACE, // Transformed in view space, and not in world space DYNAMIC, // Dynamic and bound will change unlike static item @@ -62,6 +63,7 @@ public: Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); } + Builder& withTypeBackground() { _flags.set(TYPE_BACKGROUND); return (*this); } Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); } Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); } Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); } @@ -75,6 +77,7 @@ public: static ItemKey opaqueShape() { return Builder().withTypeShape().build(); } static ItemKey transparentShape() { return Builder().withTypeShape().withTransparent().build(); } static ItemKey light() { return Builder().withTypeLight().build(); } + static ItemKey background() { return Builder().withTypeBackground().build(); } }; bool isOpaque() const { return !_flags[TRANSLUCENT]; } @@ -126,6 +129,7 @@ public: Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); } Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); } + Builder& withTypeBackground() { _value.set(ItemKey::TYPE_BACKGROUND); _mask.set(ItemKey::TYPE_BACKGROUND); return (*this); } Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); } @@ -154,6 +158,7 @@ public: static ItemFilter opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace().build(); } static ItemFilter transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace().build(); } static ItemFilter light() { return Builder().withTypeLight().build(); } + static ItemFilter background() { return Builder().withTypeBackground().build(); } }; // Item Filter operator testing if a key pass the filter diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index e86389d705..08602dbacd 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -111,6 +111,8 @@ public: int _translucentMeshPartsRendered; int _opaqueMeshPartsRendered; + + float _alphaThreshold = 0.5f; }; #endif // hifi_RenderArgs_h From ef2d8a0dbe32a80371606cdd1cca835cedd51afd Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 10:58:56 -0700 Subject: [PATCH 04/10] tuesday morning rendering poor performances networking issue --- interface/src/Application.cpp | 39 ++++++++++++------------ libraries/render-utils/src/Model.cpp | 2 +- libraries/render/src/render/DrawTask.cpp | 8 ++++- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fdb7277a0c..f483f0bacc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3464,6 +3464,26 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se }); } + if (!billboard) { + DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); + auto skyStage = DependencyManager::get()->getSkyStage(); + DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); + DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); + + auto skybox = model::SkyboxPointer(); + if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { + skybox = skyStage->getSkybox(); + } + DependencyManager::get()->setGlobalSkybox(skybox); + + // Not needed anymore here, taken care off by the Engine + /* + PROFILE_RANGE("DeferredLighting"); + PerformanceTimer perfTimer("lighting"); + DependencyManager::get()->render();*/ + + } + { PerformanceTimer perfTimer("SceneProcessPendingChanges"); _main3DScene->enqueuePendingChanges(pendingChanges); @@ -3489,25 +3509,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se } - if (!billboard) { - DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); - auto skyStage = DependencyManager::get()->getSkyStage(); - DependencyManager::get()->setGlobalLight(skyStage->getSunLight()->getDirection(), skyStage->getSunLight()->getColor(), skyStage->getSunLight()->getIntensity(), skyStage->getSunLight()->getAmbientIntensity()); - DependencyManager::get()->setGlobalAtmosphere(skyStage->getAtmosphere()); - - auto skybox = model::SkyboxPointer(); - if (skyStage->getBackgroundMode() == model::SunSkyStage::SKY_BOX) { - skybox = skyStage->getSkybox(); - } - DependencyManager::get()->setGlobalSkybox(skybox); - - // Not needed anymore here, taken care off by the Engine - /* - PROFILE_RANGE("DeferredLighting"); - PerformanceTimer perfTimer("lighting"); - DependencyManager::get()->render();*/ - - } //Render the sixense lasers if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 72857476cb..80e7e4cae7 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2313,7 +2313,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran model::MaterialPointer material = part._material; if (material == nullptr) { - qCDebug(renderutils) << "WARNING: material == nullptr!!!"; + // qCDebug(renderutils) << "WARNING: material == nullptr!!!"; } if (material != nullptr) { diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 37180ff0aa..6a092bf7d9 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -94,6 +94,7 @@ bool LODManager::shouldRenderMesh(float largestDimension, float distanceToCamera }*/ void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems, ItemIDs& outItems) { + PerformanceTimer perfTimer("cullItems"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -156,6 +157,7 @@ struct BackToFrontSort { }; void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDs& inItems, ItemIDs& outItems) { + PerformanceTimer perfTimer("depthSortItems"); assert(renderContext->args); assert(renderContext->args->_viewFrustum); @@ -194,6 +196,7 @@ void render::depthSortItems(const SceneContextPointer& sceneContext, const Rende } void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDs& inItems) { + PerformanceTimer perfTimer("renderItems"); auto& scene = sceneContext->_scene; RenderArgs* args = renderContext->args; // render @@ -300,7 +303,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo ItemIDs inItems; inItems.reserve(items.size()); for (auto id : items) { - inItems.push_back(id); + // inItems.push_back(id); } ItemIDs& renderedItems = inItems; @@ -397,4 +400,7 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi renderItems(sceneContext, renderContext, inItems); args->_context->render((*args->_batch)); args->_batch = nullptr; + + // Force the context sync + args->_context->syncCache(); } From 901717fb2cddbcc53c3f13fd5f1a420b8f257615 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 11:52:22 -0700 Subject: [PATCH 05/10] trying to fix the issues of model disappearing --- interface/src/Application.cpp | 2 ++ libraries/render-utils/src/Model.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f483f0bacc..629a833be0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3495,7 +3495,9 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se { PerformanceTimer perfTimer("EngineRun"); render::RenderContext renderContext; + renderContext.args = renderArgs; + renderArgs->_viewFrustum = getDisplayViewFrustum(); _renderEngine->setRenderContext(renderContext); // Before the deferred pass, let's try to use the render engine diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 80e7e4cae7..db8b53d129 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2231,7 +2231,8 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran _transforms.push_back(Transform()); } - _transforms[0] = _viewState->getViewTransform(); + // _transforms[0] = _viewState->getViewTransform(); + _transforms[0].evalFromRawMatrix(args->_viewFrustum->getView()); //_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); From 453fa876548bcf0e747e5d25ea245b3f5de0baff Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 14:31:40 -0700 Subject: [PATCH 06/10] making sure the proj and view matrix are correctly assigned --- interface/src/Util.cpp | 1 + interface/src/avatar/MyAvatar.cpp | 6 ++- .../src/EntityTreeRenderer.cpp | 6 +-- libraries/render-utils/src/Model.cpp | 2 +- libraries/render/src/render/DrawTask.cpp | 42 +++++++++++++------ 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 1f217d92b9..c07c2877e8 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -34,6 +34,7 @@ using namespace std; void renderWorldBox() { + return; auto geometryCache = DependencyManager::get(); // Show edge of world diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index bdf66eb1b5..249f8166ac 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -45,6 +45,9 @@ #include "Util.h" #include "InterfaceLogging.h" +#include "gpu/GLBackend.h" + + using namespace std; const glm::vec3 DEFAULT_UP_DIRECTION(0.0f, 1.0f, 0.0f); @@ -1472,7 +1475,8 @@ void MyAvatar::maybeUpdateBillboard() { return; } } - RenderArgs renderArgs; + gpu::Context context(new gpu::GLBackend()); + RenderArgs renderArgs(&context); QImage image = Application::getInstance()->renderAvatarBillboard(&renderArgs); _billboard.clear(); QBuffer buffer(&_billboard); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 9a8966dbc0..949d73b10f 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -523,9 +523,9 @@ void EntityTreeRenderer::render(RenderArgs* renderArgs) { Model::endScene(renderArgs); _tree->unlock(); - glPushMatrix(); - renderArgs->_context->render(batch); - glPopMatrix(); + // glPushMatrix(); + // renderArgs->_context->render(batch); + // glPopMatrix(); renderArgs->_batch = nullptr; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index db8b53d129..4adc375a6a 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2232,7 +2232,7 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } // _transforms[0] = _viewState->getViewTransform(); - _transforms[0].evalFromRawMatrix(args->_viewFrustum->getView()); //_viewState->getViewTransform(); + args->_viewFrustum->evalViewTransform(_transforms[0]); // 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); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 6a092bf7d9..65353b5b99 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -267,12 +267,15 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - args->_batch = &theBatch; + gpu::Batch batch; + args->_batch = &batch; - glm::mat4 proj; - args->_viewFrustum->evalProjectionMatrix(proj); - theBatch.setProjectionTransform(proj); + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; { @@ -281,7 +284,7 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - theBatch._glDrawBuffers(bufferCount, buffers); + batch._glDrawBuffers(bufferCount, buffers); } renderItems(sceneContext, renderContext, renderedItems); @@ -316,8 +319,15 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo renderedItems = sortedItems; RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - args->_batch = &theBatch; + gpu::Batch batch; + args->_batch = &batch; + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; @@ -330,7 +340,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - theBatch._glDrawBuffers(bufferCount, buffers); + batch._glDrawBuffers(bufferCount, buffers); args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; } @@ -340,7 +350,7 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo GLenum buffers[3]; int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - theBatch._glDrawBuffers(bufferCount, buffers); + batch._glDrawBuffers(bufferCount, buffers); args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; } @@ -395,8 +405,16 @@ template <> void render::jobRun(const DrawBackground& job, const SceneContextPoi inItems.push_back(id); } RenderArgs* args = renderContext->args; - gpu::Batch theBatch; - args->_batch = &theBatch; + gpu::Batch batch; + args->_batch = &batch; + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + renderItems(sceneContext, renderContext, inItems); args->_context->render((*args->_batch)); args->_batch = nullptr; From 903837ab4f883652197e43f5289512ae44e2deae Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 15:57:37 -0700 Subject: [PATCH 07/10] exposing some controls on the engine to js for debugging --- interface/src/Application.cpp | 9 + libraries/render-utils/src/Model.cpp | 6 + .../render-utils/src/RenderDeferredTask.cpp | 1 + libraries/render/src/render/DrawTask.cpp | 168 ++++++++++-------- libraries/render/src/render/DrawTask.h | 5 + libraries/render/src/render/Engine.h | 7 + .../src/SceneScriptingInterface.cpp | 26 ++- .../src/SceneScriptingInterface.h | 25 +++ 8 files changed, 171 insertions(+), 76 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5cdaf1e225..b7f38cd0da 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3496,6 +3496,15 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se PerformanceTimer perfTimer("EngineRun"); render::RenderContext renderContext; + auto sceneInterface = DependencyManager::get(); + + renderContext._cullOpaque = sceneInterface->doEngineCullOpaque(); + renderContext._sortOpaque = sceneInterface->doEngineSortOpaque(); + renderContext._renderOpaque = sceneInterface->doEngineRenderOpaque(); + renderContext._cullTransparent = sceneInterface->doEngineCullTransparent(); + renderContext._sortTransparent = sceneInterface->doEngineSortTransparent(); + renderContext._renderTransparent = sceneInterface->doEngineRenderTransparent(); + renderArgs->_shouldRender = LODManager::shouldRender; renderContext.args = renderArgs; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 1827515d37..91f4e68d6d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -858,6 +858,9 @@ namespace render { bool Model::addToScene(std::shared_ptr scene, render::PendingChanges& pendingChanges) { bool somethingAdded = false; + + qDebug() << "Model::addToScene : " << this->getURL().toString(); + // allow the attachments to add to scene foreach (Model* attachment, _attachments) { bool attachementSomethingAdded = attachment->addToScene(scene, pendingChanges); @@ -894,6 +897,9 @@ void Model::removeFromScene(std::shared_ptr scene, render::Pendin pendingChanges.removeItem(item); } _renderItems.clear(); + + qDebug() << "Model::removeFromScene : " << this->getURL().toString(); + } bool Model::render(RenderArgs* renderArgs, float alpha) { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 4483fedfb2..6c83946940 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -34,6 +34,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(DrawOpaque())); _jobs.push_back(Job(DrawLight())); _jobs.push_back(Job(DrawTransparent())); + _jobs.push_back(Job(ResetGLState())); _jobs.push_back(Job(ResolveDeferred())); } diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index f627bd27f6..e4c6508729 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -29,6 +29,7 @@ DrawSceneTask::DrawSceneTask() : Task() { _jobs.push_back(Job(DrawOpaque())); _jobs.push_back(Job(DrawLight())); _jobs.push_back(Job(DrawTransparent())); + _jobs.push_back(Job(ResetGLState())); } DrawSceneTask::~DrawSceneTask() { @@ -198,6 +199,13 @@ void addClearStateCommands(gpu::Batch& batch) { batch._glUseProgram(0); } +template <> void render::jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + + gpu::Batch theBatch; + addClearStateCommands(theBatch); + assert(renderContext->args); + renderContext->args->_context->render(theBatch); +} template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("DrawOpaque"); @@ -216,39 +224,44 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer ItemIDs& renderedItems = inItems; ItemIDs culledItems; - cullItems(sceneContext, renderContext, inItems, culledItems); - renderedItems = culledItems; - - ItemIDs sortedItems; - depthSortItems(sceneContext, renderContext, true, culledItems, sortedItems); // Sort Front to back opaque items! - renderedItems = sortedItems; - - - RenderArgs* args = renderContext->args; - gpu::Batch batch; - args->_batch = &batch; - - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; - { - GLenum buffers[3]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - batch._glDrawBuffers(bufferCount, buffers); + if (renderContext->_cullOpaque) { + cullItems(sceneContext, renderContext, renderedItems, culledItems); + renderedItems = culledItems; } - renderItems(sceneContext, renderContext, renderedItems); + ItemIDs sortedItems; + if (renderContext->_sortOpaque) { + depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items! + renderedItems = sortedItems; + } - args->_context->render((*args->_batch)); - args->_batch = nullptr; + if (renderContext->_renderOpaque) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + renderContext->args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + batch._glDrawBuffers(bufferCount, buffers); + } + + renderItems(sceneContext, renderContext, renderedItems); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } } @@ -269,55 +282,60 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo ItemIDs& renderedItems = inItems; ItemIDs culledItems; - cullItems(sceneContext, renderContext, inItems, culledItems); - renderedItems = culledItems; - - ItemIDs sortedItems; - depthSortItems(sceneContext, renderContext, false, culledItems, sortedItems); // Sort Back to front transparent items! - renderedItems = sortedItems; - - RenderArgs* args = renderContext->args; - gpu::Batch batch; - args->_batch = &batch; - - glm::mat4 projMat; - Transform viewMat; - args->_viewFrustum->evalProjectionMatrix(projMat); - args->_viewFrustum->evalViewTransform(viewMat); - batch.setProjectionTransform(projMat); - batch.setViewTransform(viewMat); - - args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; - - const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; - - // render translucent meshes afterwards - { - GLenum buffers[2]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - batch._glDrawBuffers(bufferCount, buffers); - args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; - } - - renderItems(sceneContext, renderContext, renderedItems); - - { - GLenum buffers[3]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - batch._glDrawBuffers(bufferCount, buffers); - args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; + if (renderContext->_cullTransparent) { + cullItems(sceneContext, renderContext, inItems, culledItems); + renderedItems = culledItems; } + ItemIDs sortedItems; + if (renderContext->_sortTransparent) { + depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items! + renderedItems = sortedItems; + } - renderItems(sceneContext, renderContext, renderedItems); + if (renderContext->_renderTransparent) { + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; - addClearStateCommands((*args->_batch)); - args->_context->render((*args->_batch)); - args->_batch = nullptr; + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + + args->_renderMode = RenderArgs::NORMAL_RENDER_MODE; + + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f; + + // render translucent meshes afterwards + { + GLenum buffers[2]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + batch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = MOSTLY_OPAQUE_THRESHOLD; + } + + renderItems(sceneContext, renderContext, renderedItems); + + { + GLenum buffers[3]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + batch._glDrawBuffers(bufferCount, buffers); + args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD; + } + + + renderItems(sceneContext, renderContext, renderedItems); + + args->_context->render((*args->_batch)); + args->_batch = nullptr; + } } template <> void render::jobRun(const DrawLight& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index d9213aca4a..9572a68bf0 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -83,6 +83,11 @@ public: }; template <> void jobRun(const DrawBackground& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +class ResetGLState { +public: +}; +template <> void jobRun(const ResetGLState& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); + class DrawSceneTask : public Task { public: diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index 247cb69c35..e97934b6eb 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -30,6 +30,13 @@ class RenderContext { public: RenderArgs* args; + bool _cullOpaque = true; + bool _sortOpaque = true; + bool _renderOpaque = true; + bool _cullTransparent = true; + bool _sortTransparent = true; + bool _renderTransparent = true; + RenderContext() {} }; typedef std::shared_ptr RenderContextPointer; diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index ad76dbcc38..f5e0e3facd 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -128,4 +128,28 @@ void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities) _shouldRenderEntities = shouldRenderEntities; emit shouldRenderEntitiesChanged(_shouldRenderEntities); } -} \ No newline at end of file +} + +void SceneScriptingInterface::setEngineRenderOpaque(bool renderOpaque) { + _engineRenderOpaque = renderOpaque; +} + +void SceneScriptingInterface::setEngineRenderTransparent(bool renderTransparent) { + _engineRenderTransparent = renderTransparent; +} + +void SceneScriptingInterface::setEngineCullOpaque(bool cullOpaque) { + _engineCullOpaque = cullOpaque; +} + +void SceneScriptingInterface::setEngineCullTransparent(bool cullTransparent) { + _engineCullTransparent = cullTransparent; +} + +void SceneScriptingInterface::setEngineSortOpaque(bool sortOpaque) { + _engineSortOpaque = sortOpaque; +} + +void SceneScriptingInterface::setEngineSortTransparent(bool sortTransparent) { + _engineSortOpaque = sortTransparent; +} diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 50aaae83ff..38f07345d5 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -67,7 +67,24 @@ public: Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities); Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; } + + + // Controlling the rendering engine + Q_INVOKABLE void setEngineRenderOpaque(bool renderOpaque); + Q_INVOKABLE bool doEngineRenderOpaque() const { return _engineRenderOpaque; } + Q_INVOKABLE void setEngineRenderTransparent(bool renderTransparent); + Q_INVOKABLE bool doEngineRenderTransparent() const { return _engineRenderTransparent; } + Q_INVOKABLE void setEngineCullOpaque(bool cullOpaque); + Q_INVOKABLE bool doEngineCullOpaque() const { return _engineCullOpaque; } + Q_INVOKABLE void setEngineCullTransparent(bool cullTransparent); + Q_INVOKABLE bool doEngineCullTransparent() const { return _engineCullTransparent; } + + Q_INVOKABLE void setEngineSortOpaque(bool sortOpaque); + Q_INVOKABLE bool doEngineSortOpaque() const { return _engineSortOpaque; } + Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent); + Q_INVOKABLE bool doEngineSortTransparent() const { return _engineSortTransparent; } + signals: void shouldRenderAvatarsChanged(bool shouldRenderAvatars); void shouldRenderEntitiesChanged(bool shouldRenderEntities); @@ -79,6 +96,14 @@ protected: bool _shouldRenderAvatars = true; bool _shouldRenderEntities = true; + + bool _engineRenderOpaque = true; + bool _engineRenderTransparent = true; + bool _engineCullOpaque = true; + bool _engineCullTransparent = true; + bool _engineSortOpaque = true; + bool _engineSortTransparent = true; + }; #endif // hifi_SceneScriptingInterface_h From 640071dd35783a4339c0ed9c5c20041d439d8f70 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 18:23:53 -0700 Subject: [PATCH 08/10] Avoiding any setVIewTransform in payloadREnder and introducing monitoring values --- examples/utilities/tools/cookies.js | 8 +- examples/utilities/tools/renderEngineDebug.js | 92 +++++++++++++++++++ interface/src/Application.cpp | 6 ++ libraries/render-utils/src/Model.cpp | 19 +++- libraries/render/src/render/DrawTask.cpp | 11 ++- libraries/render/src/render/Engine.h | 7 ++ .../src/SceneScriptingInterface.cpp | 7 ++ .../src/SceneScriptingInterface.h | 16 ++++ 8 files changed, 156 insertions(+), 10 deletions(-) create mode 100755 examples/utilities/tools/renderEngineDebug.js diff --git a/examples/utilities/tools/cookies.js b/examples/utilities/tools/cookies.js index 0182bf8db0..136b5b7f82 100755 --- a/examples/utilities/tools/cookies.js +++ b/examples/utilities/tools/cookies.js @@ -134,7 +134,7 @@ Slider = function(x,y,width,thumbSize) { } // The Checkbox class -Checkbox = function(x,y,width,thumbSize) { +Checkbox = function(x,y,thumbSize) { this.thumb = Overlays.addOverlay("text", { backgroundColor: { red: 255, green: 255, blue: 255 }, @@ -150,7 +150,7 @@ Checkbox = function(x,y,width,thumbSize) { backgroundColor: { red: 125, green: 125, blue: 255 }, x: x, y: y, - width: width, + width: thumbSize * 2, height: thumbSize, alpha: 1.0, backgroundAlpha: 0.5, @@ -161,7 +161,7 @@ Checkbox = function(x,y,width,thumbSize) { this.thumbHalfSize = 0.5 * thumbSize; this.minThumbX = x + this.thumbHalfSize; - this.maxThumbX = x + width - this.thumbHalfSize; + this.maxThumbX = x + thumbSize * 2 - this.thumbHalfSize; this.thumbX = this.minThumbX; this.minValue = 0.0; @@ -553,7 +553,7 @@ Panel = function(x, y) { var item = new PanelItem(name, setValue, getValue, displayValue, this.x, this.nextY, textWidth, valueWidth, rawHeight); - var checkbox = new Checkbox(this.widgetX, this.nextY, widgetWidth, rawHeight); + var checkbox = new Checkbox(this.widgetX, this.nextY, rawHeight); item.widget = checkbox; item.widget.onValueChanged = function(value) { item.setterFromWidget(value); }; diff --git a/examples/utilities/tools/renderEngineDebug.js b/examples/utilities/tools/renderEngineDebug.js new file mode 100755 index 0000000000..9b4a60977e --- /dev/null +++ b/examples/utilities/tools/renderEngineDebug.js @@ -0,0 +1,92 @@ +// +// SunLightExample.js +// examples +// Sam Gateau +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +Script.include("cookies.js"); + +var panel = new Panel(10, 400); + +panel.newCheckbox("Enable Cull Opaque", + function(value) { Scene.setEngineCullOpaque((value != 0)); }, + function() { return Scene.doEngineCullOpaque(); }, + function(value) { return (value); } +); + +panel.newCheckbox("Enable Sort Opaque", + function(value) { Scene.setEngineSortOpaque((value != 0)); }, + function() { return Scene.doEngineSortOpaque(); }, + function(value) { return (value); } +); + +panel.newCheckbox("Enable Render Opaque", + function(value) { Scene.setEngineRenderOpaque((value != 0)); }, + function() { return Scene.doEngineRenderOpaque(); }, + function(value) { return (value); } +); + +panel.newSlider("Num Feed Opaques", 0, 1000, + function(value) { }, + function() { return Scene.getEngineNumFeedOpaqueItems(); }, + function(value) { return (value); } +); + +panel.newSlider("Num Drawn Opaques", 0, 1000, + function(value) { }, + function() { return Scene.getEngineNumDrawnOpaqueItems(); }, + function(value) { return (value); } +); + +panel.newCheckbox("Enable Cull Transparent", + function(value) { Scene.setEngineCullTransparent((value != 0)); }, + function() { return Scene.doEngineCullTransparent(); }, + function(value) { return (value); } +); + +panel.newCheckbox("Enable Sort Transparent", + function(value) { Scene.setEngineSortTransparent((value != 0)); }, + function() { return Scene.doEngineSortTransparent(); }, + function(value) { return (value); } +); + +panel.newCheckbox("Enable Render Transparent", + function(value) { Scene.setEngineRenderTransparent((value != 0)); }, + function() { return Scene.doEngineRenderTransparent(); }, + function(value) { return (value); } +); + +panel.newSlider("Num Feed Transparents", 0, 1000, + function(value) { }, + function() { return Scene.getEngineNumFeedTransparentItems(); }, + function(value) { return (value); } +); + +panel.newSlider("Num Drawn Transparents", 0, 1000, + function(value) { }, + function() { return Scene.getEngineNumDrawnTransparentItems(); }, + function(value) { return (value); } +); + +var tickTackPeriod = 500; + +function updateCounters() { + panel.set("Num Feed Opaques", panel.get("Num Feed Opaques")); + panel.set("Num Drawn Opaques", panel.get("Num Drawn Opaques")); + panel.set("Num Feed Transparents", panel.get("Num Feed Transparents")); + panel.set("Num Drawn Transparents", panel.get("Num Drawn Transparents")); +} +Script.setInterval(updateCounters, tickTackPeriod); + +Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); }); +Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); }); +Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); }); + +function scriptEnding() { + panel.destroy(); +} +Script.scriptEnding.connect(scriptEnding); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b7f38cd0da..76feb77076 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3519,6 +3519,12 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se qDebug() << "renderArgs._trianglesRendered:" << renderArgs->_trianglesRendered; qDebug() << "renderArgs._quadsRendered:" << renderArgs->_quadsRendered; */ + auto engineRC = _renderEngine->getRenderContext(); + sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems); + sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems); + + sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems); + sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems); } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 91f4e68d6d..54f0fbd540 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -918,6 +918,8 @@ bool Model::render(RenderArgs* renderArgs, float alpha) { } bool Model::renderCore(RenderArgs* args, float alpha) { + return true; + PROFILE_RANGE(__FUNCTION__); if (!_viewState) { return false; @@ -2242,12 +2244,12 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran } // _transforms[0] = _viewState->getViewTransform(); - args->_viewFrustum->evalViewTransform(_transforms[0]); + // args->_viewFrustum->evalViewTransform(_transforms[0]); // 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); + // _transforms[0].setTranslation(_translation); - batch.setViewTransform(_transforms[0]); + // batch.setViewTransform(_transforms[0]); // const float OPAQUE_ALPHA_THRESHOLD = 0.5f; @@ -2298,10 +2300,17 @@ void Model::renderPart(RenderArgs* args, int meshIndex, int partIndex, bool tran if (state.clusterMatrices.size() > 1) { GLBATCH(glUniformMatrix4fv)(locations->clusterMatrices, state.clusterMatrices.size(), false, (const float*)state.clusterMatrices.constData()); - batch.setModelTransform(Transform()); + // batch.setModelTransform(Transform()); + _transforms[0].setTranslation(_translation); + } else { - batch.setModelTransform(Transform(state.clusterMatrices[0])); + _transforms[0] = Transform(state.clusterMatrices[0]); + _transforms[0].preTranslate(_translation); + + //batch.setModelTransform(Transform(state.clusterMatrices[0])); } + batch.setModelTransform(_transforms[0]); + if (mesh.blendshapes.isEmpty()) { batch.setInputFormat(networkMesh._vertexFormat); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index e4c6508729..dd57a71fcf 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -223,12 +223,17 @@ template <> void render::jobRun(const DrawOpaque& job, const SceneContextPointer } ItemIDs& renderedItems = inItems; + renderContext->_numFeedOpaqueItems = renderedItems.size(); + ItemIDs culledItems; if (renderContext->_cullOpaque) { cullItems(sceneContext, renderContext, renderedItems, culledItems); renderedItems = culledItems; } + renderContext->_numDrawnOpaqueItems = renderedItems.size(); + + ItemIDs sortedItems; if (renderContext->_sortOpaque) { depthSortItems(sceneContext, renderContext, true, renderedItems, sortedItems); // Sort Front to back opaque items! @@ -277,16 +282,20 @@ template <> void render::jobRun(const DrawTransparent& job, const SceneContextPo ItemIDs inItems; inItems.reserve(items.size()); for (auto id : items) { - // inItems.push_back(id); + inItems.push_back(id); } ItemIDs& renderedItems = inItems; + renderContext->_numFeedTransparentItems = renderedItems.size(); + ItemIDs culledItems; if (renderContext->_cullTransparent) { cullItems(sceneContext, renderContext, inItems, culledItems); renderedItems = culledItems; } + renderContext->_numDrawnTransparentItems = renderedItems.size(); + ItemIDs sortedItems; if (renderContext->_sortTransparent) { depthSortItems(sceneContext, renderContext, false, renderedItems, sortedItems); // Sort Back to front transparent items! diff --git a/libraries/render/src/render/Engine.h b/libraries/render/src/render/Engine.h index e97934b6eb..dbd193af29 100644 --- a/libraries/render/src/render/Engine.h +++ b/libraries/render/src/render/Engine.h @@ -37,6 +37,12 @@ public: bool _sortTransparent = true; bool _renderTransparent = true; + int _numFeedOpaqueItems = 0; + int _numDrawnOpaqueItems = 0; + + int _numFeedTransparentItems = 0; + int _numDrawnTransparentItems = 0; + RenderContext() {} }; typedef std::shared_ptr RenderContextPointer; @@ -67,6 +73,7 @@ public: // Push a RenderContext void setRenderContext(const RenderContext& renderContext); + RenderContextPointer getRenderContext() const { return _renderContext; } void addTask(const TaskPointer& task); const Tasks& getTasks() const { return _tasks; } diff --git a/libraries/script-engine/src/SceneScriptingInterface.cpp b/libraries/script-engine/src/SceneScriptingInterface.cpp index f5e0e3facd..679ec1180f 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.cpp +++ b/libraries/script-engine/src/SceneScriptingInterface.cpp @@ -153,3 +153,10 @@ void SceneScriptingInterface::setEngineSortOpaque(bool sortOpaque) { void SceneScriptingInterface::setEngineSortTransparent(bool sortTransparent) { _engineSortOpaque = sortTransparent; } + +void SceneScriptingInterface::clearEngineCounters() { + _numFeedOpaqueItems = 0; + _numDrawnOpaqueItems = 0; + _numFeedTransparentItems = 0; + _numDrawnTransparentItems = 0; +} diff --git a/libraries/script-engine/src/SceneScriptingInterface.h b/libraries/script-engine/src/SceneScriptingInterface.h index 38f07345d5..b6dc4110c0 100644 --- a/libraries/script-engine/src/SceneScriptingInterface.h +++ b/libraries/script-engine/src/SceneScriptingInterface.h @@ -85,6 +85,18 @@ public: Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent); Q_INVOKABLE bool doEngineSortTransparent() const { return _engineSortTransparent; } + void clearEngineCounters(); + void setEngineDrawnOpaqueItems(int count) { _numDrawnOpaqueItems = count; } + Q_INVOKABLE int getEngineNumDrawnOpaqueItems() { return _numDrawnOpaqueItems; } + void setEngineDrawnTransparentItems(int count) { _numDrawnTransparentItems = count; } + Q_INVOKABLE int getEngineNumDrawnTransparentItems() { return _numDrawnTransparentItems; } + + void setEngineFeedOpaqueItems(int count) { _numFeedOpaqueItems = count; } + Q_INVOKABLE int getEngineNumFeedOpaqueItems() { return _numFeedOpaqueItems; } + void setEngineFeedTransparentItems(int count) { _numFeedTransparentItems = count; } + Q_INVOKABLE int getEngineNumFeedTransparentItems() { return _numFeedTransparentItems; } + + signals: void shouldRenderAvatarsChanged(bool shouldRenderAvatars); void shouldRenderEntitiesChanged(bool shouldRenderEntities); @@ -104,6 +116,10 @@ protected: bool _engineSortOpaque = true; bool _engineSortTransparent = true; + int _numFeedOpaqueItems = 0; + int _numDrawnOpaqueItems = 0; + int _numFeedTransparentItems = 0; + int _numDrawnTransparentItems = 0; }; #endif // hifi_SceneScriptingInterface_h From eea7ddf4914c3f28a2421f6e18a35f61100e152d Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 19:27:32 -0700 Subject: [PATCH 09/10] Trying to get Ubuntu to build --- libraries/render-utils/src/RenderDeferredTask.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 6c83946940..1fccb57cee 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -14,20 +14,21 @@ #include + using namespace render; - -template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { +template <> void render::jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("PrepareDeferred"); DependencyManager::get()->prepare(); } -template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) { +template <> void render::jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { PerformanceTimer perfTimer("ResolveDeferred"); DependencyManager::get()->render(); } + RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(PrepareDeferred())); _jobs.push_back(Job(DrawBackground())); From 8bf08b34d792a3977f51183812af16f449a405c7 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 2 Jun 2015 19:37:54 -0700 Subject: [PATCH 10/10] Trying to get Ubuntu to build... again --- libraries/render-utils/src/RenderDeferredTask.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index 010fa80d3d..318859e71c 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -19,13 +19,16 @@ class PrepareDeferred { public: }; -template <> void render::jobRun(const PrepareDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); +namespace render { +template <> void jobRun(const PrepareDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} class ResolveDeferred { public: }; -template <> void render::jobRun(const ResolveDeferred& job, const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext); - +namespace render { +template <> void jobRun(const ResolveDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} class RenderDeferredTask : public render::Task { public: