From c2b58c9781f242657446cddb6248d5470bc60103 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 11 Sep 2014 16:39:17 -0700 Subject: [PATCH 01/43] Move deferred lighting into its own class. --- interface/src/Application.cpp | 8 + interface/src/Application.h | 2 + interface/src/MetavoxelSystem.cpp | 150 ---------------- interface/src/MetavoxelSystem.h | 22 --- .../src/renderer/DeferredLightingEffect.cpp | 163 ++++++++++++++++++ .../src/renderer/DeferredLightingEffect.h | 46 +++++ 6 files changed, 219 insertions(+), 172 deletions(-) create mode 100644 interface/src/renderer/DeferredLightingEffect.cpp create mode 100644 interface/src/renderer/DeferredLightingEffect.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7fad196cd0..17d36380ee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1735,6 +1735,7 @@ void Application::init() { _environment.init(); + _deferredLightingEffect.init(); _glowEffect.init(); _ambientOcclusionEffect.init(); _voxelShader.init(); @@ -2842,11 +2843,13 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } // Draw voxels + bool deferredLightingRequired = false; if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceTimer perfTimer("voxels"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxels..."); _voxels.render(); + deferredLightingRequired = true; } // also, metavoxels @@ -2855,6 +2858,11 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... metavoxels..."); _metavoxels.render(); + deferredLightingRequired = true; + } + + if (deferredLightingRequired) { + _deferredLightingEffect.render(); } if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { diff --git a/interface/src/Application.h b/interface/src/Application.h index fbcc67cf80..aa7ef94c5b 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -68,6 +68,7 @@ #include "entities/EntityTreeRenderer.h" #include "particles/ParticleTreeRenderer.h" #include "renderer/AmbientOcclusionEffect.h" +#include "renderer/DeferredLightingEffect.h" #include "renderer/GeometryCache.h" #include "renderer/GlowEffect.h" #include "renderer/PointShader.h" @@ -556,6 +557,7 @@ private: AnimationCache _animationCache; TextureCache _textureCache; + DeferredLightingEffect _deferredLightingEffect; GlowEffect _glowEffect; AmbientOcclusionEffect _ambientOcclusionEffect; VoxelShader _voxelShader; diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 903e443cda..b3e31ce56e 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -51,12 +51,6 @@ void MetavoxelSystem::init() { new BufferDataAttribute("voxelBuffer")); _voxelBufferAttribute->setLODThresholdMultiplier( AttributeRegistry::getInstance()->getVoxelColorAttribute()->getLODThresholdMultiplier()); - - loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations); - loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap, - _directionalLightShadowMapLocations); - loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap, - _directionalLightCascadedShadowMapLocations); } MetavoxelLOD MetavoxelSystem::getLOD() { @@ -138,8 +132,6 @@ void MetavoxelSystem::render() { viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(), viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight()); - _needToLight = false; - // clear the normal buffer glDrawBuffers(sizeof(NORMAL_DRAW_BUFFERS) / sizeof(NORMAL_DRAW_BUFFERS[0]), NORMAL_DRAW_BUFFERS); glClear(GL_COLOR_BUFFER_BIT); @@ -151,126 +143,6 @@ void MetavoxelSystem::render() { // give external parties a chance to join in emit rendering(); - - if (!_needToLight) { - return; // skip lighting if not needed - } - - // perform deferred lighting, rendering to free fbo - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glDisable(GL_BLEND); - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glDepthMask(false); - - QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); - primaryFBO->release(); - - QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); - freeFBO->bind(); - glClear(GL_COLOR_BUFFER_BIT); - - glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); - - // get the viewport side (left, right, both) - int viewport[4]; - glGetIntegerv(GL_VIEWPORT, viewport); - const int VIEWPORT_X_INDEX = 0; - const int VIEWPORT_WIDTH_INDEX = 2; - float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); - float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); - - if (Menu::getInstance()->getShadowsEnabled()) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); - - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); - - ProgramObject* program = &_directionalLightShadowMap; - const LightLocations* locations = &_directionalLightShadowMapLocations; - if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { - program = &_directionalLightCascadedShadowMap; - locations = &_directionalLightCascadedShadowMapLocations; - _directionalLightCascadedShadowMap.bind(); - _directionalLightCascadedShadowMap.setUniform(locations->shadowDistances, - Application::getInstance()->getShadowDistances()); - - } else { - program->bind(); - } - program->setUniformValue(locations->shadowScale, - 1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width()); - - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - Application::getInstance()->computeOffAxisFrustum( - left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - program->setUniformValue(locations->nearLocation, nearVal); - program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); - float nearScale = -1.0f / nearVal; - float sScale = 1.0f / sWidth; - float depthTexCoordScaleS = (right - left) * nearScale * sScale; - program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, - bottom * nearScale); - program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale); - - renderFullscreenQuad(sMin, sMin + sWidth); - - program->release(); - - glBindTexture(GL_TEXTURE_2D, 0); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - - glActiveTexture(GL_TEXTURE1); - - } else { - _directionalLight.bind(); - renderFullscreenQuad(sMin, sMin + sWidth); - _directionalLight.release(); - } - - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - - freeFBO->release(); - - // now transfer the lit region to the primary fbo - glEnable(GL_BLEND); - - primaryFBO->bind(); - - glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); - glEnable(GL_TEXTURE_2D); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - - renderFullscreenQuad(sMin, sMin + sWidth); - - glBindTexture(GL_TEXTURE_2D, 0); - glDisable(GL_TEXTURE_2D); - - glEnable(GL_LIGHTING); - glEnable(GL_DEPTH_TEST); - glDepthMask(true); - - glDisable(GL_ALPHA_TEST); - - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); } class RayHeightfieldIntersectionVisitor : public RayIntersectionVisitor { @@ -630,24 +502,6 @@ void MetavoxelSystem::guideToAugmented(MetavoxelVisitor& visitor, bool render) { } } -void MetavoxelSystem::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) { - program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name); - program.link(); - - program.bind(); - program.setUniformValue("diffuseMap", 0); - program.setUniformValue("normalMap", 1); - program.setUniformValue("depthMap", 2); - program.setUniformValue("shadowMap", 3); - locations.shadowDistances = program.uniformLocation("shadowDistances"); - locations.shadowScale = program.uniformLocation("shadowScale"); - locations.nearLocation = program.uniformLocation("near"); - locations.depthScale = program.uniformLocation("depthScale"); - locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset"); - locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); - program.release(); -} - MetavoxelSystemClient::MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater) : MetavoxelClient(node, updater) { } @@ -1077,8 +931,6 @@ void HeightfieldBuffer::render(bool cursor) { bufferPair.first.release(); bufferPair.second.release(); - - Application::getInstance()->getMetavoxels()->noteNeedToLight(); } QHash HeightfieldBuffer::_bufferPairs; @@ -1245,8 +1097,6 @@ void VoxelBuffer::render(bool cursor) { _vertexBuffer.release(); _indexBuffer.release(); - - Application::getInstance()->getMetavoxels()->noteNeedToLight(); } BufferDataAttribute::BufferDataAttribute(const QString& name) : diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index f3b9a02117..f99a5834c9 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -52,8 +52,6 @@ public: Q_INVOKABLE void deleteTextures(int heightID, int colorID, int textureID); - void noteNeedToLight() { _needToLight = true; } - signals: void rendering(); @@ -66,18 +64,6 @@ private: void guideToAugmented(MetavoxelVisitor& visitor, bool render = false); - class LightLocations { - public: - int shadowDistances; - int shadowScale; - int nearLocation; - int depthScale; - int depthTexCoordOffset; - int depthTexCoordScale; - }; - - static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); - AttributePointer _pointBufferAttribute; AttributePointer _heightfieldBufferAttribute; AttributePointer _voxelBufferAttribute; @@ -85,14 +71,6 @@ private: MetavoxelLOD _lod; QReadWriteLock _lodLock; Frustum _frustum; - bool _needToLight; - - ProgramObject _directionalLight; - LightLocations _directionalLightLocations; - ProgramObject _directionalLightShadowMap; - LightLocations _directionalLightShadowMapLocations; - ProgramObject _directionalLightCascadedShadowMap; - LightLocations _directionalLightCascadedShadowMapLocations; }; /// Describes contents of a point in a point buffer. diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp new file mode 100644 index 0000000000..95df2d5c72 --- /dev/null +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -0,0 +1,163 @@ +// +// DeferredLightingEffect.cpp +// interface/src/renderer +// +// Created by Andrzej Kapolka on 9/11/14. +// Copyright 2014 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 +// + +// include this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL +#include "InterfaceConfig.h" + +#include + +#include "Application.h" +#include "DeferredLightingEffect.h" +#include "RenderUtil.h" + +void DeferredLightingEffect::init() { + loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations); + loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap, + _directionalLightShadowMapLocations); + loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap, + _directionalLightCascadedShadowMapLocations); +} + +void DeferredLightingEffect::render() { + // perform deferred lighting, rendering to free fbo + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glDisable(GL_BLEND); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glDepthMask(false); + + QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); + primaryFBO->release(); + + QOpenGLFramebufferObject* freeFBO = Application::getInstance()->getGlowEffect()->getFreeFramebufferObject(); + freeFBO->bind(); + glClear(GL_COLOR_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); + + // get the viewport side (left, right, both) + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + const int VIEWPORT_X_INDEX = 0; + const int VIEWPORT_WIDTH_INDEX = 2; + float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); + float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); + + if (Menu::getInstance()->getShadowsEnabled()) { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); + + ProgramObject* program = &_directionalLightShadowMap; + const LightLocations* locations = &_directionalLightShadowMapLocations; + if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { + program = &_directionalLightCascadedShadowMap; + locations = &_directionalLightCascadedShadowMapLocations; + _directionalLightCascadedShadowMap.bind(); + _directionalLightCascadedShadowMap.setUniform(locations->shadowDistances, + Application::getInstance()->getShadowDistances()); + + } else { + program->bind(); + } + program->setUniformValue(locations->shadowScale, + 1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width()); + + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; + Application::getInstance()->computeOffAxisFrustum( + left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + program->setUniformValue(locations->nearLocation, nearVal); + program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); + float nearScale = -1.0f / nearVal; + float sScale = 1.0f / sWidth; + float depthTexCoordScaleS = (right - left) * nearScale * sScale; + program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, + bottom * nearScale); + program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale); + + renderFullscreenQuad(sMin, sMin + sWidth); + + program->release(); + + glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE1); + + } else { + _directionalLight.bind(); + renderFullscreenQuad(sMin, sMin + sWidth); + _directionalLight.release(); + } + + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + + freeFBO->release(); + + // now transfer the lit region to the primary fbo + glEnable(GL_BLEND); + + primaryFBO->bind(); + + glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); + glEnable(GL_TEXTURE_2D); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + renderFullscreenQuad(sMin, sMin + sWidth); + + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + + glEnable(GL_LIGHTING); + glEnable(GL_DEPTH_TEST); + glDepthMask(true); + + glDisable(GL_ALPHA_TEST); + + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + +void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) { + program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name); + program.link(); + + program.bind(); + program.setUniformValue("diffuseMap", 0); + program.setUniformValue("normalMap", 1); + program.setUniformValue("depthMap", 2); + program.setUniformValue("shadowMap", 3); + locations.shadowDistances = program.uniformLocation("shadowDistances"); + locations.shadowScale = program.uniformLocation("shadowScale"); + locations.nearLocation = program.uniformLocation("near"); + locations.depthScale = program.uniformLocation("depthScale"); + locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset"); + locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); + program.release(); +} diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h new file mode 100644 index 0000000000..e67b3b9153 --- /dev/null +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -0,0 +1,46 @@ +// +// DeferredLightingEffect.h +// interface/src/renderer +// +// Created by Andrzej Kapolka on 9/11/14. +// Copyright 2014 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 +// + +#ifndef hifi_DeferredLightingEffect_h +#define hifi_DeferredLightingEffect_h + +#include "ProgramObject.h" + +/// Handles deferred lighting for the bits that require it (voxels, metavoxels...) +class DeferredLightingEffect { +public: + + void init(); + void render(); + +private: + + class LightLocations { + public: + int shadowDistances; + int shadowScale; + int nearLocation; + int depthScale; + int depthTexCoordOffset; + int depthTexCoordScale; + }; + + static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); + + ProgramObject _directionalLight; + LightLocations _directionalLightLocations; + ProgramObject _directionalLightShadowMap; + LightLocations _directionalLightShadowMapLocations; + ProgramObject _directionalLightCascadedShadowMap; + LightLocations _directionalLightCascadedShadowMapLocations; +}; + +#endif // hifi_DeferredLightingEffect_h From e6f37544fd556fee686d2d4e472feb05b0b9cffd Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 11 Sep 2014 18:06:56 -0700 Subject: [PATCH 02/43] Use deferred lighting for voxels as well as metavoxels. --- .../shaders/cascaded_shadow_map.frag | 40 ------------ .../shaders/cascaded_shadow_map.vert | 33 ---------- .../resources/shaders/perlin_modulate.frag | 8 ++- .../resources/shaders/perlin_modulate.vert | 8 ++- interface/resources/shaders/shadow_map.frag | 28 --------- interface/resources/shaders/shadow_map.vert | 32 ---------- interface/resources/shaders/voxel.frag | 21 +++++++ interface/resources/shaders/voxel.vert | 26 ++++++++ interface/src/Application.cpp | 4 +- interface/src/MetavoxelSystem.cpp | 28 +++------ .../src/renderer/DeferredLightingEffect.cpp | 9 +++ .../src/renderer/DeferredLightingEffect.h | 2 + interface/src/renderer/TextureCache.cpp | 12 ++++ interface/src/renderer/TextureCache.h | 3 + interface/src/voxels/VoxelSystem.cpp | 62 +++++-------------- interface/src/voxels/VoxelSystem.h | 4 +- 16 files changed, 114 insertions(+), 206 deletions(-) delete mode 100644 interface/resources/shaders/cascaded_shadow_map.frag delete mode 100644 interface/resources/shaders/cascaded_shadow_map.vert delete mode 100644 interface/resources/shaders/shadow_map.frag delete mode 100644 interface/resources/shaders/shadow_map.vert create mode 100644 interface/resources/shaders/voxel.frag create mode 100644 interface/resources/shaders/voxel.vert diff --git a/interface/resources/shaders/cascaded_shadow_map.frag b/interface/resources/shaders/cascaded_shadow_map.frag deleted file mode 100644 index 337f98a228..0000000000 --- a/interface/resources/shaders/cascaded_shadow_map.frag +++ /dev/null @@ -1,40 +0,0 @@ -#version 120 - -// -// cascaded_shadow_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the distances to the cascade sections -uniform vec3 shadowDistances; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the color in shadow -varying vec4 shadowColor; - -// the interpolated position -varying vec4 position; - -void main(void) { - // compute the index of the cascade to use and the corresponding texture coordinates - int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0))); - vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), - dot(gl_EyePlaneR[shadowIndex], position)); - - gl_FragColor = mix(shadowColor, gl_Color, 0.25 * - (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r)); -} diff --git a/interface/resources/shaders/cascaded_shadow_map.vert b/interface/resources/shaders/cascaded_shadow_map.vert deleted file mode 100644 index 68ff95b28a..0000000000 --- a/interface/resources/shaders/cascaded_shadow_map.vert +++ /dev/null @@ -1,33 +0,0 @@ -#version 120 - -// -// cascaded_shadow_map.vert -// vertex shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the color in shadow -varying vec4 shadowColor; - -// the interpolated position -varying vec4 position; - -void main(void) { - // the shadow color includes only the ambient terms - shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient); - - // the normal color includes diffuse - vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position))); - - // generate the shadow texture coordinates using the eye position - position = gl_ModelViewMatrix * gl_Vertex; - - // use the fixed function transform - gl_Position = ftransform(); -} diff --git a/interface/resources/shaders/perlin_modulate.frag b/interface/resources/shaders/perlin_modulate.frag index 23d31ff72e..bce88713d1 100644 --- a/interface/resources/shaders/perlin_modulate.frag +++ b/interface/resources/shaders/perlin_modulate.frag @@ -26,6 +26,9 @@ const float amplitude = 0.5; // the position in model space varying vec3 position; +// the normal in view space +varying vec4 normal; + // gradient based on gradients from cube edge centers rather than random from texture lookup float randomEdgeGrad(int hash, vec3 position){ int h = int(mod(hash, 16)); @@ -114,7 +117,8 @@ void main(void) { // apply vertex lighting vec3 color = gl_Color.rgb * vec3(noise, noise, noise); - gl_FragColor = vec4(color, 1); + gl_FragData[0] = vec4(color, 1); + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); } @@ -156,4 +160,4 @@ float perlin(vec3 location) { mix(mix(ffcv, cfcv, params.x), mix(fccv, cccv, params.x), params.y), params.z); } -*/ \ No newline at end of file +*/ diff --git a/interface/resources/shaders/perlin_modulate.vert b/interface/resources/shaders/perlin_modulate.vert index 428615017a..c5750cedad 100644 --- a/interface/resources/shaders/perlin_modulate.vert +++ b/interface/resources/shaders/perlin_modulate.vert @@ -14,10 +14,12 @@ // the position in model space varying vec3 position; +// the interpolated normal +varying vec4 normal; + void main(void) { position = gl_Vertex.xyz; - vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - gl_FrontColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient + - gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position))); + normal = vec4(gl_NormalMatrix * gl_Normal, 0.0); + gl_FrontColor = gl_Color; gl_Position = ftransform(); } diff --git a/interface/resources/shaders/shadow_map.frag b/interface/resources/shaders/shadow_map.frag deleted file mode 100644 index fa79040ce3..0000000000 --- a/interface/resources/shaders/shadow_map.frag +++ /dev/null @@ -1,28 +0,0 @@ -#version 120 - -// -// shadow_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 11/21/13. -// Copyright 2013 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 -// - -uniform sampler2DShadow shadowMap; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the color in shadow -varying vec4 shadowColor; - -void main(void) { - gl_FragColor = mix(shadowColor, gl_Color, 0.25 * - (shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[0].stp + vec3(shadowScale, shadowScale, 0.0)).r)); -} diff --git a/interface/resources/shaders/shadow_map.vert b/interface/resources/shaders/shadow_map.vert deleted file mode 100644 index 5d2affba98..0000000000 --- a/interface/resources/shaders/shadow_map.vert +++ /dev/null @@ -1,32 +0,0 @@ -#version 120 - -// -// shadow_map.vert -// vertex shader -// -// Created by Andrzej Kapolka on 3/27/14. -// Copyright 2014 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 -// - -// the color in shadow -varying vec4 shadowColor; - -void main(void) { - // the shadow color includes only the ambient terms - shadowColor = gl_Color * (gl_LightModel.ambient + gl_LightSource[0].ambient); - - // the normal color includes diffuse - vec4 normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - gl_FrontColor = shadowColor + gl_Color * (gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position))); - - // generate the shadow texture coordinates using the eye position - vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex; - gl_TexCoord[0] = vec4(dot(gl_EyePlaneS[0], eyePosition), dot(gl_EyePlaneT[0], eyePosition), - dot(gl_EyePlaneR[0], eyePosition), 1.0); - - // use the fixed function transform - gl_Position = ftransform(); -} diff --git a/interface/resources/shaders/voxel.frag b/interface/resources/shaders/voxel.frag new file mode 100644 index 0000000000..2db24bdc95 --- /dev/null +++ b/interface/resources/shaders/voxel.frag @@ -0,0 +1,21 @@ +#version 120 + +// +// voxel.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/11/14. +// Copyright 2014 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 +// + +// the interpolated normal +varying vec4 normal; + +void main(void) { + // store the color and normal directly + gl_FragData[0] = gl_Color; + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); +} diff --git a/interface/resources/shaders/voxel.vert b/interface/resources/shaders/voxel.vert new file mode 100644 index 0000000000..c41b1c1477 --- /dev/null +++ b/interface/resources/shaders/voxel.vert @@ -0,0 +1,26 @@ +#version 120 + +// +// voxel.vert +// vertex shader +// +// Created by Andrzej Kapolka on 9/11/14. +// Copyright 2014 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 +// + +// the interpolated normal +varying vec4 normal; + +void main(void) { + // store the normal for interpolation + normal = vec4(gl_NormalMatrix * gl_Normal, 0.0); + + // use the standard position + gl_Position = ftransform(); + + // store the color directly + gl_FrontColor = gl_Color; +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 17d36380ee..a989df9091 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2842,8 +2842,10 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _audioReflector.render(); } - // Draw voxels + _deferredLightingEffect.prepare(); bool deferredLightingRequired = false; + + // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceTimer perfTimer("voxels"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index b3e31ce56e..b8d56b9653 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -121,23 +121,13 @@ int RenderVisitor::visit(MetavoxelInfo& info) { return STOP_RECURSION; } -const GLenum COLOR_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0 }; -const GLenum NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT1 }; -const GLenum COLOR_NORMAL_DRAW_BUFFERS[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; - void MetavoxelSystem::render() { // update the frustum ViewFrustum* viewFrustum = Application::getInstance()->getDisplayViewFrustum(); _frustum.set(viewFrustum->getFarTopLeft(), viewFrustum->getFarTopRight(), viewFrustum->getFarBottomLeft(), viewFrustum->getFarBottomRight(), viewFrustum->getNearTopLeft(), viewFrustum->getNearTopRight(), viewFrustum->getNearBottomLeft(), viewFrustum->getNearBottomRight()); - - // clear the normal buffer - glDrawBuffers(sizeof(NORMAL_DRAW_BUFFERS) / sizeof(NORMAL_DRAW_BUFFERS[0]), NORMAL_DRAW_BUFFERS); - glClear(GL_COLOR_BUFFER_BIT); - - glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS); - + RenderVisitor renderVisitor(getLOD()); guideToAugmented(renderVisitor, true); @@ -834,7 +824,7 @@ void HeightfieldBuffer::render(bool cursor) { glDrawRangeElements(GL_TRIANGLES, 0, vertexCount - 1, indexCount, GL_UNSIGNED_INT, 0); - glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); glDepthFunc(GL_LEQUAL); glDepthMask(false); @@ -907,7 +897,7 @@ void HeightfieldBuffer::render(bool cursor) { glDepthMask(true); glDepthFunc(GL_LESS); - glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); DefaultMetavoxelRendererImplementation::getBaseHeightfieldProgram().bind(); @@ -936,7 +926,7 @@ void HeightfieldBuffer::render(bool cursor) { QHash HeightfieldBuffer::_bufferPairs; void HeightfieldPreview::render(const glm::vec3& translation, float scale) const { - glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); glDisable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -969,7 +959,7 @@ void HeightfieldPreview::render(const glm::vec3& translation, float scale) const glDisable(GL_CULL_FACE); glEnable(GL_BLEND); - glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); } VoxelBuffer::VoxelBuffer(const QVector& vertices, const QVector& indices, @@ -1017,7 +1007,7 @@ void VoxelBuffer::render(bool cursor) { glDrawRangeElements(GL_QUADS, 0, _vertexCount - 1, _indexCount, GL_UNSIGNED_INT, 0); if (!_materials.isEmpty()) { - glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); glDepthFunc(GL_LEQUAL); glDepthMask(false); @@ -1087,7 +1077,7 @@ void VoxelBuffer::render(bool cursor) { glDepthMask(true); glDepthFunc(GL_LESS); - glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materials); DefaultMetavoxelRendererImplementation::getSplatVoxelProgram().disableAttributeArray(locations.materialWeights); @@ -2132,7 +2122,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox _pointProgram.release(); - glDrawBuffers(sizeof(COLOR_NORMAL_DRAW_BUFFERS) / sizeof(COLOR_NORMAL_DRAW_BUFFERS[0]), COLOR_NORMAL_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); glEnable(GL_CULL_FACE); glEnable(GL_ALPHA_TEST); @@ -2175,7 +2165,7 @@ void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, Metavox glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); - glDrawBuffers(sizeof(COLOR_DRAW_BUFFERS) / sizeof(COLOR_DRAW_BUFFERS[0]), COLOR_DRAW_BUFFERS); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); } void DefaultMetavoxelRendererImplementation::loadSplatProgram(const char* type, diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 95df2d5c72..0e0e4c4615 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -26,6 +26,13 @@ void DeferredLightingEffect::init() { _directionalLightCascadedShadowMapLocations); } +void DeferredLightingEffect::prepare() { + // clear the normal buffer + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true); + glClear(GL_COLOR_BUFFER_BIT); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); +} + void DeferredLightingEffect::render() { // perform deferred lighting, rendering to free fbo glPushMatrix(); @@ -38,6 +45,7 @@ void DeferredLightingEffect::render() { glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); + glDisable(GL_COLOR_MATERIAL); glDepthMask(false); QOpenGLFramebufferObject* primaryFBO = Application::getInstance()->getTextureCache()->getPrimaryFramebufferObject(); @@ -133,6 +141,7 @@ void DeferredLightingEffect::render() { glDisable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); + glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); glDepthMask(true); diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index e67b3b9153..5be7ea1038 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -19,6 +19,8 @@ class DeferredLightingEffect { public: void init(); + + void prepare(); void render(); private: diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index f22e1bf7a5..d97a7c503a 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -242,6 +242,18 @@ GLuint TextureCache::getPrimaryNormalTextureID() { return _primaryNormalTextureID; } +void TextureCache::setPrimaryDrawBuffers(bool color, bool normal) { + GLenum buffers[2]; + int bufferCount = 0; + if (color) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; + } + if (normal) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; + } + glDrawBuffers(bufferCount, buffers); +} + QOpenGLFramebufferObject* TextureCache::getSecondaryFramebufferObject() { if (!_secondaryFramebufferObject) { _secondaryFramebufferObject = createFramebufferObject(); diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index ce0e7661af..964f1f8501 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -64,6 +64,9 @@ public: /// Returns the ID of the primary framebuffer object's normal texture. GLuint getPrimaryNormalTextureID(); + /// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound. + void setPrimaryDrawBuffers(bool color, bool normal); + /// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full /// screen effects. QOpenGLFramebufferObject* getSecondaryFramebufferObject(); diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 77ae4a6ad6..0a05d66d13 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -506,29 +506,13 @@ void VoxelSystem::initVoxelMemory() { _memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels); // create our simple fragment shader if we're the first system to init - if (!_shadowMapProgram.isLinked()) { - _shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/shadow_map.vert"); - _shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/shadow_map.frag"); - _shadowMapProgram.link(); - - _shadowMapProgram.bind(); - _shadowMapProgram.setUniformValue("shadowMap", 0); - _shadowMapProgram.release(); - - _cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/cascaded_shadow_map.vert"); - _cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/cascaded_shadow_map.frag"); - _cascadedShadowMapProgram.link(); - - _cascadedShadowMapProgram.bind(); - _cascadedShadowMapProgram.setUniformValue("shadowMap", 0); - _shadowDistancesLocation = _cascadedShadowMapProgram.uniformLocation("shadowDistances"); - _cascadedShadowMapProgram.release(); + if (!_program.isLinked()) { + _program.addShaderFromSourceFile(QGLShader::Vertex, + Application::resourcesPath() + "shaders/voxel.vert"); + _program.addShaderFromSourceFile(QGLShader::Fragment, + Application::resourcesPath() + "shaders/voxel.frag"); + _program.link(); } - } _renderer = new PrimitiveRenderer(_maxVoxels); @@ -1150,10 +1134,8 @@ glm::vec3 VoxelSystem::computeVoxelVertex(const glm::vec3& startVertex, float vo return startVertex + glm::vec3(identityVertex[0], identityVertex[1], identityVertex[2]) * voxelScale; } +ProgramObject VoxelSystem::_program; ProgramObject VoxelSystem::_perlinModulateProgram; -ProgramObject VoxelSystem::_shadowMapProgram; -ProgramObject VoxelSystem::_cascadedShadowMapProgram; -int VoxelSystem::_shadowDistancesLocation; void VoxelSystem::init() { if (_initialized) { @@ -1478,41 +1460,31 @@ void VoxelSystem::render() { } void VoxelSystem::applyScaleAndBindProgram(bool texture) { - - if (Menu::getInstance()->getShadowsEnabled()) { - if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { - _cascadedShadowMapProgram.bind(); - _cascadedShadowMapProgram.setUniform(_shadowDistancesLocation, Application::getInstance()->getShadowDistances()); - } else { - _shadowMapProgram.bind(); - } - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); - - } else if (texture) { + if (texture) { bindPerlinModulateProgram(); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPermutationNormalTextureID()); + } else { + _program.bind(); } glPushMatrix(); glScalef(_treeScale, _treeScale, _treeScale); + + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true); } void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { // scale back down to 1 so heads aren't massive glPopMatrix(); - if (Menu::getInstance()->getShadowsEnabled()) { - if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { - _cascadedShadowMapProgram.release(); - } else { - _shadowMapProgram.release(); - } - glBindTexture(GL_TEXTURE_2D, 0); - - } else if (texture) { + if (texture) { _perlinModulateProgram.release(); glBindTexture(GL_TEXTURE_2D, 0); + } else { + _program.release(); } + + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); } int VoxelSystem::_nodeCount = 0; diff --git a/interface/src/voxels/VoxelSystem.h b/interface/src/voxels/VoxelSystem.h index 732255cd63..8e60cbe073 100644 --- a/interface/src/voxels/VoxelSystem.h +++ b/interface/src/voxels/VoxelSystem.h @@ -228,10 +228,8 @@ private: bool _voxelsDirty; + static ProgramObject _program; static ProgramObject _perlinModulateProgram; - static ProgramObject _shadowMapProgram; - static ProgramObject _cascadedShadowMapProgram; - static int _shadowDistancesLocation; static void bindPerlinModulateProgram(); From f954e4d7ea4f65a8847261cb57918f8b51123ee8 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 11 Sep 2014 19:06:29 -0700 Subject: [PATCH 03/43] Fix for deferred lighting on voxels. --- interface/resources/shaders/voxel.vert | 2 +- interface/src/renderer/DeferredLightingEffect.cpp | 2 +- interface/src/voxels/VoxelSystem.cpp | 6 +++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/interface/resources/shaders/voxel.vert b/interface/resources/shaders/voxel.vert index c41b1c1477..3cd06eb000 100644 --- a/interface/resources/shaders/voxel.vert +++ b/interface/resources/shaders/voxel.vert @@ -22,5 +22,5 @@ void main(void) { gl_Position = ftransform(); // store the color directly - gl_FrontColor = gl_Color; + gl_FrontColor = vec4(gl_Color.rgb, 0.0); } diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 0e0e4c4615..6c91f1bf05 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -67,7 +67,7 @@ void DeferredLightingEffect::render() { const int VIEWPORT_WIDTH_INDEX = 2; float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); - + if (Menu::getInstance()->getShadowsEnabled()) { glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 0a05d66d13..8d16245962 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -1392,8 +1392,11 @@ void VoxelSystem::render() { applyScaleAndBindProgram(texture); - // for performance, enable backface culling + // for performance, enable backface culling and disable blending glEnable(GL_CULL_FACE); + glDisable(GL_BLEND); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } // draw voxels in 6 passes @@ -1435,6 +1438,7 @@ void VoxelSystem::render() { PerformanceWarning warn(showWarnings, "render().. cleanup after glDrawRangeElementsEXT()..."); glDisable(GL_CULL_FACE); + glEnable(GL_BLEND); removeScaleAndReleaseProgram(texture); From 618f6415dadea3d2d5003cd70b3c35c90d5c5390 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 11 Sep 2014 19:36:37 -0700 Subject: [PATCH 04/43] Working on specular bits for deferred lighting. --- .../src/renderer/DeferredLightingEffect.cpp | 4 +-- interface/src/renderer/TextureCache.cpp | 26 +++++++++++++++++-- interface/src/renderer/TextureCache.h | 6 ++++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 6c91f1bf05..38a92fb153 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -27,8 +27,8 @@ void DeferredLightingEffect::init() { } void DeferredLightingEffect::prepare() { - // clear the normal buffer - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true); + // clear the normal and specular buffers + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); glClear(GL_COLOR_BUFFER_BIT); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); } diff --git a/interface/src/renderer/TextureCache.cpp b/interface/src/renderer/TextureCache.cpp index d97a7c503a..00e9fcd482 100644 --- a/interface/src/renderer/TextureCache.cpp +++ b/interface/src/renderer/TextureCache.cpp @@ -30,6 +30,7 @@ TextureCache::TextureCache() : _blueTextureID(0), _primaryDepthTextureID(0), _primaryNormalTextureID(0), + _primarySpecularTextureID(0), _primaryFramebufferObject(NULL), _secondaryFramebufferObject(NULL), _tertiaryFramebufferObject(NULL), @@ -48,6 +49,7 @@ TextureCache::~TextureCache() { if (_primaryFramebufferObject) { glDeleteTextures(1, &_primaryDepthTextureID); glDeleteTextures(1, &_primaryNormalTextureID); + glDeleteTextures(1, &_primarySpecularTextureID); } if (_primaryFramebufferObject) { @@ -75,6 +77,8 @@ void TextureCache::setFrameBufferSize(QSize frameBufferSize) { _primaryDepthTextureID = 0; glDeleteTextures(1, &_primaryNormalTextureID); _primaryNormalTextureID = 0; + glDeleteTextures(1, &_primarySpecularTextureID); + _primarySpecularTextureID = 0; } if (_secondaryFramebufferObject) { @@ -222,9 +226,18 @@ QOpenGLFramebufferObject* TextureCache::getPrimaryFramebufferObject() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); + glGenTextures(1, &_primarySpecularTextureID); + glBindTexture(GL_TEXTURE_2D, _primarySpecularTextureID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _frameBufferSize.width(), _frameBufferSize.height(), + 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glBindTexture(GL_TEXTURE_2D, 0); + _primaryFramebufferObject->bind(); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _primaryDepthTextureID, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, _primaryNormalTextureID, 0); + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, _primarySpecularTextureID, 0); _primaryFramebufferObject->release(); } return _primaryFramebufferObject; @@ -242,8 +255,13 @@ GLuint TextureCache::getPrimaryNormalTextureID() { return _primaryNormalTextureID; } -void TextureCache::setPrimaryDrawBuffers(bool color, bool normal) { - GLenum buffers[2]; +GLuint TextureCache::getPrimarySpecularTextureID() { + getPrimaryFramebufferObject(); + return _primarySpecularTextureID; +} + +void TextureCache::setPrimaryDrawBuffers(bool color, bool normal, bool specular) { + GLenum buffers[3]; int bufferCount = 0; if (color) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT0; @@ -251,6 +269,9 @@ void TextureCache::setPrimaryDrawBuffers(bool color, bool normal) { if (normal) { buffers[bufferCount++] = GL_COLOR_ATTACHMENT1; } + if (specular) { + buffers[bufferCount++] = GL_COLOR_ATTACHMENT2; + } glDrawBuffers(bufferCount, buffers); } @@ -308,6 +329,7 @@ bool TextureCache::eventFilter(QObject* watched, QEvent* event) { _primaryFramebufferObject = NULL; glDeleteTextures(1, &_primaryDepthTextureID); glDeleteTextures(1, &_primaryNormalTextureID); + glDeleteTextures(1, &_primarySpecularTextureID); } if (_secondaryFramebufferObject && _secondaryFramebufferObject->size() != size) { delete _secondaryFramebufferObject; diff --git a/interface/src/renderer/TextureCache.h b/interface/src/renderer/TextureCache.h index 964f1f8501..be4d16832b 100644 --- a/interface/src/renderer/TextureCache.h +++ b/interface/src/renderer/TextureCache.h @@ -64,8 +64,11 @@ public: /// Returns the ID of the primary framebuffer object's normal texture. GLuint getPrimaryNormalTextureID(); + /// Returns the ID of the primary framebuffer object's specular texture. + GLuint getPrimarySpecularTextureID(); + /// Enables or disables draw buffers on the primary framebuffer. Note: the primary framebuffer must be bound. - void setPrimaryDrawBuffers(bool color, bool normal); + void setPrimaryDrawBuffers(bool color, bool normal = false, bool specular = false); /// Returns a pointer to the secondary framebuffer object, used as an additional render target when performing full /// screen effects. @@ -102,6 +105,7 @@ private: GLuint _primaryDepthTextureID; GLuint _primaryNormalTextureID; + GLuint _primarySpecularTextureID; QOpenGLFramebufferObject* _primaryFramebufferObject; QOpenGLFramebufferObject* _secondaryFramebufferObject; QOpenGLFramebufferObject* _tertiaryFramebufferObject; From 7074d96c040081d523fed9cbe41a65117de1342a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 14:11:56 -0700 Subject: [PATCH 05/43] Working on support for specular components in deferred lights. --- .../resources/shaders/directional_light.frag | 42 ++++++++- ...directional_light_cascaded_shadow_map.frag | 21 ++++- .../shaders/directional_light_shadow_map.frag | 21 ++++- .../src/renderer/DeferredLightingEffect.cpp | 85 ++++++++++--------- 4 files changed, 121 insertions(+), 48 deletions(-) diff --git a/interface/resources/shaders/directional_light.frag b/interface/resources/shaders/directional_light.frag index 7fb5d83719..5c76fd3ff4 100644 --- a/interface/resources/shaders/directional_light.frag +++ b/interface/resources/shaders/directional_light.frag @@ -17,10 +17,44 @@ uniform sampler2D diffuseMap; // the normal texture uniform sampler2D normalMap; +// the specular texture +uniform sampler2D specularMap; + +// the depth texture +uniform sampler2D depthMap; + +// the distance to the near clip plane +uniform float near; + +// scale factor for depth: (far - near) / far +uniform float depthScale; + +// offset for depth texture coordinates +uniform vec2 depthTexCoordOffset; + +// scale for depth texture coordinates +uniform vec2 depthTexCoordScale; + void main(void) { - // compute the base color based on OpenGL lighting model + // compute the view space position using the depth + float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0); + vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 0.0); + + // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - gl_FragColor = vec4((texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor + - gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * max(0.0, dot(normal * 2.0 - - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position)))).rgb, normal.a); + vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + + // compute the base color based on OpenGL lighting model + float diffuse = dot(normalizedNormal, gl_LightSource[0].position); + float facingLight = step(0.0, diffuse); + vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor + + gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); + + // compute the specular multiplier (sans exponent) + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(position)), + normalizedNormal)); + + // add specular contribution + vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); } diff --git a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag index d16467520e..054b505f8e 100644 --- a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag +++ b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the normal texture uniform sampler2D normalMap; +// the specular texture +uniform sampler2D specularMap; + // the depth texture uniform sampler2D depthMap; @@ -51,15 +54,27 @@ void main(void) { vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), dot(gl_EyePlaneR[shadowIndex], position)); - // compute the color based on OpenGL lighting model, use the alpha from the normal map + // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position); + vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + + // average values from the shadow map + float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); + + // compute the base color based on OpenGL lighting model vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); - gl_FragColor = vec4(baseColor.rgb, normal.a); + + // compute the specular multiplier (sans exponent) + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), + normalizedNormal)); + + // add specular contribution + vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); } diff --git a/interface/resources/shaders/directional_light_shadow_map.frag b/interface/resources/shaders/directional_light_shadow_map.frag index d4ac254fc5..b167d58b2a 100644 --- a/interface/resources/shaders/directional_light_shadow_map.frag +++ b/interface/resources/shaders/directional_light_shadow_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the normal texture uniform sampler2D normalMap; +// the specular texture +uniform sampler2D specularMap; + // the depth texture uniform sampler2D depthMap; @@ -46,15 +49,27 @@ void main(void) { // compute the corresponding texture coordinates vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position)); - // compute the color based on OpenGL lighting model, use the alpha from the normal map + // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - float diffuse = dot(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0), gl_LightSource[0].position); + vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + + // average values from the shadow map + float diffuse = dot(normalizedNormal, gl_LightSource[0].position); float facingLight = step(0.0, diffuse) * 0.25 * (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); + + // compute the base color based on OpenGL lighting model vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + gl_FrontLightProduct[0].diffuse * (diffuse * facingLight)); - gl_FragColor = vec4(baseColor.rgb, normal.a); + + // compute the specular multiplier (sans exponent) + float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), + normalizedNormal)); + + // add specular contribution + vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); } diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 38a92fb153..7fd53af70a 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -60,6 +60,12 @@ void DeferredLightingEffect::render() { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimarySpecularTextureID()); + + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); + // get the viewport side (left, right, both) int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); @@ -68,15 +74,15 @@ void DeferredLightingEffect::render() { float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); - if (Menu::getInstance()->getShadowsEnabled()) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); - - glActiveTexture(GL_TEXTURE3); + ProgramObject* program = &_directionalLight; + const LightLocations* locations = &_directionalLightLocations; + bool shadowsEnabled = Menu::getInstance()->getShadowsEnabled(); + if (shadowsEnabled) { + glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); - ProgramObject* program = &_directionalLightShadowMap; - const LightLocations* locations = &_directionalLightShadowMapLocations; + program = &_directionalLightShadowMap; + locations = &_directionalLightShadowMapLocations; if (Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows)) { program = &_directionalLightCascadedShadowMap; locations = &_directionalLightCascadedShadowMapLocations; @@ -90,38 +96,42 @@ void DeferredLightingEffect::render() { program->setUniformValue(locations->shadowScale, 1.0f / Application::getInstance()->getTextureCache()->getShadowFramebufferObject()->width()); - float left, right, bottom, top, nearVal, farVal; - glm::vec4 nearClipPlane, farClipPlane; - Application::getInstance()->computeOffAxisFrustum( - left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); - program->setUniformValue(locations->nearLocation, nearVal); - program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); - float nearScale = -1.0f / nearVal; - float sScale = 1.0f / sWidth; - float depthTexCoordScaleS = (right - left) * nearScale * sScale; - program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, - bottom * nearScale); - program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale); - - renderFullscreenQuad(sMin, sMin + sWidth); - - program->release(); - - glBindTexture(GL_TEXTURE_2D, 0); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - - glActiveTexture(GL_TEXTURE1); - } else { - _directionalLight.bind(); - renderFullscreenQuad(sMin, sMin + sWidth); - _directionalLight.release(); + program->bind(); + } + + float left, right, bottom, top, nearVal, farVal; + glm::vec4 nearClipPlane, farClipPlane; + Application::getInstance()->computeOffAxisFrustum( + left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + program->setUniformValue(locations->nearLocation, nearVal); + program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); + float nearScale = -1.0f / nearVal; + float sScale = 1.0f / sWidth; + float depthTexCoordScaleS = (right - left) * nearScale * sScale; + program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, + bottom * nearScale); + program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale); + + renderFullscreenQuad(sMin, sMin + sWidth); + + program->release(); + + if (shadowsEnabled) { + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE3); } glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); freeFBO->release(); @@ -145,8 +155,6 @@ void DeferredLightingEffect::render() { glEnable(GL_DEPTH_TEST); glDepthMask(true); - glDisable(GL_ALPHA_TEST); - glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -160,8 +168,9 @@ void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& p program.bind(); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); - program.setUniformValue("depthMap", 2); - program.setUniformValue("shadowMap", 3); + program.setUniformValue("specularMap", 2); + program.setUniformValue("depthMap", 3); + program.setUniformValue("shadowMap", 4); locations.shadowDistances = program.uniformLocation("shadowDistances"); locations.shadowScale = program.uniformLocation("shadowScale"); locations.nearLocation = program.uniformLocation("near"); From 53933fc9c6316462dff39602e14b1462d6485bb0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 17:09:07 -0700 Subject: [PATCH 06/43] Working on deferred lighting for models. --- interface/resources/shaders/model.frag | 36 +-- interface/resources/shaders/model.vert | 12 - .../shaders/model_cascaded_shadow_map.frag | 71 ---- .../model_cascaded_shadow_normal_map.frag | 84 ----- ...l_cascaded_shadow_normal_specular_map.frag | 87 ----- .../model_cascaded_shadow_specular_map.frag | 74 ----- .../resources/shaders/model_normal_map.frag | 38 +-- .../resources/shaders/model_normal_map.vert | 11 +- .../shaders/model_normal_specular_map.frag | 39 +-- .../resources/shaders/model_shadow_map.frag | 63 ---- .../shaders/model_shadow_normal_map.frag | 75 ----- .../model_shadow_normal_specular_map.frag | 78 ----- .../shaders/model_shadow_specular_map.frag | 66 ---- .../resources/shaders/model_specular_map.frag | 38 +-- interface/resources/shaders/skin_model.vert | 11 +- .../shaders/skin_model_normal_map.vert | 12 +- interface/src/Application.cpp | 16 +- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/avatar/Avatar.cpp | 5 +- interface/src/avatar/Head.cpp | 3 +- interface/src/avatar/MyAvatar.cpp | 5 +- interface/src/renderer/Model.cpp | 305 ++---------------- interface/src/renderer/Model.h | 58 +--- 24 files changed, 68 insertions(+), 1121 deletions(-) delete mode 100644 interface/resources/shaders/model_cascaded_shadow_map.frag delete mode 100644 interface/resources/shaders/model_cascaded_shadow_normal_map.frag delete mode 100644 interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag delete mode 100644 interface/resources/shaders/model_cascaded_shadow_specular_map.frag delete mode 100644 interface/resources/shaders/model_shadow_map.frag delete mode 100644 interface/resources/shaders/model_shadow_normal_map.frag delete mode 100644 interface/resources/shaders/model_shadow_normal_specular_map.frag delete mode 100644 interface/resources/shaders/model_shadow_specular_map.frag diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index d8e1efab14..70949c48b4 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -11,43 +11,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - // the diffuse texture uniform sampler2D diffuseMap; -// the interpolated position -varying vec4 position; - // the interpolated normal varying vec4 normal; void main(void) { - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); + // set the diffuse, normal, specular data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 255.0); } diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 13eee2fa3d..4e7de7723d 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -11,31 +11,19 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -const int MAX_LOCAL_LIGHTS = 4; - -// the interpolated position -varying vec4 position; - // the interpolated normal varying vec4 normal; void main(void) { - // transform and store the normal for interpolation normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - // likewise with the position - position = gl_ModelViewMatrix * gl_Vertex; - // pass along the vertex color gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - // and the shadow texture coordinates - gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0); - // use standard pipeline transform gl_Position = ftransform(); } diff --git a/interface/resources/shaders/model_cascaded_shadow_map.frag b/interface/resources/shaders/model_cascaded_shadow_map.frag deleted file mode 100644 index 63500e7e2a..0000000000 --- a/interface/resources/shaders/model_cascaded_shadow_map.frag +++ /dev/null @@ -1,71 +0,0 @@ -#version 120 - -// -// model_cascaded_shadow_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the distances to the cascade sections -uniform vec3 shadowDistances; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 position; - -// the interpolated normal -varying vec4 normal; - -void main(void) { - // compute the index of the cascade to use and the corresponding texture coordinates - int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0))); - vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), - dot(gl_EyePlaneR[shadowIndex], position)); - - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); -} diff --git a/interface/resources/shaders/model_cascaded_shadow_normal_map.frag b/interface/resources/shaders/model_cascaded_shadow_normal_map.frag deleted file mode 100644 index 1fef1ef82a..0000000000 --- a/interface/resources/shaders/model_cascaded_shadow_normal_map.frag +++ /dev/null @@ -1,84 +0,0 @@ -#version 120 - -// -// model_cascaded_shadow_normal_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the normal map texture -uniform sampler2D normalMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the distances to the cascade sections -uniform vec3 shadowDistances; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 interpolatedPosition; - -// the interpolated normal -varying vec4 interpolatedNormal; - -// the interpolated tangent -varying vec4 interpolatedTangent; - -void main(void) { - vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); - vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // compute the index of the cascade to use and the corresponding texture coordinates - int shadowIndex = int(dot(step(vec3(interpolatedPosition.z), shadowDistances), vec3(1.0, 1.0, 1.0))); - vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], interpolatedPosition), - dot(gl_EyePlaneT[shadowIndex], interpolatedPosition), - dot(gl_EyePlaneR[shadowIndex], interpolatedPosition)); - - // add up the local lights - vec4 viewNormal = vec4(normalizedTangent * localNormal.x + - normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); -} diff --git a/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag b/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag deleted file mode 100644 index f0751bcca9..0000000000 --- a/interface/resources/shaders/model_cascaded_shadow_normal_specular_map.frag +++ /dev/null @@ -1,87 +0,0 @@ -#version 120 - -// -// model_cascaded_shadow_normal_specular_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the normal map texture -uniform sampler2D normalMap; - -// the specular map texture -uniform sampler2D specularMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the distances to the cascade sections -uniform vec3 shadowDistances; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 interpolatedPosition; - -// the interpolated normal -varying vec4 interpolatedNormal; - -// the interpolated tangent -varying vec4 interpolatedTangent; - -void main(void) { - vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); - vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // compute the index of the cascade to use and the corresponding texture coordinates - int shadowIndex = int(dot(step(vec3(interpolatedPosition.z), shadowDistances), vec3(1.0, 1.0, 1.0))); - vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], interpolatedPosition), - dot(gl_EyePlaneT[shadowIndex], interpolatedPosition), - dot(gl_EyePlaneR[shadowIndex], interpolatedPosition)); - - // add up the local lights - vec4 viewNormal = vec4(normalizedTangent * localNormal.x + - normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, shadowTexCoord + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); -} diff --git a/interface/resources/shaders/model_cascaded_shadow_specular_map.frag b/interface/resources/shaders/model_cascaded_shadow_specular_map.frag deleted file mode 100644 index b2881e6c13..0000000000 --- a/interface/resources/shaders/model_cascaded_shadow_specular_map.frag +++ /dev/null @@ -1,74 +0,0 @@ -#version 120 - -// -// model_cascaded_shadow_specular_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/29/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the specular texture -uniform sampler2D specularMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the distances to the cascade sections -uniform vec3 shadowDistances; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position in view space -varying vec4 position; - -// the interpolated normal -varying vec4 normal; - -void main(void) { - // compute the index of the cascade to use and the corresponding texture coordinates - int shadowIndex = int(dot(step(vec3(position.z), shadowDistances), vec3(1.0, 1.0, 1.0))); - vec3 shadowTexCoord = vec3(dot(gl_EyePlaneS[shadowIndex], position), dot(gl_EyePlaneT[shadowIndex], position), - dot(gl_EyePlaneR[shadowIndex], position)); - - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); -} diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 73d2fc0ef6..5ec3513fb5 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -11,24 +11,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - // the diffuse texture uniform sampler2D diffuseMap; // the normal map texture uniform sampler2D normalMap; -// the interpolated position -varying vec4 interpolatedPosition; - // the interpolated normal varying vec4 interpolatedNormal; @@ -36,30 +24,16 @@ varying vec4 interpolatedNormal; varying vec4 interpolatedTangent; void main(void) { + // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // add up the local lights + vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); + // set the diffuse, normal, specular data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 255.0); } diff --git a/interface/resources/shaders/model_normal_map.vert b/interface/resources/shaders/model_normal_map.vert index 2a2f4156f0..add76d5588 100644 --- a/interface/resources/shaders/model_normal_map.vert +++ b/interface/resources/shaders/model_normal_map.vert @@ -14,9 +14,6 @@ // the tangent vector attribute vec3 tangent; -// the interpolated position -varying vec4 interpolatedPosition; - // the interpolated normal varying vec4 interpolatedNormal; @@ -24,9 +21,7 @@ varying vec4 interpolatedNormal; varying vec4 interpolatedTangent; void main(void) { - - // transform and store the position, normal and tangent for interpolation - interpolatedPosition = gl_ModelViewMatrix * gl_Vertex; + // transform and store the normal and tangent for interpolation interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0); interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); @@ -36,10 +31,6 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - // and the shadow texture coordinates - gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], interpolatedPosition), dot(gl_EyePlaneT[0], interpolatedPosition), - dot(gl_EyePlaneR[0], interpolatedPosition), 1.0); - // use standard pipeline transform gl_Position = ftransform(); } diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index 5eb804292c..d43d69d1e6 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -11,15 +11,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - // the diffuse texture uniform sampler2D diffuseMap; @@ -29,9 +20,6 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; -// the interpolated position -varying vec4 interpolatedPosition; - // the interpolated normal varying vec4 interpolatedNormal; @@ -39,30 +27,17 @@ varying vec4 interpolatedNormal; varying vec4 interpolatedTangent; void main(void) { + // compute the view normal from the various bits vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // add up the local lights + vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); + // set the diffuse, normal, specular data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, + gl_FrontMaterial.shininess / 255.0); } diff --git a/interface/resources/shaders/model_shadow_map.frag b/interface/resources/shaders/model_shadow_map.frag deleted file mode 100644 index 807a9d162f..0000000000 --- a/interface/resources/shaders/model_shadow_map.frag +++ /dev/null @@ -1,63 +0,0 @@ -#version 120 - -// -// model_shadow_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/23/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 position; - -// the interpolated normal -varying vec4 normal; - -void main(void) { - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); -} diff --git a/interface/resources/shaders/model_shadow_normal_map.frag b/interface/resources/shaders/model_shadow_normal_map.frag deleted file mode 100644 index 454b88dd23..0000000000 --- a/interface/resources/shaders/model_shadow_normal_map.frag +++ /dev/null @@ -1,75 +0,0 @@ -#version 120 - -// -// model_shadow_normal_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/23/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the normal map texture -uniform sampler2D normalMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 interpolatedPosition; - -// the interpolated normal -varying vec4 interpolatedNormal; - -// the interpolated tangent -varying vec4 interpolatedTangent; - -void main(void) { - vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); - vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // add up the local lights - vec4 viewNormal = vec4(normalizedTangent * localNormal.x + - normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(vec3(interpolatedPosition), 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + - vec4(pow(specular, gl_FrontMaterial.shininess) * gl_FrontLightProduct[0].specular.rgb, 0.0); -} diff --git a/interface/resources/shaders/model_shadow_normal_specular_map.frag b/interface/resources/shaders/model_shadow_normal_specular_map.frag deleted file mode 100644 index 8283d10b93..0000000000 --- a/interface/resources/shaders/model_shadow_normal_specular_map.frag +++ /dev/null @@ -1,78 +0,0 @@ -#version 120 - -// -// model_shadow_normal_specular_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/23/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the normal map texture -uniform sampler2D normalMap; - -// the specular map texture -uniform sampler2D specularMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position -varying vec4 interpolatedPosition; - -// the interpolated normal -varying vec4 interpolatedNormal; - -// the interpolated tangent -varying vec4 interpolatedTangent; - -void main(void) { - vec3 normalizedNormal = normalize(vec3(interpolatedNormal)); - vec3 normalizedTangent = normalize(vec3(interpolatedTangent)); - vec3 normalizedBitangent = normalize(cross(normalizedNormal, normalizedTangent)); - vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) * 2.0 - vec3(1.0, 1.0, 1.0); - - // add up the local lights - vec4 viewNormal = vec4(normalizedTangent * localNormal.x + - normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(viewNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(viewNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - - normalize(vec4(interpolatedPosition.xyz, 0.0))), viewNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); -} diff --git a/interface/resources/shaders/model_shadow_specular_map.frag b/interface/resources/shaders/model_shadow_specular_map.frag deleted file mode 100644 index f30f3d7b06..0000000000 --- a/interface/resources/shaders/model_shadow_specular_map.frag +++ /dev/null @@ -1,66 +0,0 @@ -#version 120 - -// -// model_shadow_specular_map.frag -// fragment shader -// -// Created by Andrzej Kapolka on 5/23/14. -// Copyright 2014 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 -// - -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - -// the diffuse texture -uniform sampler2D diffuseMap; - -// the specular texture -uniform sampler2D specularMap; - -// the shadow texture -uniform sampler2DShadow shadowMap; - -// the inverse of the size of the shadow map -const float shadowScale = 1.0 / 2048.0; - -// the interpolated position in view space -varying vec4 position; - -// the interpolated normal -varying vec4 normal; - -void main(void) { - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse) * 0.25 * - (shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(-shadowScale, shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, -shadowScale, 0.0)).r + - shadow2D(shadowMap, gl_TexCoord[1].stp + vec3(shadowScale, shadowScale, 0.0)).r); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); -} diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 824746d575..63c1ccc17b 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -11,47 +11,19 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// the maximum number of local lights to apply -const int MAX_LOCAL_LIGHTS = 2; - -// the color of each local light -uniform vec4 localLightColors[MAX_LOCAL_LIGHTS]; - -// the direction of each local light -uniform vec4 localLightDirections[MAX_LOCAL_LIGHTS]; - // the diffuse texture uniform sampler2D diffuseMap; // the specular texture uniform sampler2D specularMap; -// the interpolated position in view space -varying vec4 position; - // the interpolated normal varying vec4 normal; void main(void) { - // add up the local lights - vec4 normalizedNormal = normalize(normal); - vec4 localLight = vec4(0.0, 0.0, 0.0, 0.0); - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - localLight += localLightColors[i] * max(0.0, dot(normalizedNormal, localLightDirections[i])); - } - - // compute the base color based on OpenGL lighting model - float diffuse = dot(normalizedNormal, gl_LightSource[0].position); - float facingLight = step(0.0, diffuse); - vec4 base = gl_Color * (gl_FrontLightModelProduct.sceneColor + gl_FrontLightProduct[0].ambient + - gl_FrontLightProduct[0].diffuse * (diffuse * facingLight) + localLight); - - // compute the specular component (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position - normalize(vec4(position.xyz, 0.0))), - normalizedNormal)); - - // modulate texture by base color and add specular contribution - gl_FragColor = base * texture2D(diffuseMap, gl_TexCoord[0].st) + vec4(pow(specular, gl_FrontMaterial.shininess) * - gl_FrontLightProduct[0].specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, 0.0); - + // set the diffuse, normal, specular data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, + gl_FrontMaterial.shininess / 255.0); } diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 943daf9061..4c2c3456d6 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -19,14 +19,11 @@ uniform mat4 clusterMatrices[MAX_CLUSTERS]; attribute vec4 clusterIndices; attribute vec4 clusterWeights; -// the interpolated position -varying vec4 position; - // the interpolated normal varying vec4 normal; void main(void) { - position = vec4(0.0, 0.0, 0.0, 0.0); + vec4 position = vec4(0.0, 0.0, 0.0, 0.0); normal = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { mat4 clusterMatrix = clusterMatrices[int(clusterIndices[i])]; @@ -35,7 +32,6 @@ void main(void) { normal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; } - position = gl_ModelViewMatrix * position; normal = normalize(gl_ModelViewMatrix * normal); // pass along the vertex color @@ -44,8 +40,5 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - // and the shadow texture coordinates - gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], position), dot(gl_EyePlaneT[0], position), dot(gl_EyePlaneR[0], position), 1.0); - - gl_Position = gl_ProjectionMatrix * position; + gl_Position = gl_ModelViewProjectionMatrix * position; } diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index 66cc7c0f58..87622936af 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -22,9 +22,6 @@ attribute vec3 tangent; attribute vec4 clusterIndices; attribute vec4 clusterWeights; -// the interpolated position -varying vec4 interpolatedPosition; - // the interpolated normal varying vec4 interpolatedNormal; @@ -32,7 +29,7 @@ varying vec4 interpolatedNormal; varying vec4 interpolatedTangent; void main(void) { - interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0); + vec4 interpolatedPosition = vec4(0.0, 0.0, 0.0, 0.0); interpolatedNormal = vec4(0.0, 0.0, 0.0, 0.0); interpolatedTangent = vec4(0.0, 0.0, 0.0, 0.0); for (int i = 0; i < INDICES_PER_VERTEX; i++) { @@ -42,7 +39,6 @@ void main(void) { interpolatedNormal += clusterMatrix * vec4(gl_Normal, 0.0) * clusterWeight; interpolatedTangent += clusterMatrix * vec4(tangent, 0.0) * clusterWeight; } - interpolatedPosition = gl_ModelViewMatrix * interpolatedPosition; interpolatedNormal = gl_ModelViewMatrix * interpolatedNormal; interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; @@ -52,9 +48,5 @@ void main(void) { // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; - // and the shadow texture coordinates - gl_TexCoord[1] = vec4(dot(gl_EyePlaneS[0], interpolatedPosition), dot(gl_EyePlaneT[0], interpolatedPosition), - dot(gl_EyePlaneR[0], interpolatedPosition), 1.0); - - gl_Position = gl_ProjectionMatrix * interpolatedPosition; + gl_Position = gl_ModelViewProjectionMatrix * interpolatedPosition; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3b85e81ea8..c657471f40 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2834,6 +2834,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); + _deferredLightingEffect.prepare(); + if (!selfAvatarOnly) { // draw a red sphere float originSphereRadius = 0.05f; @@ -2851,16 +2853,12 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _audioReflector.render(); } - _deferredLightingEffect.prepare(); - bool deferredLightingRequired = false; - // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceTimer perfTimer("voxels"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... voxels..."); _voxels.render(); - deferredLightingRequired = true; } // also, metavoxels @@ -2869,11 +2867,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... metavoxels..."); _metavoxels.render(); - deferredLightingRequired = true; - } - - if (deferredLightingRequired) { - _deferredLightingEffect.render(); } if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { @@ -2926,6 +2919,11 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } + { + PerformanceTimer perfTimer("lighting"); + _deferredLightingEffect.render(); + } + if (!selfAvatarOnly) { // Render the world box if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) && diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 87290a3e64..d1ea76687c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -361,7 +361,6 @@ Menu::Menu() : shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, "None", 0, true)); shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::SimpleShadows, 0, false)); shadowGroup->addAction(addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::CascadedShadows, 0, false)); - addCheckableActionToQMenuAndActionHash(shadowMenu, MenuOption::AvatarsReceiveShadows, 0, true); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Stars, Qt::Key_Asterisk, true); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index b43e7cb75e..be349a1b26 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -346,7 +346,6 @@ namespace MenuOption { const QString AudioSourcePinkNoise = "Pink Noise"; const QString AudioSourceSine440 = "Sine 440hz"; const QString Avatars = "Avatars"; - const QString AvatarsReceiveShadows = "Avatars Receive Shadows"; const QString Bandwidth = "Bandwidth Display"; const QString BandwidthDetails = "Bandwidth Details"; const QString BlueSpeechSphere = "Blue Sphere While Speaking"; diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index c7d69cff7a..b9f4a9be42 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -495,7 +495,7 @@ void Avatar::renderBody(RenderMode renderMode, float glowLevel) { return; } - _skeletonModel.render(1.0f, modelRenderMode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows)); + _skeletonModel.render(1.0f, modelRenderMode); renderAttachments(renderMode); getHand()->render(false, modelRenderMode); } @@ -541,9 +541,8 @@ void Avatar::simulateAttachments(float deltaTime) { void Avatar::renderAttachments(RenderMode renderMode) { Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - bool receiveShadows = Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows); foreach (Model* model, _attachmentModels) { - model->render(1.0f, modelRenderMode, receiveShadows); + model->render(1.0f, modelRenderMode); } } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index b226b8ed31..244983fd17 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -184,8 +184,7 @@ void Head::relaxLean(float deltaTime) { } void Head::render(float alpha, Model::RenderMode mode) { - if (_faceModel.render(alpha, mode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows)) && - _renderLookatVectors && mode != Model::SHADOW_RENDER_MODE) { + if (_faceModel.render(alpha, mode) && _renderLookatVectors && mode != Model::SHADOW_RENDER_MODE) { renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 48d58fb02c..396aadfa6e 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1054,7 +1054,7 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) { // Render the body's voxels and head Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - _skeletonModel.render(1.0f, modelRenderMode, Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows)); + _skeletonModel.render(1.0f, modelRenderMode); renderAttachments(renderMode); // Render head so long as the camera isn't inside it @@ -1843,11 +1843,10 @@ void MyAvatar::renderAttachments(RenderMode renderMode) { QString headJointName = (geometry.headJointIndex == -1) ? QString() : geometry.joints.at(geometry.headJointIndex).name; Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - bool receiveShadows = Menu::getInstance()->isOptionChecked(MenuOption::AvatarsReceiveShadows); for (int i = 0; i < _attachmentData.size(); i++) { const QString& jointName = _attachmentData.at(i).jointName; if (jointName != headJointName && jointName != "Head") { - _attachmentModels.at(i)->render(1.0f, modelRenderMode, receiveShadows); + _attachmentModels.at(i)->render(1.0f, modelRenderMode); } } } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 0b16688056..8618af3bec 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -78,16 +78,6 @@ ProgramObject Model::_normalMapProgram; ProgramObject Model::_specularMapProgram; ProgramObject Model::_normalSpecularMapProgram; -ProgramObject Model::_shadowMapProgram; -ProgramObject Model::_shadowNormalMapProgram; -ProgramObject Model::_shadowSpecularMapProgram; -ProgramObject Model::_shadowNormalSpecularMapProgram; - -ProgramObject Model::_cascadedShadowMapProgram; -ProgramObject Model::_cascadedShadowNormalMapProgram; -ProgramObject Model::_cascadedShadowSpecularMapProgram; -ProgramObject Model::_cascadedShadowNormalSpecularMapProgram; - ProgramObject Model::_shadowProgram; ProgramObject Model::_skinProgram; @@ -95,43 +85,17 @@ ProgramObject Model::_skinNormalMapProgram; ProgramObject Model::_skinSpecularMapProgram; ProgramObject Model::_skinNormalSpecularMapProgram; -ProgramObject Model::_skinShadowMapProgram; -ProgramObject Model::_skinShadowNormalMapProgram; -ProgramObject Model::_skinShadowSpecularMapProgram; -ProgramObject Model::_skinShadowNormalSpecularMapProgram; - -ProgramObject Model::_skinCascadedShadowMapProgram; -ProgramObject Model::_skinCascadedShadowNormalMapProgram; -ProgramObject Model::_skinCascadedShadowSpecularMapProgram; -ProgramObject Model::_skinCascadedShadowNormalSpecularMapProgram; - ProgramObject Model::_skinShadowProgram; Model::Locations Model::_locations; Model::Locations Model::_normalMapLocations; Model::Locations Model::_specularMapLocations; Model::Locations Model::_normalSpecularMapLocations; -Model::Locations Model::_shadowMapLocations; -Model::Locations Model::_shadowNormalMapLocations; -Model::Locations Model::_shadowSpecularMapLocations; -Model::Locations Model::_shadowNormalSpecularMapLocations; -Model::Locations Model::_cascadedShadowMapLocations; -Model::Locations Model::_cascadedShadowNormalMapLocations; -Model::Locations Model::_cascadedShadowSpecularMapLocations; -Model::Locations Model::_cascadedShadowNormalSpecularMapLocations; - + Model::SkinLocations Model::_skinLocations; Model::SkinLocations Model::_skinNormalMapLocations; Model::SkinLocations Model::_skinSpecularMapLocations; Model::SkinLocations Model::_skinNormalSpecularMapLocations; -Model::SkinLocations Model::_skinShadowMapLocations; -Model::SkinLocations Model::_skinShadowNormalMapLocations; -Model::SkinLocations Model::_skinShadowSpecularMapLocations; -Model::SkinLocations Model::_skinShadowNormalSpecularMapLocations; -Model::SkinLocations Model::_skinCascadedShadowMapLocations; -Model::SkinLocations Model::_skinCascadedShadowNormalMapLocations; -Model::SkinLocations Model::_skinCascadedShadowSpecularMapLocations; -Model::SkinLocations Model::_skinCascadedShadowNormalSpecularMapLocations; Model::SkinLocations Model::_skinShadowLocations; void Model::setScale(const glm::vec3& scale) { @@ -164,23 +128,17 @@ void Model::setOffset(const glm::vec3& offset) { _snappedToRegistrationPoint = false; } -void Model::initProgram(ProgramObject& program, Model::Locations& locations, - int specularTextureUnit, int shadowTextureUnit) { +void Model::initProgram(ProgramObject& program, Model::Locations& locations, int specularTextureUnit) { program.bind(); locations.tangent = program.attributeLocation("tangent"); - locations.shadowDistances = program.uniformLocation("shadowDistances"); - locations.localLightColors = program.uniformLocation("localLightColors"); - locations.localLightDirections = program.uniformLocation("localLightDirections"); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); program.setUniformValue("specularMap", specularTextureUnit); - program.setUniformValue("shadowMap", shadowTextureUnit); program.release(); } -void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations, - int specularTextureUnit, int shadowTextureUnit) { - initProgram(program, locations, specularTextureUnit, shadowTextureUnit); +void Model::initSkinProgram(ProgramObject& program, Model::SkinLocations& locations, int specularTextureUnit) { + initProgram(program, locations, specularTextureUnit); program.bind(); locations.clusterMatrices = program.uniformLocation("clusterMatrices"); @@ -253,78 +211,11 @@ void Model::init() { initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations, 2); - - _shadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model.vert"); - _shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/model_shadow_map.frag"); - _shadowMapProgram.link(); - - initProgram(_shadowMapProgram, _shadowMapLocations); - - _shadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model_normal_map.vert"); - _shadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_normal_map.frag"); - _shadowNormalMapProgram.link(); - - initProgram(_shadowNormalMapProgram, _shadowNormalMapLocations, 1, 2); - - _shadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model.vert"); - _shadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_specular_map.frag"); - _shadowSpecularMapProgram.link(); - - initProgram(_shadowSpecularMapProgram, _shadowSpecularMapLocations, 1, 2); - - _shadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model_normal_map.vert"); - _shadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_normal_specular_map.frag"); - _shadowNormalSpecularMapProgram.link(); - - initProgram(_shadowNormalSpecularMapProgram, _shadowNormalSpecularMapLocations, 2, 3); - - - _cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/model.vert"); - _cascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/model_cascaded_shadow_map.frag"); - _cascadedShadowMapProgram.link(); - - initProgram(_cascadedShadowMapProgram, _cascadedShadowMapLocations); - - _cascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model_normal_map.vert"); - _cascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_map.frag"); - _cascadedShadowNormalMapProgram.link(); - - initProgram(_cascadedShadowNormalMapProgram, _cascadedShadowNormalMapLocations, 1, 2); - - _cascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model.vert"); - _cascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_specular_map.frag"); - _cascadedShadowSpecularMapProgram.link(); - - initProgram(_cascadedShadowSpecularMapProgram, _cascadedShadowSpecularMapLocations, 1, 2); - - _cascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/model_normal_map.vert"); - _cascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_specular_map.frag"); - _cascadedShadowNormalSpecularMapProgram.link(); - - initProgram(_cascadedShadowNormalSpecularMapProgram, _cascadedShadowNormalSpecularMapLocations, 2, 3); - - _shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert"); _shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_shadow.frag"); _shadowProgram.link(); - _skinProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model.vert"); _skinProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model.frag"); _skinProgram.link(); @@ -355,73 +246,6 @@ void Model::init() { initSkinProgram(_skinNormalSpecularMapProgram, _skinNormalSpecularMapLocations, 2); - - _skinShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/skin_model.vert"); - _skinShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/model_shadow_map.frag"); - _skinShadowMapProgram.link(); - - initSkinProgram(_skinShadowMapProgram, _skinShadowMapLocations); - - _skinShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); - _skinShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_normal_map.frag"); - _skinShadowNormalMapProgram.link(); - - initSkinProgram(_skinShadowNormalMapProgram, _skinShadowNormalMapLocations, 1, 2); - - _skinShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model.vert"); - _skinShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_specular_map.frag"); - _skinShadowSpecularMapProgram.link(); - - initSkinProgram(_skinShadowSpecularMapProgram, _skinShadowSpecularMapLocations, 1, 2); - - _skinShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); - _skinShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_shadow_normal_specular_map.frag"); - _skinShadowNormalSpecularMapProgram.link(); - - initSkinProgram(_skinShadowNormalSpecularMapProgram, _skinShadowNormalSpecularMapLocations, 2, 3); - - - _skinCascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + - "shaders/skin_model.vert"); - _skinCascadedShadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + - "shaders/model_cascaded_shadow_map.frag"); - _skinCascadedShadowMapProgram.link(); - - initSkinProgram(_skinCascadedShadowMapProgram, _skinCascadedShadowMapLocations); - - _skinCascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); - _skinCascadedShadowNormalMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_map.frag"); - _skinCascadedShadowNormalMapProgram.link(); - - initSkinProgram(_skinCascadedShadowNormalMapProgram, _skinCascadedShadowNormalMapLocations, 1, 2); - - _skinCascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model.vert"); - _skinCascadedShadowSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_specular_map.frag"); - _skinCascadedShadowSpecularMapProgram.link(); - - initSkinProgram(_skinCascadedShadowSpecularMapProgram, _skinCascadedShadowSpecularMapLocations, 1, 2); - - _skinCascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Vertex, - Application::resourcesPath() + "shaders/skin_model_normal_map.vert"); - _skinCascadedShadowNormalSpecularMapProgram.addShaderFromSourceFile(QGLShader::Fragment, - Application::resourcesPath() + "shaders/model_cascaded_shadow_normal_specular_map.frag"); - _skinCascadedShadowNormalSpecularMapProgram.link(); - - initSkinProgram(_skinCascadedShadowNormalSpecularMapProgram, _skinCascadedShadowNormalSpecularMapLocations, 2, 3); - - _skinShadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/skin_model_shadow.vert"); _skinShadowProgram.addShaderFromSourceFile(QGLShader::Fragment, @@ -558,7 +382,7 @@ void Model::setJointStates(QVector states) { _boundingRadius = radius; } -bool Model::render(float alpha, RenderMode mode, bool receiveShadows) { +bool Model::render(float alpha, RenderMode mode) { // render the attachments foreach (Model* attachment, _attachments) { attachment->render(alpha, mode); @@ -607,14 +431,20 @@ bool Model::render(float alpha, RenderMode mode, bool receiveShadows) { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f * alpha); - receiveShadows &= Menu::getInstance()->getShadowsEnabled(); - renderMeshes(alpha, mode, false, receiveShadows); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( + mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, + mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, + mode == DEFAULT_RENDER_MODE); + + renderMeshes(alpha, mode, false); glDisable(GL_ALPHA_TEST); // render translucent meshes afterwards - renderMeshes(alpha, mode, true, receiveShadows); + renderMeshes(alpha, mode, true); + + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); glDisable(GL_CULL_FACE); @@ -1341,12 +1171,11 @@ void Model::deleteGeometry() { } } -void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool receiveShadows) { +void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) { updateVisibleJointStates(); const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); - bool cascadedShadows = Menu::getInstance()->isOptionChecked(MenuOption::CascadedShadows); for (int i = 0; i < networkMeshes.size(); i++) { // exit early if the translucency doesn't match what we're drawing const NetworkMesh& networkMesh = networkMeshes.at(i); @@ -1370,7 +1199,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re ProgramObject* skinProgram = &_skinProgram; SkinLocations* skinLocations = &_skinLocations; GLenum specularTextureUnit = 0; - GLenum shadowTextureUnit = 0; if (mode == SHADOW_RENDER_MODE) { program = &_shadowProgram; skinProgram = &_skinShadowProgram; @@ -1378,40 +1206,12 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re } else if (!mesh.tangents.isEmpty()) { if (mesh.hasSpecularTexture()) { - if (receiveShadows) { - if (cascadedShadows) { - program = &_cascadedShadowNormalSpecularMapProgram; - locations = &_cascadedShadowNormalSpecularMapLocations; - skinProgram = &_skinCascadedShadowNormalSpecularMapProgram; - skinLocations = &_skinCascadedShadowNormalSpecularMapLocations; - } else { - program = &_shadowNormalSpecularMapProgram; - locations = &_shadowNormalSpecularMapLocations; - skinProgram = &_skinShadowNormalSpecularMapProgram; - skinLocations = &_skinShadowNormalSpecularMapLocations; - } - shadowTextureUnit = GL_TEXTURE3; - } else { - program = &_normalSpecularMapProgram; - locations = &_normalSpecularMapLocations; - skinProgram = &_skinNormalSpecularMapProgram; - skinLocations = &_skinNormalSpecularMapLocations; - } + program = &_normalSpecularMapProgram; + locations = &_normalSpecularMapLocations; + skinProgram = &_skinNormalSpecularMapProgram; + skinLocations = &_skinNormalSpecularMapLocations; specularTextureUnit = GL_TEXTURE2; - } else if (receiveShadows) { - if (cascadedShadows) { - program = &_cascadedShadowNormalMapProgram; - locations = &_cascadedShadowNormalMapLocations; - skinProgram = &_skinCascadedShadowNormalMapProgram; - skinLocations = &_skinCascadedShadowNormalMapLocations; - } else { - program = &_shadowNormalMapProgram; - locations = &_shadowNormalMapLocations; - skinProgram = &_skinShadowNormalMapProgram; - skinLocations = &_skinShadowNormalMapLocations; - } - shadowTextureUnit = GL_TEXTURE2; } else { program = &_normalMapProgram; locations = &_normalMapLocations; @@ -1419,40 +1219,11 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re skinLocations = &_skinNormalMapLocations; } } else if (mesh.hasSpecularTexture()) { - if (receiveShadows) { - if (cascadedShadows) { - program = &_cascadedShadowSpecularMapProgram; - locations = &_cascadedShadowSpecularMapLocations; - skinProgram = &_skinCascadedShadowSpecularMapProgram; - skinLocations = &_skinCascadedShadowSpecularMapLocations; - } else { - program = &_shadowSpecularMapProgram; - locations = &_shadowSpecularMapLocations; - skinProgram = &_skinShadowSpecularMapProgram; - skinLocations = &_skinShadowSpecularMapLocations; - } - shadowTextureUnit = GL_TEXTURE2; - } else { - program = &_specularMapProgram; - locations = &_specularMapLocations; - skinProgram = &_skinSpecularMapProgram; - skinLocations = &_skinSpecularMapLocations; - } - specularTextureUnit = GL_TEXTURE1; - - } else if (receiveShadows) { - if (cascadedShadows) { - program = &_cascadedShadowMapProgram; - locations = &_cascadedShadowMapLocations; - skinProgram = &_skinCascadedShadowMapProgram; - skinLocations = &_skinCascadedShadowMapLocations; - } else { - program = &_shadowMapProgram; - locations = &_shadowMapLocations; - skinProgram = &_skinShadowMapProgram; - skinLocations = &_skinShadowMapLocations; - } - shadowTextureUnit = GL_TEXTURE1; + program = &_specularMapProgram; + locations = &_specularMapLocations; + skinProgram = &_skinSpecularMapProgram; + skinLocations = &_skinSpecularMapLocations; + specularTextureUnit = GL_TEXTURE1; } const MeshState& state = _meshStates.at(i); @@ -1480,14 +1251,7 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re glMultMatrixf((const GLfloat*)&state.clusterMatrices[0]); program->bind(); } - if (cascadedShadows) { - activeProgram->setUniform(activeLocations->shadowDistances, Application::getInstance()->getShadowDistances()); - } - if (mode != SHADOW_RENDER_MODE) { - activeProgram->setUniformValueArray(activeLocations->localLightDirections, - (const GLfloat*)_localLightDirections, MAX_LOCAL_LIGHTS, 4); - } - + if (mesh.blendshapes.isEmpty()) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); @@ -1539,12 +1303,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular); glMaterialf(GL_FRONT, GL_SHININESS, part.shininess); - for (int k = 0; k < qMin(MAX_LOCAL_LIGHTS, _localLights.size()); k++) { - _localLightColors[k] = glm::vec4(_localLights.at(k).color, 1.0f) * diffuse; - } - activeProgram->setUniformValueArray(activeLocations->localLightColors, - (const GLfloat*)_localLightColors, MAX_LOCAL_LIGHTS, 4); - Texture* diffuseMap = networkPart.diffuseTexture.data(); if (mesh.isEye && diffuseMap) { diffuseMap = (_dilatedTextures[i][j] = @@ -1553,7 +1311,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re glBindTexture(GL_TEXTURE_2D, !diffuseMap ? Application::getInstance()->getTextureCache()->getWhiteTextureID() : diffuseMap->getID()); - if (!mesh.tangents.isEmpty()) { glActiveTexture(GL_TEXTURE1); Texture* normalMap = networkPart.normalTexture.data(); @@ -1569,12 +1326,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re Application::getInstance()->getTextureCache()->getWhiteTextureID() : specularMap->getID()); glActiveTexture(GL_TEXTURE0); } - - if (shadowTextureUnit) { - glActiveTexture(shadowTextureUnit); - glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getShadowDepthTextureID()); - glActiveTexture(GL_TEXTURE0); - } } glDrawRangeElementsEXT(GL_QUADS, 0, vertexCount - 1, part.quadIndices.size(), GL_UNSIGNED_INT, (void*)offset); offset += part.quadIndices.size() * sizeof(int); @@ -1604,12 +1355,6 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent, bool re glActiveTexture(GL_TEXTURE0); } - if (shadowTextureUnit) { - glActiveTexture(shadowTextureUnit); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - } - if (state.clusterMatrices.size() > 1) { skinProgram->disableAttributeArray(skinLocations->clusterIndices); skinProgram->disableAttributeArray(skinLocations->clusterWeights); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 396a3e576c..71006e3e1d 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -89,7 +89,7 @@ public: enum RenderMode { DEFAULT_RENDER_MODE, SHADOW_RENDER_MODE, DIFFUSE_RENDER_MODE, NORMAL_RENDER_MODE }; - bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE, bool receiveShadows = true); + bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE); /// Sets the URL of the model to render. /// \param fallback the URL of a fallback model to render if the requested model fails to load @@ -255,7 +255,7 @@ private: void applyNextGeometry(); void deleteGeometry(); - void renderMeshes(float alpha, RenderMode mode, bool translucent, bool receiveShadows); + void renderMeshes(float alpha, RenderMode mode, bool translucent); QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); @@ -292,16 +292,6 @@ private: static ProgramObject _specularMapProgram; static ProgramObject _normalSpecularMapProgram; - static ProgramObject _shadowMapProgram; - static ProgramObject _shadowNormalMapProgram; - static ProgramObject _shadowSpecularMapProgram; - static ProgramObject _shadowNormalSpecularMapProgram; - - static ProgramObject _cascadedShadowMapProgram; - static ProgramObject _cascadedShadowNormalMapProgram; - static ProgramObject _cascadedShadowSpecularMapProgram; - static ProgramObject _cascadedShadowNormalSpecularMapProgram; - static ProgramObject _shadowProgram; static ProgramObject _skinProgram; @@ -309,53 +299,22 @@ private: static ProgramObject _skinSpecularMapProgram; static ProgramObject _skinNormalSpecularMapProgram; - static ProgramObject _skinShadowMapProgram; - static ProgramObject _skinShadowNormalMapProgram; - static ProgramObject _skinShadowSpecularMapProgram; - static ProgramObject _skinShadowNormalSpecularMapProgram; - - static ProgramObject _skinCascadedShadowMapProgram; - static ProgramObject _skinCascadedShadowNormalMapProgram; - static ProgramObject _skinCascadedShadowSpecularMapProgram; - static ProgramObject _skinCascadedShadowNormalSpecularMapProgram; - static ProgramObject _skinShadowProgram; static int _normalMapTangentLocation; static int _normalSpecularMapTangentLocation; - static int _shadowNormalMapTangentLocation; - static int _shadowNormalSpecularMapTangentLocation; - static int _cascadedShadowNormalMapTangentLocation; - static int _cascadedShadowNormalSpecularMapTangentLocation; - - static int _cascadedShadowMapDistancesLocation; - static int _cascadedShadowNormalMapDistancesLocation; - static int _cascadedShadowSpecularMapDistancesLocation; - static int _cascadedShadowNormalSpecularMapDistancesLocation; class Locations { public: - int localLightColors; - int localLightDirections; int tangent; - int shadowDistances; }; static Locations _locations; static Locations _normalMapLocations; static Locations _specularMapLocations; static Locations _normalSpecularMapLocations; - static Locations _shadowMapLocations; - static Locations _shadowNormalMapLocations; - static Locations _shadowSpecularMapLocations; - static Locations _shadowNormalSpecularMapLocations; - static Locations _cascadedShadowMapLocations; - static Locations _cascadedShadowNormalMapLocations; - static Locations _cascadedShadowSpecularMapLocations; - static Locations _cascadedShadowNormalSpecularMapLocations; - static void initProgram(ProgramObject& program, Locations& locations, - int specularTextureUnit = 1, int shadowTextureUnit = 1); + static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1); class SkinLocations : public Locations { public: @@ -368,18 +327,9 @@ private: static SkinLocations _skinNormalMapLocations; static SkinLocations _skinSpecularMapLocations; static SkinLocations _skinNormalSpecularMapLocations; - static SkinLocations _skinShadowMapLocations; - static SkinLocations _skinShadowNormalMapLocations; - static SkinLocations _skinShadowSpecularMapLocations; - static SkinLocations _skinShadowNormalSpecularMapLocations; - static SkinLocations _skinCascadedShadowMapLocations; - static SkinLocations _skinCascadedShadowNormalMapLocations; - static SkinLocations _skinCascadedShadowSpecularMapLocations; - static SkinLocations _skinCascadedShadowNormalSpecularMapLocations; static SkinLocations _skinShadowLocations; - static void initSkinProgram(ProgramObject& program, SkinLocations& locations, - int specularTextureUnit = 1, int shadowTextureUnit = 1); + static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1); }; Q_DECLARE_METATYPE(QPointer) From 72f38900bb5546107492f6503fa142fc70b3e145 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 17:31:03 -0700 Subject: [PATCH 07/43] Fix for blending on models. --- interface/resources/shaders/model.vert | 2 +- interface/resources/shaders/model_normal_map.vert | 2 +- interface/resources/shaders/skin_model.vert | 2 +- interface/resources/shaders/skin_model_normal_map.vert | 2 +- interface/src/renderer/Model.cpp | 5 ++++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 4e7de7723d..091526fda3 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -19,7 +19,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); // pass along the vertex color - gl_FrontColor = gl_Color; + gl_FrontColor = vec4(gl_Color.rgb, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/model_normal_map.vert b/interface/resources/shaders/model_normal_map.vert index add76d5588..e65f2e70c4 100644 --- a/interface/resources/shaders/model_normal_map.vert +++ b/interface/resources/shaders/model_normal_map.vert @@ -26,7 +26,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the vertex color - gl_FrontColor = gl_Color; + gl_FrontColor = vec4(gl_Color.rgb, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 4c2c3456d6..754467a449 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -35,7 +35,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); // pass along the vertex color - gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); + gl_FrontColor = vec4(gl_Color.rgb, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index 87622936af..06b0a6359c 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -43,7 +43,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; // pass along the vertex color - gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0); + gl_FrontColor = vec4(gl_Color.rgb, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 54971a3742..4e841c4abd 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -428,8 +428,9 @@ bool Model::render(float alpha, RenderMode mode) { // render opaque meshes with alpha testing + glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f * alpha); + glAlphaFunc(GL_EQUAL, 0.0f); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, @@ -452,6 +453,8 @@ bool Model::render(float alpha, RenderMode mode) { glCullFace(GL_BACK); } + glEnable(GL_BLEND); + // deactivate vertex arrays after drawing glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); From 42c8701b269e8b018856a18df4fc7bfe435bfbaa Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 17:36:58 -0700 Subject: [PATCH 08/43] Don't use gl_Color for skin. --- interface/resources/shaders/skin_model.vert | 2 +- interface/resources/shaders/skin_model_normal_map.vert | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 754467a449..5ab1029d2a 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -35,7 +35,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); // pass along the vertex color - gl_FrontColor = vec4(gl_Color.rgb, 0.0); + gl_FrontColor = vec4(1.0, 1.0, 1.0, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index 06b0a6359c..a8e33228a2 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -43,7 +43,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; // pass along the vertex color - gl_FrontColor = vec4(gl_Color.rgb, 0.0); + gl_FrontColor = vec4(1.0, 1.0, 1.0, 0.0); // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; From 24b193b5dc4c95378ed644c3cc3f25706df98aed Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 18:11:46 -0700 Subject: [PATCH 09/43] Alpha testing bits. --- interface/resources/shaders/directional_light.frag | 2 +- .../shaders/directional_light_cascaded_shadow_map.frag | 2 +- .../resources/shaders/directional_light_shadow_map.frag | 2 +- interface/resources/shaders/model.frag | 5 +++-- interface/resources/shaders/model_normal_map.frag | 5 +++-- interface/resources/shaders/model_normal_specular_map.frag | 5 +++-- interface/resources/shaders/model_specular_map.frag | 5 +++-- 7 files changed, 15 insertions(+), 11 deletions(-) diff --git a/interface/resources/shaders/directional_light.frag b/interface/resources/shaders/directional_light.frag index 5c76fd3ff4..8ca10ce27e 100644 --- a/interface/resources/shaders/directional_light.frag +++ b/interface/resources/shaders/directional_light.frag @@ -56,5 +56,5 @@ void main(void) { // add specular contribution vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a); } diff --git a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag index 054b505f8e..980baf24f3 100644 --- a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag +++ b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag @@ -76,5 +76,5 @@ void main(void) { // add specular contribution vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a); } diff --git a/interface/resources/shaders/directional_light_shadow_map.frag b/interface/resources/shaders/directional_light_shadow_map.frag index b167d58b2a..ea2b9889d3 100644 --- a/interface/resources/shaders/directional_light_shadow_map.frag +++ b/interface/resources/shaders/directional_light_shadow_map.frag @@ -71,5 +71,5 @@ void main(void) { // add specular contribution vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 255.0) * specularColor.rgb, normal.a); + gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normal.a); } diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 70949c48b4..ac03158146 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -19,7 +19,8 @@ varying vec4 normal; void main(void) { // set the diffuse, normal, specular data - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 255.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 5ec3513fb5..7b1624b257 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -33,7 +33,8 @@ void main(void) { normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); // set the diffuse, normal, specular data - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 255.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index d43d69d1e6..9c3e603cb7 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -36,8 +36,9 @@ void main(void) { normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); // set the diffuse, normal, specular data - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 255.0); + gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 63c1ccc17b..ec8ed073d5 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -22,8 +22,9 @@ varying vec4 normal; void main(void) { // set the diffuse, normal, specular data - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 255.0); + gl_FrontMaterial.shininess / 128.0); } From f8772135b1a3c7b134748f331b580f2892ea5550 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 18:35:56 -0700 Subject: [PATCH 10/43] Color fix. --- interface/src/renderer/DeferredLightingEffect.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 7fd53af70a..987de96d68 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -42,6 +42,8 @@ void DeferredLightingEffect::render() { glPushMatrix(); glLoadIdentity(); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glDisable(GL_BLEND); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); @@ -143,8 +145,6 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); glEnable(GL_TEXTURE_2D); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - renderFullscreenQuad(sMin, sMin + sWidth); glBindTexture(GL_TEXTURE_2D, 0); From e36ff0d238f0fb16a6d211343cb5c07ae56bf2fb Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 18:56:07 -0700 Subject: [PATCH 11/43] Fix deferred lighting for rear view mirror. --- interface/src/Application.cpp | 4 ++-- .../src/renderer/DeferredLightingEffect.cpp | 16 ++++++++++------ interface/src/renderer/RenderUtil.cpp | 10 +++++----- interface/src/renderer/RenderUtil.h | 4 ++-- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c657471f40..b507f3d346 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -695,8 +695,6 @@ void Application::paintGL() { displaySide(whichCamera); glPopMatrix(); - _glowEffect.render(); - if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) { renderRearViewMirror(_mirrorViewRect); @@ -704,6 +702,8 @@ void Application::paintGL() { _rearMirrorTools->render(true); } + _glowEffect.render(); + { PerformanceTimer perfTimer("renderOverlay"); // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 987de96d68..1bfec70db6 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -72,9 +72,13 @@ void DeferredLightingEffect::render() { int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_X_INDEX = 0; + const int VIEWPORT_Y_INDEX = 1; const int VIEWPORT_WIDTH_INDEX = 2; + const int VIEWPORT_HEIGHT_INDEX = 3; float sMin = viewport[VIEWPORT_X_INDEX] / (float)primaryFBO->width(); float sWidth = viewport[VIEWPORT_WIDTH_INDEX] / (float)primaryFBO->width(); + float tMin = viewport[VIEWPORT_Y_INDEX] / (float)primaryFBO->height(); + float tHeight = viewport[VIEWPORT_HEIGHT_INDEX] / (float)primaryFBO->height(); ProgramObject* program = &_directionalLight; const LightLocations* locations = &_directionalLightLocations; @@ -109,13 +113,13 @@ void DeferredLightingEffect::render() { program->setUniformValue(locations->nearLocation, nearVal); program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); float nearScale = -1.0f / nearVal; - float sScale = 1.0f / sWidth; - float depthTexCoordScaleS = (right - left) * nearScale * sScale; + float depthTexCoordScaleS = (right - left) * nearScale / sWidth; + float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, - bottom * nearScale); - program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, (top - bottom) * nearScale); + bottom * nearScale - tMin * depthTexCoordScaleT); + program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); - renderFullscreenQuad(sMin, sMin + sWidth); + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); program->release(); @@ -145,7 +149,7 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); glEnable(GL_TEXTURE_2D); - renderFullscreenQuad(sMin, sMin + sWidth); + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); diff --git a/interface/src/renderer/RenderUtil.cpp b/interface/src/renderer/RenderUtil.cpp index 0575ceaa88..c2f05d373e 100644 --- a/interface/src/renderer/RenderUtil.cpp +++ b/interface/src/renderer/RenderUtil.cpp @@ -12,15 +12,15 @@ #include "InterfaceConfig.h" #include "RenderUtil.h" -void renderFullscreenQuad(float sMin, float sMax) { +void renderFullscreenQuad(float sMin, float sMax, float tMin, float tMax) { glBegin(GL_QUADS); - glTexCoord2f(sMin, 0.0f); + glTexCoord2f(sMin, tMin); glVertex2f(-1.0f, -1.0f); - glTexCoord2f(sMax, 0.0f); + glTexCoord2f(sMax, tMin); glVertex2f(1.0f, -1.0f); - glTexCoord2f(sMax, 1.0f); + glTexCoord2f(sMax, tMax); glVertex2f(1.0f, 1.0f); - glTexCoord2f(sMin, 1.0f); + glTexCoord2f(sMin, tMax); glVertex2f(-1.0f, 1.0f); glEnd(); } diff --git a/interface/src/renderer/RenderUtil.h b/interface/src/renderer/RenderUtil.h index 637596c78b..b2f244733a 100644 --- a/interface/src/renderer/RenderUtil.h +++ b/interface/src/renderer/RenderUtil.h @@ -12,7 +12,7 @@ #ifndef hifi_RenderUtil_h #define hifi_RenderUtil_h -/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, 0) to (sMax, 1). -void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f); +/// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax). +void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f); #endif // hifi_RenderUtil_h From 48adbdfbd235bc71d2794b0c32506bfa09a03610 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 19:05:49 -0700 Subject: [PATCH 12/43] Shadow fix. --- interface/resources/shaders/model_shadow.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/shaders/model_shadow.frag b/interface/resources/shaders/model_shadow.frag index 50a4d3895d..567899fd82 100644 --- a/interface/resources/shaders/model_shadow.frag +++ b/interface/resources/shaders/model_shadow.frag @@ -13,5 +13,5 @@ void main(void) { // fixed color for now (we may eventually want to use texture alpha) - gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); + gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0); } From af546e6b050122b50d77a6681a2f60f7b26f537e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 12 Sep 2014 19:18:31 -0700 Subject: [PATCH 13/43] Fix for shadows in rear view mirror. --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b507f3d346..d5fb95ade3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2999,7 +2999,7 @@ void Application::computeOffAxisFrustum(float& left, float& right, float& bottom float& farVal, glm::vec4& nearClipPlane, glm::vec4& farClipPlane) const { // allow 3DTV/Oculus to override parameters from camera - _viewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); + _displayViewFrustum.computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); if (OculusManager::isConnected()) { OculusManager::overrideOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); From 447575946176363bf03994fd95d4ce3f130d36a2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 11:52:44 -0700 Subject: [PATCH 14/43] Revert the normal-based ambient occlusion; I wasn't crazy about the look of it. Will perhaps revisit later. --- .../resources/shaders/ambient_occlusion.frag | 12 +++++++---- interface/src/Application.cpp | 18 +++++++++------- .../src/renderer/AmbientOcclusionEffect.cpp | 21 +++++++++++++------ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/interface/resources/shaders/ambient_occlusion.frag b/interface/resources/shaders/ambient_occlusion.frag index 512922ca43..621b123966 100644 --- a/interface/resources/shaders/ambient_occlusion.frag +++ b/interface/resources/shaders/ambient_occlusion.frag @@ -14,6 +14,9 @@ // the depth texture uniform sampler2D depthTexture; +// the normal texture +uniform sampler2D normalTexture; + // the random rotation texture uniform sampler2D rotationTexture; @@ -57,10 +60,11 @@ vec3 texCoordToViewSpace(vec2 texCoord) { } void main(void) { - vec3 rotationX = texture2D(rotationTexture, gl_TexCoord[0].st * noiseScale).rgb; - vec3 rotationY = normalize(cross(rotationX, vec3(0.0, 0.0, 1.0))); - mat3 rotation = mat3(rotationX, rotationY, cross(rotationX, rotationY)); - + vec3 rotationZ = texture2D(normalTexture, gl_TexCoord[0].st).xyz * 2.0 - vec3(1.0, 1.0, 1.0); + vec3 rotationY = normalize(cross(rotationZ, texture2D(rotationTexture, + gl_TexCoord[0].st * noiseScale).xyz - vec3(0.5, 0.5, 0.5))); + mat3 rotation = mat3(cross(rotationY, rotationZ), rotationY, rotationZ); + vec3 center = texCoordToViewSpace(gl_TexCoord[0].st); vec2 rdenominator = 1.0 / (rightTop - leftBottom); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d5fb95ade3..8131b7b882 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2892,14 +2892,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _entities.render(); } - // render the ambient occlusion effect if enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { - PerformanceTimer perfTimer("ambientOcclusion"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... AmbientOcclusion..."); - _ambientOcclusionEffect.render(); - } - // restore default, white specular glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); @@ -2919,6 +2911,16 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { } } + if (!selfAvatarOnly) { + // render the ambient occlusion effect if enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { + PerformanceTimer perfTimer("ambientOcclusion"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... AmbientOcclusion..."); + _ambientOcclusionEffect.render(); + } + } + { PerformanceTimer perfTimer("lighting"); _deferredLightingEffect.render(); diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index f1c1538800..4941f715c0 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -36,12 +36,13 @@ void AmbientOcclusionEffect::init() { + "shaders/ambient_occlusion.frag"); _occlusionProgram->link(); - // create the sample kernel: an array of spherically distributed offset vectors + // create the sample kernel: an array of hemispherically distributed offset vectors const int SAMPLE_KERNEL_SIZE = 16; QVector3D sampleKernel[SAMPLE_KERNEL_SIZE]; for (int i = 0; i < SAMPLE_KERNEL_SIZE; i++) { // square the length in order to increase density towards the center glm::vec3 vector = glm::sphericalRand(1.0f); + vector.z = glm::abs(vector.z); float scale = randFloat(); const float MIN_VECTOR_LENGTH = 0.01f; const float MAX_VECTOR_LENGTH = 1.0f; @@ -51,7 +52,8 @@ void AmbientOcclusionEffect::init() { _occlusionProgram->bind(); _occlusionProgram->setUniformValue("depthTexture", 0); - _occlusionProgram->setUniformValue("rotationTexture", 1); + _occlusionProgram->setUniformValue("normalTexture", 1); + _occlusionProgram->setUniformValue("rotationTexture", 2); _occlusionProgram->setUniformValueArray("sampleKernel", sampleKernel, SAMPLE_KERNEL_SIZE); _occlusionProgram->setUniformValue("radius", 0.1f); _occlusionProgram->release(); @@ -71,10 +73,10 @@ void AmbientOcclusionEffect::init() { unsigned char rotationData[ROTATION_WIDTH * ROTATION_HEIGHT * ELEMENTS_PER_PIXEL]; unsigned char* rotation = rotationData; for (int i = 0; i < ROTATION_WIDTH * ROTATION_HEIGHT; i++) { - glm::vec3 randvec = glm::sphericalRand(1.0f); - *rotation++ = ((randvec.x + 1.0f) / 2.0f) * 255.0f; - *rotation++ = ((randvec.y + 1.0f) / 2.0f) * 255.0f; - *rotation++ = ((randvec.z + 1.0f) / 2.0f) * 255.0f; + float angle = randFloatInRange(0.0f, TWO_PI); + *rotation++ = ((glm::cos(angle) + 1.0f) / 2.0f) * 255.0f; + *rotation++ = ((glm::sin(angle) + 1.0f) / 2.0f) * 255.0f; + *rotation++ = 0.0f; } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ROTATION_WIDTH, ROTATION_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, rotationData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -101,6 +103,9 @@ void AmbientOcclusionEffect::render() { glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryDepthTextureID()); glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, Application::getInstance()->getTextureCache()->getPrimaryNormalTextureID()); + + glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, _rotationTextureID); // render with the occlusion shader to the secondary/tertiary buffer @@ -137,6 +142,10 @@ void AmbientOcclusionEffect::render() { freeFBO->release(); glBindTexture(GL_TEXTURE_2D, 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); // now render secondary to primary with 4x4 blur From 919112fe7c398e291b4f44e4e3284139ecdaddc6 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 12:18:59 -0700 Subject: [PATCH 15/43] Starting to work on handling translucent meshes with deferred lighting. --- interface/src/renderer/DeferredLightingEffect.cpp | 6 ++++++ interface/src/renderer/DeferredLightingEffect.h | 15 +++++++++++++++ interface/src/renderer/Model.cpp | 3 +++ interface/src/renderer/Model.h | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 1bfec70db6..559584157a 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -163,6 +163,12 @@ void DeferredLightingEffect::render() { glMatrixMode(GL_MODELVIEW); glPopMatrix(); + + // now render the objects we held back until after deferred lighting + foreach (PostLightingRenderable* renderable, _postLightingRenderables) { + renderable->renderPostLighting(); + } + _postLightingRenderables.clear(); } void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) { diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index 5be7ea1038..46a4b4d7f6 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -12,13 +12,20 @@ #ifndef hifi_DeferredLightingEffect_h #define hifi_DeferredLightingEffect_h +#include + #include "ProgramObject.h" +class PostLightingRenderable; + /// Handles deferred lighting for the bits that require it (voxels, metavoxels...) class DeferredLightingEffect { public: void init(); + + /// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object). + void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); } void prepare(); void render(); @@ -43,6 +50,14 @@ private: LightLocations _directionalLightShadowMapLocations; ProgramObject _directionalLightCascadedShadowMap; LightLocations _directionalLightCascadedShadowMapLocations; + + QVector _postLightingRenderables; +}; + +/// Simple interface for objects that require something to be rendered after deferred lighting. +class PostLightingRenderable { +public: + virtual void renderPostLighting() = 0; }; #endif // hifi_DeferredLightingEffect_h diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 4e841c4abd..8fc2bfa8af 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -471,6 +471,9 @@ bool Model::render(float alpha, RenderMode mode) { return true; } +void Model::renderPostLighting() { +} + Extents Model::getBindExtents() const { if (!isActive()) { return Extents(); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index f51ef14d9c..40e40865e1 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -20,6 +20,7 @@ #include +#include "DeferredLightingEffect.h" #include "GeometryCache.h" #include "InterfaceConfig.h" #include "JointState.h" @@ -37,7 +38,7 @@ typedef QWeakPointer WeakAnimationHandlePointer; const int MAX_LOCAL_LIGHTS = 2; /// A generic 3D model displaying geometry loaded from a URL. -class Model : public QObject, public PhysicsEntity { +class Model : public QObject, public PhysicsEntity, public PostLightingRenderable { Q_OBJECT public: @@ -91,6 +92,8 @@ public: bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE); + virtual void renderPostLighting(); + /// Sets the URL of the model to render. /// \param fallback the URL of a fallback model to render if the requested model fails to load /// \param retainCurrent if true, keep rendering the current model until the new one is loaded From 70c8c146bc3c3df6fd26cb371dc3333dbf12442c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 12:44:25 -0700 Subject: [PATCH 16/43] Fix for specular issue on Nvidia, try passing along material colors. --- interface/resources/shaders/model.vert | 4 ++-- interface/resources/shaders/model_normal_map.vert | 4 ++-- interface/resources/shaders/skin_model.vert | 4 ++-- interface/resources/shaders/skin_model_normal_map.vert | 4 ++-- interface/src/renderer/DeferredLightingEffect.cpp | 10 ++++++++-- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 091526fda3..6bcf7fbbe1 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -18,8 +18,8 @@ void main(void) { // transform and store the normal for interpolation normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); - // pass along the vertex color - gl_FrontColor = vec4(gl_Color.rgb, 0.0); + // pass along the diffuse color + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/model_normal_map.vert b/interface/resources/shaders/model_normal_map.vert index e65f2e70c4..937bdcaf33 100644 --- a/interface/resources/shaders/model_normal_map.vert +++ b/interface/resources/shaders/model_normal_map.vert @@ -25,8 +25,8 @@ void main(void) { interpolatedNormal = gl_ModelViewMatrix * vec4(gl_Normal, 0.0); interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); - // pass along the vertex color - gl_FrontColor = vec4(gl_Color.rgb, 0.0); + // pass along the diffuse color + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 5ab1029d2a..072bf3c336 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -34,8 +34,8 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); - // pass along the vertex color - gl_FrontColor = vec4(1.0, 1.0, 1.0, 0.0); + // pass along the diffuse color + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index a8e33228a2..ac6c77f7cb 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -42,8 +42,8 @@ void main(void) { interpolatedNormal = gl_ModelViewMatrix * interpolatedNormal; interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; - // pass along the vertex color - gl_FrontColor = vec4(1.0, 1.0, 1.0, 0.0); + // pass along the diffuse color + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 559584157a..ec925c18e8 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -28,9 +28,15 @@ void DeferredLightingEffect::init() { void DeferredLightingEffect::prepare() { // clear the normal and specular buffers - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false); glClear(GL_COLOR_BUFFER_BIT); - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, false, true); + // clearing to zero alpha for specular causes problems on my Nvidia card; clear to lowest non-zero value instead + const float MAX_SPECULAR_EXPONENT = 128.0f; + glClearColor(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false); } void DeferredLightingEffect::render() { From b3b82ba56cc77a17829281590296fc80e63efb50 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 12:49:51 -0700 Subject: [PATCH 17/43] I think we need to include the color. --- interface/resources/shaders/model.vert | 2 +- interface/resources/shaders/model_normal_map.vert | 2 +- interface/resources/shaders/skin_model.vert | 2 +- interface/resources/shaders/skin_model_normal_map.vert | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/resources/shaders/model.vert b/interface/resources/shaders/model.vert index 6bcf7fbbe1..a304187591 100644 --- a/interface/resources/shaders/model.vert +++ b/interface/resources/shaders/model.vert @@ -19,7 +19,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/model_normal_map.vert b/interface/resources/shaders/model_normal_map.vert index 937bdcaf33..9fde196b06 100644 --- a/interface/resources/shaders/model_normal_map.vert +++ b/interface/resources/shaders/model_normal_map.vert @@ -26,7 +26,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index 072bf3c336..e490a76cc3 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -35,7 +35,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index ac6c77f7cb..94166ba4a6 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -43,7 +43,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; From e3a1341be1a4648f5d8a300475bf5ac791216282 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 12:52:35 -0700 Subject: [PATCH 18/43] Don't include the color on the skin. --- interface/resources/shaders/skin_model.vert | 2 +- interface/resources/shaders/skin_model_normal_map.vert | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/shaders/skin_model.vert b/interface/resources/shaders/skin_model.vert index e490a76cc3..072bf3c336 100644 --- a/interface/resources/shaders/skin_model.vert +++ b/interface/resources/shaders/skin_model.vert @@ -35,7 +35,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; diff --git a/interface/resources/shaders/skin_model_normal_map.vert b/interface/resources/shaders/skin_model_normal_map.vert index 94166ba4a6..ac6c77f7cb 100644 --- a/interface/resources/shaders/skin_model_normal_map.vert +++ b/interface/resources/shaders/skin_model_normal_map.vert @@ -43,7 +43,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_FrontMaterial.diffuse; // and the texture coordinates gl_TexCoord[0] = gl_MultiTexCoord0; From 467a9582c7f336eaba5e35275af7f815bcb6600b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 13:29:03 -0700 Subject: [PATCH 19/43] Somehow my reverting the ambient occlusion effect didn't take. --- interface/src/Application.cpp | 18 ++++++++---------- interface/src/Application.h | 1 + .../src/renderer/AmbientOcclusionEffect.cpp | 9 ++++----- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8131b7b882..011df7757e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2895,6 +2895,14 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { // restore default, white specular glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); + // render the ambient occlusion effect if enabled + if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { + PerformanceTimer perfTimer("ambientOcclusion"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... AmbientOcclusion..."); + _ambientOcclusionEffect.render(); + } + _nodeBoundsDisplay.draw(); } @@ -2910,16 +2918,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _myAvatar->renderLaserPointers(); } } - - if (!selfAvatarOnly) { - // render the ambient occlusion effect if enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { - PerformanceTimer perfTimer("ambientOcclusion"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... AmbientOcclusion..."); - _ambientOcclusionEffect.render(); - } - } { PerformanceTimer perfTimer("lighting"); diff --git a/interface/src/Application.h b/interface/src/Application.h index 799a0501c1..d17bacd413 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -248,6 +248,7 @@ public: GeometryCache* getGeometryCache() { return &_geometryCache; } AnimationCache* getAnimationCache() { return &_animationCache; } TextureCache* getTextureCache() { return &_textureCache; } + DeferredLightingEffect* getDeferredLightingEffect() { return &_deferredLightingEffect; } GlowEffect* getGlowEffect() { return &_glowEffect; } ControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; } diff --git a/interface/src/renderer/AmbientOcclusionEffect.cpp b/interface/src/renderer/AmbientOcclusionEffect.cpp index 4941f715c0..33a0b6e77d 100644 --- a/interface/src/renderer/AmbientOcclusionEffect.cpp +++ b/interface/src/renderer/AmbientOcclusionEffect.cpp @@ -42,7 +42,6 @@ void AmbientOcclusionEffect::init() { for (int i = 0; i < SAMPLE_KERNEL_SIZE; i++) { // square the length in order to increase density towards the center glm::vec3 vector = glm::sphericalRand(1.0f); - vector.z = glm::abs(vector.z); float scale = randFloat(); const float MIN_VECTOR_LENGTH = 0.01f; const float MAX_VECTOR_LENGTH = 1.0f; @@ -73,10 +72,10 @@ void AmbientOcclusionEffect::init() { unsigned char rotationData[ROTATION_WIDTH * ROTATION_HEIGHT * ELEMENTS_PER_PIXEL]; unsigned char* rotation = rotationData; for (int i = 0; i < ROTATION_WIDTH * ROTATION_HEIGHT; i++) { - float angle = randFloatInRange(0.0f, TWO_PI); - *rotation++ = ((glm::cos(angle) + 1.0f) / 2.0f) * 255.0f; - *rotation++ = ((glm::sin(angle) + 1.0f) / 2.0f) * 255.0f; - *rotation++ = 0.0f; + glm::vec3 vector = glm::sphericalRand(1.0f); + *rotation++ = ((vector.x + 1.0f) / 2.0f) * 255.0f; + *rotation++ = ((vector.y + 1.0f) / 2.0f) * 255.0f; + *rotation++ = ((vector.z + 1.0f) / 2.0f) * 255.0f; } glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, ROTATION_WIDTH, ROTATION_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, rotationData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); From 0f3a020b5d89088036a58a1b219c3fc37e53bd59 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 16:07:48 -0700 Subject: [PATCH 20/43] Working on getting particles/entities to work with deferred lighting; normalize normals from buffer. --- .../resources/shaders/directional_light.frag | 2 +- ...directional_light_cascaded_shadow_map.frag | 2 +- .../shaders/directional_light_shadow_map.frag | 2 +- interface/resources/shaders/simple.frag | 22 ++++++++++ interface/resources/shaders/simple.vert | 26 ++++++++++++ interface/src/Application.cpp | 20 ++++------ .../src/entities/RenderableBoxEntityItem.cpp | 6 ++- .../entities/RenderableModelEntityItem.cpp | 6 +-- .../entities/RenderableSphereEntityItem.cpp | 2 +- .../src/particles/ParticleTreeRenderer.cpp | 5 ++- .../src/renderer/DeferredLightingEffect.cpp | 40 +++++++++++++++++++ .../src/renderer/DeferredLightingEffect.h | 26 +++++++++++- 12 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 interface/resources/shaders/simple.frag create mode 100644 interface/resources/shaders/simple.vert diff --git a/interface/resources/shaders/directional_light.frag b/interface/resources/shaders/directional_light.frag index 8ca10ce27e..da48149001 100644 --- a/interface/resources/shaders/directional_light.frag +++ b/interface/resources/shaders/directional_light.frag @@ -42,7 +42,7 @@ void main(void) { // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); // compute the base color based on OpenGL lighting model float diffuse = dot(normalizedNormal, gl_LightSource[0].position); diff --git a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag index 980baf24f3..ac9c784d9a 100644 --- a/interface/resources/shaders/directional_light_cascaded_shadow_map.frag +++ b/interface/resources/shaders/directional_light_cascaded_shadow_map.frag @@ -56,7 +56,7 @@ void main(void) { // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); // average values from the shadow map float diffuse = dot(normalizedNormal, gl_LightSource[0].position); diff --git a/interface/resources/shaders/directional_light_shadow_map.frag b/interface/resources/shaders/directional_light_shadow_map.frag index ea2b9889d3..f1eaa20826 100644 --- a/interface/resources/shaders/directional_light_shadow_map.frag +++ b/interface/resources/shaders/directional_light_shadow_map.frag @@ -51,7 +51,7 @@ void main(void) { // get the normal from the map vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); - vec4 normalizedNormal = normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0); + vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); // average values from the shadow map float diffuse = dot(normalizedNormal, gl_LightSource[0].position); diff --git a/interface/resources/shaders/simple.frag b/interface/resources/shaders/simple.frag new file mode 100644 index 0000000000..5c47e29d74 --- /dev/null +++ b/interface/resources/shaders/simple.frag @@ -0,0 +1,22 @@ +#version 120 + +// +// simple.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 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 +// + +// the interpolated normal +varying vec4 normal; + +void main(void) { + // set the diffuse, normal, specular data + gl_FragData[0] = vec4(gl_Color.rgb, 0.0); + gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); +} diff --git a/interface/resources/shaders/simple.vert b/interface/resources/shaders/simple.vert new file mode 100644 index 0000000000..c8fa0a9ebb --- /dev/null +++ b/interface/resources/shaders/simple.vert @@ -0,0 +1,26 @@ +#version 120 + +// +// simple.vert +// vertex shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 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 +// + +// the interpolated normal +varying vec4 normal; + +void main(void) { + // transform and store the normal for interpolation + normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); + + // pass along the diffuse color + gl_FrontColor = gl_Color; + + // use standard pipeline transform + gl_Position = ftransform(); +} diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 011df7757e..9d8f90c611 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2844,15 +2844,19 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { glutSolidSphere(originSphereRadius, 15, 15); glPopMatrix(); - // disable specular lighting for ground and voxels - glMaterialfv(GL_FRONT, GL_SPECULAR, NO_SPECULAR_COLOR); - // draw the audio reflector overlay { PerformanceTimer perfTimer("audio"); _audioReflector.render(); } + if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { + PerformanceTimer perfTimer("buckyBalls"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::displaySide() ... bucky balls..."); + _buckyBalls.render(); + } + // Draw voxels if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { PerformanceTimer perfTimer("voxels"); @@ -2869,13 +2873,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _metavoxels.render(); } - if (Menu::getInstance()->isOptionChecked(MenuOption::BuckyBalls)) { - PerformanceTimer perfTimer("buckyBalls"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... bucky balls..."); - _buckyBalls.render(); - } - // render particles... if (Menu::getInstance()->isOptionChecked(MenuOption::Particles)) { PerformanceTimer perfTimer("particles"); @@ -2892,9 +2889,6 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _entities.render(); } - // restore default, white specular - glMaterialfv(GL_FRONT, GL_SPECULAR, WORLD_SPECULAR_COLOR); - // render the ambient occlusion effect if enabled if (Menu::getInstance()->isOptionChecked(MenuOption::AmbientOcclusion)) { PerformanceTimer perfTimer("ambientOcclusion"); diff --git a/interface/src/entities/RenderableBoxEntityItem.cpp b/interface/src/entities/RenderableBoxEntityItem.cpp index 17cfbdcdaf..c39fb222bf 100644 --- a/interface/src/entities/RenderableBoxEntityItem.cpp +++ b/interface/src/entities/RenderableBoxEntityItem.cpp @@ -50,7 +50,7 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, dimensions.z); - glutSolidCube(1.0f); + Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f); glPopMatrix(); glPopMatrix(); } else { @@ -86,6 +86,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { glColor3ub(getColor()[RED_INDEX], getColor()[GREEN_INDEX], getColor()[BLUE_INDEX]); + Application::getInstance()->getDeferredLightingEffect()->bindSimpleProgram(); + glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); @@ -99,6 +101,8 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { glPopMatrix(); glPopMatrix(); + Application::getInstance()->getDeferredLightingEffect()->releaseSimpleProgram(); + glDisableClientState(GL_VERTEX_ARRAY); // disable vertex arrays glDisableClientState(GL_NORMAL_ARRAY); } diff --git a/interface/src/entities/RenderableModelEntityItem.cpp b/interface/src/entities/RenderableModelEntityItem.cpp index 4347087287..6eb19bde31 100644 --- a/interface/src/entities/RenderableModelEntityItem.cpp +++ b/interface/src/entities/RenderableModelEntityItem.cpp @@ -125,7 +125,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]); glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glutWireCube(size); + Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size); glPopMatrix(); } } else { @@ -133,7 +133,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]); glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glutWireCube(size); + Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size); glPopMatrix(); } } @@ -142,7 +142,7 @@ void RenderableModelEntityItem::render(RenderArgs* args) { glColor3ub(getColor()[RED_INDEX],getColor()[GREEN_INDEX],getColor()[BLUE_INDEX]); glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glutWireCube(size); + Application::getInstance()->getDeferredLightingEffect()->renderWireCube(size); glPopMatrix(); } } diff --git a/interface/src/entities/RenderableSphereEntityItem.cpp b/interface/src/entities/RenderableSphereEntityItem.cpp index d5286b0ab3..2ff725ad03 100644 --- a/interface/src/entities/RenderableSphereEntityItem.cpp +++ b/interface/src/entities/RenderableSphereEntityItem.cpp @@ -48,7 +48,7 @@ void RenderableSphereEntityItem::render(RenderArgs* args) { glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, dimensions.z); - glutSolidSphere(0.5f, 15, 15); + Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(0.5f, 15, 15); glPopMatrix(); glPopMatrix(); }; diff --git a/interface/src/particles/ParticleTreeRenderer.cpp b/interface/src/particles/ParticleTreeRenderer.cpp index d9683405e2..4d47adedf0 100644 --- a/interface/src/particles/ParticleTreeRenderer.cpp +++ b/interface/src/particles/ParticleTreeRenderer.cpp @@ -11,6 +11,7 @@ #include +#include "Application.h" #include "InterfaceConfig.h" #include "ParticleTreeRenderer.h" @@ -112,7 +113,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg if (wantDebugSphere) { glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glutWireSphere(radius, 15, 15); + Application::getInstance()->getDeferredLightingEffect()->renderWireSphere(radius, 15, 15); glPopMatrix(); } @@ -120,7 +121,7 @@ void ParticleTreeRenderer::renderElement(OctreeElement* element, RenderArgs* arg } else { glPushMatrix(); glTranslatef(position.x, position.y, position.z); - glutSolidSphere(radius, 15, 15); + Application::getInstance()->getDeferredLightingEffect()->renderSolidSphere(radius, 15, 15); glPopMatrix(); } } diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index ec925c18e8..68f1c7aa3d 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -19,6 +19,10 @@ #include "RenderUtil.h" void DeferredLightingEffect::init() { + _simpleProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/simple.vert"); + _simpleProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/simple.frag"); + _simpleProgram.link(); + loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations); loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap, _directionalLightShadowMapLocations); @@ -26,6 +30,42 @@ void DeferredLightingEffect::init() { _directionalLightCascadedShadowMapLocations); } +void DeferredLightingEffect::bindSimpleProgram() { + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true, true); + _simpleProgram.bind(); + glDisable(GL_BLEND); +} + +void DeferredLightingEffect::releaseSimpleProgram() { + glEnable(GL_BLEND); + _simpleProgram.release(); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, false, false); +} + +void DeferredLightingEffect::renderSolidSphere(float radius, int slices, int stacks) { + bindSimpleProgram(); + glutSolidSphere(radius, slices, stacks); + releaseSimpleProgram(); +} + +void DeferredLightingEffect::renderWireSphere(float radius, int slices, int stacks) { + bindSimpleProgram(); + glutWireSphere(radius, slices, stacks); + releaseSimpleProgram(); +} + +void DeferredLightingEffect::renderSolidCube(float size) { + bindSimpleProgram(); + glutSolidCube(size); + releaseSimpleProgram(); +} + +void DeferredLightingEffect::renderWireCube(float size) { + bindSimpleProgram(); + glutWireCube(size); + releaseSimpleProgram(); +} + void DeferredLightingEffect::prepare() { // clear the normal and specular buffers Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false); diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index 46a4b4d7f6..1971019aca 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -24,6 +24,28 @@ public: void init(); + /// Returns a reference to a simple program suitable for rendering static + /// untextured geometry (such as that generated by glutSolidSphere, etc.) + ProgramObject& getSimpleProgram() { return _simpleProgram; } + + /// Sets up the state necessary to render static untextured geometry with the simple program. + void bindSimpleProgram(); + + /// Tears down the state necessary to render static untextured geometry with the simple program. + void releaseSimpleProgram(); + + //// Renders a solid sphere with the simple program. + void renderSolidSphere(float radius, int slices, int stacks); + + //// Renders a wireframe sphere with the simple program. + void renderWireSphere(float radius, int slices, int stacks); + + //// Renders a solid cube with the simple program. + void renderSolidCube(float size); + + //// Renders a wireframe cube with the simple program. + void renderWireCube(float size); + /// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object). void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); } @@ -43,7 +65,9 @@ private: }; static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); - + + ProgramObject _simpleProgram; + ProgramObject _directionalLight; LightLocations _directionalLightLocations; ProgramObject _directionalLightShadowMap; From 580d591dc44f6f2f7f02ed624f01bb276a178d66 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 17:11:36 -0700 Subject: [PATCH 21/43] Working on getting glow to work with deferred lighting. --- interface/resources/shaders/model.frag | 2 +- interface/resources/shaders/model_normal_map.frag | 2 +- .../shaders/model_normal_specular_map.frag | 2 +- .../resources/shaders/model_specular_map.frag | 2 +- interface/src/Application.cpp | 1 - interface/src/renderer/GlowEffect.h | 3 +++ interface/src/renderer/Model.cpp | 14 +++++++------- interface/src/renderer/Model.h | 2 +- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index ac03158146..58a5d24463 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -20,7 +20,7 @@ varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 7b1624b257..28c65f20b4 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -34,7 +34,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index 9c3e603cb7..3d4f795111 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -37,7 +37,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index ec8ed073d5..0c021d333c 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -23,7 +23,7 @@ varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, step(diffuse.a, 0.5)); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9d8f90c611..b87f173ab9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2700,7 +2700,6 @@ void Application::updateShadowMap() { const GLfloat WORLD_AMBIENT_COLOR[] = { 0.525f, 0.525f, 0.6f }; const GLfloat WORLD_DIFFUSE_COLOR[] = { 0.6f, 0.525f, 0.525f }; const GLfloat WORLD_SPECULAR_COLOR[] = { 0.94f, 0.94f, 0.737f, 1.0f }; -const GLfloat NO_SPECULAR_COLOR[] = { 0.0f, 0.0f, 0.0f, 1.0f }; void Application::setupWorldLight() { diff --git a/interface/src/renderer/GlowEffect.h b/interface/src/renderer/GlowEffect.h index b675589526..9f15a8b860 100644 --- a/interface/src/renderer/GlowEffect.h +++ b/interface/src/renderer/GlowEffect.h @@ -43,6 +43,9 @@ public: /// Stops using the glow effect. void end(); + /// Returns the current glow intensity. + float getIntensity() const { return _intensity; } + /// Renders the glow effect. To be called after rendering the scene. /// \param toTexture whether to render to a texture, rather than to the frame buffer /// \return the framebuffer object to which we rendered, or NULL if to the frame buffer diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index dd10d57337..a6a856edb8 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -430,20 +430,20 @@ bool Model::render(float alpha, RenderMode mode) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_EQUAL, 0.0f); + glAlphaFunc(GL_EQUAL, Application::getInstance()->getGlowEffect()->getIntensity()); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, mode == DEFAULT_RENDER_MODE || mode == NORMAL_RENDER_MODE, mode == DEFAULT_RENDER_MODE); - renderMeshes(alpha, mode, false); + renderMeshes(mode, false); glDisable(GL_ALPHA_TEST); // render translucent meshes afterwards - renderMeshes(alpha, mode, true); + renderMeshes(mode, true); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); @@ -1192,7 +1192,7 @@ void Model::deleteGeometry() { } } -void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) { +void Model::renderMeshes(RenderMode mode, bool translucent) { updateVisibleJointStates(); const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); @@ -1298,7 +1298,7 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) { if (!mesh.colors.isEmpty()) { glEnableClientState(GL_COLOR_ARRAY); } else { - glColor4f(1.0f, 1.0f, 1.0f, alpha); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } if (!mesh.texCoords.isEmpty()) { glEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1317,8 +1317,8 @@ void Model::renderMeshes(float alpha, RenderMode mode, bool translucent) { glBindTexture(GL_TEXTURE_2D, 0); } else { - glm::vec4 diffuse = glm::vec4(part.diffuseColor, alpha); - glm::vec4 specular = glm::vec4(part.specularColor, alpha); + glm::vec4 diffuse = glm::vec4(part.diffuseColor, Application::getInstance()->getGlowEffect()->getIntensity()); + glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, (const float*)&specular); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 40e40865e1..82afd3cf42 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -259,7 +259,7 @@ private: void applyNextGeometry(); void deleteGeometry(); - void renderMeshes(float alpha, RenderMode mode, bool translucent); + void renderMeshes(RenderMode mode, bool translucent); QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); From da05d37015e89305207edc2f6aa1e4e1d26d47f7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 17:19:15 -0700 Subject: [PATCH 22/43] Leave the glow level alone when writing the deferred-lit bits. --- interface/src/renderer/DeferredLightingEffect.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 68f1c7aa3d..2e2086e02b 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -189,6 +189,7 @@ void DeferredLightingEffect::render() { // now transfer the lit region to the primary fbo glEnable(GL_BLEND); + glColorMask(true, true, true, false); primaryFBO->bind(); @@ -200,6 +201,7 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); + glColorMask(true, true, true, true); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); glEnable(GL_DEPTH_TEST); From 7580a1da89ae56673dfa25b8e96c4630f258ddf4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 17:33:07 -0700 Subject: [PATCH 23/43] Glow fix for simple shader. --- interface/resources/shaders/simple.frag | 5 ++++- interface/src/renderer/DeferredLightingEffect.cpp | 5 +++++ interface/src/renderer/DeferredLightingEffect.h | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/interface/resources/shaders/simple.frag b/interface/resources/shaders/simple.frag index 5c47e29d74..347cb0a859 100644 --- a/interface/resources/shaders/simple.frag +++ b/interface/resources/shaders/simple.frag @@ -14,9 +14,12 @@ // the interpolated normal varying vec4 normal; +// the glow intensity +uniform float glowIntensity; + void main(void) { // set the diffuse, normal, specular data - gl_FragData[0] = vec4(gl_Color.rgb, 0.0); + gl_FragData[0] = vec4(gl_Color.rgb, glowIntensity); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 2e2086e02b..48fbf30898 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -23,6 +23,10 @@ void DeferredLightingEffect::init() { _simpleProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/simple.frag"); _simpleProgram.link(); + _simpleProgram.bind(); + _glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity"); + _simpleProgram.release(); + loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations); loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap, _directionalLightShadowMapLocations); @@ -33,6 +37,7 @@ void DeferredLightingEffect::init() { void DeferredLightingEffect::bindSimpleProgram() { Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true, true, true); _simpleProgram.bind(); + _simpleProgram.setUniformValue(_glowIntensityLocation, Application::getInstance()->getGlowEffect()->getIntensity()); glDisable(GL_BLEND); } diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index 1971019aca..1953afd4c3 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -67,6 +67,7 @@ private: static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); ProgramObject _simpleProgram; + int _glowIntensityLocation; ProgramObject _directionalLight; LightLocations _directionalLightLocations; From bfaac9eae1bb790caaa6eddef4aa9765ca3656db Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 15 Sep 2014 18:38:10 -0700 Subject: [PATCH 24/43] Deferred lighting tweaks. --- interface/src/Application.cpp | 18 ++++++++---------- interface/src/avatar/Head.cpp | 6 +++++- interface/src/avatar/Head.h | 4 +++- interface/src/renderer/Model.cpp | 3 --- interface/src/renderer/Model.h | 5 +---- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b87f173ab9..04d4bcb250 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2895,21 +2895,12 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { "Application::displaySide() ... AmbientOcclusion..."); _ambientOcclusionEffect.render(); } - - _nodeBoundsDisplay.draw(); - } bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); { PerformanceTimer perfTimer("avatars"); - - _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly); - - //Render the sixense lasers - if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { - _myAvatar->renderLaserPointers(); - } + _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly); } { @@ -2917,7 +2908,14 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _deferredLightingEffect.render(); } + //Render the sixense lasers + if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { + _myAvatar->renderLaserPointers(); + } + if (!selfAvatarOnly) { + _nodeBoundsDisplay.draw(); + // Render the world box if (whichCamera.getMode() != CAMERA_MODE_MIRROR && Menu::getInstance()->isOptionChecked(MenuOption::Stats) && Menu::getInstance()->isOptionChecked(MenuOption::UserInterface)) { diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 244983fd17..89e0ad89bc 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -185,10 +185,14 @@ void Head::relaxLean(float deltaTime) { void Head::render(float alpha, Model::RenderMode mode) { if (_faceModel.render(alpha, mode) && _renderLookatVectors && mode != Model::SHADOW_RENDER_MODE) { - renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); + Application::getInstance()->getDeferredLightingEffect()->addPostLightingRenderable(this); } } +void Head::renderPostLighting() { + renderLookatVectors(_leftEyePosition, _rightEyePosition, _lookAtPosition); +} + void Head::setScale (float scale) { if (_scale == scale) { return; diff --git a/interface/src/avatar/Head.h b/interface/src/avatar/Head.h index 1cdfdaf5a3..4c21bfa255 100644 --- a/interface/src/avatar/Head.h +++ b/interface/src/avatar/Head.h @@ -23,6 +23,7 @@ #include "FaceModel.h" #include "InterfaceConfig.h" #include "world.h" +#include "renderer/DeferredLightingEffect.h" enum eyeContactTargets { LEFT_EYE, @@ -35,7 +36,7 @@ const float EYE_EAR_GAP = 0.08f; class Avatar; class ProgramObject; -class Head : public HeadData { +class Head : public HeadData, public PostLightingRenderable { public: Head(Avatar* owningAvatar); @@ -43,6 +44,7 @@ public: void reset(); void simulate(float deltaTime, bool isMine, bool billboard = false); void render(float alpha, Model::RenderMode mode); + virtual void renderPostLighting(); void setScale(float scale); void setPosition(glm::vec3 position) { _position = position; } void setAverageLoudness(float averageLoudness) { _averageLoudness = averageLoudness; } diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index a6a856edb8..e215a8adcd 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -471,9 +471,6 @@ bool Model::render(float alpha, RenderMode mode) { return true; } -void Model::renderPostLighting() { -} - Extents Model::getBindExtents() const { if (!isActive()) { return Extents(); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 82afd3cf42..f8118c70f2 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -20,7 +20,6 @@ #include -#include "DeferredLightingEffect.h" #include "GeometryCache.h" #include "InterfaceConfig.h" #include "JointState.h" @@ -38,7 +37,7 @@ typedef QWeakPointer WeakAnimationHandlePointer; const int MAX_LOCAL_LIGHTS = 2; /// A generic 3D model displaying geometry loaded from a URL. -class Model : public QObject, public PhysicsEntity, public PostLightingRenderable { +class Model : public QObject, public PhysicsEntity { Q_OBJECT public: @@ -92,8 +91,6 @@ public: bool render(float alpha = 1.0f, RenderMode mode = DEFAULT_RENDER_MODE); - virtual void renderPostLighting(); - /// Sets the URL of the model to render. /// \param fallback the URL of a fallback model to render if the requested model fails to load /// \param retainCurrent if true, keep rendering the current model until the new one is loaded From fb7e633cac7895f7fc5742dbbe05e9ba5e5cc869 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 13:17:23 -0700 Subject: [PATCH 25/43] Post-merge fixes. --- interface/src/renderer/Model.cpp | 6 +++--- interface/src/renderer/Model.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index ebc1b97aa6..8db0d3b000 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -1199,13 +1199,13 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { for (int i = 0; i < networkMeshes.size(); i++) { // exit early if the translucency doesn't match what we're drawing const NetworkMesh& networkMesh = networkMeshes.at(i); - if (translucent ? (networkMesh.getTranslucentPartCount() == 0) : - (networkMesh.getTranslucentPartCount() == networkMesh.parts.size())) { + const FBXMesh& mesh = geometry.meshes.at(i); + if (translucent ? (networkMesh.getTranslucentPartCount(mesh) == 0) : + (networkMesh.getTranslucentPartCount(mesh) == networkMesh.parts.size())) { continue; } const_cast(networkMesh.indexBuffer).bind(); - const FBXMesh& mesh = geometry.meshes.at(i); int vertexCount = mesh.vertices.size(); if (vertexCount == 0) { // sanity check diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 68484a3f71..381e373449 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -185,6 +185,8 @@ public: QVector& getJointStates() { return _jointStates; } const QVector& getJointStates() const { return _jointStates; } + void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority); + protected: QSharedPointer _geometry; @@ -240,8 +242,6 @@ protected: bool useRotation = false, int lastFreeIndex = -1, bool allIntermediatesFree = false, const glm::vec3& alignment = glm::vec3(0.0f, -1.0f, 0.0f), float priority = 1.0f); - void inverseKinematics(int jointIndex, glm::vec3 position, const glm::quat& rotation, float priority); - /// Restores the indexed joint to its default position. /// \param fraction the fraction of the default position to apply (i.e., 0.25f to slerp one fourth of the way to /// the original position From 5c22fe7bd1bbd8476ebf4fa00830675c9eb8d0c2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 13:27:15 -0700 Subject: [PATCH 26/43] Translucency tweak. --- interface/src/renderer/Model.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 8db0d3b000..a4f09d12c3 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -439,12 +439,12 @@ bool Model::render(float alpha, RenderMode mode) { renderMeshes(mode, false); - glDisable(GL_ALPHA_TEST); - // render translucent meshes afterwards renderMeshes(mode, true); + glDisable(GL_ALPHA_TEST); + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); glDisable(GL_CULL_FACE); From b9ae005e53da18080f0055c379215f9596f807f9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 16:12:46 -0700 Subject: [PATCH 27/43] Working on the actual deferred lights. --- .../resources/shaders/deferred_light.vert | 17 +++ interface/resources/shaders/point_light.frag | 69 ++++++++++ interface/resources/shaders/spot_light.frag | 71 +++++++++++ .../src/renderer/DeferredLightingEffect.cpp | 119 ++++++++++++++++-- .../src/renderer/DeferredLightingEffect.h | 39 ++++++ interface/src/renderer/Model.cpp | 12 +- interface/src/renderer/Model.h | 3 - 7 files changed, 308 insertions(+), 22 deletions(-) create mode 100644 interface/resources/shaders/deferred_light.vert create mode 100644 interface/resources/shaders/point_light.frag create mode 100644 interface/resources/shaders/spot_light.frag diff --git a/interface/resources/shaders/deferred_light.vert b/interface/resources/shaders/deferred_light.vert new file mode 100644 index 0000000000..88076165a7 --- /dev/null +++ b/interface/resources/shaders/deferred_light.vert @@ -0,0 +1,17 @@ +#version 120 + +// +// deferred_light.vert +// vertex shader +// +// Created by Andrzej Kapolka on 9/18/14. +// Copyright 2014 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 +// + +void main(void) { + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; +} diff --git a/interface/resources/shaders/point_light.frag b/interface/resources/shaders/point_light.frag new file mode 100644 index 0000000000..31de0fe7d2 --- /dev/null +++ b/interface/resources/shaders/point_light.frag @@ -0,0 +1,69 @@ +#version 120 + +// +// spot_light.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/18/14. +// Copyright 2014 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 +// + +// the diffuse texture +uniform sampler2D diffuseMap; + +// the normal texture +uniform sampler2D normalMap; + +// the specular texture +uniform sampler2D specularMap; + +// the depth texture +uniform sampler2D depthMap; + +// the distance to the near clip plane +uniform float near; + +// scale factor for depth: (far - near) / far +uniform float depthScale; + +// offset for depth texture coordinates +uniform vec2 depthTexCoordOffset; + +// scale for depth texture coordinates +uniform vec2 depthTexCoordScale; + +// the radius (hard cutoff) of the light effect +uniform float radius; + +void main(void) { + // compute the view space position using the depth + float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0); + vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0); + + // get the normal from the map + vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); + vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); + + // compute the base color based on OpenGL lighting model + vec4 lightVector = gl_LightSource[1].position - position; + float lightDistance = length(lightVector); + lightVector = lightVector / lightDistance; + float diffuse = dot(normalizedNormal, lightVector); + float facingLight = step(0.0, diffuse); + vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightProduct[1].ambient + + gl_FrontLightProduct[1].diffuse * (diffuse * facingLight)); + + // compute attenuation based on distance, etc. + float attenuation = step(lightDistance, radius) / dot(vec3(gl_LightSource[1].constantAttenuation, + gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), + vec3(1.0, lightDistance, lightDistance * lightDistance)); + + // add base to specular, modulate by attenuation + float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))), + normalizedNormal)); + vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); + gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); +} diff --git a/interface/resources/shaders/spot_light.frag b/interface/resources/shaders/spot_light.frag new file mode 100644 index 0000000000..33469be0c7 --- /dev/null +++ b/interface/resources/shaders/spot_light.frag @@ -0,0 +1,71 @@ +#version 120 + +// +// spot_light.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/18/14. +// Copyright 2014 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 +// + +// the diffuse texture +uniform sampler2D diffuseMap; + +// the normal texture +uniform sampler2D normalMap; + +// the specular texture +uniform sampler2D specularMap; + +// the depth texture +uniform sampler2D depthMap; + +// the distance to the near clip plane +uniform float near; + +// scale factor for depth: (far - near) / far +uniform float depthScale; + +// offset for depth texture coordinates +uniform vec2 depthTexCoordOffset; + +// scale for depth texture coordinates +uniform vec2 depthTexCoordScale; + +// the radius (hard cutoff) of the light effect +uniform float radius; + +void main(void) { + // compute the view space position using the depth + float z = near / (texture2D(depthMap, gl_TexCoord[0].st).r * depthScale - 1.0); + vec4 position = vec4((depthTexCoordOffset + gl_TexCoord[0].st * depthTexCoordScale) * z, z, 1.0); + + // get the normal from the map + vec4 normal = texture2D(normalMap, gl_TexCoord[0].st); + vec4 normalizedNormal = normalize(normal * 2.0 - vec4(1.0, 1.0, 1.0, 2.0)); + + // compute the base color based on OpenGL lighting model + vec4 lightVector = gl_LightSource[1].position - position; + float lightDistance = length(lightVector); + lightVector = lightVector / lightDistance; + float diffuse = dot(normalizedNormal, lightVector); + float facingLight = step(0.0, diffuse); + vec4 baseColor = texture2D(diffuseMap, gl_TexCoord[0].st) * (gl_FrontLightProduct[1].ambient + + gl_FrontLightProduct[1].diffuse * (diffuse * facingLight)); + + // compute attenuation based on spot angle, distance, etc. + float cosSpotAngle = max(-dot(lightVector.xyz, gl_LightSource[1].spotDirection), 0.0); + float attenuation = step(lightDistance, radius) * step(gl_LightSource[1].spotCosCutoff, cosSpotAngle) * + pow(cosSpotAngle, gl_LightSource[1].spotExponent) / dot(vec3(gl_LightSource[1].constantAttenuation, + gl_LightSource[1].linearAttenuation, gl_LightSource[1].quadraticAttenuation), + vec3(1.0, lightDistance, lightDistance * lightDistance)); + + // add base to specular, modulate by attenuation + float specular = facingLight * max(0.0, dot(normalize(lightVector - normalize(vec4(position.xyz, 0.0))), + normalizedNormal)); + vec4 specularColor = texture2D(specularMap, gl_TexCoord[0].st); + gl_FragColor = vec4((baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb) * attenuation, 0.0); +} diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 48fbf30898..198cb50f13 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -32,6 +32,8 @@ void DeferredLightingEffect::init() { _directionalLightShadowMapLocations); loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap, _directionalLightCascadedShadowMapLocations); + loadLightProgram("shaders/point_light.frag", _pointLight, _pointLightLocations); + loadLightProgram("shaders/spot_light.frag", _spotLight, _spotLightLocations); } void DeferredLightingEffect::bindSimpleProgram() { @@ -71,6 +73,42 @@ void DeferredLightingEffect::renderWireCube(float size) { releaseSimpleProgram(); } +void DeferredLightingEffect::addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient, + const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, + float linearAttenuation, float quadraticAttenuation) { + addSpotLight(position, radius, ambient, diffuse, specular, constantAttenuation, linearAttenuation, quadraticAttenuation); +} + +void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient, + const glm::vec3& diffuse, const glm::vec3& specular, float constantAttenuation, float linearAttenuation, + float quadraticAttenuation, const glm::vec3& direction, float exponent, float cutoff) { + if (exponent == 0.0f && cutoff == PI) { + PointLight light; + light.position = glm::vec4(position, 1.0f); + light.radius = radius; + light.ambient = glm::vec4(ambient, 1.0f); + light.diffuse = glm::vec4(diffuse, 1.0f); + light.specular = glm::vec4(specular, 1.0f); + light.constantAttenuation = constantAttenuation; + light.linearAttenuation = linearAttenuation; + _pointLights.append(light); + + } else { + SpotLight light; + light.position = glm::vec4(position, 1.0f); + light.radius = radius; + light.ambient = glm::vec4(ambient, 1.0f); + light.diffuse = glm::vec4(diffuse, 1.0f); + light.specular = glm::vec4(specular, 1.0f); + light.constantAttenuation = constantAttenuation; + light.linearAttenuation = linearAttenuation; + light.direction = direction; + light.exponent = exponent; + light.cutoff = cutoff; + _spotLights.append(light); + } +} + void DeferredLightingEffect::prepare() { // clear the normal and specular buffers Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, false); @@ -86,13 +124,6 @@ void DeferredLightingEffect::prepare() { void DeferredLightingEffect::render() { // perform deferred lighting, rendering to free fbo - glPushMatrix(); - glLoadIdentity(); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glDisable(GL_BLEND); @@ -162,12 +193,14 @@ void DeferredLightingEffect::render() { Application::getInstance()->computeOffAxisFrustum( left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane); program->setUniformValue(locations->nearLocation, nearVal); - program->setUniformValue(locations->depthScale, (farVal - nearVal) / farVal); + float depthScale = (farVal - nearVal) / farVal; + program->setUniformValue(locations->depthScale, depthScale); float nearScale = -1.0f / nearVal; float depthTexCoordScaleS = (right - left) * nearScale / sWidth; float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight; - program->setUniformValue(locations->depthTexCoordOffset, left * nearScale - sMin * depthTexCoordScaleS, - bottom * nearScale - tMin * depthTexCoordScaleT); + float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS; + float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT; + program->setUniformValue(locations->depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); program->setUniformValue(locations->depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); @@ -179,6 +212,61 @@ void DeferredLightingEffect::render() { glActiveTexture(GL_TEXTURE3); } + // additive blending + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + if (!_pointLights.isEmpty()) { + _pointLight.bind(); + _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); + _pointLight.setUniformValue(_pointLightLocations.depthScale, depthScale); + _pointLight.setUniformValue(_pointLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); + _pointLight.setUniformValue(_pointLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); + + foreach (const PointLight& light, _pointLights) { + _pointLight.setUniformValue(_pointLightLocations.radius, light.radius); + glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); + glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position); + glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, light.constantAttenuation); + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation); + glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation); + + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); + } + _pointLights.clear(); + + _pointLight.release(); + } + + if (!_spotLights.isEmpty()) { + _spotLight.bind(); + _spotLight.setUniformValue(_spotLightLocations.nearLocation, nearVal); + _spotLight.setUniformValue(_spotLightLocations.depthScale, depthScale); + _spotLight.setUniformValue(_spotLightLocations.depthTexCoordOffset, depthTexCoordOffsetS, depthTexCoordOffsetT); + _spotLight.setUniformValue(_spotLightLocations.depthTexCoordScale, depthTexCoordScaleS, depthTexCoordScaleT); + + foreach (const SpotLight& light, _spotLights) { + _spotLight.setUniformValue(_spotLightLocations.radius, light.radius); + glLightfv(GL_LIGHT1, GL_AMBIENT, (const GLfloat*)&light.ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, (const GLfloat*)&light.diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, (const GLfloat*)&light.specular); + glLightfv(GL_LIGHT1, GL_POSITION, (const GLfloat*)&light.position); + glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, light.constantAttenuation); + glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation); + glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation); + glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, (const GLfloat*)&light.direction); + glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent); + glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff)); + + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); + } + _spotLights.clear(); + + _spotLight.release(); + } + glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE2); @@ -193,7 +281,7 @@ void DeferredLightingEffect::render() { freeFBO->release(); // now transfer the lit region to the primary fbo - glEnable(GL_BLEND); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); glColorMask(true, true, true, false); primaryFBO->bind(); @@ -201,6 +289,13 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, freeFBO->texture()); glEnable(GL_TEXTURE_2D); + glPushMatrix(); + glLoadIdentity(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); glBindTexture(GL_TEXTURE_2D, 0); @@ -225,6 +320,7 @@ void DeferredLightingEffect::render() { } void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) { + program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/deferred_light.vert"); program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name); program.link(); @@ -240,5 +336,6 @@ void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& p locations.depthScale = program.uniformLocation("depthScale"); locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset"); locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); + locations.radius = program.uniformLocation("radius"); program.release(); } diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index 1953afd4c3..6eb8947689 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -14,6 +14,8 @@ #include +#include + #include "ProgramObject.h" class PostLightingRenderable; @@ -46,6 +48,17 @@ public: //// Renders a wireframe cube with the simple program. void renderWireCube(float size); + /// Adds a point light to render for the current frame. + void addPointLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f), + const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f), + float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f); + + /// Adds a spot light to render for the current frame. + void addSpotLight(const glm::vec3& position, float radius, const glm::vec3& ambient = glm::vec3(0.0f, 0.0f, 0.0f), + const glm::vec3& diffuse = glm::vec3(1.0f, 1.0f, 1.0f), const glm::vec3& specular = glm::vec3(1.0f, 1.0f, 1.0f), + float constantAttenuation = 1.0f, float linearAttenuation = 0.0f, float quadraticAttenuation = 0.0f, + const glm::vec3& direction = glm::vec3(0.0f, 0.0f, -1.0f), float exponent = 0.0f, float cutoff = PI); + /// Adds an object to render after performing the deferred lighting for the current frame (e.g., a translucent object). void addPostLightingRenderable(PostLightingRenderable* renderable) { _postLightingRenderables.append(renderable); } @@ -62,6 +75,7 @@ private: int depthScale; int depthTexCoordOffset; int depthTexCoordScale; + int radius; }; static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); @@ -75,7 +89,32 @@ private: LightLocations _directionalLightShadowMapLocations; ProgramObject _directionalLightCascadedShadowMap; LightLocations _directionalLightCascadedShadowMapLocations; + ProgramObject _pointLight; + LightLocations _pointLightLocations; + ProgramObject _spotLight; + LightLocations _spotLightLocations; + class PointLight { + public: + glm::vec4 position; + float radius; + glm::vec4 ambient; + glm::vec4 diffuse; + glm::vec4 specular; + float constantAttenuation; + float linearAttenuation; + float quadraticAttenuation; + }; + + class SpotLight : public PointLight { + public: + glm::vec3 direction; + float exponent; + float cutoff; + }; + + QVector _pointLights; + QVector _spotLights; QVector _postLightingRenderables; }; diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index a4f09d12c3..edbbcb04cb 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -414,14 +414,10 @@ bool Model::render(float alpha, RenderMode mode) { glCullFace(GL_FRONT); } else if (mode == DEFAULT_RENDER_MODE) { - // update the local lights - for (int i = 0; i < MAX_LOCAL_LIGHTS; i++) { - if (i < _localLights.size()) { - _localLightDirections[i] = glm::normalize(Application::getInstance()->getUntranslatedViewMatrix() * - glm::vec4(_rotation * _localLights.at(i).direction, 0.0f)); - } else { - _localLightColors[i] = glm::vec4(); - } + // add the local lights + foreach (const LocalLight& light, _localLights) { + Application::getInstance()->getDeferredLightingEffect()->addSpotLight(glm::vec3(), 1.0f, glm::vec3(), + light.color, light.color, 1.0f, 0.0f, 0.0f); } } } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index 381e373449..a9bc775d0a 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -284,9 +284,6 @@ private: QList _runningAnimations; - glm::vec4 _localLightColors[MAX_LOCAL_LIGHTS]; - glm::vec4 _localLightDirections[MAX_LOCAL_LIGHTS]; - QVector _blendedBlendshapeCoefficients; int _blendNumber; int _appliedBlendNumber; From c6aad42f21e8522acb097b1a388a16155a8cf7d4 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 17:09:53 -0700 Subject: [PATCH 28/43] Move LocalLight to AvatarManager, apply it at the avatar level. --- interface/src/Application.cpp | 4 ++-- interface/src/avatar/Avatar.cpp | 20 +++++++++++------ interface/src/avatar/AvatarManager.cpp | 30 +++++++++++++++++++++----- interface/src/avatar/AvatarManager.h | 19 +++++++++++++--- interface/src/renderer/Model.cpp | 26 ---------------------- interface/src/renderer/Model.h | 18 ---------------- 6 files changed, 57 insertions(+), 60 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 28a1b8b84b..a33a4e4595 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3800,8 +3800,8 @@ ScriptEngine* Application::loadScript(const QString& scriptFilename, bool isUser scriptEngine->getEntityScriptingInterface()->setPacketSender(&_entityEditSender); scriptEngine->getEntityScriptingInterface()->setEntityTree(_entities.getTree()); - // model has some custom types - Model::registerMetaTypes(scriptEngine); + // AvatarManager has some custom types + AvatarManager::registerMetaTypes(scriptEngine); // hook our avatar object into this script engine scriptEngine->setAvatarData(_myAvatar, "MyAvatar"); // leave it as a MyAvatar class to expose thrust features diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 469494760e..67a00d21df 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -345,17 +345,25 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { ? 1.0f : GLOW_FROM_AVERAGE_LOUDNESS; - - // local lights directions and colors - const QVector& localLights = Application::getInstance()->getAvatarManager().getLocalLights(); - _skeletonModel.setLocalLights(localLights); - getHead()->getFaceModel().setLocalLights(localLights); - // render body if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { renderBody(renderMode, glowLevel); } if (renderMode != SHADOW_RENDER_MODE) { + // add local lights + const float BASE_LIGHT_DISTANCE = 2.0f; + const float LIGHT_EXPONENT = 1.0f; + const float LIGHT_CUTOFF = glm::radians(80.0f); + float distance = BASE_LIGHT_DISTANCE * _scale; + glm::vec3 position = glm::mix(getPosition(), getHead()->getEyePosition(), 0.75f); + glm::quat orientation = getOrientation(); + foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { + glm::vec3 direction = orientation * light.direction; + Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, + distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.0f, 0.0f, direction, + LIGHT_EXPONENT, LIGHT_CUTOFF); + } + bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes); bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes); bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 0a9cbfe762..a5e74e42ba 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -11,9 +11,12 @@ #include +#include + #include #include +#include #include #include "Application.h" @@ -26,6 +29,23 @@ // We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key. const QUuid MY_AVATAR_KEY; // NULL key +static QScriptValue localLightToScriptValue(QScriptEngine* engine, const AvatarManager::LocalLight& light) { + QScriptValue object = engine->newObject(); + object.setProperty("direction", vec3toScriptValue(engine, light.direction)); + object.setProperty("color", vec3toScriptValue(engine, light.color)); + return object; +} + +static void localLightFromScriptValue(const QScriptValue& value, AvatarManager::LocalLight& light) { + vec3FromScriptValue(value.property("direction"), light.direction); + vec3FromScriptValue(value.property("color"), light.color); +} + +void AvatarManager::registerMetaTypes(QScriptEngine* engine) { + qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); + qScriptRegisterSequenceMetaType >(engine); +} + AvatarManager::AvatarManager(QObject* parent) : _avatarFades() { // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar @@ -159,19 +179,19 @@ void AvatarManager::clearOtherAvatars() { _myAvatar->clearLookAtTargetAvatar(); } -void AvatarManager::setLocalLights(const QVector& localLights) { +void AvatarManager::setLocalLights(const QVector& localLights) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector&, localLights)); + QMetaObject::invokeMethod(this, "setLocalLights", Q_ARG(const QVector&, localLights)); return; } _localLights = localLights; } -QVector AvatarManager::getLocalLights() const { +QVector AvatarManager::getLocalLights() const { if (QThread::currentThread() != thread()) { - QVector result; + QVector result; QMetaObject::invokeMethod(const_cast(this), "getLocalLights", Qt::BlockingQueuedConnection, - Q_RETURN_ARG(QVector, result)); + Q_RETURN_ARG(QVector, result)); return result; } return _localLights; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index ccb7459217..48f0546373 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -26,6 +26,10 @@ class AvatarManager : public AvatarHashMap { Q_OBJECT public: + + /// Registers the script types associated with the avatar manager. + static void registerMetaTypes(QScriptEngine* engine); + AvatarManager(QObject* parent = 0); void init(); @@ -37,8 +41,14 @@ public: void clearOtherAvatars(); - Q_INVOKABLE void setLocalLights(const QVector& localLights); - Q_INVOKABLE QVector getLocalLights() const; + class LocalLight { + public: + glm::vec3 color; + glm::vec3 direction; + }; + + Q_INVOKABLE void setLocalLights(const QVector& localLights); + Q_INVOKABLE QVector getLocalLights() const; private: AvatarManager(const AvatarManager& other); @@ -54,7 +64,10 @@ private: QVector _avatarFades; QSharedPointer _myAvatar; - QVector _localLights; + QVector _localLights; }; +Q_DECLARE_METATYPE(AvatarManager::LocalLight) +Q_DECLARE_METATYPE(QVector) + #endif // hifi_AvatarManager_h diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index edbbcb04cb..56ab0c8219 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include #include @@ -33,23 +31,6 @@ static int modelPointerTypeId = qRegisterMetaType >(); static int weakNetworkGeometryPointerTypeId = qRegisterMetaType >(); static int vec3VectorTypeId = qRegisterMetaType >(); -static QScriptValue localLightToScriptValue(QScriptEngine* engine, const Model::LocalLight& light) { - QScriptValue object = engine->newObject(); - object.setProperty("direction", vec3toScriptValue(engine, light.direction)); - object.setProperty("color", vec3toScriptValue(engine, light.color)); - return object; -} - -static void localLightFromScriptValue(const QScriptValue& value, Model::LocalLight& light) { - vec3FromScriptValue(value.property("direction"), light.direction); - vec3FromScriptValue(value.property("color"), light.color); -} - -void Model::registerMetaTypes(QScriptEngine* engine) { - qScriptRegisterMetaType(engine, localLightToScriptValue, localLightFromScriptValue); - qScriptRegisterSequenceMetaType >(engine); -} - Model::Model(QObject* parent) : QObject(parent), _scale(1.0f, 1.0f, 1.0f), @@ -412,13 +393,6 @@ bool Model::render(float alpha, RenderMode mode) { glEnable(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { glCullFace(GL_FRONT); - - } else if (mode == DEFAULT_RENDER_MODE) { - // add the local lights - foreach (const LocalLight& light, _localLights) { - Application::getInstance()->getDeferredLightingEffect()->addSpotLight(glm::vec3(), 1.0f, glm::vec3(), - light.color, light.color, 1.0f, 0.0f, 0.0f); - } } } diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index a9bc775d0a..fbf0167844 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -34,17 +34,12 @@ class Shape; typedef QSharedPointer AnimationHandlePointer; typedef QWeakPointer WeakAnimationHandlePointer; -const int MAX_LOCAL_LIGHTS = 2; - /// A generic 3D model displaying geometry loaded from a URL. class Model : public QObject, public PhysicsEntity { Q_OBJECT public: - /// Registers the script types associated with models. - static void registerMetaTypes(QScriptEngine* engine); - Model(QObject* parent = NULL); virtual ~Model(); @@ -171,15 +166,6 @@ public: void setBlendedVertices(int blendNumber, const QWeakPointer& geometry, const QVector& vertices, const QVector& normals); - class LocalLight { - public: - glm::vec3 color; - glm::vec3 direction; - }; - - void setLocalLights(const QVector& localLights) { _localLights = localLights; } - const QVector& getLocalLights() const { return _localLights; } - void setShowTrueJointTransforms(bool show) { _showTrueJointTransforms = show; } QVector& getJointStates() { return _jointStates; } @@ -203,8 +189,6 @@ protected: bool _showTrueJointTransforms; - QVector _localLights; - QVector _jointStates; class MeshState { @@ -336,8 +320,6 @@ private: Q_DECLARE_METATYPE(QPointer) Q_DECLARE_METATYPE(QWeakPointer) Q_DECLARE_METATYPE(QVector) -Q_DECLARE_METATYPE(Model::LocalLight) -Q_DECLARE_METATYPE(QVector) /// Represents a handle to a model animation. class AnimationHandle : public QObject { From e356b06c757e7d98f17fbc499a4cdbc240fdafac Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 18 Sep 2014 17:39:40 -0700 Subject: [PATCH 29/43] Fix for lights in rear view mirror/head mode. --- interface/src/avatar/Avatar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 67a00d21df..125d134657 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -355,12 +355,12 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { const float LIGHT_EXPONENT = 1.0f; const float LIGHT_CUTOFF = glm::radians(80.0f); float distance = BASE_LIGHT_DISTANCE * _scale; - glm::vec3 position = glm::mix(getPosition(), getHead()->getEyePosition(), 0.75f); + glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); glm::quat orientation = getOrientation(); foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { glm::vec3 direction = orientation * light.direction; Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, - distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.0f, 0.0f, direction, + distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, LIGHT_EXPONENT, LIGHT_CUTOFF); } From 446c2193ff19bc496c5c132b53f66c6968899960 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 12:18:00 -0700 Subject: [PATCH 30/43] Limit what we render for deferred point/spot lights based on the light's radius. --- .../shaders/deferred_light_limited.vert | 60 +++++++++++++++++++ .../src/renderer/DeferredLightingEffect.cpp | 24 +++++--- .../src/renderer/DeferredLightingEffect.h | 2 +- 3 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 interface/resources/shaders/deferred_light_limited.vert diff --git a/interface/resources/shaders/deferred_light_limited.vert b/interface/resources/shaders/deferred_light_limited.vert new file mode 100644 index 0000000000..8a69632f44 --- /dev/null +++ b/interface/resources/shaders/deferred_light_limited.vert @@ -0,0 +1,60 @@ +#version 120 + +// +// deferred_light_limited.vert +// vertex shader +// +// Created by Andrzej Kapolka on 9/19/14. +// Copyright 2014 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 +// + +// the radius (hard cutoff) of the light effect +uniform float radius; + +void main(void) { + // find the right "right" direction + vec3 firstRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(0.0, 1.0, 0.0)); + vec3 secondRightCandidate = cross(gl_LightSource[1].spotDirection, vec3(1.0, 0.0, 0.0)); + vec3 right = mix(firstRightCandidate, secondRightCandidate, step(length(firstRightCandidate), length(secondRightCandidate))); + right = normalize(right); + + // and the "up" + vec3 up = cross(right, gl_LightSource[1].spotDirection); + + // and the "back," which depends on whether this is a spot light + vec3 back = -gl_LightSource[1].spotDirection * step(gl_LightSource[1].spotCosCutoff, 0.0); + + // find the eight corners of the bounds + vec4 c0 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (-up - right + back), 1.0); + vec4 c1 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (-up + right + back), 1.0); + vec4 c2 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (up - right + back), 1.0); + vec4 c3 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (up + right + back), 1.0); + vec4 c4 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (-up - right + gl_LightSource[1].spotDirection), 1.0); + vec4 c5 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (-up + right + gl_LightSource[1].spotDirection), 1.0); + vec4 c6 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (up - right + gl_LightSource[1].spotDirection), 1.0); + vec4 c7 = gl_ProjectionMatrix * vec4(gl_LightSource[1].position.xyz + + radius * (up + right + gl_LightSource[1].spotDirection), 1.0); + + // find their projected extents + vec2 extents = max( + max(max(gl_Vertex.xy * (c0.xy / max(c0.w, 0.001)), gl_Vertex.xy * (c1.xy / max(c1.w, 0.001))), + max(gl_Vertex.xy * (c2.xy / max(c2.w, 0.001)), gl_Vertex.xy * (c3.xy / max(c3.w, 0.001)))), + max(max(gl_Vertex.xy * (c4.xy / max(c4.w, 0.001)), gl_Vertex.xy * (c5.xy / max(c5.w, 0.001))), + max(gl_Vertex.xy * (c6.xy / max(c6.w, 0.001)), gl_Vertex.xy * (c7.xy / max(c7.w, 0.001))))); + + // make sure they don't extend beyond the screen + extents = min(extents, vec2(1.0, 1.0)); + + gl_Position = vec4(gl_Vertex.xy * extents, 0.0, 1.0); + gl_TexCoord[0] = vec4(dot(gl_Position, gl_ObjectPlaneS[3]), dot(gl_Position, gl_ObjectPlaneT[3]), 0.0, 1.0); +} diff --git a/interface/src/renderer/DeferredLightingEffect.cpp b/interface/src/renderer/DeferredLightingEffect.cpp index 198cb50f13..585fa9b31c 100644 --- a/interface/src/renderer/DeferredLightingEffect.cpp +++ b/interface/src/renderer/DeferredLightingEffect.cpp @@ -27,13 +27,13 @@ void DeferredLightingEffect::init() { _glowIntensityLocation = _simpleProgram.uniformLocation("glowIntensity"); _simpleProgram.release(); - loadLightProgram("shaders/directional_light.frag", _directionalLight, _directionalLightLocations); - loadLightProgram("shaders/directional_light_shadow_map.frag", _directionalLightShadowMap, + loadLightProgram("shaders/directional_light.frag", false, _directionalLight, _directionalLightLocations); + loadLightProgram("shaders/directional_light_shadow_map.frag", false, _directionalLightShadowMap, _directionalLightShadowMapLocations); - loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", _directionalLightCascadedShadowMap, + loadLightProgram("shaders/directional_light_cascaded_shadow_map.frag", false, _directionalLightCascadedShadowMap, _directionalLightCascadedShadowMapLocations); - loadLightProgram("shaders/point_light.frag", _pointLight, _pointLightLocations); - loadLightProgram("shaders/spot_light.frag", _spotLight, _spotLightLocations); + loadLightProgram("shaders/point_light.frag", true, _pointLight, _pointLightLocations); + loadLightProgram("shaders/spot_light.frag", true, _spotLight, _spotLightLocations); } void DeferredLightingEffect::bindSimpleProgram() { @@ -216,6 +216,11 @@ void DeferredLightingEffect::render() { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); + glm::vec4 sCoefficients(sWidth / 2.0f, 0.0f, 0.0f, sMin + sWidth / 2.0f); + glm::vec4 tCoefficients(0.0f, tHeight / 2.0f, 0.0f, tMin + tHeight / 2.0f); + glTexGenfv(GL_S, GL_OBJECT_PLANE, (const GLfloat*)&sCoefficients); + glTexGenfv(GL_T, GL_OBJECT_PLANE, (const GLfloat*)&tCoefficients); + if (!_pointLights.isEmpty()) { _pointLight.bind(); _pointLight.setUniformValue(_pointLightLocations.nearLocation, nearVal); @@ -233,7 +238,7 @@ void DeferredLightingEffect::render() { glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, light.linearAttenuation); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, light.quadraticAttenuation); - renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); + renderFullscreenQuad(); } _pointLights.clear(); @@ -260,7 +265,7 @@ void DeferredLightingEffect::render() { glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, light.exponent); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, glm::degrees(light.cutoff)); - renderFullscreenQuad(sMin, sMin + sWidth, tMin, tMin + tHeight); + renderFullscreenQuad(); } _spotLights.clear(); @@ -319,8 +324,9 @@ void DeferredLightingEffect::render() { _postLightingRenderables.clear(); } -void DeferredLightingEffect::loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations) { - program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/deferred_light.vert"); +void DeferredLightingEffect::loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations) { + program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + + (limited ? "shaders/deferred_light_limited.vert" : "shaders/deferred_light.vert")); program.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + name); program.link(); diff --git a/interface/src/renderer/DeferredLightingEffect.h b/interface/src/renderer/DeferredLightingEffect.h index 6eb8947689..33fe6b474d 100644 --- a/interface/src/renderer/DeferredLightingEffect.h +++ b/interface/src/renderer/DeferredLightingEffect.h @@ -78,7 +78,7 @@ private: int radius; }; - static void loadLightProgram(const char* name, ProgramObject& program, LightLocations& locations); + static void loadLightProgram(const char* name, bool limited, ProgramObject& program, LightLocations& locations); ProgramObject _simpleProgram; int _glowIntensityLocation; From 8d3eef708a806d3a670bcbdc36fd31897ca43061 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 13:13:05 -0700 Subject: [PATCH 31/43] Move various avatar render bits to post-lighting section. --- interface/src/Application.cpp | 9 +++++- interface/src/avatar/Avatar.cpp | 42 ++++++++++++++------------ interface/src/avatar/Avatar.h | 3 +- interface/src/avatar/AvatarManager.cpp | 6 ++-- interface/src/avatar/AvatarManager.h | 2 +- interface/src/avatar/MyAvatar.cpp | 6 ++-- interface/src/avatar/MyAvatar.h | 2 +- 7 files changed, 40 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6b77cd6274..e1ee1333ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2910,7 +2910,8 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { bool mirrorMode = (whichCamera.getInterpolatedMode() == CAMERA_MODE_MIRROR); { PerformanceTimer perfTimer("avatars"); - _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, selfAvatarOnly); + _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, + false, selfAvatarOnly); } { @@ -2918,6 +2919,12 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) { _deferredLightingEffect.render(); } + { + PerformanceTimer perfTimer("avatarsPostLighting"); + _avatarManager.renderAvatars(mirrorMode ? Avatar::MIRROR_RENDER_MODE : Avatar::NORMAL_RENDER_MODE, + true, selfAvatarOnly); + } + //Render the sixense lasers if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseLasers)) { _myAvatar->renderLaserPointers(); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index afa3c70ed7..539c24e68e 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -273,13 +273,12 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { +void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool postLighting) { if (_referential) { _referential->update(); } - if (glm::distance(Application::getInstance()->getAvatar()->getPosition(), - _position) < 10.0f) { + if (postLighting && glm::distance(Application::getInstance()->getAvatar()->getPosition(), _position) < 10.0f) { // render pointing lasers glm::vec3 laserColor = glm::vec3(1.0f, 0.0f, 1.0f); float laserLength = 50.0f; @@ -352,24 +351,27 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { : GLOW_FROM_AVERAGE_LOUDNESS; // render body - if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { + if (!postLighting && Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { renderBody(renderMode, glowLevel); - } - if (renderMode != SHADOW_RENDER_MODE) { - // add local lights - const float BASE_LIGHT_DISTANCE = 2.0f; - const float LIGHT_EXPONENT = 1.0f; - const float LIGHT_CUTOFF = glm::radians(80.0f); - float distance = BASE_LIGHT_DISTANCE * _scale; - glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); - glm::quat orientation = getOrientation(); - foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { - glm::vec3 direction = orientation * light.direction; - Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, - distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, - LIGHT_EXPONENT, LIGHT_CUTOFF); + + if (renderMode != SHADOW_RENDER_MODE) { + // add local lights + const float BASE_LIGHT_DISTANCE = 2.0f; + const float LIGHT_EXPONENT = 1.0f; + const float LIGHT_CUTOFF = glm::radians(80.0f); + float distance = BASE_LIGHT_DISTANCE * _scale; + glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); + glm::quat orientation = getOrientation(); + foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { + glm::vec3 direction = orientation * light.direction; + Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, + distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, + LIGHT_EXPONENT, LIGHT_CUTOFF); + } } + } + if (postLighting) { bool renderSkeleton = Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionShapes); bool renderHead = Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionShapes); bool renderBounding = Menu::getInstance()->isOptionChecked(MenuOption::RenderBoundingCollisionShapes); @@ -405,7 +407,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { // quick check before falling into the code below: // (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m) const float MIN_VOICE_SPHERE_DISTANCE = 12.0f; - if (Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere) + if (postLighting && Menu::getInstance()->isOptionChecked(MenuOption::BlueSpeechSphere) && distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) { // render voice intensity sphere for avatars that are farther away @@ -433,7 +435,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { const float DISPLAYNAME_DISTANCE = 20.0f; setShowDisplayName(renderMode == NORMAL_RENDER_MODE && distanceToTarget < DISPLAYNAME_DISTANCE); - if (renderMode != NORMAL_RENDER_MODE || (isMyAvatar() && + if (!postLighting || renderMode != NORMAL_RENDER_MODE || (isMyAvatar() && Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON)) { return; } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index c449a0d1b9..2dbd7d5dd6 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -79,7 +79,8 @@ public: enum RenderMode { NORMAL_RENDER_MODE, SHADOW_RENDER_MODE, MIRROR_RENDER_MODE }; - virtual void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE); + virtual void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, + bool postLighting = false); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index a5e74e42ba..ba5ba8141d 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -99,7 +99,7 @@ void AvatarManager::updateOtherAvatars(float deltaTime) { simulateAvatarFades(deltaTime); } -void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly) { +void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool postLighting, bool selfAvatarOnly) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::RenderLookAtVectors); @@ -112,13 +112,13 @@ void AvatarManager::renderAvatars(Avatar::RenderMode renderMode, bool selfAvatar if (!avatar->isInitialized()) { continue; } - avatar->render(cameraPosition, renderMode); + avatar->render(cameraPosition, renderMode, postLighting); avatar->setDisplayingLookatVectors(renderLookAtVectors); } renderAvatarFades(cameraPosition, renderMode); } else { // just render myAvatar - _myAvatar->render(cameraPosition, renderMode); + _myAvatar->render(cameraPosition, renderMode, postLighting); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 48f0546373..add6e45758 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -37,7 +37,7 @@ public: MyAvatar* getMyAvatar() { return _myAvatar.data(); } void updateOtherAvatars(float deltaTime); - void renderAvatars(Avatar::RenderMode renderMode, bool selfAvatarOnly = false); + void renderAvatars(Avatar::RenderMode renderMode, bool postLighting = false, bool selfAvatarOnly = false); void clearOtherAvatars(); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ca141ea382..72f42cc002 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -411,16 +411,16 @@ void MyAvatar::renderDebugBodyPoints() { } // virtual -void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode) { +void MyAvatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool postLighting) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early } - Avatar::render(cameraPosition, renderMode); + Avatar::render(cameraPosition, renderMode, postLighting); // don't display IK constraints in shadow mode - if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && renderMode != SHADOW_RENDER_MODE) { + if (Menu::getInstance()->isOptionChecked(MenuOption::ShowIKConstraints) && postLighting) { _skeletonModel.renderIKConstraints(); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d553d4f367..8f04afff94 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -48,7 +48,7 @@ public: void updateFromTrackers(float deltaTime); void moveWithLean(); - void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE); + void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, bool postLighting = false); void renderBody(RenderMode renderMode, float glowLevel = 0.0f); bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; void renderDebugBodyPoints(); From 646c0dc48f8f147e7e79c2fdee5dd554d007c2bd Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 15:31:46 -0700 Subject: [PATCH 32/43] Working on translucent model bits. --- interface/resources/shaders/model.frag | 5 +- .../resources/shaders/model_normal_map.frag | 5 +- .../shaders/model_normal_specular_map.frag | 5 +- .../resources/shaders/model_specular_map.frag | 5 +- .../resources/shaders/model_translucent.frag | 20 +++++++ interface/src/renderer/Model.cpp | 54 ++++++++++++++++--- interface/src/renderer/Model.h | 11 ++-- 7 files changed, 91 insertions(+), 14 deletions(-) create mode 100644 interface/resources/shaders/model_translucent.frag diff --git a/interface/resources/shaders/model.frag b/interface/resources/shaders/model.frag index 58a5d24463..82bc70ec46 100644 --- a/interface/resources/shaders/model.frag +++ b/interface/resources/shaders/model.frag @@ -14,13 +14,16 @@ // the diffuse texture uniform sampler2D diffuseMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_map.frag b/interface/resources/shaders/model_normal_map.frag index 28c65f20b4..f5a1047b2b 100644 --- a/interface/resources/shaders/model_normal_map.frag +++ b/interface/resources/shaders/model_normal_map.frag @@ -17,6 +17,9 @@ uniform sampler2D diffuseMap; // the normal map texture uniform sampler2D normalMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 interpolatedNormal; @@ -34,7 +37,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); } diff --git a/interface/resources/shaders/model_normal_specular_map.frag b/interface/resources/shaders/model_normal_specular_map.frag index 3d4f795111..08321c0017 100644 --- a/interface/resources/shaders/model_normal_specular_map.frag +++ b/interface/resources/shaders/model_normal_specular_map.frag @@ -20,6 +20,9 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 interpolatedNormal; @@ -37,7 +40,7 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/resources/shaders/model_specular_map.frag b/interface/resources/shaders/model_specular_map.frag index 0c021d333c..bcf658dc15 100644 --- a/interface/resources/shaders/model_specular_map.frag +++ b/interface/resources/shaders/model_specular_map.frag @@ -17,13 +17,16 @@ uniform sampler2D diffuseMap; // the specular texture uniform sampler2D specularMap; +// the alpha threshold +uniform float alphaThreshold; + // the interpolated normal varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, 0.5))); + gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); diff --git a/interface/resources/shaders/model_translucent.frag b/interface/resources/shaders/model_translucent.frag new file mode 100644 index 0000000000..dbb640d3b1 --- /dev/null +++ b/interface/resources/shaders/model_translucent.frag @@ -0,0 +1,20 @@ +#version 120 + +// +// model_translucent.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/19/14. +// Copyright 2014 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 +// + +// the diffuse texture +uniform sampler2D diffuseMap; + +void main(void) { + // set the diffuse data + gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); +} diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 56ab0c8219..3411097b49 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -58,6 +58,7 @@ ProgramObject Model::_program; ProgramObject Model::_normalMapProgram; ProgramObject Model::_specularMapProgram; ProgramObject Model::_normalSpecularMapProgram; +ProgramObject Model::_translucentProgram; ProgramObject Model::_shadowProgram; @@ -65,6 +66,7 @@ ProgramObject Model::_skinProgram; ProgramObject Model::_skinNormalMapProgram; ProgramObject Model::_skinSpecularMapProgram; ProgramObject Model::_skinNormalSpecularMapProgram; +ProgramObject Model::_skinTranslucentProgram; ProgramObject Model::_skinShadowProgram; @@ -72,12 +74,14 @@ Model::Locations Model::_locations; Model::Locations Model::_normalMapLocations; Model::Locations Model::_specularMapLocations; Model::Locations Model::_normalSpecularMapLocations; +Model::Locations Model::_translucentLocations; Model::SkinLocations Model::_skinLocations; Model::SkinLocations Model::_skinNormalMapLocations; Model::SkinLocations Model::_skinSpecularMapLocations; Model::SkinLocations Model::_skinNormalSpecularMapLocations; Model::SkinLocations Model::_skinShadowLocations; +Model::SkinLocations Model::_skinTranslucentLocations; void Model::setScale(const glm::vec3& scale) { setScaleInternal(scale); @@ -112,6 +116,7 @@ void Model::setOffset(const glm::vec3& offset) { void Model::initProgram(ProgramObject& program, Model::Locations& locations, int specularTextureUnit) { program.bind(); locations.tangent = program.attributeLocation("tangent"); + locations.alphaThreshold = program.uniformLocation("alphaThreshold"); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); program.setUniformValue("specularMap", specularTextureUnit); @@ -192,6 +197,14 @@ void Model::init() { initProgram(_normalSpecularMapProgram, _normalSpecularMapLocations, 2); + _translucentProgram.addShaderFromSourceFile(QGLShader::Vertex, + Application::resourcesPath() + "shaders/model.vert"); + _translucentProgram.addShaderFromSourceFile(QGLShader::Fragment, + Application::resourcesPath() + "shaders/model_translucent.frag"); + _translucentProgram.link(); + + initProgram(_translucentProgram, _translucentLocations); + _shadowProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/model_shadow.vert"); _shadowProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + "shaders/model_shadow.frag"); @@ -234,6 +247,14 @@ void Model::init() { _skinShadowProgram.link(); initSkinProgram(_skinShadowProgram, _skinShadowLocations); + + _skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Vertex, + Application::resourcesPath() + "shaders/skin_model.vert"); + _skinTranslucentProgram.addShaderFromSourceFile(QGLShader::Fragment, + Application::resourcesPath() + "shaders/model_translucent.frag"); + _skinTranslucentProgram.link(); + + initSkinProgram(_skinTranslucentProgram, _skinTranslucentLocations); } } @@ -410,21 +431,31 @@ bool Model::render(float alpha, RenderMode mode) { renderMeshes(mode, false); // render translucent meshes afterwards - - renderMeshes(mode, true); + if (mode == DEFAULT_RENDER_MODE) { + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + renderMeshes(mode, true, 0.75f); + } glDisable(GL_ALPHA_TEST); + glEnable(GL_BLEND); + glDepthMask(false); + glDepthFunc(GL_LEQUAL); + //glEnable(GL_POLYGON_OFFSET_FILL); + //glPolygonOffset(-1.0f, -1.0f); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); + renderMeshes(mode, true, 0.0f); + + //glDisable(GL_POLYGON_OFFSET_FILL); + glDepthMask(true); + glDepthFunc(GL_LESS); glDisable(GL_CULL_FACE); if (mode == SHADOW_RENDER_MODE) { glCullFace(GL_BACK); } - glEnable(GL_BLEND); - // deactivate vertex arrays after drawing glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); @@ -1161,7 +1192,7 @@ void Model::deleteGeometry() { _blendedBlendshapeCoefficients.clear(); } -void Model::renderMeshes(RenderMode mode, bool translucent) { +void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold) { updateVisibleJointStates(); const FBXGeometry& geometry = _geometry->getFBXGeometry(); const QVector& networkMeshes = _geometry->getMeshes(); @@ -1193,6 +1224,12 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { program = &_shadowProgram; skinProgram = &_skinShadowProgram; skinLocations = &_skinShadowLocations; + + } else if (translucent && alphaThreshold == 0.0f) { + program = &_translucentProgram; + locations = &_translucentLocations; + skinProgram = &_skinTranslucentProgram; + skinLocations = &_skinTranslucentLocations; } else if (!mesh.tangents.isEmpty()) { if (mesh.hasSpecularTexture()) { @@ -1242,6 +1279,8 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { program->bind(); } + activeProgram->setUniformValue(activeLocations->alphaThreshold, alphaThreshold); + if (mesh.blendshapes.isEmpty()) { if (!(mesh.tangents.isEmpty() || mode == SHADOW_RENDER_MODE)) { activeProgram->setAttributeBuffer(activeLocations->tangent, GL_FLOAT, vertexCount * 2 * sizeof(glm::vec3), 3); @@ -1277,7 +1316,7 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { for (int j = 0; j < networkMesh.parts.size(); j++) { const NetworkMeshPart& networkPart = networkMesh.parts.at(j); const FBXMeshPart& part = mesh.parts.at(j); - if (networkPart.isTranslucent() != translucent) { + if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); continue; } @@ -1286,7 +1325,8 @@ void Model::renderMeshes(RenderMode mode, bool translucent) { glBindTexture(GL_TEXTURE_2D, 0); } else { - glm::vec4 diffuse = glm::vec4(part.diffuseColor, Application::getInstance()->getGlowEffect()->getIntensity()); + glm::vec4 diffuse = glm::vec4(part.diffuseColor, (translucent && alphaThreshold == 0.0f) ? + part.opacity : Application::getInstance()->getGlowEffect()->getIntensity()); glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); diff --git a/interface/src/renderer/Model.h b/interface/src/renderer/Model.h index fbf0167844..89c47e229d 100644 --- a/interface/src/renderer/Model.h +++ b/interface/src/renderer/Model.h @@ -242,7 +242,7 @@ private: void applyNextGeometry(); void deleteGeometry(); - void renderMeshes(RenderMode mode, bool translucent); + void renderMeshes(RenderMode mode, bool translucent, float alphaThreshold = 0.5f); QVector createJointStates(const FBXGeometry& geometry); void initJointTransforms(); @@ -276,6 +276,7 @@ private: static ProgramObject _normalMapProgram; static ProgramObject _specularMapProgram; static ProgramObject _normalSpecularMapProgram; + static ProgramObject _translucentProgram; static ProgramObject _shadowProgram; @@ -283,6 +284,7 @@ private: static ProgramObject _skinNormalMapProgram; static ProgramObject _skinSpecularMapProgram; static ProgramObject _skinNormalSpecularMapProgram; + static ProgramObject _skinTranslucentProgram; static ProgramObject _skinShadowProgram; @@ -292,12 +294,14 @@ private: class Locations { public: int tangent; + int alphaThreshold; }; static Locations _locations; static Locations _normalMapLocations; static Locations _specularMapLocations; static Locations _normalSpecularMapLocations; + static Locations _translucentLocations; static void initProgram(ProgramObject& program, Locations& locations, int specularTextureUnit = 1); @@ -311,9 +315,10 @@ private: static SkinLocations _skinLocations; static SkinLocations _skinNormalMapLocations; static SkinLocations _skinSpecularMapLocations; - static SkinLocations _skinNormalSpecularMapLocations; + static SkinLocations _skinNormalSpecularMapLocations; static SkinLocations _skinShadowLocations; - + static SkinLocations _skinTranslucentLocations; + static void initSkinProgram(ProgramObject& program, SkinLocations& locations, int specularTextureUnit = 1); }; From 9515145b9b79d02e302bd460b1dc56d78e6c6671 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 15:48:56 -0700 Subject: [PATCH 33/43] Removed commented lines. --- interface/src/renderer/Model.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 3411097b49..1e77662ecd 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -440,14 +440,11 @@ bool Model::render(float alpha, RenderMode mode) { glEnable(GL_BLEND); glDepthMask(false); glDepthFunc(GL_LEQUAL); - //glEnable(GL_POLYGON_OFFSET_FILL); - //glPolygonOffset(-1.0f, -1.0f); Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); renderMeshes(mode, true, 0.0f); - //glDisable(GL_POLYGON_OFFSET_FILL); glDepthMask(true); glDepthFunc(GL_LESS); glDisable(GL_CULL_FACE); From 6c907a9d835a9fb0fd558549a67082c374a084c0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 19 Sep 2014 16:49:51 -0700 Subject: [PATCH 34/43] Read the emissive color property and use it to effect glow. --- interface/src/renderer/Model.cpp | 25 +++++++++++++++++-------- libraries/fbx/src/FBXReader.cpp | 7 ++++++- libraries/fbx/src/FBXReader.h | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/interface/src/renderer/Model.cpp b/interface/src/renderer/Model.cpp index 1e77662ecd..2031035726 100644 --- a/interface/src/renderer/Model.cpp +++ b/interface/src/renderer/Model.cpp @@ -421,7 +421,10 @@ bool Model::render(float alpha, RenderMode mode) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_EQUAL, Application::getInstance()->getGlowEffect()->getIntensity()); + + if (mode == SHADOW_RENDER_MODE) { + glAlphaFunc(GL_EQUAL, 0.0f); + } Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers( mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE, @@ -431,10 +434,8 @@ bool Model::render(float alpha, RenderMode mode) { renderMeshes(mode, false); // render translucent meshes afterwards - if (mode == DEFAULT_RENDER_MODE) { - Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); - renderMeshes(mode, true, 0.75f); - } + Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(false, true, true); + renderMeshes(mode, true, 0.75f); glDisable(GL_ALPHA_TEST); glEnable(GL_BLEND); @@ -443,7 +444,9 @@ bool Model::render(float alpha, RenderMode mode) { Application::getInstance()->getTextureCache()->setPrimaryDrawBuffers(true); - renderMeshes(mode, true, 0.0f); + if (mode == DEFAULT_RENDER_MODE || mode == DIFFUSE_RENDER_MODE) { + renderMeshes(mode, true, 0.0f); + } glDepthMask(true); glDepthFunc(GL_LESS); @@ -1322,8 +1325,14 @@ void Model::renderMeshes(RenderMode mode, bool translucent, float alphaThreshold glBindTexture(GL_TEXTURE_2D, 0); } else { - glm::vec4 diffuse = glm::vec4(part.diffuseColor, (translucent && alphaThreshold == 0.0f) ? - part.opacity : Application::getInstance()->getGlowEffect()->getIntensity()); + glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity); + if (!(translucent && alphaThreshold == 0.0f)) { + float emissive = (part.emissiveColor.r + part.emissiveColor.g + part.emissiveColor.b) / 3.0f; + diffuse.a = qMax(Application::getInstance()->getGlowEffect()->getIntensity(), emissive); + glAlphaFunc(GL_EQUAL, diffuse.a); + diffuse = glm::vec4(qMax(diffuse.r, part.emissiveColor.r), qMax(diffuse.g, part.emissiveColor.g), + qMax(diffuse.b, part.emissiveColor.b), diffuse.a); + } glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); glMaterialfv(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); glMaterialfv(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 3b9a340ed2..47120bda7a 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -656,6 +656,7 @@ class Material { public: glm::vec3 diffuse; glm::vec3 specular; + glm::vec3 emissive; float shininess; float opacity; }; @@ -1281,7 +1282,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) textureContent.insert(filename, content); } } else if (object.name == "Material") { - Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), 96.0f, 1.0f }; + Material material = { glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(), 96.0f, 1.0f }; foreach (const FBXNode& subobject, object.children) { bool properties = false; QByteArray propertyName; @@ -1305,6 +1306,9 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) } else if (property.properties.at(0) == "SpecularColor") { material.specular = getVec3(property.properties, index); + } else if (property.properties.at(0) == "Emissive") { + material.emissive = getVec3(property.properties, index); + } else if (property.properties.at(0) == "Shininess") { material.shininess = property.properties.at(index).value(); @@ -1605,6 +1609,7 @@ FBXGeometry extractFBXGeometry(const FBXNode& node, const QVariantHash& mapping) FBXMeshPart& part = extracted.mesh.parts[j]; part.diffuseColor = material.diffuse; part.specularColor = material.specular; + part.emissiveColor = material.emissive; part.shininess = material.shininess; part.opacity = material.opacity; if (!diffuseTexture.filename.isNull()) { diff --git a/libraries/fbx/src/FBXReader.h b/libraries/fbx/src/FBXReader.h index 363cf491d8..423c810418 100644 --- a/libraries/fbx/src/FBXReader.h +++ b/libraries/fbx/src/FBXReader.h @@ -108,6 +108,7 @@ public: glm::vec3 diffuseColor; glm::vec3 specularColor; + glm::vec3 emissiveColor; float shininess; float opacity; From 47c6ba708fcfaf4dae9d943078dfeaa2c7f49b55 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Sat, 20 Sep 2014 04:45:58 -0700 Subject: [PATCH 35/43] new audio edit buffer object / click removal / apply linear fade to sound clip endpoints --- libraries/audio/src/AudioEditBuffer.h | 108 ++++++++++++++++++++++++++ libraries/audio/src/Sound.cpp | 25 +++++- libraries/audio/src/Sound.h | 1 + 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 libraries/audio/src/AudioEditBuffer.h diff --git a/libraries/audio/src/AudioEditBuffer.h b/libraries/audio/src/AudioEditBuffer.h new file mode 100644 index 0000000000..1fa2794e79 --- /dev/null +++ b/libraries/audio/src/AudioEditBuffer.h @@ -0,0 +1,108 @@ +// +// AudioEditBuffer.h +// hifi +// +// Created by Craig Hansen-Sturm on 8/29/14. +// Copyright 2014 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 +// + +#ifndef hifi_AudioEditBuffer_h +#define hifi_AudioEditBuffer_h + +template< typename T > +class AudioEditBuffer + : public AudioFrameBuffer { + +public: + + AudioEditBuffer() : + AudioFrameBuffer() { + } + + AudioEditBuffer(const uint32_t channelCount, const uint32_t frameCount) : + AudioFrameBuffer(channelCount, frameCount) { + } + + ~AudioEditBuffer() { + } + + bool getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero); + + void linearFade(uint32_t start, uint32_t stop, bool slope); + void exponentialFade(uint32_t start, uint32_t stop, bool slope); +}; + +template< typename T > +bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero) { + + zero = this->_frameCount; + + if (direction) { // scan from the left + if (start < this->_frameCount) { + for (uint32_t i = start; i < this->_frameCount; ++i) { + for (uint32_t j = 0; j < this->_channelCount; ++j) { + if (this->_frameBuffer[j][i] >= -epsilon && this->_frameBuffer[j][i] <= epsilon) { + zero = i; + return true; + } + } + } + } + } + else { // scan from the right + if (start != 0 && start < this->_frameCount) { + for (uint32_t i = start; i != 0; --i) { + for (uint32_t j = 0; j < this->_channelCount; ++j) { + if (this->_frameBuffer[j][i] >= -epsilon && this->_frameBuffer[j][i] <= epsilon) { + zero = i; + return true; + } + } + } + } + } + + return false; +} + +template< typename T > +void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool slope) { + + if (start >= stop || start > this->_frameCount || stop > this->_frameCount ) { + return; + } + + uint32_t count = stop - start; + float32_t delta; + float32_t gain; + + if (slope) { // 0.0 to 1.0f in delta increments + delta = 1.0f / (float32_t)count; + gain = 0.0f; + } + else { // 1.0f to 0.0f in delta increments + delta = -1.0f / (float32_t)count; + gain = 1.0f; + } + + for (uint32_t i = start; i < stop; ++i) { + for (uint32_t j = 0; j < this->_channelCount; ++j) { + this->_frameBuffer[j][i] *= gain; + gain += delta; + } + } +} + +template< typename T > +void AudioEditBuffer::exponentialFade(uint32_t start, uint32_t stop, bool slope) { + // TBD +} + +typedef AudioEditBuffer< float32_t > AudioEditBufferFloat32; +typedef AudioEditBuffer< int32_t > AudioEditBufferSInt32; + +#endif // hifi_AudioEditBuffer_h + diff --git a/libraries/audio/src/Sound.cpp b/libraries/audio/src/Sound.cpp index f52f5c04dd..9edb04aa2c 100644 --- a/libraries/audio/src/Sound.cpp +++ b/libraries/audio/src/Sound.cpp @@ -24,6 +24,9 @@ #include #include "AudioRingBuffer.h" +#include "AudioFormat.h" +#include "AudioBuffer.h" +#include "AudioEditBuffer.h" #include "Sound.h" // procedural audio version of Sound @@ -120,6 +123,7 @@ void Sound::replyFinished() { // Process as RAW file downSample(rawAudioByteArray); } + trimFrames(); } else { qDebug() << "Network reply without 'Content-Type'."; } @@ -133,7 +137,6 @@ void Sound::replyError(QNetworkReply::NetworkError code) { } void Sound::downSample(const QByteArray& rawAudioByteArray) { - // assume that this was a RAW file and is now an array of samples that are // signed, 16-bit, 48Khz, mono @@ -155,6 +158,26 @@ void Sound::downSample(const QByteArray& rawAudioByteArray) { } } +void Sound::trimFrames() { + + const uint32_t inputFrameCount = _byteArray.size() / sizeof(int16_t); + const uint32_t trimCount = 1024; // number of leading and trailing frames to trim + + if (inputFrameCount <= (2 * trimCount)) { + return; + } + + int16_t* inputFrameData = (int16_t*)_byteArray.data(); + + AudioEditBufferFloat32 editBuffer(1, inputFrameCount); + editBuffer.copyFrames(1, inputFrameCount, inputFrameData, false /*copy in*/); + + editBuffer.linearFade(0, trimCount, true); + editBuffer.linearFade(inputFrameCount - trimCount, inputFrameCount, false); + + editBuffer.copyFrames(1, inputFrameCount, inputFrameData, true /*copy out*/); +} + // // Format description from https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ // diff --git a/libraries/audio/src/Sound.h b/libraries/audio/src/Sound.h index 7dae3679f1..fa2dd97903 100644 --- a/libraries/audio/src/Sound.h +++ b/libraries/audio/src/Sound.h @@ -33,6 +33,7 @@ private: QByteArray _byteArray; bool _hasDownloaded; + void trimFrames(); void downSample(const QByteArray& rawAudioByteArray); void interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& outputAudioByteArray); From 90379ee7ebfb5c3e06e14404dc0f65f3860f9d03 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Sat, 20 Sep 2014 04:50:11 -0700 Subject: [PATCH 36/43] frame and channel counts are now consistently uint32_t / float32_t replaces float --- interface/src/Audio.cpp | 2 +- libraries/audio/src/AudioBuffer.h | 46 ++++---- libraries/audio/src/AudioFilter.h | 150 ++++++++++++------------- libraries/audio/src/AudioFilterBank.h | 61 +++++----- libraries/audio/src/AudioGain.h | 8 +- libraries/audio/src/AudioPan.h | 4 +- libraries/audio/src/AudioSourceNoise.h | 4 +- libraries/audio/src/AudioSourceTone.h | 4 +- 8 files changed, 141 insertions(+), 138 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 79704eebf1..e9cc6f9271 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -509,7 +509,7 @@ void Audio::handleAudioInput() { if (!_muted && (_audioSourceInjectEnabled || _peqEnabled)) { int16_t* inputFrameData = (int16_t*)inputByteArray.data(); - const int inputFrameCount = inputByteArray.size() / sizeof(int16_t); + const uint32_t inputFrameCount = inputByteArray.size() / sizeof(int16_t); _inputFrameBuffer.copyFrames(1, inputFrameCount, inputFrameData, false /*copy in*/); diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index 863bbdf22a..cf6a2fb55a 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -17,17 +17,19 @@ template< typename T > class AudioFrameBuffer { - uint16_t _channelCount; - uint16_t _channelCountMax; - uint16_t _frameCount; - uint16_t _frameCountMax; +protected: + + uint32_t _channelCount; + uint32_t _channelCountMax; + uint32_t _frameCount; + uint32_t _frameCountMax; T** _frameBuffer; void allocateFrames() { _frameBuffer = new T*[_channelCountMax]; if (_frameBuffer) { - for (uint16_t i = 0; i < _channelCountMax; ++i) { + for (uint32_t i = 0; i < _channelCountMax; ++i) { _frameBuffer[i] = new T[_frameCountMax]; } } @@ -35,7 +37,7 @@ class AudioFrameBuffer { void deallocateFrames() { if (_frameBuffer) { - for (uint16_t i = 0; i < _channelCountMax; ++i) { + for (uint32_t i = 0; i < _channelCountMax; ++i) { delete _frameBuffer[i]; } delete _frameBuffer; @@ -52,7 +54,7 @@ public: _frameBuffer(NULL) { } - AudioFrameBuffer(const uint16_t channelCount, const uint16_t frameCount) : + AudioFrameBuffer(const uint32_t channelCount, const uint32_t frameCount) : _channelCount(channelCount), _channelCountMax(channelCount), _frameCount(frameCount), @@ -61,11 +63,11 @@ public: allocateFrames(); } - ~AudioFrameBuffer() { + virtual ~AudioFrameBuffer() { finalize(); } - void initialize(const uint16_t channelCount, const uint16_t frameCount) { + void initialize(const uint32_t channelCount, const uint32_t frameCount) { if (_frameBuffer) { finalize(); } @@ -88,25 +90,25 @@ public: return _frameBuffer; } - uint16_t getChannelCount() { + uint32_t getChannelCount() { return _channelCount; } - uint16_t getFrameCount() { + uint32_t getFrameCount() { return _frameCount; } - + void zeroFrames() { if (!_frameBuffer) { return; } - for (uint16_t i = 0; i < _channelCountMax; ++i) { + for (uint32_t i = 0; i < _channelCountMax; ++i) { memset(_frameBuffer[i], 0, sizeof(T)*_frameCountMax); } } template< typename S > - void copyFrames(uint16_t channelCount, const uint16_t frameCount, S* frames, const bool copyOut = false) { + void copyFrames(uint32_t channelCount, const uint32_t frameCount, S* frames, const bool copyOut = false) { if ( !_frameBuffer || !frames) { return; } @@ -152,8 +154,8 @@ public: S* dst = frames; if(typeid(T) == typeid(S)) { // source and destination types are the same - for (int i = 0; i < _frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { *dst++ = _frameBuffer[j][i]; } } @@ -164,8 +166,8 @@ public: const int scale = (2 << ((8 * sizeof(S)) - 1)); - for (int i = 0; i < _frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { *dst++ = (S)(_frameBuffer[j][i] * scale); } } @@ -179,8 +181,8 @@ public: S* src = frames; if(typeid(T) == typeid(S)) { // source and destination types are the same - for (int i = 0; i < _frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { _frameBuffer[j][i] = *src++; } } @@ -191,8 +193,8 @@ public: const int scale = (2 << ((8 * sizeof(S)) - 1)); - for (int i = 0; i < _frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { _frameBuffer[j][i] = ((T)(*src++)) / scale; } } diff --git a/libraries/audio/src/AudioFilter.h b/libraries/audio/src/AudioFilter.h index c792b5fec4..ee823c00da 100644 --- a/libraries/audio/src/AudioFilter.h +++ b/libraries/audio/src/AudioFilter.h @@ -21,16 +21,16 @@ class AudioBiquad { // // private data // - float _a0; // gain - float _a1; // feedforward 1 - float _a2; // feedforward 2 - float _b1; // feedback 1 - float _b2; // feedback 2 + float32_t _a0; // gain + float32_t _a1; // feedforward 1 + float32_t _a2; // feedforward 2 + float32_t _b1; // feedback 1 + float32_t _b2; // feedback 2 - float _xm1; - float _xm2; - float _ym1; - float _ym2; + float32_t _xm1; + float32_t _xm2; + float32_t _ym1; + float32_t _ym2; public: @@ -51,20 +51,20 @@ public: // // public interface // - void setParameters(const float a0, const float a1, const float a2, const float b1, const float b2) { + void setParameters(const float32_t a0, const float32_t a1, const float32_t a2, const float32_t b1, const float32_t b2) { _a0 = a0; _a1 = a1; _a2 = a2; _b1 = b1; _b2 = b2; } - void getParameters(float& a0, float& a1, float& a2, float& b1, float& b2) { + void getParameters(float32_t& a0, float32_t& a1, float32_t& a2, float32_t& b1, float32_t& b2) { a0 = _a0; a1 = _a1; a2 = _a2; b1 = _b1; b2 = _b2; } - void render(const float* in, float* out, const int frames) { + void render(const float32_t* in, float32_t* out, const uint32_t frames) { - float x; - float y; + float32_t x; + float32_t y; - for (int i = 0; i < frames; ++i) { + for (uint32_t i = 0; i < frames; ++i) { x = *in++; @@ -105,10 +105,10 @@ protected: // data // AudioBiquad _kernel; - float _sampleRate; - float _frequency; - float _gain; - float _slope; + float32_t _sampleRate; + float32_t _frequency; + float32_t _gain; + float32_t _slope; // // helpers @@ -131,7 +131,7 @@ public: // // public interface // - void setParameters(const float sampleRate, const float frequency, const float gain, const float slope) { + void setParameters(const float32_t sampleRate, const float32_t frequency, const float32_t gain, const float32_t slope) { _sampleRate = std::max(sampleRate, 1.0f); _frequency = std::max(frequency, 2.0f); @@ -141,11 +141,11 @@ public: updateKernel(); } - void getParameters(float& sampleRate, float& frequency, float& gain, float& slope) { + void getParameters(float32_t& sampleRate, float32_t& frequency, float32_t& gain, float32_t& slope) { sampleRate = _sampleRate; frequency = _frequency; gain = _gain; slope = _slope; } - void render(const float* in, float* out, const int frames) { + void render(const float32_t* in, float32_t* out, const uint32_t frames) { _kernel.render(in,out,frames); } @@ -166,14 +166,14 @@ public: // void updateKernel() { - const float a = _gain; - const float aAdd1 = a + 1.0f; - const float aSub1 = a - 1.0f; - const float omega = TWO_PI * _frequency / _sampleRate; - const float aAdd1TimesCosOmega = aAdd1 * cosf(omega); - const float aSub1TimesCosOmega = aSub1 * cosf(omega); - const float alpha = 0.5f * sinf(omega) / _slope; - const float zeta = 2.0f * sqrtf(a) * alpha; + const float32_t a = _gain; + const float32_t aAdd1 = a + 1.0f; + const float32_t aSub1 = a - 1.0f; + const float32_t omega = TWO_PI * _frequency / _sampleRate; + const float32_t aAdd1TimesCosOmega = aAdd1 * cosf(omega); + const float32_t aSub1TimesCosOmega = aSub1 * cosf(omega); + const float32_t alpha = 0.5f * sinf(omega) / _slope; + const float32_t zeta = 2.0f * sqrtf(a) * alpha; /* b0 = A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha ) b1 = 2*A*( (A-1) - (A+1)*cos(w0) ) @@ -182,14 +182,14 @@ public: a1 = -2*( (A-1) + (A+1)*cos(w0) ) a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha */ - const float b0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta) * a; - const float b1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO) * a; - const float b2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta) * a; - const float a0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta); - const float a1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO); - const float a2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta); + const float32_t b0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta) * a; + const float32_t b1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO) * a; + const float32_t b2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta) * a; + const float32_t a0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta); + const float32_t a1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO); + const float32_t a2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta); - const float normA0 = 1.0f / a0; + const float32_t normA0 = 1.0f / a0; _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } @@ -207,14 +207,14 @@ public: // void updateKernel() { - const float a = _gain; - const float aAdd1 = a + 1.0f; - const float aSub1 = a - 1.0f; - const float omega = TWO_PI * _frequency / _sampleRate; - const float aAdd1TimesCosOmega = aAdd1 * cosf(omega); - const float aSub1TimesCosOmega = aSub1 * cosf(omega); - const float alpha = 0.5f * sinf(omega) / _slope; - const float zeta = 2.0f * sqrtf(a) * alpha; + const float32_t a = _gain; + const float32_t aAdd1 = a + 1.0f; + const float32_t aSub1 = a - 1.0f; + const float32_t omega = TWO_PI * _frequency / _sampleRate; + const float32_t aAdd1TimesCosOmega = aAdd1 * cosf(omega); + const float32_t aSub1TimesCosOmega = aSub1 * cosf(omega); + const float32_t alpha = 0.5f * sinf(omega) / _slope; + const float32_t zeta = 2.0f * sqrtf(a) * alpha; /* b0 = A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha ) b1 = -2*A*( (A-1) + (A+1)*cos(w0) ) @@ -223,14 +223,14 @@ public: a1 = 2*( (A-1) - (A+1)*cos(w0) ) a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha */ - const float b0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta) * a; - const float b1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO) * a; - const float b2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta) * a; - const float a0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta); - const float a1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO); - const float a2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta); + const float32_t b0 = +1.0f * (aAdd1 + aSub1TimesCosOmega + zeta) * a; + const float32_t b1 = -2.0f * (aSub1 + aAdd1TimesCosOmega + ZERO) * a; + const float32_t b2 = +1.0f * (aAdd1 + aSub1TimesCosOmega - zeta) * a; + const float32_t a0 = +1.0f * (aAdd1 - aSub1TimesCosOmega + zeta); + const float32_t a1 = +2.0f * (aSub1 - aAdd1TimesCosOmega + ZERO); + const float32_t a2 = +1.0f * (aAdd1 - aSub1TimesCosOmega - zeta); - const float normA0 = 1.0f / a0; + const float32_t normA0 = 1.0f / a0; _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } @@ -248,9 +248,9 @@ public: // void updateKernel() { - const float omega = TWO_PI * _frequency / _sampleRate; - const float cosOmega = cosf(omega); - const float alpha = 0.5f * sinf(omega) / _slope; + const float32_t omega = TWO_PI * _frequency / _sampleRate; + const float32_t cosOmega = cosf(omega); + const float32_t alpha = 0.5f * sinf(omega) / _slope; /* b0 = 1 - alpha b1 = -2*cos(w0) @@ -259,14 +259,14 @@ public: a1 = -2*cos(w0) a2 = 1 - alpha */ - const float b0 = +1.0f - alpha; - const float b1 = -2.0f * cosOmega; - const float b2 = +1.0f + alpha; - const float a0 = +1.0f + alpha; - const float a1 = -2.0f * cosOmega; - const float a2 = +1.0f - alpha; + const float32_t b0 = +1.0f - alpha; + const float32_t b1 = -2.0f * cosOmega; + const float32_t b2 = +1.0f + alpha; + const float32_t a0 = +1.0f + alpha; + const float32_t a1 = -2.0f * cosOmega; + const float32_t a2 = +1.0f - alpha; - const float normA0 = 1.0f / a0; + const float32_t normA0 = 1.0f / a0; _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } @@ -284,12 +284,12 @@ public: // void updateKernel() { - const float a = _gain; - const float omega = TWO_PI * _frequency / _sampleRate; - const float cosOmega = cosf(omega); - const float alpha = 0.5f * sinf(omega) / _slope; - const float alphaMulA = alpha * a; - const float alphaDivA = alpha / a; + const float32_t a = _gain; + const float32_t omega = TWO_PI * _frequency / _sampleRate; + const float32_t cosOmega = cosf(omega); + const float32_t alpha = 0.5f * sinf(omega) / _slope; + const float32_t alphaMulA = alpha * a; + const float32_t alphaDivA = alpha / a; /* b0 = 1 + alpha*A b1 = -2*cos(w0) @@ -298,14 +298,14 @@ public: a1 = -2*cos(w0) a2 = 1 - alpha/A */ - const float b0 = +1.0f + alphaMulA; - const float b1 = -2.0f * cosOmega; - const float b2 = +1.0f - alphaMulA; - const float a0 = +1.0f + alphaDivA; - const float a1 = -2.0f * cosOmega; - const float a2 = +1.0f - alphaDivA; + const float32_t b0 = +1.0f + alphaMulA; + const float32_t b1 = -2.0f * cosOmega; + const float32_t b2 = +1.0f - alphaMulA; + const float32_t a0 = +1.0f + alphaDivA; + const float32_t a1 = -2.0f * cosOmega; + const float32_t a2 = +1.0f - alphaDivA; - const float normA0 = 1.0f / a0; + const float32_t normA0 = 1.0f / a0; _kernel.setParameters(b0 * normA0, b1 * normA0 , b2 * normA0, a1 * normA0, a2 * normA0); } diff --git a/libraries/audio/src/AudioFilterBank.h b/libraries/audio/src/AudioFilterBank.h index b9546999d9..41b2985cbe 100644 --- a/libraries/audio/src/AudioFilterBank.h +++ b/libraries/audio/src/AudioFilterBank.h @@ -15,24 +15,24 @@ // // Helper/convenience class that implements a bank of Filter objects // -template< typename T, const int N, const int C > +template< typename T, const uint32_t N, const uint32_t C > class AudioFilterBank { // // types // struct FilterParameter { - float _p1; - float _p2; - float _p3; + float32_t _p1; + float32_t _p2; + float32_t _p3; }; // // private static data // - static const int _filterCount = N; - static const int _channelCount = C; - static const int _profileCount = 4; + static const uint32_t _filterCount = N; + static const uint32_t _channelCount = C; + static const uint32_t _profileCount = 4; static FilterParameter _profiles[ _profileCount ][ _filterCount ]; @@ -40,9 +40,9 @@ class AudioFilterBank { // private data // T _filters[ _filterCount ][ _channelCount ]; - float* _buffer[ _channelCount ]; - float _sampleRate; - uint16_t _frameCount; + float32_t* _buffer[ _channelCount ]; + float32_t _sampleRate; + uint32_t _frameCount; public: @@ -64,11 +64,11 @@ public: // // public interface // - void initialize(const float sampleRate, const int frameCount = 0) { + void initialize(const float32_t sampleRate, const uint32_t frameCount = 0) { finalize(); - for (int i = 0; i < _channelCount; ++i) { - _buffer[i] = (float*)malloc(frameCount * sizeof(float)); + for (uint32_t i = 0; i < _channelCount; ++i) { + _buffer[i] = (float32_t*)malloc(frameCount * sizeof(float32_t)); } _sampleRate = sampleRate; @@ -79,7 +79,7 @@ public: } void finalize() { - for (int i = 0; i < _channelCount; ++i) { + for (uint32_t i = 0; i < _channelCount; ++i) { if (_buffer[i]) { free (_buffer[i]); _buffer[i] = NULL; @@ -90,52 +90,53 @@ public: void loadProfile(int profileIndex) { if (profileIndex >= 0 && profileIndex < _profileCount) { - for (int i = 0; i < _filterCount; ++i) { + for (uint32_t i = 0; i < _filterCount; ++i) { FilterParameter p = _profiles[profileIndex][i]; - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t j = 0; j < _channelCount; ++j) { _filters[i][j].setParameters(_sampleRate,p._p1,p._p2,p._p3); } } } } - void setParameters(int filterStage, int filterChannel, const float sampleRate, const float frequency, const float gain, - const float slope) { + void setParameters(uint32_t filterStage, uint32_t filterChannel, const float32_t sampleRate, const float32_t frequency, + const float32_t gain, const float32_t slope) { if (filterStage >= 0 && filterStage < _filterCount && filterChannel >= 0 && filterChannel < _channelCount) { _filters[filterStage][filterChannel].setParameters(sampleRate,frequency,gain,slope); } } - void getParameters(int filterStage, int filterChannel, float& sampleRate, float& frequency, float& gain, float& slope) { + void getParameters(uint32_t filterStage, uint32_t filterChannel, float32_t& sampleRate, float32_t& frequency, + float32_t& gain, float32_t& slope) { if (filterStage >= 0 && filterStage < _filterCount && filterChannel >= 0 && filterChannel < _channelCount) { _filters[filterStage][filterChannel].getParameters(sampleRate,frequency,gain,slope); } } - void render(const int16_t* in, int16_t* out, const int frameCount) { + void render(const int16_t* in, int16_t* out, const uint32_t frameCount) { if (!_buffer || (frameCount > _frameCount)) return; const int scale = (2 << ((8 * sizeof(int16_t)) - 1)); // de-interleave and convert int16_t to float32 (normalized to -1. ... 1.) - for (int i = 0; i < frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { _buffer[j][i] = ((float)(*in++)) / scale; } } // now step through each filter - for (int i = 0; i < _channelCount; ++i) { - for (int j = 0; j < _filterCount; ++j) { + for (uint32_t i = 0; i < _channelCount; ++i) { + for (uint32_t j = 0; j < _filterCount; ++j) { _filters[j][i].render( &_buffer[i][0], &_buffer[i][0], frameCount ); } } // convert float32 to int16_t and interleave - for (int i = 0; i < frameCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { *out++ = (int16_t)(_buffer[j][i] * scale); } } @@ -144,16 +145,16 @@ public: void render(AudioBufferFloat32& frameBuffer) { float32_t** samples = frameBuffer.getFrameData(); - for (uint16_t j = 0; j < frameBuffer.getChannelCount(); ++j) { - for (int i = 0; i < _filterCount; ++i) { + for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { + for (uint32_t i = 0; i < _filterCount; ++i) { _filters[i][j].render( samples[j], samples[j], frameBuffer.getFrameCount() ); } } } void reset() { - for (int i = 0; i < _filterCount; ++i) { - for (int j = 0; j < _channelCount; ++j) { + for (uint32_t i = 0; i < _filterCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { _filters[i][j].reset(); } } diff --git a/libraries/audio/src/AudioGain.h b/libraries/audio/src/AudioGain.h index ac1923528b..485e239128 100644 --- a/libraries/audio/src/AudioGain.h +++ b/libraries/audio/src/AudioGain.h @@ -61,7 +61,7 @@ public: if (frameBuffer.getChannelCount() == 1) { - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { samples[0][i + 0] *= _gain; samples[0][i + 1] *= _gain; samples[0][i + 2] *= _gain; @@ -82,7 +82,7 @@ public: } else if (frameBuffer.getChannelCount() == 2) { - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { samples[0][i + 0] *= _gain; samples[0][i + 1] *= _gain; samples[0][i + 2] *= _gain; @@ -123,8 +123,8 @@ public: } else { - for (uint16_t j = 0; j < frameBuffer.getChannelCount(); ++j) { - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { + for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { samples[j][i] *= _gain; } } diff --git a/libraries/audio/src/AudioPan.h b/libraries/audio/src/AudioPan.h index 85e739b255..78e42d2ed5 100644 --- a/libraries/audio/src/AudioPan.h +++ b/libraries/audio/src/AudioPan.h @@ -88,7 +88,7 @@ public: if (frameBuffer.getChannelCount() == 2) { - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { samples[0][i + 0] *= _gainLeft; samples[0][i + 1] *= _gainLeft; samples[0][i + 2] *= _gainLeft; @@ -128,7 +128,7 @@ public: } } else { - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { samples[0][i] *= _gainLeft; samples[1][i] *= _gainRight; } diff --git a/libraries/audio/src/AudioSourceNoise.h b/libraries/audio/src/AudioSourceNoise.h index 3e71703893..b7f6889179 100644 --- a/libraries/audio/src/AudioSourceNoise.h +++ b/libraries/audio/src/AudioSourceNoise.h @@ -70,8 +70,8 @@ public: uint32_t randomNumber; float32_t** samples = frameBuffer.getFrameData(); - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); ++i) { - for (uint16_t j = 0; j < frameBuffer.getChannelCount(); ++j) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); ++i) { + for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { _index = (_index + 1) & _indexMask; // increment and mask index. if (_index != 0) { // if index is zero, don't update any random values. diff --git a/libraries/audio/src/AudioSourceTone.h b/libraries/audio/src/AudioSourceTone.h index 22ec95496f..f0c72ca9b3 100644 --- a/libraries/audio/src/AudioSourceTone.h +++ b/libraries/audio/src/AudioSourceTone.h @@ -44,7 +44,7 @@ inline void AudioSourceTone::render(AudioBufferFloat32& frameBuffer) { float32_t** samples = frameBuffer.getFrameData(); float32_t yq; float32_t y; - for (uint16_t i = 0; i < frameBuffer.getFrameCount(); ++i) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); ++i) { yq = _yq1 - (_epsilon * _y1); y = _y1 + (_epsilon * yq); @@ -53,7 +53,7 @@ inline void AudioSourceTone::render(AudioBufferFloat32& frameBuffer) { _yq1 = yq; _y1 = y; - for (uint16_t j = 0; j < frameBuffer.getChannelCount(); ++j) { + for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { samples[j][i] = _amplitude * y; } } From 1b2ee4023aacc1ebf34e4fb2d08c6e51fe0f61b0 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Sat, 20 Sep 2014 05:46:27 -0700 Subject: [PATCH 37/43] out of line inline members for coding standard --- libraries/audio/src/AudioBuffer.h | 346 ++++++++++++++------------ libraries/audio/src/AudioEditBuffer.h | 36 +-- libraries/audio/src/AudioGain.cpp | 48 ++++ libraries/audio/src/AudioGain.h | 181 ++++++-------- libraries/audio/src/AudioPan.cpp | 33 ++- libraries/audio/src/AudioPan.h | 186 +++++++------- 6 files changed, 456 insertions(+), 374 deletions(-) create mode 100644 libraries/audio/src/AudioGain.cpp diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index cf6a2fb55a..277466ac89 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -26,186 +26,216 @@ protected: T** _frameBuffer; - void allocateFrames() { - _frameBuffer = new T*[_channelCountMax]; - if (_frameBuffer) { - for (uint32_t i = 0; i < _channelCountMax; ++i) { - _frameBuffer[i] = new T[_frameCountMax]; - } - } - } - - void deallocateFrames() { - if (_frameBuffer) { - for (uint32_t i = 0; i < _channelCountMax; ++i) { - delete _frameBuffer[i]; - } - delete _frameBuffer; - } - _frameBuffer = NULL; - } + void allocateFrames(); + void deallocateFrames(); public: - AudioFrameBuffer() : - _channelCount(0), - _frameCount(0), - _frameCountMax(0), - _frameBuffer(NULL) { - } + AudioFrameBuffer(); + AudioFrameBuffer(const uint32_t channelCount, const uint32_t frameCount); + virtual ~AudioFrameBuffer(); - AudioFrameBuffer(const uint32_t channelCount, const uint32_t frameCount) : - _channelCount(channelCount), - _channelCountMax(channelCount), - _frameCount(frameCount), - _frameCountMax(frameCount), - _frameBuffer(NULL) { - allocateFrames(); + void initialize(const uint32_t channelCount, const uint32_t frameCount); + void finalize(); + + T**& getFrameData(); + uint32_t getChannelCount(); + uint32_t getFrameCount(); + + template< typename S > + void copyFrames(uint32_t channelCount, const uint32_t frameCount, S* frames, const bool copyOut = false); + void zeroFrames(); +}; + +template< typename T > +AudioFrameBuffer< T >::AudioFrameBuffer() : + _channelCount(0), + _frameCount(0), + _frameCountMax(0), + _frameBuffer(NULL) { +} + +template< typename T > +AudioFrameBuffer< T >::AudioFrameBuffer(const uint32_t channelCount, const uint32_t frameCount) : + _channelCount(channelCount), + _channelCountMax(channelCount), + _frameCount(frameCount), + _frameCountMax(frameCount), + _frameBuffer(NULL) { + allocateFrames(); +} + +template< typename T > +AudioFrameBuffer< T >::~AudioFrameBuffer() { + finalize(); +} + +template< typename T > +void AudioFrameBuffer< T >::allocateFrames() { + _frameBuffer = new T*[_channelCountMax]; + if (_frameBuffer) { + for (uint32_t i = 0; i < _channelCountMax; ++i) { + _frameBuffer[i] = new T[_frameCountMax]; + } } - - virtual ~AudioFrameBuffer() { +} + +template< typename T > +void AudioFrameBuffer< T >::deallocateFrames() { + if (_frameBuffer) { + for (uint32_t i = 0; i < _channelCountMax; ++i) { + delete _frameBuffer[i]; + } + delete _frameBuffer; + } + _frameBuffer = NULL; +} + +template< typename T > +void AudioFrameBuffer< T >::initialize(const uint32_t channelCount, const uint32_t frameCount) { + if (_frameBuffer) { finalize(); } + _channelCount = channelCount; + _channelCountMax = channelCount; + _frameCount = frameCount; + _frameCountMax = frameCount; + allocateFrames(); +} + +template< typename T > +void AudioFrameBuffer< T >::finalize() { + deallocateFrames(); + _channelCount = 0; + _channelCountMax = 0; + _frameCount = 0; + _frameCountMax = 0; +} + +template< typename T > +inline T**& AudioFrameBuffer< T >::getFrameData() { + return _frameBuffer; +} + +template< typename T > +inline uint32_t AudioFrameBuffer< T >::getChannelCount() { + return _channelCount; +} + +template< typename T > +inline uint32_t AudioFrameBuffer< T >::getFrameCount() { + return _frameCount; +} + +template< typename T > +inline void AudioFrameBuffer< T >::zeroFrames() { + if (!_frameBuffer) { + return; + } + for (uint32_t i = 0; i < _channelCountMax; ++i) { + memset(_frameBuffer[i], 0, sizeof(T)*_frameCountMax); + } +} + +template< typename T > +template< typename S > +inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint32_t frameCount, S* frames, const bool copyOut) { + if ( !_frameBuffer || !frames) { + return; + } - void initialize(const uint32_t channelCount, const uint32_t frameCount) { - if (_frameBuffer) { - finalize(); - } - _channelCount = channelCount; - _channelCountMax = channelCount; + if (channelCount <=_channelCountMax && frameCount <=_frameCountMax) { + // We always allow copying fewer frames than we have allocated _frameCount = frameCount; - _frameCountMax = frameCount; - allocateFrames(); + _channelCount = channelCount; + } + else { + // + // However we do not attempt to copy more frames than we've allocated ;-) This is a framing error caused by either + // a/ the platform audio driver not correctly queuing and regularly smoothing device IO capture frames -or- + // b/ our IO processing thread (currently running on a Qt GUI thread) has been delayed/scheduled too late. + // + // The fix is not to make the problem worse by allocating additional frames on this thread, rather, it is to handle + // dynamic re-sizing off the IO processing thread. While a/ is not in our control, we will address the off thread + // re-sizing,, as well as b/, in later releases. + // + // For now, we log this condition, and do our best to recover by copying as many frames as we have allocated. + // Unfortunately, this will result (temporarily), in an audible discontinuity. + // + // If you repeatedly receive this error, contact craig@highfidelity.io and send me what audio device you are using, + // what audio-stack you are using (pulse/alsa, core audio, ...), what OS, and what the reported frame/channel + // counts are. In addition, any information about what you were doing at the time of the discontinuity, would be + // useful (e.g., accessing any client features/menus) + // + qDebug() << "Audio framing error: _channelCount=" + << _channelCount + << "channelCountMax=" + << _channelCountMax + << "_frameCount=" + << _frameCount + << "frameCountMax=" + << _frameCountMax; + + + _channelCount = std::min(_channelCount,_channelCountMax); + _frameCount = std::min(_frameCount,_frameCountMax); } - void finalize() { - deallocateFrames(); - _channelCount = 0; - _channelCountMax = 0; - _frameCount = 0; - _frameCountMax = 0; - } - - T**& getFrameData() { - return _frameBuffer; - } - - uint32_t getChannelCount() { - return _channelCount; - } - - uint32_t getFrameCount() { - return _frameCount; - } - - void zeroFrames() { - if (!_frameBuffer) { - return; - } - for (uint32_t i = 0; i < _channelCountMax; ++i) { - memset(_frameBuffer[i], 0, sizeof(T)*_frameCountMax); - } - } - - template< typename S > - void copyFrames(uint32_t channelCount, const uint32_t frameCount, S* frames, const bool copyOut = false) { - if ( !_frameBuffer || !frames) { - return; - } - - if (channelCount <=_channelCountMax && frameCount <=_frameCountMax) { - // We always allow copying fewer frames than we have allocated - _frameCount = frameCount; - _channelCount = channelCount; + if (copyOut) { + S* dst = frames; + + if(typeid(T) == typeid(S)) { // source and destination types are the same + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + *dst++ = _frameBuffer[j][i]; + } + } } else { - // - // However we do not attempt to copy more frames than we've allocated ;-) This is a framing error caused by either - // a/ the platform audio driver not correctly queuing and regularly smoothing device IO capture frames -or- - // b/ our IO processing thread (currently running on a Qt GUI thread) has been delayed/scheduled too late. - // - // The fix is not to make the problem worse by allocating additional frames on this thread, rather, it is to handle - // dynamic re-sizing off the IO processing thread. While a/ is not in our control, we will address the off thread - // re-sizing,, as well as b/, in later releases. - // - // For now, we log this condition, and do our best to recover by copying as many frames as we have allocated. - // Unfortunately, this will result (temporarily), in an audible discontinuity. - // - // If you repeatedly receive this error, contact craig@highfidelity.io and send me what audio device you are using, - // what audio-stack you are using (pulse/alsa, core audio, ...), what OS, and what the reported frame/channel - // counts are. In addition, any information about what you were doing at the time of the discontinuity, would be - // useful (e.g., accessing any client features/menus) - // - qDebug() << "Audio framing error: _channelCount=" - << _channelCount - << "channelCountMax=" - << _channelCountMax - << "_frameCount=" - << _frameCount - << "frameCountMax=" - << _frameCountMax; - - - _channelCount = std::min(_channelCount,_channelCountMax); - _frameCount = std::min(_frameCount,_frameCountMax); - } - - if (copyOut) { - S* dst = frames; - - if(typeid(T) == typeid(S)) { // source and destination types are the same + if(typeid(T) == typeid(float32_t) && + typeid(S) == typeid(int16_t)) { + + const int scale = (2 << ((8 * sizeof(S)) - 1)); + for (uint32_t i = 0; i < _frameCount; ++i) { for (uint32_t j = 0; j < _channelCount; ++j) { - *dst++ = _frameBuffer[j][i]; + *dst++ = (S)(_frameBuffer[j][i] * scale); } } } else { - if(typeid(T) == typeid(float32_t) && - typeid(S) == typeid(int16_t)) { - - const int scale = (2 << ((8 * sizeof(S)) - 1)); - - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - *dst++ = (S)(_frameBuffer[j][i] * scale); - } - } - } - else { - assert(0); // currently unsupported conversion - } - } - } - else { // copyIn - S* src = frames; - - if(typeid(T) == typeid(S)) { // source and destination types are the same - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - _frameBuffer[j][i] = *src++; - } - } - } - else { - if(typeid(T) == typeid(float32_t) && - typeid(S) == typeid(int16_t)) { - - const int scale = (2 << ((8 * sizeof(S)) - 1)); - - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - _frameBuffer[j][i] = ((T)(*src++)) / scale; - } - } - } - else { - assert(0); // currently unsupported conversion - } + assert(0); // currently unsupported conversion } } } -}; + else { // copyIn + S* src = frames; + + if(typeid(T) == typeid(S)) { // source and destination types are the same + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + _frameBuffer[j][i] = *src++; + } + } + } + else { + if(typeid(T) == typeid(float32_t) && + typeid(S) == typeid(int16_t)) { + + const int scale = (2 << ((8 * sizeof(S)) - 1)); + + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + _frameBuffer[j][i] = ((T)(*src++)) / scale; + } + } + } + else { + assert(0); // currently unsupported conversion + } + } + } +} typedef AudioFrameBuffer< float32_t > AudioBufferFloat32; typedef AudioFrameBuffer< int32_t > AudioBufferSInt32; diff --git a/libraries/audio/src/AudioEditBuffer.h b/libraries/audio/src/AudioEditBuffer.h index 1fa2794e79..2761eee97c 100644 --- a/libraries/audio/src/AudioEditBuffer.h +++ b/libraries/audio/src/AudioEditBuffer.h @@ -13,21 +13,13 @@ #define hifi_AudioEditBuffer_h template< typename T > -class AudioEditBuffer - : public AudioFrameBuffer { +class AudioEditBuffer : public AudioFrameBuffer { public: - AudioEditBuffer() : - AudioFrameBuffer() { - } - - AudioEditBuffer(const uint32_t channelCount, const uint32_t frameCount) : - AudioFrameBuffer(channelCount, frameCount) { - } - - ~AudioEditBuffer() { - } + AudioEditBuffer(); + AudioEditBuffer(const uint32_t channelCount, const uint32_t frameCount); + ~AudioEditBuffer(); bool getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero); @@ -36,7 +28,21 @@ public: }; template< typename T > -bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero) { +AudioEditBuffer::AudioEditBuffer() : + AudioFrameBuffer() { +} + +template< typename T > +AudioEditBuffer::AudioEditBuffer(const uint32_t channelCount, const uint32_t frameCount) : + AudioFrameBuffer(channelCount, frameCount) { +} + +template< typename T > + AudioEditBuffer::~AudioEditBuffer() { +} + +template< typename T > +inline bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, float32_t epsilon, uint32_t& zero) { zero = this->_frameCount; @@ -69,7 +75,7 @@ bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, float32 } template< typename T > -void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool slope) { +inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool slope) { if (start >= stop || start > this->_frameCount || stop > this->_frameCount ) { return; @@ -97,7 +103,7 @@ void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool slope) { } template< typename T > -void AudioEditBuffer::exponentialFade(uint32_t start, uint32_t stop, bool slope) { +inline void AudioEditBuffer::exponentialFade(uint32_t start, uint32_t stop, bool slope) { // TBD } diff --git a/libraries/audio/src/AudioGain.cpp b/libraries/audio/src/AudioGain.cpp new file mode 100644 index 0000000000..8bd2b5b7a3 --- /dev/null +++ b/libraries/audio/src/AudioGain.cpp @@ -0,0 +1,48 @@ +// +// AudioGain.cpp +// hifi +// +// Created by Craig Hansen-Sturm on 9/10/14. +// Copyright 2014 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 +// + +#include +#include +#include +#include "AudioRingBuffer.h" +#include "AudioFormat.h" +#include "AudioBuffer.h" +#include "AudioGain.h" + +AudioGain::AudioGain() { + initialize(); +} + +AudioGain::~AudioGain() { + finalize(); +} + +void AudioGain::initialize() { + setParameters(1.0f,0.0f); +} + +void AudioGain::finalize() { +} + +void AudioGain::reset() { + initialize(); +} + +void AudioGain::setParameters(const float gain, const float mute) { + _gain = std::min(std::max(gain, 0.0f), 1.0f); + _mute = mute != 0.0f; + +} + +void AudioGain::getParameters(float& gain, float& mute) { + gain = _gain; + mute = _mute ? 1.0f : 0.0f; +} diff --git a/libraries/audio/src/AudioGain.h b/libraries/audio/src/AudioGain.h index 485e239128..a321ec2eba 100644 --- a/libraries/audio/src/AudioGain.h +++ b/libraries/audio/src/AudioGain.h @@ -18,119 +18,102 @@ class AudioGain bool _mute; public: - AudioGain() { - initialize(); - } + AudioGain(); + ~AudioGain(); - ~AudioGain() { - finalize(); - } + void initialize(); + void finalize(); + void reset(); - void initialize() { - setParameters(1.0f,0.0f); - } + void setParameters(const float gain, const float mute); + void getParameters(float& gain, float& mute); - void finalize() { - } + void render(AudioBufferFloat32& frameBuffer); +}; + + +inline void AudioGain::render(AudioBufferFloat32& frameBuffer) { + if (_mute) { + frameBuffer.zeroFrames(); + return; + } - void reset() { - initialize(); - } + float32_t** samples = frameBuffer.getFrameData(); - void setParameters(const float gain, const float mute) { - _gain = std::min(std::max(gain, 0.0f), 1.0f); - _mute = mute != 0.0f; + bool frameAlignment16 = (frameBuffer.getFrameCount() & 0x0F) == 0; + if (frameAlignment16) { - } - - void getParameters(float& gain, float& mute) { - gain = _gain; - mute = _mute ? 1.0f : 0.0f; - } - - void render(AudioBufferFloat32& frameBuffer) { - if (_mute) { - frameBuffer.zeroFrames(); - return; - } - - float32_t** samples = frameBuffer.getFrameData(); - - bool frameAlignment16 = (frameBuffer.getFrameCount() & 0x0F) == 0; - if (frameAlignment16) { + if (frameBuffer.getChannelCount() == 1) { - if (frameBuffer.getChannelCount() == 1) { - - for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { - samples[0][i + 0] *= _gain; - samples[0][i + 1] *= _gain; - samples[0][i + 2] *= _gain; - samples[0][i + 3] *= _gain; - samples[0][i + 4] *= _gain; - samples[0][i + 5] *= _gain; - samples[0][i + 6] *= _gain; - samples[0][i + 7] *= _gain; - samples[0][i + 8] *= _gain; - samples[0][i + 9] *= _gain; - samples[0][i + 10] *= _gain; - samples[0][i + 11] *= _gain; - samples[0][i + 12] *= _gain; - samples[0][i + 13] *= _gain; - samples[0][i + 14] *= _gain; - samples[0][i + 15] *= _gain; - } + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + samples[0][i + 0] *= _gain; + samples[0][i + 1] *= _gain; + samples[0][i + 2] *= _gain; + samples[0][i + 3] *= _gain; + samples[0][i + 4] *= _gain; + samples[0][i + 5] *= _gain; + samples[0][i + 6] *= _gain; + samples[0][i + 7] *= _gain; + samples[0][i + 8] *= _gain; + samples[0][i + 9] *= _gain; + samples[0][i + 10] *= _gain; + samples[0][i + 11] *= _gain; + samples[0][i + 12] *= _gain; + samples[0][i + 13] *= _gain; + samples[0][i + 14] *= _gain; + samples[0][i + 15] *= _gain; } - else if (frameBuffer.getChannelCount() == 2) { - - for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { - samples[0][i + 0] *= _gain; - samples[0][i + 1] *= _gain; - samples[0][i + 2] *= _gain; - samples[0][i + 3] *= _gain; - samples[0][i + 4] *= _gain; - samples[0][i + 5] *= _gain; - samples[0][i + 6] *= _gain; - samples[0][i + 7] *= _gain; - samples[0][i + 8] *= _gain; - samples[0][i + 9] *= _gain; - samples[0][i + 10] *= _gain; - samples[0][i + 11] *= _gain; - samples[0][i + 12] *= _gain; - samples[0][i + 13] *= _gain; - samples[0][i + 14] *= _gain; - samples[0][i + 15] *= _gain; - samples[1][i + 0] *= _gain; - samples[1][i + 1] *= _gain; - samples[1][i + 2] *= _gain; - samples[1][i + 3] *= _gain; - samples[1][i + 4] *= _gain; - samples[1][i + 5] *= _gain; - samples[1][i + 6] *= _gain; - samples[1][i + 7] *= _gain; - samples[1][i + 8] *= _gain; - samples[1][i + 9] *= _gain; - samples[1][i + 10] *= _gain; - samples[1][i + 11] *= _gain; - samples[1][i + 12] *= _gain; - samples[1][i + 13] *= _gain; - samples[1][i + 14] *= _gain; - samples[1][i + 15] *= _gain; - } - } - else { - assert("unsupported channel format"); + } + else if (frameBuffer.getChannelCount() == 2) { + + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + samples[0][i + 0] *= _gain; + samples[0][i + 1] *= _gain; + samples[0][i + 2] *= _gain; + samples[0][i + 3] *= _gain; + samples[0][i + 4] *= _gain; + samples[0][i + 5] *= _gain; + samples[0][i + 6] *= _gain; + samples[0][i + 7] *= _gain; + samples[0][i + 8] *= _gain; + samples[0][i + 9] *= _gain; + samples[0][i + 10] *= _gain; + samples[0][i + 11] *= _gain; + samples[0][i + 12] *= _gain; + samples[0][i + 13] *= _gain; + samples[0][i + 14] *= _gain; + samples[0][i + 15] *= _gain; + samples[1][i + 0] *= _gain; + samples[1][i + 1] *= _gain; + samples[1][i + 2] *= _gain; + samples[1][i + 3] *= _gain; + samples[1][i + 4] *= _gain; + samples[1][i + 5] *= _gain; + samples[1][i + 6] *= _gain; + samples[1][i + 7] *= _gain; + samples[1][i + 8] *= _gain; + samples[1][i + 9] *= _gain; + samples[1][i + 10] *= _gain; + samples[1][i + 11] *= _gain; + samples[1][i + 12] *= _gain; + samples[1][i + 13] *= _gain; + samples[1][i + 14] *= _gain; + samples[1][i + 15] *= _gain; } } else { - - for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { - for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { - samples[j][i] *= _gain; - } + assert("unsupported channel format"); + } + } + else { + + for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { + samples[j][i] *= _gain; } } } -}; +} #endif // AudioGain_h diff --git a/libraries/audio/src/AudioPan.cpp b/libraries/audio/src/AudioPan.cpp index 8f9b568b6a..d5728762ea 100644 --- a/libraries/audio/src/AudioPan.cpp +++ b/libraries/audio/src/AudioPan.cpp @@ -1,8 +1,8 @@ // -// AudioSourceTone.cpp +// AudioPan.cpp // hifi // -// Created by Craig Hansen-Sturm on 8/10/14. +// Created by Craig Hansen-Sturm on 9/10/14. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -21,3 +21,32 @@ float32_t AudioPan::ONE_MINUS_EPSILON = 1.0f - EPSILON; float32_t AudioPan::ZERO_PLUS_EPSILON = 0.0f + EPSILON; float32_t AudioPan::ONE_HALF_MINUS_EPSILON = 0.5f - EPSILON; float32_t AudioPan::ONE_HALF_PLUS_EPSILON = 0.5f + EPSILON; + +AudioPan::AudioPan() { + initialize(); +} + +AudioPan::~AudioPan() { + finalize(); +} + +void AudioPan::initialize() { + setParameters(0.5f); +} + +void AudioPan::finalize() { +} + +void AudioPan::reset() { + initialize(); +} + +void AudioPan::setParameters(const float32_t pan) { + // pan ranges between 0.0 and 1.0f inclusive. 0.5f is midpoint between full left and full right + _pan = std::min(std::max(pan, 0.0f), 1.0f); + updateCoefficients(); +} + +void AudioPan::getParameters(float32_t& pan) { + pan = _pan; +} diff --git a/libraries/audio/src/AudioPan.h b/libraries/audio/src/AudioPan.h index 78e42d2ed5..ea5e90a7f7 100644 --- a/libraries/audio/src/AudioPan.h +++ b/libraries/audio/src/AudioPan.h @@ -23,118 +23,104 @@ class AudioPan static float32_t ONE_HALF_MINUS_EPSILON; static float32_t ONE_HALF_PLUS_EPSILON; - void updateCoefficients() { - - // implement constant power sin^2 + cos^2 = 1 panning law - - if (_pan >= ONE_MINUS_EPSILON) { // full right - _gainLeft = 0.0f; - _gainRight = 1.0f; - } - else if (_pan <= ZERO_PLUS_EPSILON) { // full left - _gainLeft = 1.0f; - _gainRight = 0.0f; - } - else if ((_pan >= ONE_HALF_MINUS_EPSILON) && (_pan <= ONE_HALF_PLUS_EPSILON)) { // center - _gainLeft = 1.0f / SQUARE_ROOT_OF_2; - _gainRight = 1.0f / SQUARE_ROOT_OF_2; - } - else { // intermediate cases - _gainLeft = cosf( TWO_PI * _pan ); - _gainRight = sinf( TWO_PI * _pan ); - } - } + void updateCoefficients(); public: - AudioPan() { - initialize(); + AudioPan(); + ~AudioPan(); + + void initialize(); + void finalize(); + void reset(); + + void setParameters(const float32_t pan); + void getParameters(float32_t& pan); + + void render(AudioBufferFloat32& frameBuffer); +}; + + +inline void AudioPan::render(AudioBufferFloat32& frameBuffer) { + + if (frameBuffer.getChannelCount() != 2) { + return; } - ~AudioPan() { - finalize(); - } + float32_t** samples = frameBuffer.getFrameData(); - void initialize() { - setParameters(0.5f); - } - - void finalize() { - } - - void reset() { - initialize(); - } - - void setParameters(const float32_t pan) { - // pan ranges between 0.0 and 1.0f inclusive. 0.5f is midpoint between full left and full right - _pan = std::min(std::max(pan, 0.0f), 1.0f); - updateCoefficients(); - } - - void getParameters(float32_t& pan) { - pan = _pan; - } - - void render(AudioBufferFloat32& frameBuffer) { + bool frameAlignment16 = (frameBuffer.getFrameCount() & 0x0F) == 0; + if (frameAlignment16) { - if (frameBuffer.getChannelCount() != 2) { - return; - } - - float32_t** samples = frameBuffer.getFrameData(); - - bool frameAlignment16 = (frameBuffer.getFrameCount() & 0x0F) == 0; - if (frameAlignment16) { + if (frameBuffer.getChannelCount() == 2) { - if (frameBuffer.getChannelCount() == 2) { - - for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { - samples[0][i + 0] *= _gainLeft; - samples[0][i + 1] *= _gainLeft; - samples[0][i + 2] *= _gainLeft; - samples[0][i + 3] *= _gainLeft; - samples[0][i + 4] *= _gainLeft; - samples[0][i + 5] *= _gainLeft; - samples[0][i + 6] *= _gainLeft; - samples[0][i + 7] *= _gainLeft; - samples[0][i + 8] *= _gainLeft; - samples[0][i + 9] *= _gainLeft; - samples[0][i + 10] *= _gainLeft; - samples[0][i + 11] *= _gainLeft; - samples[0][i + 12] *= _gainLeft; - samples[0][i + 13] *= _gainLeft; - samples[0][i + 14] *= _gainLeft; - samples[0][i + 15] *= _gainLeft; - samples[1][i + 0] *= _gainRight; - samples[1][i + 1] *= _gainRight; - samples[1][i + 2] *= _gainRight; - samples[1][i + 3] *= _gainRight; - samples[1][i + 4] *= _gainRight; - samples[1][i + 5] *= _gainRight; - samples[1][i + 6] *= _gainRight; - samples[1][i + 7] *= _gainRight; - samples[1][i + 8] *= _gainRight; - samples[1][i + 9] *= _gainRight; - samples[1][i + 10] *= _gainRight; - samples[1][i + 11] *= _gainRight; - samples[1][i + 12] *= _gainRight; - samples[1][i + 13] *= _gainRight; - samples[1][i + 14] *= _gainRight; - samples[1][i + 15] *= _gainRight; - } - } - else { - assert("unsupported channel format"); + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { + samples[0][i + 0] *= _gainLeft; + samples[0][i + 1] *= _gainLeft; + samples[0][i + 2] *= _gainLeft; + samples[0][i + 3] *= _gainLeft; + samples[0][i + 4] *= _gainLeft; + samples[0][i + 5] *= _gainLeft; + samples[0][i + 6] *= _gainLeft; + samples[0][i + 7] *= _gainLeft; + samples[0][i + 8] *= _gainLeft; + samples[0][i + 9] *= _gainLeft; + samples[0][i + 10] *= _gainLeft; + samples[0][i + 11] *= _gainLeft; + samples[0][i + 12] *= _gainLeft; + samples[0][i + 13] *= _gainLeft; + samples[0][i + 14] *= _gainLeft; + samples[0][i + 15] *= _gainLeft; + samples[1][i + 0] *= _gainRight; + samples[1][i + 1] *= _gainRight; + samples[1][i + 2] *= _gainRight; + samples[1][i + 3] *= _gainRight; + samples[1][i + 4] *= _gainRight; + samples[1][i + 5] *= _gainRight; + samples[1][i + 6] *= _gainRight; + samples[1][i + 7] *= _gainRight; + samples[1][i + 8] *= _gainRight; + samples[1][i + 9] *= _gainRight; + samples[1][i + 10] *= _gainRight; + samples[1][i + 11] *= _gainRight; + samples[1][i + 12] *= _gainRight; + samples[1][i + 13] *= _gainRight; + samples[1][i + 14] *= _gainRight; + samples[1][i + 15] *= _gainRight; } } else { - for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { - samples[0][i] *= _gainLeft; - samples[1][i] *= _gainRight; - } + assert("unsupported channel format"); } } -}; + else { + for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { + samples[0][i] *= _gainLeft; + samples[1][i] *= _gainRight; + } + } +} + +inline void AudioPan::updateCoefficients() { + + // implement constant power sin^2 + cos^2 = 1 panning law + + if (_pan >= ONE_MINUS_EPSILON) { // full right + _gainLeft = 0.0f; + _gainRight = 1.0f; + } + else if (_pan <= ZERO_PLUS_EPSILON) { // full left + _gainLeft = 1.0f; + _gainRight = 0.0f; + } + else if ((_pan >= ONE_HALF_MINUS_EPSILON) && (_pan <= ONE_HALF_PLUS_EPSILON)) { // center + _gainLeft = 1.0f / SQUARE_ROOT_OF_2; + _gainRight = 1.0f / SQUARE_ROOT_OF_2; + } + else { // intermediate cases + _gainLeft = cosf( TWO_PI * _pan ); + _gainRight = sinf( TWO_PI * _pan ); + } +} #endif // AudioPan_h From 4372410fa765783c63a43798d4c5035a632adc64 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Sat, 20 Sep 2014 14:49:41 -0700 Subject: [PATCH 38/43] unrolling for int16_t<->float32_t conversion/scaling and copy in/out --- libraries/audio/src/AudioBuffer.h | 304 ++++++++++++++++++++++++++---- 1 file changed, 267 insertions(+), 37 deletions(-) diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index 277466ac89..b0d9d7da8e 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -150,23 +150,6 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _channelCount = channelCount; } else { - // - // However we do not attempt to copy more frames than we've allocated ;-) This is a framing error caused by either - // a/ the platform audio driver not correctly queuing and regularly smoothing device IO capture frames -or- - // b/ our IO processing thread (currently running on a Qt GUI thread) has been delayed/scheduled too late. - // - // The fix is not to make the problem worse by allocating additional frames on this thread, rather, it is to handle - // dynamic re-sizing off the IO processing thread. While a/ is not in our control, we will address the off thread - // re-sizing,, as well as b/, in later releases. - // - // For now, we log this condition, and do our best to recover by copying as many frames as we have allocated. - // Unfortunately, this will result (temporarily), in an audible discontinuity. - // - // If you repeatedly receive this error, contact craig@highfidelity.io and send me what audio device you are using, - // what audio-stack you are using (pulse/alsa, core audio, ...), what OS, and what the reported frame/channel - // counts are. In addition, any information about what you were doing at the time of the discontinuity, would be - // useful (e.g., accessing any client features/menus) - // qDebug() << "Audio framing error: _channelCount=" << _channelCount << "channelCountMax=" @@ -176,30 +159,154 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 << "frameCountMax=" << _frameCountMax; - _channelCount = std::min(_channelCount,_channelCountMax); _frameCount = std::min(_frameCount,_frameCountMax); } + bool frameAlignment16 = (_frameCount & 0x0F) == 0; + if (copyOut) { S* dst = frames; - if(typeid(T) == typeid(S)) { // source and destination types are the same - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - *dst++ = _frameBuffer[j][i]; + if(typeid(T) == typeid(S)) { // source and destination types are the same, just copy out + + if (frameAlignment16 && (_channelCount == 1 || _channelCount == 2)) { + + if (_channelCount == 1) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + *dst++ = _frameBuffer[0][0]; + *dst++ = _frameBuffer[0][1]; + *dst++ = _frameBuffer[0][2]; + *dst++ = _frameBuffer[0][3]; + *dst++ = _frameBuffer[0][4]; + *dst++ = _frameBuffer[0][5]; + *dst++ = _frameBuffer[0][6]; + *dst++ = _frameBuffer[0][7]; + *dst++ = _frameBuffer[0][8]; + *dst++ = _frameBuffer[0][9]; + *dst++ = _frameBuffer[0][10]; + *dst++ = _frameBuffer[0][11]; + *dst++ = _frameBuffer[0][12]; + *dst++ = _frameBuffer[0][13]; + *dst++ = _frameBuffer[0][14]; + *dst++ = _frameBuffer[0][15]; + } + } + else if (_channelCount == 2) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + *dst++ = _frameBuffer[0][0]; + *dst++ = _frameBuffer[1][0]; + *dst++ = _frameBuffer[0][1]; + *dst++ = _frameBuffer[1][1]; + *dst++ = _frameBuffer[0][2]; + *dst++ = _frameBuffer[1][2]; + *dst++ = _frameBuffer[0][3]; + *dst++ = _frameBuffer[1][3]; + *dst++ = _frameBuffer[0][4]; + *dst++ = _frameBuffer[1][4]; + *dst++ = _frameBuffer[0][5]; + *dst++ = _frameBuffer[1][5]; + *dst++ = _frameBuffer[0][6]; + *dst++ = _frameBuffer[1][6]; + *dst++ = _frameBuffer[0][7]; + *dst++ = _frameBuffer[1][7]; + *dst++ = _frameBuffer[0][8]; + *dst++ = _frameBuffer[1][8]; + *dst++ = _frameBuffer[0][9]; + *dst++ = _frameBuffer[1][9]; + *dst++ = _frameBuffer[0][10]; + *dst++ = _frameBuffer[1][10]; + *dst++ = _frameBuffer[0][11]; + *dst++ = _frameBuffer[1][11]; + *dst++ = _frameBuffer[0][12]; + *dst++ = _frameBuffer[1][12]; + *dst++ = _frameBuffer[0][13]; + *dst++ = _frameBuffer[1][13]; + *dst++ = _frameBuffer[0][14]; + *dst++ = _frameBuffer[1][14]; + *dst++ = _frameBuffer[0][15]; + *dst++ = _frameBuffer[1][15]; + } + } + } + else { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + *dst++ = _frameBuffer[j][i]; + } } } } else { if(typeid(T) == typeid(float32_t) && - typeid(S) == typeid(int16_t)) { + typeid(S) == typeid(int16_t)) { // source and destination aare not the same, convert from float32_t to int16_t and copy out const int scale = (2 << ((8 * sizeof(S)) - 1)); - - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - *dst++ = (S)(_frameBuffer[j][i] * scale); + + if (frameAlignment16 && (_channelCount == 1 || _channelCount == 2)) { + + if (_channelCount == 1) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + *dst++ = (S)(_frameBuffer[0][0] * scale); + *dst++ = (S)(_frameBuffer[0][1] * scale); + *dst++ = (S)(_frameBuffer[0][2] * scale); + *dst++ = (S)(_frameBuffer[0][3] * scale); + *dst++ = (S)(_frameBuffer[0][4] * scale); + *dst++ = (S)(_frameBuffer[0][5] * scale); + *dst++ = (S)(_frameBuffer[0][6] * scale); + *dst++ = (S)(_frameBuffer[0][7] * scale); + *dst++ = (S)(_frameBuffer[0][8] * scale); + *dst++ = (S)(_frameBuffer[0][9] * scale); + *dst++ = (S)(_frameBuffer[0][10] * scale); + *dst++ = (S)(_frameBuffer[0][11] * scale); + *dst++ = (S)(_frameBuffer[0][12] * scale); + *dst++ = (S)(_frameBuffer[0][13] * scale); + *dst++ = (S)(_frameBuffer[0][14] * scale); + *dst++ = (S)(_frameBuffer[0][15] * scale); + } + } + else if (_channelCount == 2) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + *dst++ = (S)(_frameBuffer[0][0] * scale); + *dst++ = (S)(_frameBuffer[1][0] * scale); + *dst++ = (S)(_frameBuffer[0][1] * scale); + *dst++ = (S)(_frameBuffer[1][1] * scale); + *dst++ = (S)(_frameBuffer[0][2] * scale); + *dst++ = (S)(_frameBuffer[1][2] * scale); + *dst++ = (S)(_frameBuffer[0][3] * scale); + *dst++ = (S)(_frameBuffer[1][3] * scale); + *dst++ = (S)(_frameBuffer[0][4] * scale); + *dst++ = (S)(_frameBuffer[1][4] * scale); + *dst++ = (S)(_frameBuffer[0][5] * scale); + *dst++ = (S)(_frameBuffer[1][5] * scale); + *dst++ = (S)(_frameBuffer[0][6] * scale); + *dst++ = (S)(_frameBuffer[1][6] * scale); + *dst++ = (S)(_frameBuffer[0][7] * scale); + *dst++ = (S)(_frameBuffer[1][7] * scale); + *dst++ = (S)(_frameBuffer[0][8] * scale); + *dst++ = (S)(_frameBuffer[1][8] * scale); + *dst++ = (S)(_frameBuffer[0][9] * scale); + *dst++ = (S)(_frameBuffer[1][9] * scale); + *dst++ = (S)(_frameBuffer[0][10] * scale); + *dst++ = (S)(_frameBuffer[1][10] * scale); + *dst++ = (S)(_frameBuffer[0][11] * scale); + *dst++ = (S)(_frameBuffer[1][11] * scale); + *dst++ = (S)(_frameBuffer[0][12] * scale); + *dst++ = (S)(_frameBuffer[1][12] * scale); + *dst++ = (S)(_frameBuffer[0][13] * scale); + *dst++ = (S)(_frameBuffer[1][13] * scale); + *dst++ = (S)(_frameBuffer[0][14] * scale); + *dst++ = (S)(_frameBuffer[1][14] * scale); + *dst++ = (S)(_frameBuffer[0][15] * scale); + *dst++ = (S)(_frameBuffer[1][15] * scale); + } + } + } + else { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + *dst++ = (S)(_frameBuffer[j][i] * scale); + } } } } @@ -208,25 +315,148 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 } } } - else { // copyIn + else { // copyIn S* src = frames; - if(typeid(T) == typeid(S)) { // source and destination types are the same - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - _frameBuffer[j][i] = *src++; + if(typeid(T) == typeid(S)) { // source and destination types are the same, copy in + + if (frameAlignment16 && (_channelCount == 1 || _channelCount == 2)) { + + if (_channelCount == 1) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + _frameBuffer[0][0] = *src++; + _frameBuffer[0][1] = *src++; + _frameBuffer[0][2] = *src++; + _frameBuffer[0][3] = *src++; + _frameBuffer[0][4] = *src++; + _frameBuffer[0][5] = *src++; + _frameBuffer[0][6] = *src++; + _frameBuffer[0][7] = *src++; + _frameBuffer[0][8] = *src++; + _frameBuffer[0][9] = *src++; + _frameBuffer[0][10] = *src++; + _frameBuffer[0][11] = *src++; + _frameBuffer[0][12] = *src++; + _frameBuffer[0][13] = *src++; + _frameBuffer[0][14] = *src++; + _frameBuffer[0][15] = *src++; + } + } + else if (_channelCount == 2) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + _frameBuffer[0][0] = *src++; + _frameBuffer[1][0] = *src++; + _frameBuffer[0][1] = *src++; + _frameBuffer[1][1] = *src++; + _frameBuffer[0][2] = *src++; + _frameBuffer[1][2] = *src++; + _frameBuffer[0][3] = *src++; + _frameBuffer[1][3] = *src++; + _frameBuffer[0][4] = *src++; + _frameBuffer[1][4] = *src++; + _frameBuffer[0][5] = *src++; + _frameBuffer[1][5] = *src++; + _frameBuffer[0][6] = *src++; + _frameBuffer[1][6] = *src++; + _frameBuffer[0][7] = *src++; + _frameBuffer[1][7] = *src++; + _frameBuffer[0][8] = *src++; + _frameBuffer[1][8] = *src++; + _frameBuffer[0][9] = *src++; + _frameBuffer[1][9] = *src++; + _frameBuffer[0][10] = *src++; + _frameBuffer[1][10] = *src++; + _frameBuffer[0][11] = *src++; + _frameBuffer[1][11] = *src++; + _frameBuffer[0][12] = *src++; + _frameBuffer[1][12] = *src++; + _frameBuffer[0][13] = *src++; + _frameBuffer[1][13] = *src++; + _frameBuffer[0][14] = *src++; + _frameBuffer[1][14] = *src++; + _frameBuffer[0][15] = *src++; + _frameBuffer[1][15] = *src++; + } + } + } + else { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + _frameBuffer[j][i] = *src++; + } } } } - else { + else { if(typeid(T) == typeid(float32_t) && - typeid(S) == typeid(int16_t)) { + typeid(S) == typeid(int16_t)) { // source and destination aare not the same, convert from int16_t to float32_t and copy in const int scale = (2 << ((8 * sizeof(S)) - 1)); - for (uint32_t i = 0; i < _frameCount; ++i) { - for (uint32_t j = 0; j < _channelCount; ++j) { - _frameBuffer[j][i] = ((T)(*src++)) / scale; + if (frameAlignment16 && (_channelCount == 1 || _channelCount == 2)) { + + if (_channelCount == 1) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + _frameBuffer[0][0] = ((T)(*src++)) / scale; + _frameBuffer[0][1] = ((T)(*src++)) / scale; + _frameBuffer[0][2] = ((T)(*src++)) / scale; + _frameBuffer[0][3] = ((T)(*src++)) / scale; + _frameBuffer[0][4] = ((T)(*src++)) / scale; + _frameBuffer[0][5] = ((T)(*src++)) / scale; + _frameBuffer[0][6] = ((T)(*src++)) / scale; + _frameBuffer[0][7] = ((T)(*src++)) / scale; + _frameBuffer[0][8] = ((T)(*src++)) / scale; + _frameBuffer[0][9] = ((T)(*src++)) / scale; + _frameBuffer[0][10] = ((T)(*src++)) / scale; + _frameBuffer[0][11] = ((T)(*src++)) / scale; + _frameBuffer[0][12] = ((T)(*src++)) / scale; + _frameBuffer[0][13] = ((T)(*src++)) / scale; + _frameBuffer[0][14] = ((T)(*src++)) / scale; + _frameBuffer[0][15] = ((T)(*src++)) / scale; + } + } + else if (_channelCount == 2) { + for (uint32_t i = 0; i < _frameCount; i += 16) { + _frameBuffer[0][0] = ((T)(*src++)) / scale; + _frameBuffer[1][0] = ((T)(*src++)) / scale; + _frameBuffer[0][1] = ((T)(*src++)) / scale; + _frameBuffer[1][1] = ((T)(*src++)) / scale; + _frameBuffer[0][2] = ((T)(*src++)) / scale; + _frameBuffer[1][2] = ((T)(*src++)) / scale; + _frameBuffer[0][3] = ((T)(*src++)) / scale; + _frameBuffer[1][3] = ((T)(*src++)) / scale; + _frameBuffer[0][4] = ((T)(*src++)) / scale; + _frameBuffer[1][4] = ((T)(*src++)) / scale; + _frameBuffer[0][5] = ((T)(*src++)) / scale; + _frameBuffer[1][5] = ((T)(*src++)) / scale; + _frameBuffer[0][6] = ((T)(*src++)) / scale; + _frameBuffer[1][6] = ((T)(*src++)) / scale; + _frameBuffer[0][7] = ((T)(*src++)) / scale; + _frameBuffer[1][7] = ((T)(*src++)) / scale; + _frameBuffer[0][8] = ((T)(*src++)) / scale; + _frameBuffer[1][8] = ((T)(*src++)) / scale; + _frameBuffer[0][9] = ((T)(*src++)) / scale; + _frameBuffer[1][9] = ((T)(*src++)) / scale; + _frameBuffer[0][10] = ((T)(*src++)) / scale; + _frameBuffer[1][10] = ((T)(*src++)) / scale; + _frameBuffer[0][11] = ((T)(*src++)) / scale; + _frameBuffer[1][11] = ((T)(*src++)) / scale; + _frameBuffer[0][12] = ((T)(*src++)) / scale; + _frameBuffer[1][12] = ((T)(*src++)) / scale; + _frameBuffer[0][13] = ((T)(*src++)) / scale; + _frameBuffer[1][13] = ((T)(*src++)) / scale; + _frameBuffer[0][14] = ((T)(*src++)) / scale; + _frameBuffer[1][14] = ((T)(*src++)) / scale; + _frameBuffer[0][15] = ((T)(*src++)) / scale; + _frameBuffer[1][15] = ((T)(*src++)) / scale; + } + } + } + else { + for (uint32_t i = 0; i < _frameCount; ++i) { + for (uint32_t j = 0; j < _channelCount; ++j) { + _frameBuffer[j][i] = ((T)(*src++)) / scale; + } } } } From 66ec43c06615b276acb81e17751309c3273c164c Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Mon, 22 Sep 2014 11:04:21 -0700 Subject: [PATCH 39/43] coding standard - else clause --- libraries/audio/src/AudioBuffer.h | 44 +++++++++------------------ libraries/audio/src/AudioEditBuffer.h | 3 +- libraries/audio/src/AudioGain.h | 9 ++---- libraries/audio/src/AudioPan.h | 15 +++------ 4 files changed, 24 insertions(+), 47 deletions(-) diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index b0d9d7da8e..b8ff1635a8 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -148,8 +148,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 // We always allow copying fewer frames than we have allocated _frameCount = frameCount; _channelCount = channelCount; - } - else { + } else { qDebug() << "Audio framing error: _channelCount=" << _channelCount << "channelCountMax=" @@ -163,7 +162,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameCount = std::min(_frameCount,_frameCountMax); } - bool frameAlignment16 = (_frameCount & 0x0F) == 0; + bool frameAlignment16 = false; // (_frameCount & 0x0F) == 0; if (copyOut) { S* dst = frames; @@ -191,8 +190,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 *dst++ = _frameBuffer[0][14]; *dst++ = _frameBuffer[0][15]; } - } - else if (_channelCount == 2) { + } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { *dst++ = _frameBuffer[0][0]; *dst++ = _frameBuffer[1][0]; @@ -228,16 +226,14 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 *dst++ = _frameBuffer[1][15]; } } - } - else { + } else { for (uint32_t i = 0; i < _frameCount; ++i) { for (uint32_t j = 0; j < _channelCount; ++j) { *dst++ = _frameBuffer[j][i]; } } } - } - else { + } else { if(typeid(T) == typeid(float32_t) && typeid(S) == typeid(int16_t)) { // source and destination aare not the same, convert from float32_t to int16_t and copy out @@ -264,8 +260,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 *dst++ = (S)(_frameBuffer[0][14] * scale); *dst++ = (S)(_frameBuffer[0][15] * scale); } - } - else if (_channelCount == 2) { + } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { *dst++ = (S)(_frameBuffer[0][0] * scale); *dst++ = (S)(_frameBuffer[1][0] * scale); @@ -301,21 +296,18 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 *dst++ = (S)(_frameBuffer[1][15] * scale); } } - } - else { + } else { for (uint32_t i = 0; i < _frameCount; ++i) { for (uint32_t j = 0; j < _channelCount; ++j) { *dst++ = (S)(_frameBuffer[j][i] * scale); } } } - } - else { + } else { assert(0); // currently unsupported conversion } } - } - else { // copyIn + } else { // copyIn S* src = frames; if(typeid(T) == typeid(S)) { // source and destination types are the same, copy in @@ -341,8 +333,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameBuffer[0][14] = *src++; _frameBuffer[0][15] = *src++; } - } - else if (_channelCount == 2) { + } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { _frameBuffer[0][0] = *src++; _frameBuffer[1][0] = *src++; @@ -378,16 +369,14 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameBuffer[1][15] = *src++; } } - } - else { + } else { for (uint32_t i = 0; i < _frameCount; ++i) { for (uint32_t j = 0; j < _channelCount; ++j) { _frameBuffer[j][i] = *src++; } } } - } - else { + } else { if(typeid(T) == typeid(float32_t) && typeid(S) == typeid(int16_t)) { // source and destination aare not the same, convert from int16_t to float32_t and copy in @@ -414,8 +403,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameBuffer[0][14] = ((T)(*src++)) / scale; _frameBuffer[0][15] = ((T)(*src++)) / scale; } - } - else if (_channelCount == 2) { + } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { _frameBuffer[0][0] = ((T)(*src++)) / scale; _frameBuffer[1][0] = ((T)(*src++)) / scale; @@ -451,16 +439,14 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameBuffer[1][15] = ((T)(*src++)) / scale; } } - } - else { + } else { for (uint32_t i = 0; i < _frameCount; ++i) { for (uint32_t j = 0; j < _channelCount; ++j) { _frameBuffer[j][i] = ((T)(*src++)) / scale; } } } - } - else { + } else { assert(0); // currently unsupported conversion } } diff --git a/libraries/audio/src/AudioEditBuffer.h b/libraries/audio/src/AudioEditBuffer.h index 2761eee97c..f93d338e47 100644 --- a/libraries/audio/src/AudioEditBuffer.h +++ b/libraries/audio/src/AudioEditBuffer.h @@ -88,8 +88,7 @@ inline void AudioEditBuffer::linearFade(uint32_t start, uint32_t stop, bool s if (slope) { // 0.0 to 1.0f in delta increments delta = 1.0f / (float32_t)count; gain = 0.0f; - } - else { // 1.0f to 0.0f in delta increments + } else { // 1.0f to 0.0f in delta increments delta = -1.0f / (float32_t)count; gain = 1.0f; } diff --git a/libraries/audio/src/AudioGain.h b/libraries/audio/src/AudioGain.h index a321ec2eba..1d54d76f7f 100644 --- a/libraries/audio/src/AudioGain.h +++ b/libraries/audio/src/AudioGain.h @@ -63,8 +63,7 @@ inline void AudioGain::render(AudioBufferFloat32& frameBuffer) { samples[0][i + 14] *= _gain; samples[0][i + 15] *= _gain; } - } - else if (frameBuffer.getChannelCount() == 2) { + } else if (frameBuffer.getChannelCount() == 2) { for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 16) { samples[0][i + 0] *= _gain; @@ -100,12 +99,10 @@ inline void AudioGain::render(AudioBufferFloat32& frameBuffer) { samples[1][i + 14] *= _gain; samples[1][i + 15] *= _gain; } - } - else { + } else { assert("unsupported channel format"); } - } - else { + } else { for (uint32_t j = 0; j < frameBuffer.getChannelCount(); ++j) { for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { diff --git a/libraries/audio/src/AudioPan.h b/libraries/audio/src/AudioPan.h index ea5e90a7f7..2fe8c5cc28 100644 --- a/libraries/audio/src/AudioPan.h +++ b/libraries/audio/src/AudioPan.h @@ -87,12 +87,10 @@ inline void AudioPan::render(AudioBufferFloat32& frameBuffer) { samples[1][i + 14] *= _gainRight; samples[1][i + 15] *= _gainRight; } - } - else { + } else { assert("unsupported channel format"); } - } - else { + } else { for (uint32_t i = 0; i < frameBuffer.getFrameCount(); i += 1) { samples[0][i] *= _gainLeft; samples[1][i] *= _gainRight; @@ -107,16 +105,13 @@ inline void AudioPan::updateCoefficients() { if (_pan >= ONE_MINUS_EPSILON) { // full right _gainLeft = 0.0f; _gainRight = 1.0f; - } - else if (_pan <= ZERO_PLUS_EPSILON) { // full left + } else if (_pan <= ZERO_PLUS_EPSILON) { // full left _gainLeft = 1.0f; _gainRight = 0.0f; - } - else if ((_pan >= ONE_HALF_MINUS_EPSILON) && (_pan <= ONE_HALF_PLUS_EPSILON)) { // center + } else if ((_pan >= ONE_HALF_MINUS_EPSILON) && (_pan <= ONE_HALF_PLUS_EPSILON)) { // center _gainLeft = 1.0f / SQUARE_ROOT_OF_2; _gainRight = 1.0f / SQUARE_ROOT_OF_2; - } - else { // intermediate cases + } else { // intermediate cases _gainLeft = cosf( TWO_PI * _pan ); _gainRight = sinf( TWO_PI * _pan ); } From 75858b07c6a64d1869837fbace5454f2c32d6ea8 Mon Sep 17 00:00:00 2001 From: Craig Hansen-Sturm Date: Mon, 22 Sep 2014 11:21:18 -0700 Subject: [PATCH 40/43] coding standard + missing frame-offsets in audiobuffer --- libraries/audio/src/AudioBuffer.h | 386 +++++++++++++------------- libraries/audio/src/AudioEditBuffer.h | 3 +- 2 files changed, 194 insertions(+), 195 deletions(-) diff --git a/libraries/audio/src/AudioBuffer.h b/libraries/audio/src/AudioBuffer.h index b8ff1635a8..c489c169a7 100644 --- a/libraries/audio/src/AudioBuffer.h +++ b/libraries/audio/src/AudioBuffer.h @@ -162,7 +162,7 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 _frameCount = std::min(_frameCount,_frameCountMax); } - bool frameAlignment16 = false; // (_frameCount & 0x0F) == 0; + bool frameAlignment16 = (_frameCount & 0x0F) == 0; if (copyOut) { S* dst = frames; @@ -173,57 +173,57 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 if (_channelCount == 1) { for (uint32_t i = 0; i < _frameCount; i += 16) { - *dst++ = _frameBuffer[0][0]; - *dst++ = _frameBuffer[0][1]; - *dst++ = _frameBuffer[0][2]; - *dst++ = _frameBuffer[0][3]; - *dst++ = _frameBuffer[0][4]; - *dst++ = _frameBuffer[0][5]; - *dst++ = _frameBuffer[0][6]; - *dst++ = _frameBuffer[0][7]; - *dst++ = _frameBuffer[0][8]; - *dst++ = _frameBuffer[0][9]; - *dst++ = _frameBuffer[0][10]; - *dst++ = _frameBuffer[0][11]; - *dst++ = _frameBuffer[0][12]; - *dst++ = _frameBuffer[0][13]; - *dst++ = _frameBuffer[0][14]; - *dst++ = _frameBuffer[0][15]; + *dst++ = _frameBuffer[0][i + 0]; + *dst++ = _frameBuffer[0][i + 1]; + *dst++ = _frameBuffer[0][i + 2]; + *dst++ = _frameBuffer[0][i + 3]; + *dst++ = _frameBuffer[0][i + 4]; + *dst++ = _frameBuffer[0][i + 5]; + *dst++ = _frameBuffer[0][i + 6]; + *dst++ = _frameBuffer[0][i + 7]; + *dst++ = _frameBuffer[0][i + 8]; + *dst++ = _frameBuffer[0][i + 9]; + *dst++ = _frameBuffer[0][i + 10]; + *dst++ = _frameBuffer[0][i + 11]; + *dst++ = _frameBuffer[0][i + 12]; + *dst++ = _frameBuffer[0][i + 13]; + *dst++ = _frameBuffer[0][i + 14]; + *dst++ = _frameBuffer[0][i + 15]; } } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { - *dst++ = _frameBuffer[0][0]; - *dst++ = _frameBuffer[1][0]; - *dst++ = _frameBuffer[0][1]; - *dst++ = _frameBuffer[1][1]; - *dst++ = _frameBuffer[0][2]; - *dst++ = _frameBuffer[1][2]; - *dst++ = _frameBuffer[0][3]; - *dst++ = _frameBuffer[1][3]; - *dst++ = _frameBuffer[0][4]; - *dst++ = _frameBuffer[1][4]; - *dst++ = _frameBuffer[0][5]; - *dst++ = _frameBuffer[1][5]; - *dst++ = _frameBuffer[0][6]; - *dst++ = _frameBuffer[1][6]; - *dst++ = _frameBuffer[0][7]; - *dst++ = _frameBuffer[1][7]; - *dst++ = _frameBuffer[0][8]; - *dst++ = _frameBuffer[1][8]; - *dst++ = _frameBuffer[0][9]; - *dst++ = _frameBuffer[1][9]; - *dst++ = _frameBuffer[0][10]; - *dst++ = _frameBuffer[1][10]; - *dst++ = _frameBuffer[0][11]; - *dst++ = _frameBuffer[1][11]; - *dst++ = _frameBuffer[0][12]; - *dst++ = _frameBuffer[1][12]; - *dst++ = _frameBuffer[0][13]; - *dst++ = _frameBuffer[1][13]; - *dst++ = _frameBuffer[0][14]; - *dst++ = _frameBuffer[1][14]; - *dst++ = _frameBuffer[0][15]; - *dst++ = _frameBuffer[1][15]; + *dst++ = _frameBuffer[0][i + 0]; + *dst++ = _frameBuffer[1][i + 0]; + *dst++ = _frameBuffer[0][i + 1]; + *dst++ = _frameBuffer[1][i + 1]; + *dst++ = _frameBuffer[0][i + 2]; + *dst++ = _frameBuffer[1][i + 2]; + *dst++ = _frameBuffer[0][i + 3]; + *dst++ = _frameBuffer[1][i + 3]; + *dst++ = _frameBuffer[0][i + 4]; + *dst++ = _frameBuffer[1][i + 4]; + *dst++ = _frameBuffer[0][i + 5]; + *dst++ = _frameBuffer[1][i + 5]; + *dst++ = _frameBuffer[0][i + 6]; + *dst++ = _frameBuffer[1][i + 6]; + *dst++ = _frameBuffer[0][i + 7]; + *dst++ = _frameBuffer[1][i + 7]; + *dst++ = _frameBuffer[0][i + 8]; + *dst++ = _frameBuffer[1][i + 8]; + *dst++ = _frameBuffer[0][i + 9]; + *dst++ = _frameBuffer[1][i + 9]; + *dst++ = _frameBuffer[0][i + 10]; + *dst++ = _frameBuffer[1][i + 10]; + *dst++ = _frameBuffer[0][i + 11]; + *dst++ = _frameBuffer[1][i + 11]; + *dst++ = _frameBuffer[0][i + 12]; + *dst++ = _frameBuffer[1][i + 12]; + *dst++ = _frameBuffer[0][i + 13]; + *dst++ = _frameBuffer[1][i + 13]; + *dst++ = _frameBuffer[0][i + 14]; + *dst++ = _frameBuffer[1][i + 14]; + *dst++ = _frameBuffer[0][i + 15]; + *dst++ = _frameBuffer[1][i + 15]; } } } else { @@ -243,57 +243,57 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 if (_channelCount == 1) { for (uint32_t i = 0; i < _frameCount; i += 16) { - *dst++ = (S)(_frameBuffer[0][0] * scale); - *dst++ = (S)(_frameBuffer[0][1] * scale); - *dst++ = (S)(_frameBuffer[0][2] * scale); - *dst++ = (S)(_frameBuffer[0][3] * scale); - *dst++ = (S)(_frameBuffer[0][4] * scale); - *dst++ = (S)(_frameBuffer[0][5] * scale); - *dst++ = (S)(_frameBuffer[0][6] * scale); - *dst++ = (S)(_frameBuffer[0][7] * scale); - *dst++ = (S)(_frameBuffer[0][8] * scale); - *dst++ = (S)(_frameBuffer[0][9] * scale); - *dst++ = (S)(_frameBuffer[0][10] * scale); - *dst++ = (S)(_frameBuffer[0][11] * scale); - *dst++ = (S)(_frameBuffer[0][12] * scale); - *dst++ = (S)(_frameBuffer[0][13] * scale); - *dst++ = (S)(_frameBuffer[0][14] * scale); - *dst++ = (S)(_frameBuffer[0][15] * scale); + *dst++ = (S)(_frameBuffer[0][i + 0] * scale); + *dst++ = (S)(_frameBuffer[0][i + 1] * scale); + *dst++ = (S)(_frameBuffer[0][i + 2] * scale); + *dst++ = (S)(_frameBuffer[0][i + 3] * scale); + *dst++ = (S)(_frameBuffer[0][i + 4] * scale); + *dst++ = (S)(_frameBuffer[0][i + 5] * scale); + *dst++ = (S)(_frameBuffer[0][i + 6] * scale); + *dst++ = (S)(_frameBuffer[0][i + 7] * scale); + *dst++ = (S)(_frameBuffer[0][i + 8] * scale); + *dst++ = (S)(_frameBuffer[0][i + 9] * scale); + *dst++ = (S)(_frameBuffer[0][i + 10] * scale); + *dst++ = (S)(_frameBuffer[0][i + 11] * scale); + *dst++ = (S)(_frameBuffer[0][i + 12] * scale); + *dst++ = (S)(_frameBuffer[0][i + 13] * scale); + *dst++ = (S)(_frameBuffer[0][i + 14] * scale); + *dst++ = (S)(_frameBuffer[0][i + 15] * scale); } } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { - *dst++ = (S)(_frameBuffer[0][0] * scale); - *dst++ = (S)(_frameBuffer[1][0] * scale); - *dst++ = (S)(_frameBuffer[0][1] * scale); - *dst++ = (S)(_frameBuffer[1][1] * scale); - *dst++ = (S)(_frameBuffer[0][2] * scale); - *dst++ = (S)(_frameBuffer[1][2] * scale); - *dst++ = (S)(_frameBuffer[0][3] * scale); - *dst++ = (S)(_frameBuffer[1][3] * scale); - *dst++ = (S)(_frameBuffer[0][4] * scale); - *dst++ = (S)(_frameBuffer[1][4] * scale); - *dst++ = (S)(_frameBuffer[0][5] * scale); - *dst++ = (S)(_frameBuffer[1][5] * scale); - *dst++ = (S)(_frameBuffer[0][6] * scale); - *dst++ = (S)(_frameBuffer[1][6] * scale); - *dst++ = (S)(_frameBuffer[0][7] * scale); - *dst++ = (S)(_frameBuffer[1][7] * scale); - *dst++ = (S)(_frameBuffer[0][8] * scale); - *dst++ = (S)(_frameBuffer[1][8] * scale); - *dst++ = (S)(_frameBuffer[0][9] * scale); - *dst++ = (S)(_frameBuffer[1][9] * scale); - *dst++ = (S)(_frameBuffer[0][10] * scale); - *dst++ = (S)(_frameBuffer[1][10] * scale); - *dst++ = (S)(_frameBuffer[0][11] * scale); - *dst++ = (S)(_frameBuffer[1][11] * scale); - *dst++ = (S)(_frameBuffer[0][12] * scale); - *dst++ = (S)(_frameBuffer[1][12] * scale); - *dst++ = (S)(_frameBuffer[0][13] * scale); - *dst++ = (S)(_frameBuffer[1][13] * scale); - *dst++ = (S)(_frameBuffer[0][14] * scale); - *dst++ = (S)(_frameBuffer[1][14] * scale); - *dst++ = (S)(_frameBuffer[0][15] * scale); - *dst++ = (S)(_frameBuffer[1][15] * scale); + *dst++ = (S)(_frameBuffer[0][i + 0] * scale); + *dst++ = (S)(_frameBuffer[1][i + 0] * scale); + *dst++ = (S)(_frameBuffer[0][i + 1] * scale); + *dst++ = (S)(_frameBuffer[1][i + 1] * scale); + *dst++ = (S)(_frameBuffer[0][i + 2] * scale); + *dst++ = (S)(_frameBuffer[1][i + 2] * scale); + *dst++ = (S)(_frameBuffer[0][i + 3] * scale); + *dst++ = (S)(_frameBuffer[1][i + 3] * scale); + *dst++ = (S)(_frameBuffer[0][i + 4] * scale); + *dst++ = (S)(_frameBuffer[1][i + 4] * scale); + *dst++ = (S)(_frameBuffer[0][i + 5] * scale); + *dst++ = (S)(_frameBuffer[1][i + 5] * scale); + *dst++ = (S)(_frameBuffer[0][i + 6] * scale); + *dst++ = (S)(_frameBuffer[1][i + 6] * scale); + *dst++ = (S)(_frameBuffer[0][i + 7] * scale); + *dst++ = (S)(_frameBuffer[1][i + 7] * scale); + *dst++ = (S)(_frameBuffer[0][i + 8] * scale); + *dst++ = (S)(_frameBuffer[1][i + 8] * scale); + *dst++ = (S)(_frameBuffer[0][i + 9] * scale); + *dst++ = (S)(_frameBuffer[1][i + 9] * scale); + *dst++ = (S)(_frameBuffer[0][i + 10] * scale); + *dst++ = (S)(_frameBuffer[1][i + 10] * scale); + *dst++ = (S)(_frameBuffer[0][i + 11] * scale); + *dst++ = (S)(_frameBuffer[1][i + 11] * scale); + *dst++ = (S)(_frameBuffer[0][i + 12] * scale); + *dst++ = (S)(_frameBuffer[1][i + 12] * scale); + *dst++ = (S)(_frameBuffer[0][i + 13] * scale); + *dst++ = (S)(_frameBuffer[1][i + 13] * scale); + *dst++ = (S)(_frameBuffer[0][i + 14] * scale); + *dst++ = (S)(_frameBuffer[1][i + 14] * scale); + *dst++ = (S)(_frameBuffer[0][i + 15] * scale); + *dst++ = (S)(_frameBuffer[1][i + 15] * scale); } } } else { @@ -316,57 +316,57 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 if (_channelCount == 1) { for (uint32_t i = 0; i < _frameCount; i += 16) { - _frameBuffer[0][0] = *src++; - _frameBuffer[0][1] = *src++; - _frameBuffer[0][2] = *src++; - _frameBuffer[0][3] = *src++; - _frameBuffer[0][4] = *src++; - _frameBuffer[0][5] = *src++; - _frameBuffer[0][6] = *src++; - _frameBuffer[0][7] = *src++; - _frameBuffer[0][8] = *src++; - _frameBuffer[0][9] = *src++; - _frameBuffer[0][10] = *src++; - _frameBuffer[0][11] = *src++; - _frameBuffer[0][12] = *src++; - _frameBuffer[0][13] = *src++; - _frameBuffer[0][14] = *src++; - _frameBuffer[0][15] = *src++; + _frameBuffer[0][i + 0] = *src++; + _frameBuffer[0][i + 1] = *src++; + _frameBuffer[0][i + 2] = *src++; + _frameBuffer[0][i + 3] = *src++; + _frameBuffer[0][i + 4] = *src++; + _frameBuffer[0][i + 5] = *src++; + _frameBuffer[0][i + 6] = *src++; + _frameBuffer[0][i + 7] = *src++; + _frameBuffer[0][i + 8] = *src++; + _frameBuffer[0][i + 9] = *src++; + _frameBuffer[0][i + 10] = *src++; + _frameBuffer[0][i + 11] = *src++; + _frameBuffer[0][i + 12] = *src++; + _frameBuffer[0][i + 13] = *src++; + _frameBuffer[0][i + 14] = *src++; + _frameBuffer[0][i + 15] = *src++; } } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { - _frameBuffer[0][0] = *src++; - _frameBuffer[1][0] = *src++; - _frameBuffer[0][1] = *src++; - _frameBuffer[1][1] = *src++; - _frameBuffer[0][2] = *src++; - _frameBuffer[1][2] = *src++; - _frameBuffer[0][3] = *src++; - _frameBuffer[1][3] = *src++; - _frameBuffer[0][4] = *src++; - _frameBuffer[1][4] = *src++; - _frameBuffer[0][5] = *src++; - _frameBuffer[1][5] = *src++; - _frameBuffer[0][6] = *src++; - _frameBuffer[1][6] = *src++; - _frameBuffer[0][7] = *src++; - _frameBuffer[1][7] = *src++; - _frameBuffer[0][8] = *src++; - _frameBuffer[1][8] = *src++; - _frameBuffer[0][9] = *src++; - _frameBuffer[1][9] = *src++; - _frameBuffer[0][10] = *src++; - _frameBuffer[1][10] = *src++; - _frameBuffer[0][11] = *src++; - _frameBuffer[1][11] = *src++; - _frameBuffer[0][12] = *src++; - _frameBuffer[1][12] = *src++; - _frameBuffer[0][13] = *src++; - _frameBuffer[1][13] = *src++; - _frameBuffer[0][14] = *src++; - _frameBuffer[1][14] = *src++; - _frameBuffer[0][15] = *src++; - _frameBuffer[1][15] = *src++; + _frameBuffer[0][i + 0] = *src++; + _frameBuffer[1][i + 0] = *src++; + _frameBuffer[0][i + 1] = *src++; + _frameBuffer[1][i + 1] = *src++; + _frameBuffer[0][i + 2] = *src++; + _frameBuffer[1][i + 2] = *src++; + _frameBuffer[0][i + 3] = *src++; + _frameBuffer[1][i + 3] = *src++; + _frameBuffer[0][i + 4] = *src++; + _frameBuffer[1][i + 4] = *src++; + _frameBuffer[0][i + 5] = *src++; + _frameBuffer[1][i + 5] = *src++; + _frameBuffer[0][i + 6] = *src++; + _frameBuffer[1][i + 6] = *src++; + _frameBuffer[0][i + 7] = *src++; + _frameBuffer[1][i + 7] = *src++; + _frameBuffer[0][i + 8] = *src++; + _frameBuffer[1][i + 8] = *src++; + _frameBuffer[0][i + 9] = *src++; + _frameBuffer[1][i + 9] = *src++; + _frameBuffer[0][i + 10] = *src++; + _frameBuffer[1][i + 10] = *src++; + _frameBuffer[0][i + 11] = *src++; + _frameBuffer[1][i + 11] = *src++; + _frameBuffer[0][i + 12] = *src++; + _frameBuffer[1][i + 12] = *src++; + _frameBuffer[0][i + 13] = *src++; + _frameBuffer[1][i + 13] = *src++; + _frameBuffer[0][i + 14] = *src++; + _frameBuffer[1][i + 14] = *src++; + _frameBuffer[0][i + 15] = *src++; + _frameBuffer[1][i + 15] = *src++; } } } else { @@ -386,57 +386,57 @@ inline void AudioFrameBuffer< T >::copyFrames(uint32_t channelCount, const uint3 if (_channelCount == 1) { for (uint32_t i = 0; i < _frameCount; i += 16) { - _frameBuffer[0][0] = ((T)(*src++)) / scale; - _frameBuffer[0][1] = ((T)(*src++)) / scale; - _frameBuffer[0][2] = ((T)(*src++)) / scale; - _frameBuffer[0][3] = ((T)(*src++)) / scale; - _frameBuffer[0][4] = ((T)(*src++)) / scale; - _frameBuffer[0][5] = ((T)(*src++)) / scale; - _frameBuffer[0][6] = ((T)(*src++)) / scale; - _frameBuffer[0][7] = ((T)(*src++)) / scale; - _frameBuffer[0][8] = ((T)(*src++)) / scale; - _frameBuffer[0][9] = ((T)(*src++)) / scale; - _frameBuffer[0][10] = ((T)(*src++)) / scale; - _frameBuffer[0][11] = ((T)(*src++)) / scale; - _frameBuffer[0][12] = ((T)(*src++)) / scale; - _frameBuffer[0][13] = ((T)(*src++)) / scale; - _frameBuffer[0][14] = ((T)(*src++)) / scale; - _frameBuffer[0][15] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 0] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 1] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 2] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 3] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 4] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 5] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 6] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 7] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 8] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 9] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 10] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 11] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 12] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 13] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 14] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 15] = ((T)(*src++)) / scale; } } else if (_channelCount == 2) { for (uint32_t i = 0; i < _frameCount; i += 16) { - _frameBuffer[0][0] = ((T)(*src++)) / scale; - _frameBuffer[1][0] = ((T)(*src++)) / scale; - _frameBuffer[0][1] = ((T)(*src++)) / scale; - _frameBuffer[1][1] = ((T)(*src++)) / scale; - _frameBuffer[0][2] = ((T)(*src++)) / scale; - _frameBuffer[1][2] = ((T)(*src++)) / scale; - _frameBuffer[0][3] = ((T)(*src++)) / scale; - _frameBuffer[1][3] = ((T)(*src++)) / scale; - _frameBuffer[0][4] = ((T)(*src++)) / scale; - _frameBuffer[1][4] = ((T)(*src++)) / scale; - _frameBuffer[0][5] = ((T)(*src++)) / scale; - _frameBuffer[1][5] = ((T)(*src++)) / scale; - _frameBuffer[0][6] = ((T)(*src++)) / scale; - _frameBuffer[1][6] = ((T)(*src++)) / scale; - _frameBuffer[0][7] = ((T)(*src++)) / scale; - _frameBuffer[1][7] = ((T)(*src++)) / scale; - _frameBuffer[0][8] = ((T)(*src++)) / scale; - _frameBuffer[1][8] = ((T)(*src++)) / scale; - _frameBuffer[0][9] = ((T)(*src++)) / scale; - _frameBuffer[1][9] = ((T)(*src++)) / scale; - _frameBuffer[0][10] = ((T)(*src++)) / scale; - _frameBuffer[1][10] = ((T)(*src++)) / scale; - _frameBuffer[0][11] = ((T)(*src++)) / scale; - _frameBuffer[1][11] = ((T)(*src++)) / scale; - _frameBuffer[0][12] = ((T)(*src++)) / scale; - _frameBuffer[1][12] = ((T)(*src++)) / scale; - _frameBuffer[0][13] = ((T)(*src++)) / scale; - _frameBuffer[1][13] = ((T)(*src++)) / scale; - _frameBuffer[0][14] = ((T)(*src++)) / scale; - _frameBuffer[1][14] = ((T)(*src++)) / scale; - _frameBuffer[0][15] = ((T)(*src++)) / scale; - _frameBuffer[1][15] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 0] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 0] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 1] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 1] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 2] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 2] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 3] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 3] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 4] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 4] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 5] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 5] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 6] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 6] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 7] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 7] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 8] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 8] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 9] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 9] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 10] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 10] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 11] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 11] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 12] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 12] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 13] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 13] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 14] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 14] = ((T)(*src++)) / scale; + _frameBuffer[0][i + 15] = ((T)(*src++)) / scale; + _frameBuffer[1][i + 15] = ((T)(*src++)) / scale; } } } else { diff --git a/libraries/audio/src/AudioEditBuffer.h b/libraries/audio/src/AudioEditBuffer.h index f93d338e47..b773fedfb8 100644 --- a/libraries/audio/src/AudioEditBuffer.h +++ b/libraries/audio/src/AudioEditBuffer.h @@ -57,8 +57,7 @@ inline bool AudioEditBuffer::getZeroCrossing(uint32_t start, bool direction, } } } - } - else { // scan from the right + } else { // scan from the right if (start != 0 && start < this->_frameCount) { for (uint32_t i = start; i != 0; --i) { for (uint32_t j = 0; j < this->_channelCount; ++j) { From aeb424cd715cab75754d3f8ccd1d5605e613ab8c Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 22 Sep 2014 15:01:39 -0700 Subject: [PATCH 41/43] Fix for billboards. --- interface/src/Application.cpp | 7 ++-- interface/src/avatar/Avatar.cpp | 70 +++++++++++++++++-------------- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/Head.cpp | 2 - interface/src/avatar/MyAvatar.cpp | 36 +++++++++------- interface/src/avatar/MyAvatar.h | 2 +- 6 files changed, 65 insertions(+), 54 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e1ee1333ca..bcb732521d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2730,7 +2730,8 @@ void Application::setupWorldLight() { QImage Application::renderAvatarBillboard() { _textureCache.getPrimaryFramebufferObject()->bind(); - glDisable(GL_BLEND); + // the "glow" here causes an alpha of one + Glower glower; const int BILLBOARD_SIZE = 64; renderRearViewMirror(QRect(0, _glWidget->getDeviceHeight() - BILLBOARD_SIZE, BILLBOARD_SIZE, BILLBOARD_SIZE), true); @@ -2738,10 +2739,10 @@ QImage Application::renderAvatarBillboard() { QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32); glReadPixels(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE, GL_BGRA, GL_UNSIGNED_BYTE, image.bits()); - glEnable(GL_BLEND); - _textureCache.getPrimaryFramebufferObject()->release(); + image.save("billboard.png"); + return image; } diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 8e426b4a4d..6907a82421 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -351,23 +351,23 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool : GLOW_FROM_AVERAGE_LOUDNESS; // render body - if (!postLighting && Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(renderMode, glowLevel); + if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { + renderBody(renderMode, postLighting, glowLevel); + } - if (renderMode != SHADOW_RENDER_MODE) { - // add local lights - const float BASE_LIGHT_DISTANCE = 2.0f; - const float LIGHT_EXPONENT = 1.0f; - const float LIGHT_CUTOFF = glm::radians(80.0f); - float distance = BASE_LIGHT_DISTANCE * _scale; - glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); - glm::quat orientation = getOrientation(); - foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { - glm::vec3 direction = orientation * light.direction; - Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, - distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, - LIGHT_EXPONENT, LIGHT_CUTOFF); - } + if (!postLighting && renderMode != SHADOW_RENDER_MODE) { + // add local lights + const float BASE_LIGHT_DISTANCE = 2.0f; + const float LIGHT_EXPONENT = 1.0f; + const float LIGHT_CUTOFF = glm::radians(80.0f); + float distance = BASE_LIGHT_DISTANCE * _scale; + glm::vec3 position = glm::mix(_skeletonModel.getTranslation(), getHead()->getFaceModel().getTranslation(), 0.9f); + glm::quat orientation = getOrientation(); + foreach (const AvatarManager::LocalLight& light, Application::getInstance()->getAvatarManager().getLocalLights()) { + glm::vec3 direction = orientation * light.direction; + Application::getInstance()->getDeferredLightingEffect()->addSpotLight(position - direction * distance, + distance * 2.0f, glm::vec3(), light.color, light.color, 1.0f, 0.5f, 0.0f, direction, + LIGHT_EXPONENT, LIGHT_CUTOFF); } } @@ -499,34 +499,40 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { return glm::angleAxis(angle * proportion, axis); } -void Avatar::renderBody(RenderMode renderMode, float glowLevel) { +void Avatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) { Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; { Glower glower(glowLevel); - if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { + if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable()) && + (postLighting || renderMode == SHADOW_RENDER_MODE)) { // render the billboard until both models are loaded renderBillboard(); return; } - _skeletonModel.render(1.0f, modelRenderMode); - renderAttachments(renderMode); - getHand()->render(false, modelRenderMode); + if (postLighting) { + getHand()->render(false, modelRenderMode); + } else { + _skeletonModel.render(1.0f, modelRenderMode); + renderAttachments(renderMode); + } } - getHead()->render(1.0f, modelRenderMode); + if (!postLighting) { + getHead()->render(1.0f, modelRenderMode); - if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { - // Render Hair - glPushMatrix(); - glm::vec3 headPosition = getHead()->getPosition(); - glTranslatef(headPosition.x, headPosition.y, headPosition.z); - const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame(); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - _hair.render(); - glPopMatrix(); + if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { + // Render Hair + glPushMatrix(); + glm::vec3 headPosition = getHead()->getPosition(); + glTranslatef(headPosition.x, headPosition.y, headPosition.z); + const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame(); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + _hair.render(); + glPopMatrix(); + } } } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2dbd7d5dd6..cbdebc6a48 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -228,7 +228,7 @@ protected: glm::vec3 getDisplayNamePosition(); void renderDisplayName(); - virtual void renderBody(RenderMode renderMode, float glowLevel = 0.0f); + virtual void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f); virtual bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; void simulateAttachments(float deltaTime); diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index a06a060b7d..93119e6f6f 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -89,8 +89,6 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { } else { _longTermAverageLoudness = glm::mix(_longTermAverageLoudness, _averageLoudness, glm::min(deltaTime / AUDIO_LONG_TERM_AVERAGING_SECS, 1.0f)); } - float deltaLoudness = glm::max(0.0f, _averageLoudness - _longTermAverageLoudness); - //qDebug() << "deltaLoudness: " << deltaLoudness; if (!(_isFaceshiftConnected || billboard)) { // Update eye saccades diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 45ac377dc0..f1c63d44e7 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1096,7 +1096,7 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g Avatar::attach(modelURL, jointName, translation, rotation, scale, allowDuplicates, useSaved); } -void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) { +void MyAvatar::renderBody(RenderMode renderMode, bool postLighting, float glowLevel) { if (!(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { return; // wait until both models are loaded } @@ -1104,28 +1104,34 @@ void MyAvatar::renderBody(RenderMode renderMode, float glowLevel) { // Render the body's voxels and head Model::RenderMode modelRenderMode = (renderMode == SHADOW_RENDER_MODE) ? Model::SHADOW_RENDER_MODE : Model::DEFAULT_RENDER_MODE; - _skeletonModel.render(1.0f, modelRenderMode); - renderAttachments(renderMode); + if (!postLighting) { + _skeletonModel.render(1.0f, modelRenderMode); + renderAttachments(renderMode); + } // Render head so long as the camera isn't inside it const Camera *camera = Application::getInstance()->getCamera(); const glm::vec3 cameraPos = camera->getPosition() + (camera->getRotation() * glm::vec3(0.0f, 0.0f, 1.0f)) * camera->getDistance(); if (shouldRenderHead(cameraPos, renderMode)) { - getHead()->render(1.0f, modelRenderMode); + if (!postLighting) { + getHead()->render(1.0f, modelRenderMode); - if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { - // Render Hair - glPushMatrix(); - glm::vec3 headPosition = getHead()->getPosition(); - glTranslatef(headPosition.x, headPosition.y, headPosition.z); - const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame(); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - _hair.render(); - glPopMatrix(); + if (Menu::getInstance()->isOptionChecked(MenuOption::StringHair)) { + // Render Hair + glPushMatrix(); + glm::vec3 headPosition = getHead()->getPosition(); + glTranslatef(headPosition.x, headPosition.y, headPosition.z); + const glm::quat& rotation = getHead()->getFinalOrientationInWorldFrame(); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + _hair.render(); + glPopMatrix(); + } } } - getHand()->render(true, modelRenderMode); + if (postLighting) { + getHand()->render(true, modelRenderMode); + } } const float RENDER_HEAD_CUTOFF_DISTANCE = 0.50f; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 8f04afff94..b5eb7ee1ff 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -49,7 +49,7 @@ public: void moveWithLean(); void render(const glm::vec3& cameraPosition, RenderMode renderMode = NORMAL_RENDER_MODE, bool postLighting = false); - void renderBody(RenderMode renderMode, float glowLevel = 0.0f); + void renderBody(RenderMode renderMode, bool postLighting, float glowLevel = 0.0f); bool shouldRenderHead(const glm::vec3& cameraPosition, RenderMode renderMode) const; void renderDebugBodyPoints(); void renderHeadMouse(int screenWidth, int screenHeight) const; From e6b0dc592be1233228acbd5f22b78728b1b414a9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 22 Sep 2014 15:03:25 -0700 Subject: [PATCH 42/43] Don't save the billboard. --- interface/src/Application.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bcb732521d..105fb6a973 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2741,8 +2741,6 @@ QImage Application::renderAvatarBillboard() { _textureCache.getPrimaryFramebufferObject()->release(); - image.save("billboard.png"); - return image; } From 18cb15ee7dfd66483e1a2187705ce2769c48e2bc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 22 Sep 2014 15:31:46 -0700 Subject: [PATCH 43/43] Warning fixes. --- interface/src/MetavoxelSystem.cpp | 13 ++++++++++--- interface/src/MetavoxelSystem.h | 4 ++-- interface/src/avatar/Avatar.cpp | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index a0ce30d1dc..b0a1a3413d 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -2319,9 +2319,16 @@ void StaticModelRenderer::renderUnclipped(float alpha, Mode mode) { _model->render(alpha); } -bool StaticModelRenderer::findRayIntersection(RayIntersectionInfo& intersection, - const glm::vec3& clipMinimum, float clipSize) const { - return _model->findRayIntersection(intersection); +bool StaticModelRenderer::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + const glm::vec3& clipMinimum, float clipSize, float& distance) const { + RayIntersectionInfo info; + info._rayStart = origin; + info._rayDirection = direction; + if (!_model->findRayIntersection(info)) { + return false; + } + distance = info._hitDistance; + return true; } void StaticModelRenderer::applyTranslation(const glm::vec3& translation) { diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index cc402bcea1..f99a5834c9 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -370,8 +370,8 @@ public: virtual void init(Spanner* spanner); virtual void simulate(float deltaTime); - virtual bool findRayIntersection(RayIntersectionInfo& intersection, - const glm::vec3& clipMinimum, float clipSize) const; + virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, + const glm::vec3& clipMinimum, float clipSize, float& distance) const; protected: diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 6907a82421..3eae0ef382 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -505,7 +505,7 @@ void Avatar::renderBody(RenderMode renderMode, bool postLighting, float glowLeve { Glower glower(glowLevel); - if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable()) && + if ((_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) && (postLighting || renderMode == SHADOW_RENDER_MODE)) { // render the billboard until both models are loaded renderBillboard();