From 3ec6ada29d8a8f371b563de29b752ea8d835abf5 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 19 May 2015 00:32:36 -0700 Subject: [PATCH 1/7] Introduce an official syncCache on the GLBackend to catch up with the glCOntext ttrue state --- libraries/gpu/src/gpu/GLBackend.cpp | 12 ++++++++-- libraries/gpu/src/gpu/GLBackend.h | 25 ++++++++++++++++---- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 8 +++---- libraries/gpu/src/gpu/GLBackendTransform.cpp | 19 +++++++++++++++ libraries/render-utils/src/Model.cpp | 5 ++-- 5 files changed, 57 insertions(+), 12 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 08a9a39d68..f337d5c3e0 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -96,8 +96,11 @@ void GLBackend::render(Batch& batch) { } } -void GLBackend::renderBatch(Batch& batch) { +void GLBackend::renderBatch(Batch& batch, bool syncCache) { GLBackend backend; + if (syncCache) { + backend.syncCache(); + } backend.render(batch); } @@ -134,6 +137,12 @@ bool GLBackend::checkGLError(const char* name) { } } + +void GLBackend::syncCache() { + syncTransformStateCache(); + syncPipelineStateCache(); +} + void GLBackend::do_draw(Batch& batch, uint32 paramOffset) { updateInput(); updateTransform(); @@ -547,4 +556,3 @@ void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) { } - diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 3551953998..7546484cc3 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -24,12 +24,20 @@ namespace gpu { class GLBackend : public Backend { public: + explicit GLBackend(bool syncCache); GLBackend(); ~GLBackend(); void render(Batch& batch); - static void renderBatch(Batch& batch); + // Render Batch create a local Context and execute the batch with it + // WARNING: + // if syncCache is true, then the gpu::GLBackend will synchornize + // its cache with the current gl state and it's BAD + // If you know you don't rely on any state changed by naked gl calls then + // leave to false where it belongs + // if true, the needed resync IS EXPENSIVE + static void renderBatch(Batch& batch, bool syncCache = true); static bool checkGLError(const char* name = nullptr); @@ -79,6 +87,7 @@ public: static GLShader* syncGPUObject(const Shader& shader); static GLuint getShaderID(const ShaderPointer& shader); + // FIXME: Please remove these 2 calls once the text renderer doesn't use naked gl calls anymore static void loadMatrix(GLenum target, const glm::mat4 & m); static void fetchMatrix(GLenum target, glm::mat4 & m); @@ -186,6 +195,12 @@ 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 @@ -241,6 +256,8 @@ protected: void initTransform(); void killTransform(); + // Synchronize the state cache of this Backend with the actual real state of the GL Context + void syncTransformStateCache(); void updateTransform(); struct TransformStageState { TransformObject _transformObject; @@ -297,7 +314,7 @@ protected: GLState* _state; bool _invalidState = false; - bool _needStateSync = true; + // bool _needStateSync = true; PipelineStageState() : _pipeline(), @@ -306,8 +323,8 @@ protected: _stateCache(State::DEFAULT), _stateSignatureCache(0), _state(nullptr), - _invalidState(false), - _needStateSync(true) + _invalidState(false)//, + // _needStateSync(true) {} } _pipeline; diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 938ed77730..f124770cfb 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -64,10 +64,10 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { return; } - if (_pipeline._needStateSync) { + /* if (_pipeline._needStateSync) { syncPipelineStateCache(); _pipeline._needStateSync = false; - } + }*/ // null pipeline == reset if (!pipeline) { @@ -111,12 +111,12 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { #define DEBUG_GLSTATE void GLBackend::updatePipeline() { #ifdef DEBUG_GLSTATE - if (_pipeline._needStateSync) { + /* if (_pipeline._needStateSync) { State::Data state; getCurrentGLState(state); State::Signature signature = State::evalSignature(state); (void) signature; // quiet compiler - } + }*/ #endif if (_pipeline._invalidProgram) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index d619d0afee..3f760e4cc8 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -55,6 +55,25 @@ void GLBackend::killTransform() { #else #endif } + +void GLBackend::syncTransformStateCache() { + _transform._invalidProj = true; + _transform._invalidView = true; + _transform._invalidModel = true; + + GLint currentMode; + glGetIntegerv(GL_MATRIX_MODE, ¤tMode); + _transform._lastMode = currentMode; + + glGetFloatv(GL_PROJECTION_MATRIX, (float*) &_transform._projection); + + Mat4 modelView; + glGetFloatv(GL_MODELVIEW_MATRIX, (float*) &modelView); + auto modelViewInv = glm::inverse(modelView); + _transform._view.evalFromRawMatrix(modelViewInv); + _transform._model.setIdentity(); +} + void GLBackend::updateTransform() { // Check all the dirty flags and update the state accordingly if (_transform._invalidProj) { diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index c51ca9682a..2d0c6ec735 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -935,8 +935,8 @@ bool Model::renderCore(float alpha, RenderMode mode, RenderArgs* args) { glPushMatrix(); #endif - ::gpu::GLBackend::renderBatch(batch); - + ::gpu::GLBackend::renderBatch(batch, true); // force sync with gl state here + #if defined(ANDROID) #else glPopMatrix(); @@ -1846,6 +1846,7 @@ void Model::endScene(RenderMode mode, RenderArgs* args) { } gpu::GLBackend backend; + backend.syncCache(); // force sync with gl state here if (args) { glm::mat4 proj; From 314486ab889e5f44d4cd71eb94cf0f27d23f65b5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 May 2015 16:21:12 +0200 Subject: [PATCH 2/7] Ignore scale in Transform when 0.0f Also cleaned up some coding standard --- libraries/shared/src/Transform.h | 71 +++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 20 deletions(-) diff --git a/libraries/shared/src/Transform.h b/libraries/shared/src/Transform.h index fd6a4bda4b..f3b5b14385 100644 --- a/libraries/shared/src/Transform.h +++ b/libraries/shared/src/Transform.h @@ -22,6 +22,18 @@ #include +inline bool isValidScale(glm::vec3 scale) { + bool result = scale.x != 0.0f && scale.y != 0.0f && scale.z != 0.0f; + assert(result); + return result; +} + +inline bool isValidScale(float scale) { + bool result = scale != 0.0f; + assert(result); + return result; +} + class Transform { public: typedef glm::mat4 Mat4; @@ -32,7 +44,7 @@ public: typedef glm::quat Quat; Transform() : - _rotation(1.0f, 0, 0, 0), + _rotation(1.0f, 0.0f, 0.0f, 0.0f), _scale(1.0f), _translation(0.0f), _flags(FLAG_CACHE_INVALID_BITSET) // invalid cache @@ -44,6 +56,9 @@ public: _translation(translation), _flags(FLAG_CACHE_INVALID_BITSET) // invalid cache { + if (!isValidScale(_scale)) { + _scale = Vec3(1.0f); + } } Transform(const Transform& transform) : _rotation(transform._rotation), @@ -166,8 +181,8 @@ protected: }; inline void Transform::setIdentity() { - _translation = Vec3(0); - _rotation = Quat(1.0f, 0, 0, 0); + _translation = Vec3(0.0f); + _rotation = Quat(1.0f, 0.0f, 0.0f, 0.0f); _scale = Vec3(1.0f); _flags = Flags(FLAG_CACHE_INVALID_BITSET); } @@ -187,19 +202,25 @@ inline void Transform::setTranslation(const Vec3& translation) { } inline void Transform::preTranslate(const Vec3& translation) { - if (translation == Vec3() ) return; + if (translation == Vec3()) { + return; + } invalidCache(); flagTranslation(); _translation += translation; } inline void Transform::postTranslate(const Vec3& translation) { - if (translation == Vec3() ) return; + if (translation == Vec3()) { + return; + } invalidCache(); flagTranslation(); Vec3 scaledT = translation; - if (isScaling()) scaledT *= _scale; + if (isScaling()) { + scaledT *= _scale; + } if (isRotating()) { _translation += glm::rotate(_rotation, scaledT); @@ -223,7 +244,9 @@ inline void Transform::setRotation(const Quat& rotation) { } inline void Transform::preRotate(const Quat& rotation) { - if (rotation == Quat()) return; + if (rotation == Quat()) { + return; + } invalidCache(); if (isRotating()) { _rotation = rotation * _rotation; @@ -236,7 +259,9 @@ inline void Transform::preRotate(const Quat& rotation) { } inline void Transform::postRotate(const Quat& rotation) { - if (rotation == Quat()) return; + if (rotation == Quat()) { + return; + } invalidCache(); if (isNonUniform()) { @@ -269,8 +294,12 @@ inline const Transform::Vec3& Transform::getScale() const { } inline void Transform::setScale(float scale) { + if (!isValidScale(scale)) { + return; + } invalidCache(); flagUniform(); + if (scale == 1.0f) { unflagScaling(); } else { @@ -280,6 +309,9 @@ inline void Transform::setScale(float scale) { } inline void Transform::setScale(const Vec3& scale) { + if (!isValidScale(scale)) { + return; + } if ((scale.x == scale.y) && (scale.x == scale.z)) { setScale(scale.x); } else { @@ -291,9 +323,11 @@ inline void Transform::setScale(const Vec3& scale) { } inline void Transform::postScale(float scale) { - if (scale == 1.0f) return; + if (isValidScale(scale) || scale == 1.0f) { + return; + } if (isScaling()) { - // if already scaling, just invalid cache and aply uniform scale + // if already scaling, just invalid cache and apply uniform scale invalidCache(); _scale *= scale; } else { @@ -302,6 +336,9 @@ inline void Transform::postScale(float scale) { } inline void Transform::postScale(const Vec3& scale) { + if (!isValidScale(scale)) { + return; + } invalidCache(); if (isScaling()) { _scale *= scale; @@ -360,7 +397,7 @@ inline Transform::Mat4& Transform::getRotationScaleMatrixInverse(Mat4& result) c inline void Transform::evalFromRawMatrix(const Mat4& matrix) { // for now works only in the case of TRS transformation - if ((matrix[0][3] == 0) && (matrix[1][3] == 0) && (matrix[2][3] == 0) && (matrix[3][3] == 1.0f)) { + if ((matrix[0][3] == 0.0f) && (matrix[1][3] == 0.0f) && (matrix[2][3] == 0.0f) && (matrix[3][3] == 1.0f)) { setTranslation(Vec3(matrix[3])); evalFromRawMatrix(Mat3(matrix)); } @@ -377,15 +414,10 @@ inline void Transform::evalFromRawMatrix(const Mat3& rotationScaleMatrix) { inline Transform& Transform::evalInverse(Transform& inverse) const { inverse.setIdentity(); if (isScaling()) { - // TODO: At some point we will face the case when scale is 0 and so 1/0 will blow up... - // WHat should we do for this one? - assert(_scale.x != 0); - assert(_scale.y != 0); - assert(_scale.z != 0); if (isNonUniform()) { - inverse.setScale(Vec3(1.0f/_scale.x, 1.0f/_scale.y, 1.0f/_scale.z)); + inverse.setScale(Vec3(1.0f) / _scale); } else { - inverse.setScale(1.0f/_scale.x); + inverse.setScale(1.0f / _scale.x); } } if (isRotating()) { @@ -421,8 +453,7 @@ inline Transform& Transform::inverseMult( Transform& result, const Transform& le result.setIdentity(); if (left.isScaling()) { - const Vec3& s = left.getScale(); - result.setScale(Vec3(1.0f / s.x, 1.0f / s.y, 1.0f / s.z)); + result.setScale(Vec3(1.0f) / left.getScale()); } if (left.isRotating()) { result.postRotate(glm::conjugate(left.getRotation())); From 5d2187cedf2cd0cf91cfc355e5e997e4f0da3a5a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 May 2015 16:37:02 +0200 Subject: [PATCH 3/7] Remove non batch call to bind/releaseSimpleProgram --- interface/src/ui/overlays/Cube3DOverlay.cpp | 3 +-- .../src/DeferredLightingEffect.cpp | 19 ------------------- .../render-utils/src/DeferredLightingEffect.h | 7 ------- 3 files changed, 1 insertion(+), 28 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 329d81ff80..6fc9fe6e27 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -126,8 +126,7 @@ void Cube3DOverlay::render(RenderArgs* args) { } else { glScalef(dimensions.x, dimensions.y, dimensions.z); - // FIXME Remove non Batch version of renderWireCube once we use the render pipeline - DependencyManager::get()->renderWireCube(1.0f, cubeColor); + DependencyManager::get()->renderWireCube(1.0f, cubeColor); } } glPopMatrix(); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 2f23773bc1..6f2808c0cd 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -92,13 +92,6 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { lp->setAmbientSpherePreset(gpu::SphericalHarmonics::Preset(_ambientLightMode % gpu::SphericalHarmonics::NUM_PRESET)); } -void DeferredLightingEffect::bindSimpleProgram() { - DependencyManager::get()->setPrimaryDrawBuffers(true, true, true); - _simpleProgram.bind(); - _simpleProgram.setUniformValue(_glowIntensityLocation, DependencyManager::get()->getIntensity()); - glDisable(GL_BLEND); -} - void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch) { DependencyManager::get()->setPrimaryDrawBuffers(batch, true, true, true); batch._glUseProgram(_simpleProgram.programId()); @@ -106,12 +99,6 @@ void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch) { batch._glDisable(GL_BLEND); } -void DeferredLightingEffect::releaseSimpleProgram() { - glEnable(GL_BLEND); - _simpleProgram.release(); - DependencyManager::get()->setPrimaryDrawBuffers(true, false, false); -} - void DeferredLightingEffect::releaseSimpleProgram(gpu::Batch& batch) { batch._glEnable(GL_BLEND); batch._glUseProgram(0); @@ -136,12 +123,6 @@ void DeferredLightingEffect::renderSolidCube(gpu::Batch& batch, float size, cons releaseSimpleProgram(batch); } -void DeferredLightingEffect::renderWireCube(float size, const glm::vec4& color) { - gpu::Batch batch; - renderWireCube(batch, size, color); - gpu::GLBackend::renderBatch(batch); -} - void DeferredLightingEffect::renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color) { bindSimpleProgram(batch); DependencyManager::get()->renderWireCube(batch, size, color); diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 22a26dfbc7..7b17851ad7 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -33,15 +33,10 @@ public: void init(AbstractViewStateInterface* viewState); - /// Returns a reference to a simple program suitable for rendering static untextured geometry - ProgramObject& getSimpleProgram() { return _simpleProgram; } - /// Sets up the state necessary to render static untextured geometry with the simple program. - void bindSimpleProgram(); void bindSimpleProgram(gpu::Batch& batch); /// Tears down the state necessary to render static untextured geometry with the simple program. - void releaseSimpleProgram(); void releaseSimpleProgram(gpu::Batch& batch); //// Renders a solid sphere with the simple program. @@ -54,8 +49,6 @@ public: void renderSolidCube(gpu::Batch& batch, float size, const glm::vec4& color); //// Renders a wireframe cube with the simple program. - // FIXME Remove non Batch version once Cube3DOverlay uses the render pipeline - void renderWireCube(float size, const glm::vec4& color); void renderWireCube(gpu::Batch& batch, float size, const glm::vec4& color); //// Renders a quad with the simple program. From e9808590596cf00bf4109ee12b09c7c591c1dd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Brisset?= Date: Fri, 22 May 2015 16:14:32 +0100 Subject: [PATCH 4/7] Simple Program uses gpu API --- .../src/RenderableTextEntityItem.cpp | 4 +-- .../src/DeferredLightingEffect.cpp | 33 +++++++++++-------- .../render-utils/src/DeferredLightingEffect.h | 5 ++- libraries/render-utils/src/simple.slv | 18 ++++++---- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 9f209e91ef..a3bfd981ec 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -51,9 +51,9 @@ void RenderableTextEntityItem::render(RenderArgs* args) { // TODO: Determine if we want these entities to have the deferred lighting effect? I think we do, so that the color // used for a sphere, or box have the same look as those used on a text entity. - DependencyManager::get()->bindSimpleProgram(); + //DependencyManager::get()->bindSimpleProgram(); DependencyManager::get()->renderQuad(topLeft, bottomRight, glm::vec4(toGlm(getBackgroundColorX()), alpha)); - DependencyManager::get()->releaseSimpleProgram(); + //DependencyManager::get()->releaseSimpleProgram(); glTranslatef(-(halfDimensions.x - leftMargin), halfDimensions.y - topMargin, 0.0f); glm::vec4 textColor(toGlm(getTextColorX()), alpha); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 6f2808c0cd..8a9ee4bf6d 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -12,7 +12,6 @@ // include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL #include - #include #include #include @@ -48,16 +47,26 @@ #include "point_light_frag.h" #include "spot_light_frag.h" +static const std::string glowIntensityShaderHandle = "glowIntensity"; + void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { + auto vertexShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(simple_vert))); + auto pixelShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(simple_frag))); + gpu::Shader::BindingSet slotBindings; + slotBindings.insert(gpu::Shader::Binding(glowIntensityShaderHandle, 0)); + + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vertexShader, pixelShader)); + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setCullMode(gpu::State::CULL_BACK); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _simpleProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + _viewState = viewState; - _simpleProgram.addShaderFromSourceCode(QGLShader::Vertex, simple_vert); - _simpleProgram.addShaderFromSourceCode(QGLShader::Fragment, simple_frag); - _simpleProgram.link(); - - _simpleProgram.bind(); - _glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity"); - _simpleProgram.release(); - loadLightProgram(directional_light_frag, false, _directionalLight, _directionalLightLocations); loadLightProgram(directional_light_shadow_map_frag, false, _directionalLightShadowMap, _directionalLightShadowMapLocations); @@ -94,14 +103,10 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { void DeferredLightingEffect::bindSimpleProgram(gpu::Batch& batch) { DependencyManager::get()->setPrimaryDrawBuffers(batch, true, true, true); - batch._glUseProgram(_simpleProgram.programId()); - batch._glUniform1f(_glowIntensityLocation, DependencyManager::get()->getIntensity()); - batch._glDisable(GL_BLEND); + batch.setPipeline(_simpleProgram); } void DeferredLightingEffect::releaseSimpleProgram(gpu::Batch& batch) { - batch._glEnable(GL_BLEND); - batch._glUseProgram(0); DependencyManager::get()->setPrimaryDrawBuffers(batch, true, false, false); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 7b17851ad7..33728ab15a 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -98,10 +98,9 @@ private: }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); - - ProgramObject _simpleProgram; - int _glowIntensityLocation; + gpu::PipelinePointer _simpleProgram; + ProgramObject _directionalSkyboxLight; LightLocations _directionalSkyboxLightLocations; ProgramObject _directionalSkyboxLightShadowMap; diff --git a/libraries/render-utils/src/simple.slv b/libraries/render-utils/src/simple.slv index 9ad47a3e66..1460058892 100644 --- a/libraries/render-utils/src/simple.slv +++ b/libraries/render-utils/src/simple.slv @@ -12,16 +12,22 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + // the interpolated normal varying vec4 interpolatedNormal; void main(void) { - // transform and store the normal for interpolation - interpolatedNormal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - // pass along the diffuse color gl_FrontColor = gl_Color; - // use standard pipeline transform - gl_Position = ftransform(); -} + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); +} \ No newline at end of file From e5aa696ddaa6392a8d2a77a98b59e1d7b5e05750 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 May 2015 17:31:37 +0200 Subject: [PATCH 5/7] syncInputStateCache --- interface/src/Application.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.cpp | 3 +-- libraries/gpu/src/gpu/GLBackend.h | 6 ++++-- libraries/gpu/src/gpu/GLBackendInput.cpp | 16 ++++++++-------- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 05fc2fec0a..c0eb1a16f1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -391,7 +391,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // emit checkBackgroundDownloads to cause the GeometryCache to check it's queue for requested background // downloads. QSharedPointer geometryCacheP = DependencyManager::get(); - ResourceCache *geometryCache = geometryCacheP.data(); + ResourceCache* geometryCache = geometryCacheP.data(); connect(this, &Application::checkBackgroundDownloads, geometryCache, &ResourceCache::checkAsynchronousGets); // connect the DataProcessor processDatagrams slot to the QUDPSocket readyRead() signal diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 2e5a4d4508..a84af10a82 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -76,12 +76,10 @@ GLBackend::GLBackend() : _output() { initTransform(); - initInput(); } GLBackend::~GLBackend() { killTransform(); - killInput(); } void GLBackend::render(Batch& batch) { @@ -143,6 +141,7 @@ bool GLBackend::checkGLError(const char* name) { void GLBackend::syncCache() { syncTransformStateCache(); syncPipelineStateCache(); + syncInputStateCache(); } void GLBackend::do_draw(Batch& batch, uint32 paramOffset) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index e00aa2e02a..d898c9b6c6 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -216,8 +216,10 @@ protected: void do_setInputBuffer(Batch& batch, uint32 paramOffset); void do_setIndexBuffer(Batch& batch, uint32 paramOffset); - void initInput(); - void killInput(); + void pushInputState(); + void popInputState(); + // Synchronize the state cache of this Backend with the actual real state of the GL Context + void syncInputStateCache(); void updateInput(); struct InputStageState { bool _invalidFormat; diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 6646ae3f64..c5ec60f6ee 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -46,24 +46,27 @@ static const GLenum attributeSlotToClassicAttribName[NUM_CLASSIC_ATTRIBS] = { }; #endif -void GLBackend::initInput() { +void GLBackend::pushInputState() { glPushClientAttrib(GL_VERTEX_ARRAY); glPushClientAttrib(GL_NORMAL_ARRAY); glPushClientAttrib(GL_COLOR_ARRAY); glPushClientAttrib(GL_TEXTURE_COORD_ARRAY); - for (int i = 0; i < NUM_CLASSIC_ATTRIBS; i++) { - _input._attributeActivation[i] = glIsEnabled(attributeSlotToClassicAttribName[i]); - } } -void GLBackend::killInput() { +void GLBackend::popInputState() { glPopClientAttrib(); // GL_VERTEX_ARRAY glPopClientAttrib(); // GL_NORMAL_ARRAY glPopClientAttrib(); // GL_COLOR_ARRAY glPopClientAttrib(); // GL_TEXTURE_COORD_ARRAY } +void GLBackend::syncInputStateCache() { + for (int i = 0; i < NUM_CLASSIC_ATTRIBS; i++) { + _input._attributeActivation[i] = glIsEnabled(attributeSlotToClassicAttribName[i]); + } +} + void GLBackend::updateInput() { if (_input._invalidFormat || _input._buffersState.any()) { @@ -164,9 +167,6 @@ void GLBackend::updateInput() { } } } - } else { - glBindBuffer(GL_ARRAY_BUFFER, 0); - (void) CHECK_GL_ERROR(); } // everything format related should be in sync now _input._invalidFormat = false; From 20ff43e29a32ff5081febd66a0fe2f296a53d259 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 May 2015 20:28:32 +0200 Subject: [PATCH 6/7] Don't sync by default --- interface/src/Application.cpp | 2 +- .../entities-renderer/src/EntityTreeRenderer.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 6 ++---- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 15 --------------- 4 files changed, 4 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c0eb1a16f1..569c6c3564 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3291,7 +3291,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs gpu::Batch batch; model::Skybox::render(batch, _viewFrustum, *skybox); - gpu::GLBackend::renderBatch(batch); + gpu::GLBackend::renderBatch(batch, true); glUseProgram(0); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 23160be045..86baacc8a8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -510,7 +510,7 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode, _tree->unlock(); glPushMatrix(); - gpu::GLBackend::renderBatch(batch); + gpu::GLBackend::renderBatch(batch, true); glPopMatrix(); // stats... diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index d898c9b6c6..006cf70bf9 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -37,7 +37,7 @@ public: // If you know you don't rely on any state changed by naked gl calls then // leave to false where it belongs // if true, the needed resync IS EXPENSIVE - static void renderBatch(Batch& batch, bool syncCache = true); + static void renderBatch(Batch& batch, bool syncCache = false); static bool checkGLError(const char* name = nullptr); @@ -318,7 +318,6 @@ protected: GLState* _state; bool _invalidState = false; - // bool _needStateSync = true; PipelineStageState() : _pipeline(), @@ -327,8 +326,7 @@ protected: _stateCache(State::DEFAULT), _stateSignatureCache(0), _state(nullptr), - _invalidState(false)//, - // _needStateSync(true) + _invalidState(false) {} } _pipeline; diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index f124770cfb..ec9be957ae 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -63,11 +63,6 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { if (_pipeline._pipeline == pipeline) { return; } - - /* if (_pipeline._needStateSync) { - syncPipelineStateCache(); - _pipeline._needStateSync = false; - }*/ // null pipeline == reset if (!pipeline) { @@ -108,17 +103,7 @@ void GLBackend::do_setPipeline(Batch& batch, uint32 paramOffset) { } } -#define DEBUG_GLSTATE void GLBackend::updatePipeline() { -#ifdef DEBUG_GLSTATE - /* if (_pipeline._needStateSync) { - State::Data state; - getCurrentGLState(state); - State::Signature signature = State::evalSignature(state); - (void) signature; // quiet compiler - }*/ -#endif - if (_pipeline._invalidProgram) { // doing it here is aproblem for calls to glUniform.... so will do it on assing... glUseProgram(_pipeline._program); From e691a03c979cd115402106e98ec4af26aeb8030b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 22 May 2015 20:30:54 +0200 Subject: [PATCH 7/7] Remove push/popInputState --- libraries/gpu/src/gpu/GLBackend.h | 2 -- libraries/gpu/src/gpu/GLBackendInput.cpp | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 006cf70bf9..22266079bc 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -216,8 +216,6 @@ protected: void do_setInputBuffer(Batch& batch, uint32 paramOffset); void do_setIndexBuffer(Batch& batch, uint32 paramOffset); - void pushInputState(); - void popInputState(); // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncInputStateCache(); void updateInput(); diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index c5ec60f6ee..fde6ac40d0 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -46,21 +46,6 @@ static const GLenum attributeSlotToClassicAttribName[NUM_CLASSIC_ATTRIBS] = { }; #endif -void GLBackend::pushInputState() { - glPushClientAttrib(GL_VERTEX_ARRAY); - glPushClientAttrib(GL_NORMAL_ARRAY); - glPushClientAttrib(GL_COLOR_ARRAY); - glPushClientAttrib(GL_TEXTURE_COORD_ARRAY); - -} - -void GLBackend::popInputState() { - glPopClientAttrib(); // GL_VERTEX_ARRAY - glPopClientAttrib(); // GL_NORMAL_ARRAY - glPopClientAttrib(); // GL_COLOR_ARRAY - glPopClientAttrib(); // GL_TEXTURE_COORD_ARRAY -} - void GLBackend::syncInputStateCache() { for (int i = 0; i < NUM_CLASSIC_ATTRIBS; i++) { _input._attributeActivation[i] = glIsEnabled(attributeSlotToClassicAttribName[i]);