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; +}