diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index c10e5c7a27..085cd69352 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -63,8 +63,6 @@ #include "EntityEditPacketSender.h" #include "PhysicalEntitySimulation.h" -#include "FadeEffect.h" - gpu::PipelinePointer RenderablePolyVoxEntityItem::_pipelines[2] = { nullptr, nullptr }; gpu::PipelinePointer RenderablePolyVoxEntityItem::_wireframePipelines[2] = { nullptr, nullptr }; diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index a8ead00771..dd5487ff45 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/libraries/render-utils/src/Fade.slh b/libraries/render-utils/src/Fade.slh index 28fe718942..0d3c397812 100644 --- a/libraries/render-utils/src/Fade.slh +++ b/libraries/render-utils/src/Fade.slh @@ -18,16 +18,7 @@ <@func declareFadeFragment()@> -struct FadeParameters -{ - vec4 _baseInvSizeAndLevel; - vec4 _noiseInvSizeAndLevel; - vec4 _innerEdgeColor; - vec4 _outerEdgeColor; - vec2 _edgeWidthInvWidth; - int _isInverted; - float _padding; -}; +<@include Fade_shared.slh@> #define EVENT_CATEGORY_COUNT 5 @@ -37,6 +28,7 @@ uniform fadeParametersBuffer { uniform int fadeCategory; uniform vec3 fadeNoiseOffset; uniform vec3 fadeBaseOffset; +uniform vec3 fadeBaseInvSize; uniform float fadeThreshold; uniform sampler2D fadeMaskMap; @@ -76,9 +68,9 @@ float evalFadeNoiseGradient(vec3 position) { } float evalFadeBaseGradient(vec3 position) { - float gradient = length((position - fadeBaseOffset) * fadeParameters[fadeCategory]._baseInvSizeAndLevel.xyz); + float gradient = length((position - fadeBaseOffset) * fadeBaseInvSize.xyz); gradient = gradient-0.5; // Center on value 0.5 - gradient *= fadeParameters[fadeCategory]._baseInvSizeAndLevel.w; + gradient *= fadeParameters[fadeCategory]._baseLevel; return gradient; } diff --git a/libraries/render-utils/src/FadeEffect.cpp b/libraries/render-utils/src/FadeEffect.cpp index cc17aada8e..948f3f8f2b 100644 --- a/libraries/render-utils/src/FadeEffect.cpp +++ b/libraries/render-utils/src/FadeEffect.cpp @@ -21,241 +21,241 @@ inline float valueToParameterPow(float value, const double minValue, const doubl return (float)(log(double(value) / minValue) / log(maxOverMinValue)); } -FadeJobConfig::FadeJobConfig() +FadeConfig::FadeConfig() { - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f }; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseLevel = 1.f; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].timing = FadeJobConfig::LINEAR; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 1.0f, 1.0f, 1.0f }; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].baseLevel = 0.f; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]._isInverted = false; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]._duration = 4.f; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeWidth = 0.1f; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.0f }; - events[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 0.75f, 0.75f, 0.75f }; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].noiseLevel = 1.f; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 1.0f, 1.0f, 1.0f }; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].baseLevel = 0.f; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN]._isInverted = false; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN]._duration = 4.f; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].edgeWidth = 0.1f; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.0f }; + events[render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseSize = glm::vec3{ 1.5f, 1.0f/25.f, 0.5f }; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseLevel = 0.37f; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].timing = FadeJobConfig::LINEAR; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].baseLevel = 1.f; - events[FadeJobConfig::BUBBLE_ISECT_OWNER]._isInverted = false; - events[FadeJobConfig::BUBBLE_ISECT_OWNER]._duration = 4.f; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeWidth = 0.02f; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; - events[FadeJobConfig::BUBBLE_ISECT_OWNER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; + events[render::Transition::BUBBLE_ISECT_OWNER].noiseSize = glm::vec3{ 1.5f, 1.0f/25.f, 0.5f }; + events[render::Transition::BUBBLE_ISECT_OWNER].noiseLevel = 0.37f; + events[render::Transition::BUBBLE_ISECT_OWNER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; + events[render::Transition::BUBBLE_ISECT_OWNER].timing = FadeConfig::LINEAR; + events[render::Transition::BUBBLE_ISECT_OWNER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; + events[render::Transition::BUBBLE_ISECT_OWNER].baseLevel = 1.f; + events[render::Transition::BUBBLE_ISECT_OWNER]._isInverted = false; + events[render::Transition::BUBBLE_ISECT_OWNER]._duration = 4.f; + events[render::Transition::BUBBLE_ISECT_OWNER].edgeWidth = 0.02f; + events[render::Transition::BUBBLE_ISECT_OWNER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; + events[render::Transition::BUBBLE_ISECT_OWNER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseSize = glm::vec3{ 0.5f, 1.0f / 25.f, 0.5f }; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseLevel = 1.f; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].timing = FadeJobConfig::LINEAR; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].baseLevel = 0.f; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER]._isInverted = false; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER]._duration = 4.f; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeWidth = 0.025f; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; - events[FadeJobConfig::BUBBLE_ISECT_TRESPASSER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].noiseSize = glm::vec3{ 0.5f, 1.0f / 25.f, 0.5f }; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].noiseLevel = 1.f; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].noiseSpeed = glm::vec3{ 1.0f, 0.2f, 1.0f }; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].timing = FadeConfig::LINEAR; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].baseSize = glm::vec3{ 2.0f, 2.0f, 2.0f }; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].baseLevel = 0.f; + events[render::Transition::BUBBLE_ISECT_TRESPASSER]._isInverted = false; + events[render::Transition::BUBBLE_ISECT_TRESPASSER]._duration = 4.f; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].edgeWidth = 0.025f; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].edgeInnerColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 1.0f }; + events[render::Transition::BUBBLE_ISECT_TRESPASSER].edgeOuterColor = glm::vec4{ 31.f / 255.f, 198.f / 255.f, 166.f / 255.f, 2.0f }; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 10.f, 0.01f, 10.0f }; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseLevel = 0.7f; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, -0.5f, 0.0f }; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].timing = FadeJobConfig::LINEAR; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 10000.f, 1.0f, 10000.0f }; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].baseLevel = 1.f; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN]._isInverted = true; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN]._duration = 5.f; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeWidth = 0.229f; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.25f }; - events[FadeJobConfig::USER_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].noiseSize = glm::vec3{ 10.f, 0.01f, 10.0f }; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].noiseLevel = 0.7f; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].noiseSpeed = glm::vec3{ 0.0f, -0.5f, 0.0f }; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].timing = FadeConfig::LINEAR; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].baseSize = glm::vec3{ 10000.f, 1.0f, 10000.0f }; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].baseLevel = 1.f; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN]._isInverted = true; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN]._duration = 5.f; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].edgeWidth = 0.229f; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].edgeInnerColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 0.25f }; + events[render::Transition::USER_ENTER_LEAVE_DOMAIN].edgeOuterColor = glm::vec4{ 78.f / 255.f, 215.f / 255.f, 255.f / 255.f, 1.0f }; - events[FadeJobConfig::AVATAR_CHANGE].noiseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; - events[FadeJobConfig::AVATAR_CHANGE].noiseLevel = 1.f; - events[FadeJobConfig::AVATAR_CHANGE].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; - events[FadeJobConfig::AVATAR_CHANGE].timing = FadeJobConfig::LINEAR; - events[FadeJobConfig::AVATAR_CHANGE].baseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; - events[FadeJobConfig::AVATAR_CHANGE].baseLevel = 1.f; - events[FadeJobConfig::AVATAR_CHANGE]._isInverted = false; - events[FadeJobConfig::AVATAR_CHANGE]._duration = 3.f; - events[FadeJobConfig::AVATAR_CHANGE].edgeWidth = 0.05f; - events[FadeJobConfig::AVATAR_CHANGE].edgeInnerColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; - events[FadeJobConfig::AVATAR_CHANGE].edgeOuterColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; + events[render::Transition::AVATAR_CHANGE].noiseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; + events[render::Transition::AVATAR_CHANGE].noiseLevel = 1.f; + events[render::Transition::AVATAR_CHANGE].noiseSpeed = glm::vec3{ 0.0f, 0.0f, 0.0f }; + events[render::Transition::AVATAR_CHANGE].timing = FadeConfig::LINEAR; + events[render::Transition::AVATAR_CHANGE].baseSize = glm::vec3{ 0.4f, 0.4f, 0.4f }; + events[render::Transition::AVATAR_CHANGE].baseLevel = 1.f; + events[render::Transition::AVATAR_CHANGE]._isInverted = false; + events[render::Transition::AVATAR_CHANGE]._duration = 3.f; + events[render::Transition::AVATAR_CHANGE].edgeWidth = 0.05f; + events[render::Transition::AVATAR_CHANGE].edgeInnerColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; + events[render::Transition::AVATAR_CHANGE].edgeOuterColor = glm::vec4{ 1.0f, 1.0f, 1.0f, 1.0f }; } -void FadeJobConfig::setEditedCategory(int value) { +void FadeConfig::setEditedCategory(int value) { assert(value < EVENT_CATEGORY_COUNT); - editedCategory = std::min(EVENT_CATEGORY_COUNT, value); + editedCategory = std::min(render::Transition::EVENT_CATEGORY_COUNT, value); emit dirtyCategory(); emit dirty(); } -void FadeJobConfig::setDuration(float value) { +void FadeConfig::setDuration(float value) { events[editedCategory]._duration = value; emit dirty(); } -float FadeJobConfig::getDuration() const { +float FadeConfig::getDuration() const { return events[editedCategory]._duration; } -void FadeJobConfig::setBaseSizeX(float value) { +void FadeConfig::setBaseSizeX(float value) { events[editedCategory].baseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE/ FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getBaseSizeX() const { +float FadeConfig::getBaseSizeX() const { return valueToParameterPow(events[editedCategory].baseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setBaseSizeY(float value) { +void FadeConfig::setBaseSizeY(float value) { events[editedCategory].baseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getBaseSizeY() const { +float FadeConfig::getBaseSizeY() const { return valueToParameterPow(events[editedCategory].baseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setBaseSizeZ(float value) { +void FadeConfig::setBaseSizeZ(float value) { events[editedCategory].baseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getBaseSizeZ() const { +float FadeConfig::getBaseSizeZ() const { return valueToParameterPow(events[editedCategory].baseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setBaseLevel(float value) { +void FadeConfig::setBaseLevel(float value) { events[editedCategory].baseLevel = value; emit dirty(); } -void FadeJobConfig::setInverted(bool value) { +void FadeConfig::setInverted(bool value) { events[editedCategory]._isInverted = value; emit dirty(); } -bool FadeJobConfig::isInverted() const { +bool FadeConfig::isInverted() const { return events[editedCategory]._isInverted; } -void FadeJobConfig::setNoiseSizeX(float value) { +void FadeConfig::setNoiseSizeX(float value) { events[editedCategory].noiseSize.x = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getNoiseSizeX() const { +float FadeConfig::getNoiseSizeX() const { return valueToParameterPow(events[editedCategory].noiseSize.x, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setNoiseSizeY(float value) { +void FadeConfig::setNoiseSizeY(float value) { events[editedCategory].noiseSize.y = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getNoiseSizeY() const { +float FadeConfig::getNoiseSizeY() const { return valueToParameterPow(events[editedCategory].noiseSize.y, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setNoiseSizeZ(float value) { +void FadeConfig::setNoiseSizeZ(float value) { events[editedCategory].noiseSize.z = parameterToValuePow(value, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); emit dirty(); } -float FadeJobConfig::getNoiseSizeZ() const { +float FadeConfig::getNoiseSizeZ() const { return valueToParameterPow(events[editedCategory].noiseSize.z, FADE_MIN_SCALE, FADE_MAX_SCALE / FADE_MIN_SCALE); } -void FadeJobConfig::setNoiseLevel(float value) { +void FadeConfig::setNoiseLevel(float value) { events[editedCategory].noiseLevel = value; emit dirty(); } -void FadeJobConfig::setNoiseSpeedX(float value) { +void FadeConfig::setNoiseSpeedX(float value) { events[editedCategory].noiseSpeed.x = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } -float FadeJobConfig::getNoiseSpeedX() const { +float FadeConfig::getNoiseSpeedX() const { return powf(events[editedCategory].noiseSpeed.x / FADE_MAX_SPEED, 1.f / 3.f); } -void FadeJobConfig::setNoiseSpeedY(float value) { +void FadeConfig::setNoiseSpeedY(float value) { events[editedCategory].noiseSpeed.y = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } -float FadeJobConfig::getNoiseSpeedY() const { +float FadeConfig::getNoiseSpeedY() const { return powf(events[editedCategory].noiseSpeed.y / FADE_MAX_SPEED, 1.f / 3.f); } -void FadeJobConfig::setNoiseSpeedZ(float value) { +void FadeConfig::setNoiseSpeedZ(float value) { events[editedCategory].noiseSpeed.z = powf(value, 3.f)*FADE_MAX_SPEED; emit dirty(); } -float FadeJobConfig::getNoiseSpeedZ() const { +float FadeConfig::getNoiseSpeedZ() const { return powf(events[editedCategory].noiseSpeed.z / FADE_MAX_SPEED, 1.f / 3.f); } -void FadeJobConfig::setEdgeWidth(float value) { +void FadeConfig::setEdgeWidth(float value) { events[editedCategory].edgeWidth = value * value; emit dirty(); } -float FadeJobConfig::getEdgeWidth() const { +float FadeConfig::getEdgeWidth() const { return sqrtf(events[editedCategory].edgeWidth); } -void FadeJobConfig::setEdgeInnerColorR(float value) { +void FadeConfig::setEdgeInnerColorR(float value) { events[editedCategory].edgeInnerColor.r = value; emit dirty(); } -void FadeJobConfig::setEdgeInnerColorG(float value) { +void FadeConfig::setEdgeInnerColorG(float value) { events[editedCategory].edgeInnerColor.g = value; emit dirty(); } -void FadeJobConfig::setEdgeInnerColorB(float value) { +void FadeConfig::setEdgeInnerColorB(float value) { events[editedCategory].edgeInnerColor.b = value; emit dirty(); } -void FadeJobConfig::setEdgeInnerIntensity(float value) { +void FadeConfig::setEdgeInnerIntensity(float value) { events[editedCategory].edgeInnerColor.a = value; emit dirty(); } -void FadeJobConfig::setEdgeOuterColorR(float value) { +void FadeConfig::setEdgeOuterColorR(float value) { events[editedCategory].edgeOuterColor.r = value; emit dirty(); } -void FadeJobConfig::setEdgeOuterColorG(float value) { +void FadeConfig::setEdgeOuterColorG(float value) { events[editedCategory].edgeOuterColor.g = value; emit dirty(); } -void FadeJobConfig::setEdgeOuterColorB(float value) { +void FadeConfig::setEdgeOuterColorB(float value) { events[editedCategory].edgeOuterColor.b = value; emit dirty(); } -void FadeJobConfig::setEdgeOuterIntensity(float value) { +void FadeConfig::setEdgeOuterIntensity(float value) { events[editedCategory].edgeOuterColor.a = value; emit dirty(); } -void FadeJobConfig::setTiming(int value) { +void FadeConfig::setTiming(int value) { assert(value < TIMING_COUNT); events[editedCategory].timing = value; emit dirty(); } -QString FadeJobConfig::eventNames[EVENT_CATEGORY_COUNT] = { +QString FadeConfig::eventNames[render::Transition::EVENT_CATEGORY_COUNT] = { "element_enter_leave_domain", "bubble_isect_owner", "bubble_isect_trespasser", @@ -263,7 +263,7 @@ QString FadeJobConfig::eventNames[EVENT_CATEGORY_COUNT] = { "avatar_change", }; -void FadeJobConfig::save() const { +void FadeConfig::save() const { assert(category < EVENT_CATEGORY_COUNT); QJsonObject lProperties; const QString configFile = "config/" + eventNames[editedCategory] + ".json"; @@ -292,7 +292,7 @@ void FadeJobConfig::save() const { } } -void FadeJobConfig::load() { +void FadeConfig::load() { const QString configFile = "config/" + eventNames[editedCategory] + ".json"; QUrl path(PathUtils::resourcesPath() + configFile); @@ -468,7 +468,7 @@ FadeJob::FadeJob() void FadeJob::configure(const Config& config) { auto& configurations = _configurations.edit(); - for (auto i = 0; i < FadeJobConfig::EVENT_CATEGORY_COUNT; i++) { + for (auto i = 0; i < render::Transition::EVENT_CATEGORY_COUNT; i++) { auto& eventParameters = configurations.parameters[i]; const auto& eventConfig = config.events[i]; @@ -477,7 +477,7 @@ void FadeJob::configure(const Config& config) { eventParameters._noiseInvSizeAndLevel.y = 1.f / eventConfig.noiseSize.y; eventParameters._noiseInvSizeAndLevel.z = 1.f / eventConfig.noiseSize.z; eventParameters._noiseInvSizeAndLevel.w = eventConfig.noiseLevel; - eventParameters._isInverted = eventConfig._isInverted & 1; + eventParameters._isInverted = eventConfig.isInverted & 1; eventParameters._edgeWidthInvWidth.x = eventConfig.edgeWidth; eventParameters._edgeWidthInvWidth.y = 1.f / eventParameters._edgeWidthInvWidth.x; eventParameters._innerEdgeColor = eventConfig.edgeInnerColor; @@ -486,27 +486,80 @@ void FadeJob::configure(const Config& config) { } } -const FadeJob* FadeJob::_currentInstance{ nullptr }; -gpu::TexturePointer FadeJob::_currentFadeMaskMap; -const gpu::BufferView* FadeJob::_currentFadeBuffer{ nullptr }; - -void FadeJob::run(const render::RenderContextPointer& renderContext, const Input& input) { +void FadeJob::run(const render::RenderContextPointer& renderContext) { const Config* jobConfig = static_cast(renderContext->jobConfig.get()); auto scene = renderContext->args->_scene; + render::TransitionStage* transitionStage; // TODO: get transition stage + uint64_t now = usecTimestampNow(); + const double deltaTime = (int64_t(now) - int64_t(_previousTime)) / double(USECS_PER_SECOND); - // And now update fade effect on all visible items - for (auto i = 0; i < RenderFetchCullSortTask::NUM_BUCKETS; i++) { - auto& bucket = input[i].get(); - - for (const auto& itemBound : bucket) { - auto& item = scene->getItem(itemBound.id); - - //updateFadeOnItem(item); - } + // And now update fade effect + for (auto transitionId : *transitionStage) { + auto& state = transitionStage->editTransition(transitionId); + update(*jobConfig, scene, state, deltaTime); } } -float FadeJob::computeElementEnterThreshold(double time, const double period, FadeJobConfig::Timing timing) const { +void FadeJob::update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const { + auto& eventConfig = config.events[transition.eventType]; + auto& item = scene->getItem(transition.itemId); + auto& aabb = item.getBound(); + auto& dimensions = aabb.getDimensions(); + const double eventDuration = (double)eventConfig.duration; + const FadeConfig::Timing timing = (FadeConfig::Timing) eventConfig.timing; + + assert(timing < render::Transition::EVENT_CATEGORY_COUNT); + + switch (transition.eventType) { + case render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN: + transition.threshold = 1.f - computeElementEnterThreshold(transition.time, eventConfig.duration, timing); + transition.threshold = (transition.threshold - 0.5f)*_thresholdScale[transition.eventType] + 0.5f; + transition.noiseOffset = aabb.calcCenter(); + transition.baseOffset = transition.noiseOffset - dimensions.y; + transition.baseInvSize.x = 1.f / dimensions.x; + transition.baseInvSize.y = 1.f / dimensions.y; + transition.baseInvSize.z = 1.f / dimensions.z; + break; + + case render::Transition::BUBBLE_ISECT_OWNER: + { + /* const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition(); + glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos; + float distance = glm::length(delta); + + delta = glm::normalize(delta) * std::max(0.f, distance - 0.5f); + + _editBaseOffset = cameraPos + delta*_editThreshold; + _editThreshold = 0.33f;*/ + } + break; + + case render::Transition::BUBBLE_ISECT_TRESPASSER: + { + // _editBaseOffset = glm::vec3{ 0.f, 0.f, 0.f }; + } + break; + + case render::Transition::USER_ENTER_LEAVE_DOMAIN: + { +/* _editBaseOffset = itemBounds.bound.calcCenter(); + _editBaseOffset.y -= itemBounds.bound.getDimensions().y / 2.f;*/ + } + break; + + case render::Transition::AVATAR_CHANGE: + break; + + default: + assert(false); + } + + transition.time += deltaTime; + +// renderContext->jobConfig->setProperty("threshold", threshold); +} + +float FadeJob::computeElementEnterThreshold(double time, const double period, FadeConfig::Timing timing) const { assert(period > 0.0); float fadeAlpha = 1.0f; const double INV_FADE_PERIOD = 1.0 / period; @@ -517,14 +570,14 @@ float FadeJob::computeElementEnterThreshold(double time, const double period, Fa default: fadeAlpha = (float)fraction; break; - case FadeJobConfig::EASE_IN: + case FadeConfig::EASE_IN: fadeAlpha = (float)(fraction*fraction*fraction); break; - case FadeJobConfig::EASE_OUT: + case FadeConfig::EASE_OUT: fadeAlpha = 1.f - (float)fraction; fadeAlpha = 1.f- fadeAlpha*fadeAlpha*fadeAlpha; break; - case FadeJobConfig::EASE_IN_OUT: + case FadeConfig::EASE_IN_OUT: fadeAlpha = (float)(fraction*fraction*fraction*(fraction*(fraction * 6 - 15) + 10)); break; } @@ -536,8 +589,8 @@ float FadeJob::computeFadePercent(quint64 startTime) { const double time = (double)(int64_t(usecTimestampNow()) - int64_t(startTime)) / (double)(USECS_PER_SECOND); /* assert(_currentInstance); return _currentInstance->computeElementEnterThreshold(time, - _currentInstance->_parameters->_durations[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN], - _currentInstance->_parameters->_timing[FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN]);*/ + _currentInstance->_parameters->_durations[FadeConfig::ELEMENT_ENTER_LEAVE_DOMAIN], + _currentInstance->_parameters->_timing[FadeConfig::ELEMENT_ENTER_LEAVE_DOMAIN]);*/ return (float)time; } @@ -551,7 +604,7 @@ void FadeJob::updateFadeEdit(const render::RenderContextPointer& renderContext, const double deltaTime = (int64_t(now) - int64_t(_editPreviousTime)) / double(USECS_PER_SECOND); const int editedCategory = _parameters->_editedCategory; const double eventDuration = (double)_parameters->_durations[editedCategory]; - const FadeJobConfig::Timing timing = _parameters->_timing[editedCategory]; + const FadeConfig::Timing timing = _parameters->_timing[editedCategory]; const double waitTime = 0.5; // Wait between fade in and out double cycleTime = fmod(_editTime, (eventDuration + waitTime) * 2.0); bool inverseTime = false; @@ -580,7 +633,7 @@ void FadeJob::updateFadeEdit(const render::RenderContextPointer& renderContext, } float threshold = _editThreshold; - if (editedCategory != FadeJobConfig::BUBBLE_ISECT_OWNER) { + if (editedCategory != FadeConfig::BUBBLE_ISECT_OWNER) { threshold = (threshold - 0.5f)*_parameters->_thresholdScale[editedCategory] + 0.5f; } renderContext->jobConfig->setProperty("threshold", threshold); @@ -591,10 +644,10 @@ void FadeJob::updateFadeEdit(const render::RenderContextPointer& renderContext, } switch (editedCategory) { - case FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN: + case FadeConfig::ELEMENT_ENTER_LEAVE_DOMAIN: break; - case FadeJobConfig::BUBBLE_ISECT_OWNER: + case FadeConfig::BUBBLE_ISECT_OWNER: { const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition(); glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos; @@ -607,20 +660,20 @@ void FadeJob::updateFadeEdit(const render::RenderContextPointer& renderContext, } break; - case FadeJobConfig::BUBBLE_ISECT_TRESPASSER: + case FadeConfig::BUBBLE_ISECT_TRESPASSER: { _editBaseOffset = glm::vec3{ 0.f, 0.f, 0.f }; } break; - case FadeJobConfig::USER_ENTER_LEAVE_DOMAIN: + case FadeConfig::USER_ENTER_LEAVE_DOMAIN: { _editBaseOffset = itemBounds.bound.calcCenter(); _editBaseOffset.y -= itemBounds.bound.getDimensions().y / 2.f; } break; - case FadeJobConfig::AVATAR_CHANGE: + case FadeConfig::AVATAR_CHANGE: break; default: @@ -628,69 +681,45 @@ void FadeJob::updateFadeEdit(const render::RenderContextPointer& renderContext, }*/ } -void FadeJob::bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation) { - assert(_currentFadeMaskMap); - assert(_currentFadeBuffer!=nullptr); - bindPerBatch(batch, _currentFadeMaskMap, fadeMaskMapLocation, _currentFadeBuffer, fadeBufferLocation); +render::ShapePipeline::BatchSetter FadeJob::getBatchSetter() const { + return [this](const render::ShapePipeline& shapePipeline, gpu::Batch& batch) { + auto program = shapePipeline.pipeline->getProgram(); + auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap"); + auto bufferLocation = program->getUniformBuffers().findLocation("fadeParametersBuffer"); + batch.setResourceTexture(maskMapLocation, _fadeMaskMap); + batch.setUniformBuffer(bufferLocation, _configurations); + }; } -void FadeJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation) { - batch.setResourceTexture(fadeMaskMapLocation, texture); - batch.setUniformBuffer(fadeBufferLocation, *buffer); -} +render::ShapePipeline::ItemSetter FadeJob::getItemSetter() const { + return [this](const render::ShapePipeline& shapePipeline, render::Args* args, const render::Item& item) { + if (!render::TransitionStage::isIndexInvalid(item.getTransitionId())) { + auto scene = args->_scene; + auto batch = args->_batch; + render::Transition transitionState; // TODO : get the transition state + render::ShapeKey shapeKey(args->_globalShapeKey); -void FadeJob::bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline) { - auto program = pipeline->getProgram(); - auto maskMapLocation = program->getTextures().findLocation("fadeMaskMap"); - auto bufferLocation = program->getUniformBuffers().findLocation("fadeParametersBuffer"); - bindPerBatch(batch, texture, maskMapLocation, buffer, bufferLocation); -} + // TODO test various cases: polyvox... etc + // This is the normal case where we need to push the parameters in uniforms + { + auto program = shapePipeline.pipeline->getProgram(); + auto& uniforms = program->getUniforms(); + auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset"); + auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset"); + auto fadeBaseInvSizeLocation = uniforms.findLocation("fadeBaseInvSize"); + auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold"); + auto fadeCategoryLocation = uniforms.findLocation("fadeCategory"); -bool FadeJob::bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime) { - return bindPerItem(batch, args->_pipeline->pipeline.get(), offset, startTime); -} - -bool FadeJob::bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime) { - auto& uniforms = pipeline->getProgram()->getUniforms(); - auto fadeNoiseOffsetLocation = uniforms.findLocation("fadeNoiseOffset"); - auto fadeBaseOffsetLocation = uniforms.findLocation("fadeBaseOffset"); - auto fadeThresholdLocation = uniforms.findLocation("fadeThreshold"); - auto fadeCategoryLocation = uniforms.findLocation("fadeCategory"); - - if (fadeNoiseOffsetLocation >= 0 || fadeBaseOffsetLocation>=0 || fadeThresholdLocation >= 0 || fadeCategoryLocation>=0) { - float threshold; - int eventCategory = FadeJobConfig::ELEMENT_ENTER_LEAVE_DOMAIN; - glm::vec3 noiseOffset = offset; - glm::vec3 baseOffset = offset; - - threshold = 1.f-computeFadePercent(startTime); - - // Manage interactive edition override -/* assert(_currentInstance); - if (_currentInstance->_parameters->_isEditEnabled) { - eventCategory = _currentInstance->_parameters->_editedCategory; - threshold = _currentInstance->_editThreshold; - noiseOffset += _currentInstance->_editNoiseOffset; - // This works supposing offset is the world position of the object that is fading. - if (eventCategory != FadeJobConfig::BUBBLE_ISECT_TRESPASSER) { - baseOffset = _currentInstance->_editBaseOffset - offset; + if (fadeNoiseOffsetLocation >= 0 || fadeBaseInvSizeLocation >= 0 || fadeBaseOffsetLocation >= 0 || fadeThresholdLocation >= 0 || fadeCategoryLocation >= 0) { + batch->_glUniform1i(fadeCategoryLocation, transitionState.eventType); + batch->_glUniform1f(fadeThresholdLocation, transitionState.threshold); + batch->_glUniform3f(fadeNoiseOffsetLocation, transitionState.noiseOffset.x, transitionState.noiseOffset.y, transitionState.noiseOffset.z); + batch->_glUniform3f(fadeBaseOffsetLocation, transitionState.baseOffset.x, transitionState.baseOffset.y, transitionState.baseOffset.z); + batch->_glUniform3f(fadeBaseInvSizeLocation, transitionState.baseInvSize.x, transitionState.baseInvSize.y, transitionState.baseInvSize.z); + } } } - - if (eventCategory != FadeJobConfig::BUBBLE_ISECT_OWNER) { - threshold = (threshold - 0.5f)*_currentInstance->_parameters->_thresholdScale[eventCategory] + 0.5f; - } - */ - batch._glUniform1i(fadeCategoryLocation, eventCategory); - batch._glUniform1f(fadeThresholdLocation, threshold); - // This is really temporary - batch._glUniform3f(fadeNoiseOffsetLocation, noiseOffset.x, noiseOffset.y, noiseOffset.z); - // This is really temporary - batch._glUniform3f(fadeBaseOffsetLocation, baseOffset.x, baseOffset.y, baseOffset.z); - - return threshold > 0.f; - } - return false; + }; } const render::Item* FadeJob::findNearestItem(const render::RenderContextPointer& renderContext, const render::Varying& input, float& minIsectDistance) const { diff --git a/libraries/render-utils/src/FadeEffect.h b/libraries/render-utils/src/FadeEffect.h index ede3d1843f..4d0b51ffe2 100644 --- a/libraries/render-utils/src/FadeEffect.h +++ b/libraries/render-utils/src/FadeEffect.h @@ -1,21 +1,22 @@ // // FadeEffect.h -// libraries/render-utils/src/ -// -// Created by Olivier Prat on 06/06/17. + +// Created by Olivier Prat on 07/07/2017. // Copyright 2017 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_FadeEffect_h -#define hifi_FadeEffect_h + +#ifndef hifi_render_utils_FadeEffect_h +#define hifi_render_utils_FadeEffect_h #include #include #include +#include -class FadeJobConfig : public render::Job::Config { +class FadeConfig : public render::Job::Config { Q_OBJECT Q_PROPERTY(int editedCategory MEMBER editedCategory WRITE setEditedCategory NOTIFY dirtyCategory) Q_PROPERTY(float duration READ getDuration WRITE setDuration NOTIFY dirty) @@ -48,17 +49,6 @@ class FadeJobConfig : public render::Job::Config { public: - enum EventCategory { - ELEMENT_ENTER_LEAVE_DOMAIN = 0, - BUBBLE_ISECT_OWNER, - BUBBLE_ISECT_TRESPASSER, - USER_ENTER_LEAVE_DOMAIN, - AVATAR_CHANGE, - - // Don't forget to modify Fade.slh to reflect the change in number of categories - EVENT_CATEGORY_COUNT - }; - enum Timing { LINEAR, EASE_IN, @@ -68,7 +58,7 @@ public: TIMING_COUNT }; - FadeJobConfig(); + FadeConfig(); void setEditedCategory(int value); @@ -149,23 +139,23 @@ public: glm::vec3 baseSize; float noiseLevel; float baseLevel; - float _duration; + float duration; float edgeWidth; int timing; - bool _isInverted; + bool isInverted; }; - Event events[EVENT_CATEGORY_COUNT]; + Event events[render::Transition::EVENT_CATEGORY_COUNT]; float threshold{ 0.f }; float manualThreshold{ 0.f }; - int editedCategory{ ELEMENT_ENTER_LEAVE_DOMAIN }; + int editedCategory{ render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN }; bool editFade{ false }; bool manualFade{ false }; Q_INVOKABLE void save() const; Q_INVOKABLE void load(); - static QString eventNames[EVENT_CATEGORY_COUNT]; + static QString eventNames[render::Transition::EVENT_CATEGORY_COUNT]; signals: @@ -174,65 +164,42 @@ signals: }; -struct FadeParameters -{ - glm::vec4 _noiseInvSizeAndLevel; - glm::vec4 _innerEdgeColor; - glm::vec4 _outerEdgeColor; - glm::vec2 _edgeWidthInvWidth; - glm::float32 _baseLevel; - glm::int32 _isInverted; -}; - -struct FadeConfiguration -{ - FadeParameters parameters[FadeJobConfig::EVENT_CATEGORY_COUNT]; -}; - class FadeJob { public: - using Config = FadeJobConfig; - using Input = RenderFetchCullSortTask::BucketList; - using JobModel = render::Job::ModelI; + using Config = FadeConfig; + using JobModel = render::Job::Model; FadeJob(); void configure(const Config& config); - void run(const render::RenderContextPointer& renderContext, const Input& inputs); + void run(const render::RenderContextPointer& renderContext); - static void bindPerBatch(gpu::Batch& batch, int fadeMaskMapLocation, int fadeBufferLocation); - static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, int fadeMaskMapLocation, const gpu::BufferView* buffer, int fadeBufferLocation); - static void bindPerBatch(gpu::Batch& batch, gpu::TexturePointer texture, const gpu::BufferView* buffer, const gpu::PipelinePointer& pipeline); - - static bool bindPerItem(gpu::Batch& batch, RenderArgs* args, glm::vec3 offset, quint64 startTime); - static bool bindPerItem(gpu::Batch& batch, const gpu::Pipeline* pipeline, glm::vec3 offset, quint64 startTime); + render::ShapePipeline::BatchSetter getBatchSetter() const; + render::ShapePipeline::ItemSetter getItemSetter() const; static float computeFadePercent(quint64 startTime); private: - static const FadeJob* _currentInstance; - static gpu::TexturePointer _currentFadeMaskMap; - static const gpu::BufferView* _currentFadeBuffer; +#include "Fade_shared.slh" + + struct FadeConfiguration + { + FadeParameters parameters[render::Transition::EVENT_CATEGORY_COUNT]; + }; gpu::StructBuffer _configurations; gpu::TexturePointer _fadeMaskMap; - float _thresholdScale[FadeJobConfig::EVENT_CATEGORY_COUNT]; + float _thresholdScale[render::Transition::EVENT_CATEGORY_COUNT]; + uint64_t _previousTime{ 0 }; - float computeElementEnterThreshold(double time, const double period, FadeJobConfig::Timing timing) const; - - - // Everything needed for interactive edition - uint64_t _editPreviousTime{ 0 }; - double _editTime{ 0.0 }; - float _editThreshold{ 0.f }; - glm::vec3 _editNoiseOffset{ 0.f, 0.f, 0.f }; - glm::vec3 _editBaseOffset{ 0.f, 0.f, 0.f }; + void update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const; + float computeElementEnterThreshold(double time, const double period, FadeConfig::Timing timing) const; void updateFadeEdit(const render::RenderContextPointer& renderContext, const render::ItemBound& itemBounds); const render::Item* findNearestItem(const render::RenderContextPointer& renderContext, const render::Varying& input, float& minIsectDistance) const; }; -#endif // hifi_FadeEffect_h +#endif // hifi_render_utils_FadeEffect_h diff --git a/libraries/render-utils/src/Fade_shared.slh b/libraries/render-utils/src/Fade_shared.slh new file mode 100644 index 0000000000..669156abac --- /dev/null +++ b/libraries/render-utils/src/Fade_shared.slh @@ -0,0 +1,22 @@ +// glsl / C++ compatible source as interface for FadeEffect +#ifdef __cplusplus +# define VEC4 glm::vec4 +# define VEC2 glm::vec2 +# define FLOAT32 glm::float32 +# define INT32 glm::int32 +#else +# define VEC4 vec4 +# define VEC2 vec2 +# define FLOAT32 float +# define INT32 int +#endif + +struct FadeParameters +{ + VEC4 _noiseInvSizeAndLevel; + VEC4 _innerEdgeColor; + VEC4 _outerEdgeColor; + VEC2 _edgeWidthInvWidth; + FLOAT32 _baseLevel; + INT32 _isInverted; +}; \ No newline at end of file diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5c1632167e..a610e551a0 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -24,7 +24,6 @@ #include "TextureCache.h" #include "RenderUtilsLogging.h" -#include "FadeEffect.h" #include "StencilMaskPass.h" #include "gpu/StandardShaderLib.h" diff --git a/libraries/render-utils/src/MeshPartPayload.cpp b/libraries/render-utils/src/MeshPartPayload.cpp index 42cc3eb36b..8b0ff4f549 100644 --- a/libraries/render-utils/src/MeshPartPayload.cpp +++ b/libraries/render-utils/src/MeshPartPayload.cpp @@ -15,7 +15,6 @@ #include "DeferredLightingEffect.h" #include "EntityItem.h" -#include "FadeEffect.h" using namespace render; @@ -320,14 +319,6 @@ template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, Ren return payload->render(args); } -template <> const Item::FadeState* payloadGetFadeState(const ModelMeshPartPayload::Pointer& payload) { - return &payload->getFadeState(); -} - -template <> Item::FadeState* const payloadEditFadeState(ModelMeshPartPayload::Pointer& payload) { - return &payload->editFadeState(); -} - } ModelMeshPartPayload::ModelMeshPartPayload(ModelPointer model, int _meshIndex, int partIndex, int shapeIndex, const Transform& transform, const Transform& offsetTransform) : diff --git a/libraries/render-utils/src/MeshPartPayload.h b/libraries/render-utils/src/MeshPartPayload.h index 6fa49e7aa4..99c14510b5 100644 --- a/libraries/render-utils/src/MeshPartPayload.h +++ b/libraries/render-utils/src/MeshPartPayload.h @@ -22,7 +22,6 @@ #include #include "Model.h" -#include "FadeEffect.h" class Model; @@ -98,9 +97,6 @@ public: render::ShapeKey getShapeKey() const override; // shape interface void render(RenderArgs* args) override; - const render::Item::FadeState& getFadeState() const { return _fadeState; } - render::Item::FadeState& editFadeState() { return _fadeState; } - // ModelMeshPartPayload functions to perform render void bindMesh(gpu::Batch& batch) override; void bindTransform(gpu::Batch& batch, const render::ShapePipeline::LocationsPointer locations, RenderArgs::RenderMode renderMode) const override; @@ -127,8 +123,6 @@ private: }; mutable State _state { WAITING_TO_START } ; - - render::Item::FadeState _fadeState; }; namespace render { @@ -137,8 +131,6 @@ namespace render { template <> int payloadGetLayer(const ModelMeshPartPayload::Pointer& payload); template <> const ShapeKey shapeGetShapeKey(const ModelMeshPartPayload::Pointer& payload); template <> void payloadRender(const ModelMeshPartPayload::Pointer& payload, RenderArgs* args); - template <> const Item::FadeState* payloadGetFadeState(const ModelMeshPartPayload::Pointer& payload); - template <> Item::FadeState* const payloadEditFadeState(ModelMeshPartPayload::Pointer& payload); } #endif // hifi_MeshPartPayload_h diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index abd7be0093..2bb1f50774 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -46,7 +46,7 @@ using namespace render; extern void initOverlay3DPipelines(render::ShapePlumber& plumber); -extern void initDeferredPipelines(render::ShapePlumber& plumber); +extern void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter); void RenderDeferredTask::configure(const Config& config) { @@ -55,11 +55,12 @@ void RenderDeferredTask::configure(const Config& config) void RenderDeferredTask::build(JobModel& task, const render::Varying& input, render::Varying& output) { const auto& items = input.get(); -// task.addJob("Fade", fadeEditedItem, commonFadeParameters).get(); + task.addJob("Fade"); + auto& fadeJob = task._jobs.back().get(); // Prepare the ShapePipelines ShapePlumberPointer shapePlumber = std::make_shared(); - initDeferredPipelines(*shapePlumber); + initDeferredPipelines(*shapePlumber, fadeJob.getBatchSetter(), fadeJob.getItemSetter()); // Extract opaques / transparents / lights / metas / overlays / background const auto& opaques = items.get0()[RenderFetchCullSortTask::OPAQUE_SHAPE]; diff --git a/libraries/render-utils/src/RenderPipelines.cpp b/libraries/render-utils/src/RenderPipelines.cpp index d6a6cf4ff4..fdccb7e0be 100644 --- a/libraries/render-utils/src/RenderPipelines.cpp +++ b/libraries/render-utils/src/RenderPipelines.cpp @@ -100,7 +100,7 @@ using namespace render; using namespace std::placeholders; void initOverlay3DPipelines(ShapePlumber& plumber); -void initDeferredPipelines(ShapePlumber& plumber); +void initDeferredPipelines(ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter); void initForwardPipelines(ShapePlumber& plumber); void addPlumberPipeline(ShapePlumber& plumber, @@ -170,7 +170,7 @@ void initOverlay3DPipelines(ShapePlumber& plumber) { } } -void initDeferredPipelines(render::ShapePlumber& plumber) { +void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter) { // Vertex shaders auto simpleVertex = gpu::Shader::createVertex(std::string(simple_vert)); auto modelVertex = gpu::Shader::createVertex(std::string(model_vert)); @@ -255,25 +255,25 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withFade(), - modelFadeVertex, modelFadePixel); + modelFadeVertex, modelFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withFade(), - simpleFadeVertex, simpleFadePixel); + simpleFadeVertex, simpleFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withUnlit().withFade(), - modelFadeVertex, modelUnlitFadePixel); + modelFadeVertex, modelUnlitFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withUnlit().withFade(), - simpleFadeVertex, simpleUnlitFadePixel); + simpleFadeVertex, simpleUnlitFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTangents().withFade(), - modelNormalMapFadeVertex, modelNormalMapFadePixel); + modelNormalMapFadeVertex, modelNormalMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSpecular().withFade(), - modelFadeVertex, modelSpecularMapFadePixel); + modelFadeVertex, modelSpecularMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTangents().withSpecular().withFade(), - modelNormalMapFadeVertex, modelNormalSpecularMapFadePixel); + modelNormalMapFadeVertex, modelNormalSpecularMapFadePixel, batchSetter, itemSetter); // Translucents addPipeline( @@ -304,29 +304,29 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withTranslucent().withFade(), - modelFadeVertex, modelTranslucentFadePixel); + modelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withTranslucent().withFade(), - simpleFadeVertex, simpleTranslucentFadePixel); + simpleFadeVertex, simpleTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTranslucent().withUnlit().withFade(), - modelFadeVertex, modelTranslucentUnlitFadePixel); + modelFadeVertex, modelTranslucentUnlitFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withTranslucent().withUnlit().withFade(), - simpleFadeVertex, simpleTranslucentUnlitFadePixel); + simpleFadeVertex, simpleTranslucentUnlitFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents().withFade(), - modelNormalMapFadeVertex, modelTranslucentFadePixel); + modelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTranslucent().withSpecular().withFade(), - modelFadeVertex, modelTranslucentFadePixel); + modelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular().withFade(), - modelNormalMapFadeVertex, modelTranslucentFadePixel); + modelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( // FIXME: Ignore lightmap for translucents meshpart Key::Builder().withMaterial().withTranslucent().withLightmap().withFade(), - modelFadeVertex, modelTranslucentFadePixel); + modelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); // Lightmapped addPipeline( @@ -344,16 +344,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withLightmap().withFade(), - modelLightmapFadeVertex, modelLightmapFadePixel); + modelLightmapFadeVertex, modelLightmapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withLightmap().withTangents().withFade(), - modelLightmapNormalMapFadeVertex, modelLightmapNormalMapFadePixel); + modelLightmapNormalMapFadeVertex, modelLightmapNormalMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withLightmap().withSpecular().withFade(), - modelLightmapFadeVertex, modelLightmapSpecularMapFadePixel); + modelLightmapFadeVertex, modelLightmapSpecularMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withLightmap().withTangents().withSpecular().withFade(), - modelLightmapNormalMapFadeVertex, modelLightmapNormalSpecularMapFadePixel); + modelLightmapNormalMapFadeVertex, modelLightmapNormalSpecularMapFadePixel, batchSetter, itemSetter); // Skinned addPipeline( @@ -371,16 +371,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withSkinned().withFade(), - skinModelFadeVertex, modelFadePixel); + skinModelFadeVertex, modelFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTangents().withFade(), - skinModelNormalMapFadeVertex, modelNormalMapFadePixel); + skinModelNormalMapFadeVertex, modelNormalMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withSpecular().withFade(), - skinModelFadeVertex, modelSpecularMapFadePixel); + skinModelFadeVertex, modelSpecularMapFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTangents().withSpecular().withFade(), - skinModelNormalMapFadeVertex, modelNormalSpecularMapFadePixel); + skinModelNormalMapFadeVertex, modelNormalSpecularMapFadePixel, batchSetter, itemSetter); // Skinned and Translucent addPipeline( @@ -398,16 +398,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(), - skinModelFadeVertex, modelTranslucentFadePixel); + skinModelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withFade(), - skinModelNormalMapFadeVertex, modelTranslucentFadePixel); + skinModelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withSpecular().withFade(), - skinModelFadeVertex, modelTranslucentFadePixel); + skinModelFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular().withFade(), - skinModelNormalMapFadeVertex, modelTranslucentFadePixel); + skinModelNormalMapFadeVertex, modelTranslucentFadePixel, batchSetter, itemSetter); // Depth-only addPipeline( @@ -419,10 +419,10 @@ void initDeferredPipelines(render::ShapePlumber& plumber) { // Same thing but with Fade on addPipeline( Key::Builder().withDepthOnly().withFade(), - modelShadowFadeVertex, modelShadowFadePixel); + modelShadowFadeVertex, modelShadowFadePixel, batchSetter, itemSetter); addPipeline( Key::Builder().withSkinned().withDepthOnly().withFade(), - skinModelShadowFadeVertex, modelShadowFadePixel); + skinModelShadowFadeVertex, modelShadowFadePixel, batchSetter, itemSetter); } void initForwardPipelines(render::ShapePlumber& plumber) { diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index c0d7f43516..717d87310b 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -14,7 +14,6 @@ #include #include -#include "FadeEffect.h" #include #include @@ -53,7 +52,7 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, const auto& fbo = shadow->framebuffer; RenderArgs* args = renderContext->args; - ShapeKey::Builder defaultKeyBuilder;// TODO: support fade on shadows = DependencyManager::get()->getKeyBuilder(); + ShapeKey::Builder defaultKeyBuilder; gpu::doInBatch(args->_context, [&](gpu::Batch& batch) { args->_batch = &batch; @@ -74,9 +73,6 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, auto shadowPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder); auto shadowSkinnedPipeline = _shapePlumber->pickPipeline(args, defaultKeyBuilder.withSkinned()); - // Prepare fade effect - // TODO: support fade on shadows DependencyManager::get()->bindPerBatch(batch); - std::vector skinnedShapeKeys{}; // Iterate through all inShapes and render the unskinned diff --git a/libraries/render/src/render/Item.cpp b/libraries/render/src/render/Item.cpp index f80563bf73..cc679588e2 100644 --- a/libraries/render/src/render/Item.cpp +++ b/libraries/render/src/render/Item.cpp @@ -78,3 +78,11 @@ void Item::resetPayload(const PayloadPointer& payload) { _key = _payload->getKey(); } } + +const ShapeKey Item::getShapeKey() const { + auto shapeKey = _payload->getShapeKey(); + if (_transitionId != TransitionStage::INVALID_INDEX) { + return ShapeKey::Builder(shapeKey).withFade(); + } + return shapeKey; +} \ No newline at end of file diff --git a/libraries/render/src/render/Item.h b/libraries/render/src/render/Item.h index 543a130427..6ee382b1e2 100644 --- a/libraries/render/src/render/Item.h +++ b/libraries/render/src/render/Item.h @@ -27,7 +27,7 @@ #include "model/Material.h" #include "ShapePipeline.h" - +#include "TransitionStage.h" namespace render { @@ -310,23 +310,6 @@ public: }; typedef std::shared_ptr UpdateFunctorPointer; - // This holds the current state for all fade event types applied to this item - class FadeState { - public: - - enum { - INACTIVE = (uint8_t)-1 - }; - - uint8_t eventType{ INACTIVE }; - uint64_t startTime{ 0 }; - glm::vec3 noiseOffset{ 0.f, 0.f, 0.f }; - glm::vec3 baseOffset{ 0.f, 0.f, 0.f }; - glm::vec3 baseSize{ 1.f, 1.f, 1.f }; - float threshold{ 0.f }; - - }; - // Payload is whatever is in this Item and implement the Payload Interface class PayloadInterface { public: @@ -339,9 +322,6 @@ public: virtual uint32_t fetchMetaSubItems(ItemIDs& subItems) const = 0; - virtual const FadeState* getFadeState() const = 0; - virtual FadeState* const editFadeState() = 0; - ~PayloadInterface() {} // Status interface is local to the base class @@ -387,7 +367,7 @@ public: void render(RenderArgs* args) const { _payload->render(args); } // Shape Type Interface - const ShapeKey getShapeKey() const { return _payload->getShapeKey(); } + const ShapeKey getShapeKey() const; // Meta Type Interface uint32_t fetchMetaSubItems(ItemIDs& subItems) const { return _payload->fetchMetaSubItems(subItems); } @@ -395,13 +375,14 @@ public: // Access the status const StatusPointer& getStatus() const { return _payload->getStatus(); } - const FadeState* getFadeState() const { return _payload->getFadeState(); } - FadeState* const editFadeState() { return _payload->editFadeState(); } + void setTransitionId(TransitionStage::Index id) { _transitionId = id; } + TransitionStage::Index getTransitionId() const { return _transitionId; } protected: PayloadPointer _payload; ItemKey _key; ItemCell _cell{ INVALID_CELL }; + TransitionStage::Index _transitionId{ TransitionStage::INVALID_INDEX }; friend class Scene; }; @@ -431,8 +412,6 @@ template const ItemKey payloadGetKey(const std::shared_ptr& payload template const Item::Bound payloadGetBound(const std::shared_ptr& payloadData) { return Item::Bound(); } template int payloadGetLayer(const std::shared_ptr& payloadData) { return 0; } template void payloadRender(const std::shared_ptr& payloadData, RenderArgs* args) { } -template const Item::FadeState* payloadGetFadeState(const std::shared_ptr& payloadData) { return nullptr; } -template Item::FadeState* const payloadEditFadeState(std::shared_ptr& payloadData) { return nullptr; } // Shape type interface // This allows shapes to characterize their pipeline via a ShapeKey, to be picked with a subclass of Shape. @@ -460,9 +439,6 @@ public: virtual const Item::Bound getBound() const override { return payloadGetBound(_data); } virtual int getLayer() const override { return payloadGetLayer(_data); } - virtual const Item::FadeState* getFadeState() const { return payloadGetFadeState(_data); } - virtual Item::FadeState* const editFadeState() { return payloadEditFadeState(_data); } - virtual void render(RenderArgs* args) override { payloadRender(_data, args); } // Shape Type interface diff --git a/libraries/render/src/render/Transition.h b/libraries/render/src/render/Transition.h new file mode 100644 index 0000000000..40fe10c9e5 --- /dev/null +++ b/libraries/render/src/render/Transition.h @@ -0,0 +1,46 @@ +// +// Transition.h + +// Created by Olivier Prat on 07/07/2017. +// Copyright 2017 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_render_utils_Transition_h +#define hifi_render_utils_Transition_h + +#include "Item.h" + +namespace render { + + // This holds the current state for all transition event types applied to a render item + class Transition { + public: + + enum Type { + ELEMENT_ENTER_LEAVE_DOMAIN = 0, + BUBBLE_ISECT_OWNER, + BUBBLE_ISECT_TRESPASSER, + USER_ENTER_LEAVE_DOMAIN, + AVATAR_CHANGE, + + // Don't forget to modify Fade.slh to reflect the change in number of categories + EVENT_CATEGORY_COUNT + }; + + Type eventType{ ELEMENT_ENTER_LEAVE_DOMAIN }; + ItemID itemId{ Item::INVALID_ITEM_ID }; + double time{ 0.0 }; + glm::vec3 noiseOffset{ 0.f, 0.f, 0.f }; + glm::vec3 baseOffset{ 0.f, 0.f, 0.f }; + glm::vec3 baseInvSize{ 1.f, 1.f, 1.f }; + float threshold{ 0.f }; + + }; + + typedef std::shared_ptr TransitionPointer; +} + +#endif \ No newline at end of file diff --git a/libraries/render/src/render/TransitionStage.cpp b/libraries/render/src/render/TransitionStage.cpp new file mode 100644 index 0000000000..2ffb4e26fa --- /dev/null +++ b/libraries/render/src/render/TransitionStage.cpp @@ -0,0 +1,25 @@ +#include "TransitionStage.h" + +#include + +using namespace render; + +TransitionStage::Index TransitionStage::addTransition(ItemID itemId, Transition::Type type) { + Transition transition; + Index id; + + transition.eventType = type; + transition.itemId = itemId; + id = _transitions.newElement(transition); + _activeTransitionIds.push_back(id); + + return id; +} + +void TransitionStage::removeTransition(Index index) { + TransitionIdList::iterator idIterator = std::find(_activeTransitionIds.begin(), _activeTransitionIds.end(), index); + if (idIterator != _activeTransitionIds.end()) { + _activeTransitionIds.erase(idIterator); + } + _transitions.freeElement(index); +} diff --git a/libraries/render/src/render/TransitionStage.h b/libraries/render/src/render/TransitionStage.h new file mode 100644 index 0000000000..d7727c4d72 --- /dev/null +++ b/libraries/render/src/render/TransitionStage.h @@ -0,0 +1,53 @@ +// +// TransitionStage.h + +// Created by Olivier Prat on 07/07/2017. +// Copyright 2017 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_render_TransitionStage_h +#define hifi_render_TransitionStage_h + +#include +#include "IndexedContainer.h" + +#include "Transition.h" + +namespace render { + + // Transition stage to set up Transition-related effects + class TransitionStage { + public: + using Index = indexed_container::Index; + static const Index INVALID_INDEX{ indexed_container::INVALID_INDEX }; + using TransitionIdList = indexed_container::Indices; + + static bool isIndexInvalid(Index index) { return index == INVALID_INDEX; } + + bool checkTransitionId(Index index) const { return _transitions.checkIndex(index); } + + const Transition& getTransition(Index TransitionId) const { return _transitions.get(TransitionId); } + + Transition& editTransition(Index TransitionId) { return _transitions.edit(TransitionId); } + + Index addTransition(ItemID itemId, Transition::Type type); + void removeTransition(Index index); + + TransitionIdList::iterator begin() { return _activeTransitionIds.begin(); } + TransitionIdList::iterator end() { return _activeTransitionIds.end(); } + + private: + + using Transitions = indexed_container::IndexedVector; + + Transitions _transitions; + TransitionIdList _activeTransitionIds; + }; + using TransitionStagePointer = std::shared_ptr; + +} + +#endif // hifi_render_TransitionStage_h diff --git a/libraries/render/src/task/Task.h b/libraries/render/src/task/Task.h index f76ba92546..e99b33305c 100644 --- a/libraries/render/src/task/Task.h +++ b/libraries/render/src/task/Task.h @@ -155,6 +155,12 @@ public: return concept->_data; } + template const T& get() const { + auto concept = std::static_pointer_cast(_concept); + assert(concept); + return concept->_data; + } + virtual void run(const ContextPointer& renderContext) { PerformanceTimer perfTimer(_name.c_str()); PROFILE_RANGE(render, _name.c_str()); diff --git a/tests/gpu-test/src/TestWindow.cpp b/tests/gpu-test/src/TestWindow.cpp index 6436ff1ef4..d0dda3d8ee 100644 --- a/tests/gpu-test/src/TestWindow.cpp +++ b/tests/gpu-test/src/TestWindow.cpp @@ -24,7 +24,7 @@ #include #ifdef DEFERRED_LIGHTING -extern void initDeferredPipelines(render::ShapePlumber& plumber); +extern void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter); extern void initStencilPipeline(gpu::PipelinePointer& pipeline); #endif