From 642f436fbaf65358fe5e444fa2033bf52ea4f3ad Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 09:56:36 -0800 Subject: [PATCH 1/5] first draft of factorizing the rendering traversal for both sides in stereo --- interface/src/Application.cpp | 14 +- interface/src/Application.h | 14 +- interface/src/devices/TV3DManager.cpp | 4 +- interface/src/entities/EntityTreeRenderer.cpp | 8 +- interface/src/entities/EntityTreeRenderer.h | 2 +- interface/src/renderer/Model.cpp | 248 +++++++++--------- interface/src/renderer/Model.h | 4 +- interface/src/ui/overlays/Overlays.cpp | 6 +- interface/src/ui/overlays/Overlays.h | 2 +- libraries/octree/src/OctreeRenderer.cpp | 4 +- libraries/octree/src/OctreeRenderer.h | 2 +- libraries/shared/src/RenderArgs.h | 2 + 12 files changed, 168 insertions(+), 142 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f11ac14d40..83a4a46403 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -723,7 +723,7 @@ void Application::paintGL() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - displaySide(*whichCamera); + displaySide(RenderContext(*whichCamera)); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -2873,12 +2873,16 @@ QImage Application::renderAvatarBillboard() { return image; } -void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { +//void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { +void Application::displaySide(RenderContext& renderContext) { PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // transform by eye offset + Camera& whichCamera = renderContext._whichCamera; + bool selfAvatarOnly = renderContext._selfAvatarOnly; + // load the view frustum loadViewFrustum(whichCamera, _displayViewFrustum); @@ -3020,7 +3024,7 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - _entities.render(); + _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderContext._renderSide); } // render JS/scriptable overlays @@ -3265,7 +3269,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); } - displaySide(_mirrorCamera, true); + displaySide(RenderContext(_mirrorCamera, true)); // restore absolute translations _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); @@ -3279,7 +3283,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = savedShadowMatrices[i]; } } else { - displaySide(_mirrorCamera, true); + displaySide(RenderContext(_mirrorCamera, true)); } glPopMatrix(); diff --git a/interface/src/Application.h b/interface/src/Application.h index cba39317a5..2cea413dd4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,7 +262,19 @@ public: QImage renderAvatarBillboard(); - void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); + struct RenderContext { + Camera& _whichCamera; + bool _selfAvatarOnly; + RenderArgs::RenderSide _renderSide; + + RenderContext(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO) : + _whichCamera(whichCamera), + _selfAvatarOnly(selfAvatarOnly), + _renderSide(renderSide) { + } + }; + // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); + void displaySide(RenderContext& renderContext); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as /// the view matrix translation. diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 872f4ce7e6..bd0129f88e 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -126,7 +126,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(whichCamera); + Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_LEFT)); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); @@ -156,7 +156,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(whichCamera); + Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_RIGHT)); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); diff --git a/interface/src/entities/EntityTreeRenderer.cpp b/interface/src/entities/EntityTreeRenderer.cpp index 99e4916c62..2209a992c1 100644 --- a/interface/src/entities/EntityTreeRenderer.cpp +++ b/interface/src/entities/EntityTreeRenderer.cpp @@ -252,15 +252,15 @@ void EntityTreeRenderer::checkEnterLeaveEntities() { } } -void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode) { +void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { bool dontRenderAsScene = !Menu::getInstance()->isOptionChecked(MenuOption::RenderEntitiesAsScene); if (dontRenderAsScene) { - OctreeRenderer::render(renderMode); + OctreeRenderer::render(renderMode, renderSide); } else { if (_tree) { - Model::startScene(); - RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, + Model::startScene(renderSide); + RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; _tree->lockForRead(); _tree->recurseTreeWithOperation(renderOperation, &args); diff --git a/interface/src/entities/EntityTreeRenderer.h b/interface/src/entities/EntityTreeRenderer.h index 7c1c81b6c9..66107b368a 100644 --- a/interface/src/entities/EntityTreeRenderer.h +++ b/interface/src/entities/EntityTreeRenderer.h @@ -56,7 +56,7 @@ public: void processEraseMessage(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode); virtual void init(); - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem); virtual const Model* getModelForEntityItem(const EntityItem* entityItem); diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index c007f44f2e..71e42d32e0 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1484,8 +1484,10 @@ void Model::deleteGeometry() { // Scene rendering support QVector Model::_modelsInScene; gpu::Batch Model::_sceneRenderBatch; -void Model::startScene() { - _modelsInScene.clear(); +void Model::startScene(RenderArgs::RenderSide renderSide) { + if (renderSide != RenderArgs::STEREO_RIGHT) { + _modelsInScene.clear(); + } } void Model::setupBatchTransform(gpu::Batch& batch) { @@ -1503,146 +1505,152 @@ void Model::setupBatchTransform(gpu::Batch& batch) { void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); - // Let's introduce a gpu::Batch to capture all the calls to the graphics api - _sceneRenderBatch.clear(); - gpu::Batch& batch = _sceneRenderBatch; + auto side = RenderArgs::MONO; + if (args) side = args->_renderSide; - GLBATCH(glDisable)(GL_COLOR_MATERIAL); + if (side != RenderArgs::STEREO_RIGHT) { + // Let's introduce a gpu::Batch to capture all the calls to the graphics api + _sceneRenderBatch.clear(); + gpu::Batch& batch = _sceneRenderBatch; + + GLBATCH(glDisable)(GL_COLOR_MATERIAL); + + if (mode == DIFFUSE_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + GLBATCH(glDisable)(GL_CULL_FACE); + } else { + GLBATCH(glEnable)(GL_CULL_FACE); + if (mode == SHADOW_RENDER_MODE) { + GLBATCH(glCullFace)(GL_FRONT); + } + } + + // render opaque meshes with alpha testing + + GLBATCH(glDisable)(GL_BLEND); + GLBATCH(glEnable)(GL_ALPHA_TEST); - if (mode == DIFFUSE_RENDER_MODE || mode == NORMAL_RENDER_MODE) { - GLBATCH(glDisable)(GL_CULL_FACE); - } else { - GLBATCH(glEnable)(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_FRONT); + GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); } - } - - // render opaque meshes with alpha testing - - GLBATCH(glDisable)(GL_BLEND); - GLBATCH(glEnable)(GL_ALPHA_TEST); - - if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glAlphaFunc)(GL_EQUAL, 0.0f); - } - /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( - mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, - mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, - mode == DEFAULT_RENDER_MODE); - */ - { - GLenum buffers[3]; - int bufferCount = 0; - if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + /*Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, + mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, + mode == DEFAULT_RENDER_MODE); + */ + { + GLenum buffers[3]; + int bufferCount = 0; + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + } + if (mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + } + if (mode == DEFAULT_RENDER_MODE) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + } + GLBATCH(glDrawBuffers)(bufferCount, buffers); } - if (mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE) { + + const float DEFAULT_ALPHA_THRESHOLD = 0.5f; + + int opaqueMeshPartsRendered = 0; + + // now, for each model in the scene, render the mesh portions + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); + opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args); + + // render translucent meshes afterwards + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + { + GLenum buffers[2]; + int bufferCount = 0; buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - } - if (mode == DEFAULT_RENDER_MODE) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + GLBATCH(glDrawBuffers)(bufferCount, buffers); } - GLBATCH(glDrawBuffers)(bufferCount, buffers); + + int translucentParts = 0; + const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args); + + GLBATCH(glDisable)(GL_ALPHA_TEST); + GLBATCH(glEnable)(GL_BLEND); + GLBATCH(glDepthMask)(false); + GLBATCH(glDepthFunc)(GL_LEQUAL); + + //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + { + GLenum buffers[1]; + int bufferCount = 0; + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + GLBATCH(glDrawBuffers)(bufferCount, buffers); + } + + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); + translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args); + } + + GLBATCH(glDepthMask)(true); + GLBATCH(glDepthFunc)(GL_LESS); + GLBATCH(glDisable)(GL_CULL_FACE); + + if (mode == SHADOW_RENDER_MODE) { + GLBATCH(glCullFace)(GL_BACK); + } + + // deactivate vertex arrays after drawing + GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); + GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); + GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); + GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX); + GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT); + + // bind with 0 to switch back to normal operation + GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); + GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); + GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); + if (args) { + args->_translucentMeshPartsRendered = translucentParts; + args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; } - const float DEFAULT_ALPHA_THRESHOLD = 0.5f; - - int opaqueMeshPartsRendered = 0; - - // now, for each model in the scene, render the mesh portions - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, false, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, false, true, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, false, true, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, false, args); - opaqueMeshPartsRendered += renderMeshesForModelsInScene(batch, mode, false, DEFAULT_ALPHA_THRESHOLD, true, true, true, args); - - // render translucent meshes afterwards - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); - { - GLenum buffers[2]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; - GLBATCH(glDrawBuffers)(bufferCount, buffers); } - int translucentParts = 0; - const float MOSTLY_OPAQUE_THRESHOLD = 0.75f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, false, true, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_OPAQUE_THRESHOLD, true, true, true, args); - - GLBATCH(glDisable)(GL_ALPHA_TEST); - GLBATCH(glEnable)(GL_BLEND); - GLBATCH(glDepthMask)(false); - GLBATCH(glDepthFunc)(GL_LEQUAL); - - //Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); - { - GLenum buffers[1]; - int bufferCount = 0; - buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; - GLBATCH(glDrawBuffers)(bufferCount, buffers); - } - - if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { - const float MOSTLY_TRANSPARENT_THRESHOLD = 0.0f; - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, false, true, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, false, true, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, false, args); - translucentParts += renderMeshesForModelsInScene(batch, mode, true, MOSTLY_TRANSPARENT_THRESHOLD, true, true, true, args); - } - - GLBATCH(glDepthMask)(true); - GLBATCH(glDepthFunc)(GL_LESS); - GLBATCH(glDisable)(GL_CULL_FACE); - - if (mode == SHADOW_RENDER_MODE) { - GLBATCH(glCullFace)(GL_BACK); - } - - // deactivate vertex arrays after drawing - GLBATCH(glDisableClientState)(GL_NORMAL_ARRAY); - GLBATCH(glDisableClientState)(GL_VERTEX_ARRAY); - GLBATCH(glDisableClientState)(GL_TEXTURE_COORD_ARRAY); - GLBATCH(glDisableClientState)(GL_COLOR_ARRAY); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::TANGENT); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_INDEX); - GLBATCH(glDisableVertexAttribArray)(gpu::Stream::SKIN_CLUSTER_WEIGHT); - - // bind with 0 to switch back to normal operation - GLBATCH(glBindBuffer)(GL_ARRAY_BUFFER, 0); - GLBATCH(glBindBuffer)(GL_ELEMENT_ARRAY_BUFFER, 0); - GLBATCH(glBindTexture)(GL_TEXTURE_2D, 0); - // Render! { PROFILE_RANGE("render Batch"); - ::gpu::GLBackend::renderBatch(batch); + ::gpu::GLBackend::renderBatch(_sceneRenderBatch); } // restore all the default material settings Application::getInstance()->setupWorldLight(); - if (args) { - args->_translucentMeshPartsRendered = translucentParts; - args->_opaqueMeshPartsRendered = opaqueMeshPartsRendered; - } } bool Model::renderInScene(float alpha, RenderArgs* args) { diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 32c072dc99..4dceb07655 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -31,7 +31,7 @@ class QScriptEngine; class Shape; -class RenderArgs; +#include "RenderArgs.h" class ViewFrustum; @@ -91,7 +91,7 @@ public: bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL); // Scene rendering support - static void startScene(); + static void startScene(RenderArgs::RenderSide renderSide); bool renderInScene(float alpha = 1.0f, RenderArgs* args = NULL); static void endScene(RenderMode mode = DEFAULT_RENDER_MODE, RenderArgs* args = NULL); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 4bdabcc566..6584fce396 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -84,14 +84,14 @@ void Overlays::render2D() { RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), Menu::getInstance()->getVoxelSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), - RenderArgs::DEFAULT_RENDER_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foreach(Overlay* thisOverlay, _overlays2D) { thisOverlay->render(&args); } } -void Overlays::render3D(RenderArgs::RenderMode renderMode) { +void Overlays::render3D(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { QReadLocker lock(&_lock); if (_overlays3D.size() == 0) { return; @@ -106,7 +106,7 @@ void Overlays::render3D(RenderArgs::RenderMode renderMode) { RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(), Menu::getInstance()->getVoxelSizeScale(), Menu::getInstance()->getBoundaryLevelAdjust(), - renderMode, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; foreach(Overlay* thisOverlay, _overlays3D) { diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 66232196f2..31e4ad1ebc 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -39,7 +39,7 @@ public: ~Overlays(); void init(QGLWidget* parent); void update(float deltatime); - void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + void render3D(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); void render2D(); public slots: diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index a8aafbe34d..5bcf49a1a4 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -162,8 +162,8 @@ bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { return false; } -void OctreeRenderer::render(RenderArgs::RenderMode renderMode) { - RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, +void OctreeRenderer::render(RenderArgs::RenderMode renderMode, RenderArgs::RenderSide renderSide) { + RenderArgs args = { this, _viewFrustum, getSizeScale(), getBoundaryLevelAdjust(), renderMode, renderSide, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if (_tree) { _tree->lockForRead(); diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index d418467012..e8612b4cb6 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -52,7 +52,7 @@ public: virtual void init(); /// render the content of the octree - virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE); + virtual void render(RenderArgs::RenderMode renderMode = RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::RenderSide renderSide = RenderArgs::MONO); ViewFrustum* getViewFrustum() const { return _viewFrustum; } void setViewFrustum(ViewFrustum* viewFrustum) { _viewFrustum = viewFrustum; } diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 1ed43f94ad..e447472fee 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -18,12 +18,14 @@ class OctreeRenderer; class RenderArgs { public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE }; + enum RenderSide { MONO, STEREO_LEFT, STEREO_RIGHT }; OctreeRenderer* _renderer; ViewFrustum* _viewFrustum; float _sizeScale; int _boundaryLevelAdjust; RenderMode _renderMode; + RenderSide _renderSide; int _elementsTouched; int _itemsRendered; From cc78000641968b24aa3824f78fb1b88dd49c5389 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 11:22:11 -0800 Subject: [PATCH 2/5] introduce the concept of side thorugh out the rendering traversal --- interface/src/Application.cpp | 14 +++++--------- interface/src/Application.h | 13 +------------ interface/src/devices/TV3DManager.cpp | 4 ++-- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 48fa2413ea..792ad2d62e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -724,7 +724,7 @@ void Application::paintGL() { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - displaySide(RenderContext(*whichCamera)); + displaySide(*whichCamera); glPopMatrix(); if (Menu::getInstance()->isOptionChecked(MenuOption::FullscreenMirror)) { @@ -2874,16 +2874,12 @@ QImage Application::renderAvatarBillboard() { return image; } -//void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { -void Application::displaySide(RenderContext& renderContext) { +void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { PROFILE_RANGE(__FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // transform by eye offset - Camera& whichCamera = renderContext._whichCamera; - bool selfAvatarOnly = renderContext._selfAvatarOnly; - // load the view frustum loadViewFrustum(whichCamera, _displayViewFrustum); @@ -3025,7 +3021,7 @@ void Application::displaySide(RenderContext& renderContext) { PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... entities..."); - _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderContext._renderSide); + _entities.render(RenderArgs::DEFAULT_RENDER_MODE, renderSide); } // render JS/scriptable overlays @@ -3270,7 +3266,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta)); } - displaySide(RenderContext(_mirrorCamera, true)); + displaySide(_mirrorCamera, true); // restore absolute translations _myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation); @@ -3284,7 +3280,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) { _shadowMatrices[i] = savedShadowMatrices[i]; } } else { - displaySide(RenderContext(_mirrorCamera, true)); + displaySide(_mirrorCamera, true); } glPopMatrix(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 2cea413dd4..178849eec4 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,19 +262,8 @@ public: QImage renderAvatarBillboard(); - struct RenderContext { - Camera& _whichCamera; - bool _selfAvatarOnly; - RenderArgs::RenderSide _renderSide; - - RenderContext(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO) : - _whichCamera(whichCamera), - _selfAvatarOnly(selfAvatarOnly), - _renderSide(renderSide) { - } - }; // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); - void displaySide(RenderContext& renderContext); + void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as /// the view matrix translation. diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index bd0129f88e..d7d7353b24 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -126,7 +126,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_LEFT)); + Application::getInstance()->displaySide(whichCamera, false, RenderArgs::STEREO_LEFT); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); @@ -156,7 +156,7 @@ void TV3DManager::display(Camera& whichCamera) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - Application::getInstance()->displaySide(Application::RenderContext(whichCamera, false, RenderArgs::STEREO_RIGHT)); + Application::getInstance()->displaySide(whichCamera, false, RenderArgs::STEREO_RIGHT); if (displayOverlays) { applicationOverlay.displayOverlayTexture3DTV(whichCamera, _aspect, fov); From d9ae3eb5b61dc0216b900bcef094a8a7f8153545 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:07:59 -0800 Subject: [PATCH 3/5] clean version of the simple stereo ack, not available for Occulus yet --- interface/src/renderer/Model.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 28bf1ddd3e..aeff8e9a67 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1505,10 +1505,11 @@ void Model::setupBatchTransform(gpu::Batch& batch) { void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); - auto side = RenderArgs::MONO; - if (args) side = args->_renderSide; + RenderArgs::RenderSide renderSide = RenderArgs::MONO; + if (args) renderSide = args->_renderSide; - if (side != RenderArgs::STEREO_RIGHT) { + // Do the rendering batch creation for mono or left eye, not for right eye + if (renderSide != RenderArgs::STEREO_RIGHT) { // Let's introduce a gpu::Batch to capture all the calls to the graphics api _sceneRenderBatch.clear(); gpu::Batch& batch = _sceneRenderBatch; From 43a6a0420bdc650f9e10ca01cd34e013648d9a86 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:24:38 -0800 Subject: [PATCH 4/5] remove useless comments --- interface/src/Application.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 178849eec4..8ffad07122 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -262,7 +262,6 @@ public: QImage renderAvatarBillboard(); - // void displaySide(Camera& whichCamera, bool selfAvatarOnly = false); void displaySide(Camera& whichCamera, bool selfAvatarOnly = false, RenderArgs::RenderSide renderSide = RenderArgs::MONO); /// Stores the current modelview matrix as the untranslated view matrix to use for transforms and the supplied vector as From 4f878682a9df73fea04596f68e14021bc05b1a39 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 14 Nov 2014 12:38:50 -0800 Subject: [PATCH 5/5] fix syntax --- interface/src/renderer/Model.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index aeff8e9a67..fc3845d94f 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1506,7 +1506,9 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { PROFILE_RANGE(__FUNCTION__); RenderArgs::RenderSide renderSide = RenderArgs::MONO; - if (args) renderSide = args->_renderSide; + if (args) { + renderSide = args->_renderSide; + } // Do the rendering batch creation for mono or left eye, not for right eye if (renderSide != RenderArgs::STEREO_RIGHT) {