diff --git a/libs/openFrameworks/gl/ofLight.cpp b/libs/openFrameworks/gl/ofLight.cpp index 31c3995c100..dc952560fd2 100644 --- a/libs/openFrameworks/gl/ofLight.cpp +++ b/libs/openFrameworks/gl/ofLight.cpp @@ -7,10 +7,11 @@ * */ +#include "ofConstants.h" #include "ofLight.h" -#include "ofColor.h" #include "of3dUtils.h" +#include "ofColor.h" #include "ofGLBaseTypes.h" #include "ofGLUtils.h" #include "ofColor.h" @@ -21,8 +22,8 @@ #include -using std::weak_ptr; using std::vector; +using std::weak_ptr; static ofFloatColor globalAmbient(0.2, 0.2, 0.2, 1.0); @@ -37,13 +38,13 @@ void ofDisableLighting() { } //---------------------------------------- -void ofEnableSeparateSpecularLight(){ +void ofEnableSeparateSpecularLight() { ofGetGLRenderer()->enableSeparateSpecularLight(); } //---------------------------------------- -void ofDisableSeparateSpecularLight(){ - ofGetGLRenderer()->disableSeparateSpecularLight(); +void ofDisableSeparateSpecularLight() { + ofGetGLRenderer()->disableSeparateSpecularLight(); } //---------------------------------------- @@ -57,24 +58,24 @@ void ofSetSmoothLighting(bool b) { } //---------------------------------------- -void ofSetGlobalAmbientColor(const ofFloatColor& c) { +void ofSetGlobalAmbientColor(const ofFloatColor & c) { ofGetGLRenderer()->setGlobalAmbientColor(c); globalAmbient = c; } -const ofFloatColor & ofGetGlobalAmbientColor(){ +const ofFloatColor & ofGetGlobalAmbientColor() { return globalAmbient; } //---------------------------------------- -vector > & ofLightsData(){ - static vector > * lightsActive = ofIsGLProgrammableRenderer()?new vector >:new vector >(8); +vector> & ofLightsData() { + static vector> * lightsActive = ofIsGLProgrammableRenderer() ? new vector> : new vector>(8); return *lightsActive; } -ofLight::Data::Data(){ - glIndex = -1; - isEnabled = false; +ofLight::Data::Data() { + glIndex = -1; + isEnabled = false; attenuation_constant = 0.000001; attenuation_linear = 0.000001; attenuation_quadratic = 0.000001; @@ -85,36 +86,36 @@ ofLight::Data::Data(){ lightType = OF_LIGHT_POINT; } -ofLight::Data::~Data(){ - if(glIndex==-1) return; - if ( auto r = rendererP.lock() ){ - r->setLightAmbientColor( glIndex, ofFloatColor( 0.f, 0.f, 0.f, 1.f ) ); - r->setLightDiffuseColor( glIndex, ofFloatColor( 0.f, 0.f, 0.f, 1.f ) ); - r->setLightSpecularColor( glIndex, ofFloatColor( 0.f, 0.f, 0.f, 1.f ) ); - r->setLightPosition( glIndex, glm::vec4( 0, 0, 1, 0 ) ); - r->disableLight( glIndex ); +ofLight::Data::~Data() { + if (glIndex == -1) return; + if (auto r = rendererP.lock()) { + r->setLightAmbientColor(glIndex, ofFloatColor(0.f, 0.f, 0.f, 1.f)); + r->setLightDiffuseColor(glIndex, ofFloatColor(0.f, 0.f, 0.f, 1.f)); + r->setLightSpecularColor(glIndex, ofFloatColor(0.f, 0.f, 0.f, 1.f)); + r->setLightPosition(glIndex, glm::vec4(0, 0, 1, 0)); + r->disableLight(glIndex); } } //---------------------------------------- ofLight::ofLight() -:data(new Data){ - setAmbientColor(ofFloatColor(0.f,0.f,0.f)); - setDiffuseColor(ofFloatColor(1.f,1.f,1.f)); - setSpecularColor(ofFloatColor(1.f,1.f,1.f)); + : data(new Data) { + setAmbientColor(ofFloatColor(0.f, 0.f, 0.f)); + setDiffuseColor(ofFloatColor(1.f, 1.f, 1.f)); + setSpecularColor(ofFloatColor(1.f, 1.f, 1.f)); setPointLight(); - - // assume default attenuation factors // - setAttenuation(1.f,0.f,0.f); + + // assume default attenuation factors // + setAttenuation(1.f, 0.f, 0.f); } //---------------------------------------- void ofLight::setup() { - if(data->glIndex==-1){ + if (data->glIndex == -1) { bool bLightFound = false; // search for the first free block - for(size_t i=0; iglIndex = i; data->isEnabled = true; ofLightsData()[i] = data; @@ -122,70 +123,75 @@ void ofLight::setup() { break; } } - if(!bLightFound && ofIsGLProgrammableRenderer()){ + if (!bLightFound && ofIsGLProgrammableRenderer()) { ofLightsData().push_back(data); data->glIndex = ofLightsData().size() - 1; data->isEnabled = true; bLightFound = true; } - if( bLightFound ){ - // run this the first time, since it was not found before // + if (bLightFound) { + // run this the first time, since it was not found before // data->rendererP = ofGetGLRenderer(); - onPositionChanged(); - setAmbientColor( getAmbientColor() ); - setDiffuseColor( getDiffuseColor() ); - setSpecularColor( getSpecularColor() ); - setAttenuation( getAttenuationConstant(), getAttenuationLinear(), getAttenuationQuadratic() ); - if(getIsSpotlight()) { - setSpotlightCutOff(getSpotlightCutOff()); - setSpotConcentration(getSpotConcentration()); - } - if(getIsSpotlight() || getIsDirectional() || getIsAreaLight()) { - onOrientationChanged(); - } - }else{ - ofLogError("ofLight") << "setup(): couldn't get active GL light, maximum number of "<< ofLightsData().size() << " reached"; - } + onPositionChanged(); + setAmbientColor(getAmbientColor()); + setDiffuseColor(getDiffuseColor()); + setSpecularColor(getSpecularColor()); + setAttenuation(getAttenuationConstant(), getAttenuationLinear(), getAttenuationQuadratic()); + if (getIsSpotlight()) { + setSpotlightCutOff(getSpotlightCutOff()); + setSpotConcentration(getSpotConcentration()); + } + if (getIsSpotlight() || getIsDirectional() || getIsAreaLight()) { + onOrientationChanged(); + } + } else { + ofLogError("ofLight") << "setup(): couldn't get active GL light, maximum number of " << ofLightsData().size() << " reached"; + } } } //---------------------------------------- void ofLight::enable() { - setup(); + setup(); data->isEnabled = true; - onPositionChanged(); // update the position // + onPositionChanged(); // update the position // onOrientationChanged(); - if ( auto r = data->rendererP.lock() ){ - r->enableLight( data->glIndex ); + if (auto r = data->rendererP.lock()) { + r->enableLight(data->glIndex); } } //---------------------------------------- void ofLight::disable() { data->isEnabled = false; - if ( auto r = data->rendererP.lock() ){ - r->disableLight( data->glIndex ); + if (auto r = data->rendererP.lock()) { + r->disableLight(data->glIndex); } } //---------------------------------------- -int ofLight::getLightID() const{ +int ofLight::getLightID() const { return data->glIndex; } //---------------------------------------- -bool ofLight::getIsEnabled() const { +bool ofLight::isEnabled() const { return data->isEnabled; } +//---------------------------------------- +bool ofLight::getIsEnabled() const { + return isEnabled(); +} + //---------------------------------------- void ofLight::setDirectional() { - if( data->lightType != OF_LIGHT_DIRECTIONAL ) { - data->lightType = OF_LIGHT_DIRECTIONAL; + if (data->lightType != OF_LIGHT_DIRECTIONAL) { + data->lightType = OF_LIGHT_DIRECTIONAL; onOrientationChanged(); } - data->lightType = OF_LIGHT_DIRECTIONAL; - shadow.setLightType( data->lightType ); + data->lightType = OF_LIGHT_DIRECTIONAL; + shadow.setLightType(data->lightType); } //---------------------------------------- @@ -195,98 +201,98 @@ bool ofLight::getIsDirectional() const { //---------------------------------------- void ofLight::setSpotlight(float spotCutOff, float exponent) { - if( data->lightType != OF_LIGHT_SPOT ) { + if (data->lightType != OF_LIGHT_SPOT) { data->lightType = OF_LIGHT_SPOT; onPositionChanged(); onOrientationChanged(); } - data->lightType = OF_LIGHT_SPOT; - setSpotlightCutOff( spotCutOff ); - setSpotConcentration( exponent ); - shadow.setLightType( data->lightType ); + data->lightType = OF_LIGHT_SPOT; + setSpotlightCutOff(spotCutOff); + setSpotConcentration(exponent); + shadow.setLightType(data->lightType); } //---------------------------------------- -bool ofLight::getIsSpotlight() const{ +bool ofLight::getIsSpotlight() const { return data->lightType == OF_LIGHT_SPOT; } //---------------------------------------- -void ofLight::setSpotlightCutOff( float spotCutOff ) { - data->spotCutOff = ofClamp(spotCutOff, 0, 90); - if ( auto r = data->rendererP.lock() ){ - r->setLightSpotlightCutOff( data->glIndex, spotCutOff ); +void ofLight::setSpotlightCutOff(float spotCutOff) { + data->spotCutOff = ofClamp(spotCutOff, 0, 90); + if (auto r = data->rendererP.lock()) { + r->setLightSpotlightCutOff(data->glIndex, spotCutOff); } } //---------------------------------------- -float ofLight::getSpotlightCutOff() const{ - if(!getIsSpotlight()) { - ofLogWarning("ofLight") << "getSpotlightCutOff(): light " << data->glIndex << " is not a spot light"; - } - return data->spotCutOff; +float ofLight::getSpotlightCutOff() const { + if (!getIsSpotlight()) { + ofLogWarning("ofLight") << "getSpotlightCutOff(): light " << data->glIndex << " is not a spot light"; + } + return data->spotCutOff; } //---------------------------------------- -void ofLight::setSpotConcentration( float exponent ) { - data->exponent = ofClamp(exponent, 0, 128); - if ( auto r = data->rendererP.lock() ){ - r->setLightSpotConcentration( data->glIndex, exponent ); +void ofLight::setSpotConcentration(float exponent) { + data->exponent = ofClamp(exponent, 0, 128); + if (auto r = data->rendererP.lock()) { + r->setLightSpotConcentration(data->glIndex, exponent); } } //---------------------------------------- -float ofLight::getSpotConcentration() const{ - if(!getIsSpotlight()) { - ofLogWarning("ofLight") << "getSpotConcentration(): light " << data->glIndex << " is not a spot light"; - } - return data->exponent; +float ofLight::getSpotConcentration() const { + if (!getIsSpotlight()) { + ofLogWarning("ofLight") << "getSpotConcentration(): light " << data->glIndex << " is not a spot light"; + } + return data->exponent; } //---------------------------------------- void ofLight::setPointLight() { - if( data->lightType != OF_LIGHT_POINT ) { - data->lightType= OF_LIGHT_POINT; + if (data->lightType != OF_LIGHT_POINT) { + data->lightType = OF_LIGHT_POINT; onPositionChanged(); onOrientationChanged(); } - data->lightType = OF_LIGHT_POINT; - shadow.setLightType( data->lightType ); + data->lightType = OF_LIGHT_POINT; + shadow.setLightType(data->lightType); } //---------------------------------------- -bool ofLight::getIsPointLight() const{ +bool ofLight::getIsPointLight() const { return data->lightType == OF_LIGHT_POINT; } //---------------------------------------- -void ofLight::setAttenuation( float constant, float linear, float quadratic ) { - // falloff = 0 -> 1, 0 being least amount of fallof, 1.0 being most // - data->attenuation_constant = constant; - data->attenuation_linear = linear; - data->attenuation_quadratic = quadratic; - if ( auto r = data->rendererP.lock() ){ - r->setLightAttenuation( data->glIndex, constant, linear, quadratic ); +void ofLight::setAttenuation(float constant, float linear, float quadratic) { + // falloff = 0 -> 1, 0 being least amount of fallof, 1.0 being most // + data->attenuation_constant = constant; + data->attenuation_linear = linear; + data->attenuation_quadratic = quadratic; + if (auto r = data->rendererP.lock()) { + r->setLightAttenuation(data->glIndex, constant, linear, quadratic); } } //---------------------------------------- -float ofLight::getAttenuationConstant() const{ - return data->attenuation_constant; +float ofLight::getAttenuationConstant() const { + return data->attenuation_constant; } //---------------------------------------- -float ofLight::getAttenuationLinear() const{ - return data->attenuation_linear; +float ofLight::getAttenuationLinear() const { + return data->attenuation_linear; } //---------------------------------------- -float ofLight::getAttenuationQuadratic() const{ - return data->attenuation_quadratic; +float ofLight::getAttenuationQuadratic() const { + return data->attenuation_quadratic; } -void ofLight::setAreaLight(float width, float height){ - if( data->lightType != OF_LIGHT_AREA ) { +void ofLight::setAreaLight(float width, float height) { + if (data->lightType != OF_LIGHT_AREA) { data->lightType = OF_LIGHT_AREA; onPositionChanged(); onOrientationChanged(); @@ -294,41 +300,41 @@ void ofLight::setAreaLight(float width, float height){ data->lightType = OF_LIGHT_AREA; data->width = width; data->height = height; - shadow.setLightType( data->lightType ); - shadow.setAreaLightSize( width, height ); + shadow.setLightType(data->lightType); + shadow.setAreaLightSize(width, height); } -bool ofLight::getIsAreaLight() const{ +bool ofLight::getIsAreaLight() const { return data->lightType == OF_LIGHT_AREA; } //---------------------------------------- -int ofLight::getType() const{ +int ofLight::getType() const { return data->lightType; } //---------------------------------------- -void ofLight::setAmbientColor(const ofFloatColor& c) { +void ofLight::setAmbientColor(const ofFloatColor & c) { data->ambientColor = c; - if ( auto r = data->rendererP.lock() ){ - r->setLightAmbientColor( data->glIndex, c ); + if (auto r = data->rendererP.lock()) { + r->setLightAmbientColor(data->glIndex, c); } } //---------------------------------------- -void ofLight::setDiffuseColor(const ofFloatColor& c) { +void ofLight::setDiffuseColor(const ofFloatColor & c) { data->diffuseColor = c; - if ( auto r = data->rendererP.lock() ){ - r->setLightDiffuseColor( data->glIndex, c ); + if (auto r = data->rendererP.lock()) { + r->setLightDiffuseColor(data->glIndex, c); } } //---------------------------------------- -void ofLight::setSpecularColor(const ofFloatColor& c) { +void ofLight::setSpecularColor(const ofFloatColor & c) { data->specularColor = c; - if ( auto r = data->rendererP.lock() ){ - r->setLightSpecularColor( data->glIndex, c ); + if (auto r = data->rendererP.lock()) { + r->setLightSpecularColor(data->glIndex, c); } } @@ -348,62 +354,61 @@ ofFloatColor ofLight::getSpecularColor() const { } //---------------------------------------- -void ofLight::customDraw(const ofBaseRenderer * renderer) const{ - if(getIsPointLight()) { - renderer->drawSphere( 0,0,0, 10); +void ofLight::customDraw(const ofBaseRenderer * renderer) const { + if (getIsPointLight()) { + renderer->drawSphere(0, 0, 0, 10); ofDrawAxis(20); - } else if (getIsSpotlight()) { - float coneHeight = (std::sin(glm::radians(data->spotCutOff)) * 30.f) + 1; - float coneRadius = (std::cos(glm::radians(data->spotCutOff)) * 30.f) + 8; - const_cast(renderer)->rotateDeg(-90,1,0,0); - renderer->drawCone(0, -(coneHeight*.5), 0, coneHeight, coneRadius); - } else if (getIsAreaLight()) { - const_cast(renderer)->pushMatrix(); - renderer->drawPlane(data->width,data->height); - const_cast(renderer)->popMatrix(); - ofDrawArrow( glm::vec3(0,0,0), glm::vec3(0,0,-30), 10 ); - } else if( getIsDirectional() ) { + } else if (getIsSpotlight()) { + float coneHeight = (sin(ofDegToRad(data->spotCutOff)) * 30.f) + 1; + float coneRadius = (cos(ofDegToRad(data->spotCutOff)) * 30.f) + 8; + const_cast(renderer)->rotateDeg(-90, 1, 0, 0); + renderer->drawCone(0, -(coneHeight * .5), 0, coneHeight, coneRadius); + } else if (getIsAreaLight()) { + const_cast(renderer)->pushMatrix(); + renderer->drawPlane(data->width, data->height); + const_cast(renderer)->popMatrix(); + ofDrawArrow(glm::vec3(0, 0, 0), glm::vec3(0, 0, -30), 10); + } else if (getIsDirectional()) { + renderer->drawBox(10); + renderer->drawArrow(glm::vec3(0, 0, 0), glm::vec3(0, 0, -40), 10); + } else { renderer->drawBox(10); - renderer->drawArrow(glm::vec3(0,0,0),glm::vec3(0,0,-40),10); - }else{ - renderer->drawBox(10); ofDrawAxis(20); - } + } } - //---------------------------------------- void ofLight::onPositionChanged() { - if(data->glIndex==-1) return; + if (data->glIndex == -1) return; // if we are a positional light and not directional, update light position - if(getIsSpotlight() || getIsPointLight() || getIsAreaLight()) { - data->position = {getGlobalPosition().x, getGlobalPosition().y, getGlobalPosition().z, 1.f}; - if ( auto r = data->rendererP.lock() ){ - r->setLightPosition( data->glIndex, data->position ); + if (getIsSpotlight() || getIsPointLight() || getIsAreaLight()) { + data->position = { getGlobalPosition().x, getGlobalPosition().y, getGlobalPosition().z, 1.f }; + if (auto r = data->rendererP.lock()) { + r->setLightPosition(data->glIndex, data->position); } } } //---------------------------------------- void ofLight::onOrientationChanged() { - if(data->glIndex==-1) return; - if(getIsDirectional()) { + if (data->glIndex == -1) return; + if (getIsDirectional()) { // if we are a directional light and not positional, update light position (direction) - glm::vec3 lookAtDir(glm::normalize(getGlobalOrientation() * glm::vec4(0,0,-1, 1))); - data->position = {lookAtDir.x,lookAtDir.y,lookAtDir.z,0.f}; + glm::vec3 lookAtDir(glm::normalize(getGlobalOrientation() * glm::vec4(0, 0, -1, 1))); + data->position = { lookAtDir.x, lookAtDir.y, lookAtDir.z, 0.f }; data->direction = lookAtDir; - if ( auto r = data->rendererP.lock() ){ - r->setLightPosition( data->glIndex, data->position ); + if (auto r = data->rendererP.lock()) { + r->setLightPosition(data->glIndex, data->position); } - }else if(getIsSpotlight() || getIsAreaLight()) { + } else if (getIsSpotlight() || getIsAreaLight()) { // determines the axis of the cone light - glm::vec3 lookAtDir(glm::normalize(getGlobalOrientation() * glm::vec4(0,0,-1, 1))); + glm::vec3 lookAtDir(glm::normalize(getGlobalOrientation() * glm::vec4(0, 0, -1, 1))); data->direction = lookAtDir; - if ( auto r = data->rendererP.lock() ){ - r->setLightSpotDirection( data->glIndex, glm::vec4( data->direction, 0.0f ) ); + if (auto r = data->rendererP.lock()) { + r->setLightSpotDirection(data->glIndex, glm::vec4(data->direction, 0.0f)); } } - if(getIsAreaLight()){ + if (getIsAreaLight()) { data->up = getUpDir(); data->right = getXAxis(); } @@ -411,15 +416,15 @@ void ofLight::onOrientationChanged() { //------------------------------- bool ofLight::shouldRenderShadowDepthPass() { - if( !ofIsGLProgrammableRenderer() ) { + if (!ofIsGLProgrammableRenderer()) { return false; } - return getIsEnabled() && shadow.getIsEnabled(); + return isEnabled() && shadow.isEnabled(); } //------------------------------- int ofLight::getNumShadowDepthPasses() { - if( !ofIsGLProgrammableRenderer() ) { + if (!ofIsGLProgrammableRenderer()) { return 0; } return shadow.getNumShadowDepthPasses(); @@ -427,12 +432,12 @@ int ofLight::getNumShadowDepthPasses() { //------------------------------- bool ofLight::beginShadowDepthPass() { - if(!shouldRenderShadowDepthPass()) { + if (!shouldRenderShadowDepthPass()) { return false; } shadow.update(*this); shadow.beginDepth(); - if( getNumShadowDepthPasses() > 1 ) { + if (getNumShadowDepthPasses() > 1) { ofLogWarning("ofLight :: beginShadowDepthPass : shadow has more than one depth pass! Call beginShadowDepthPass( GLenum aPassIndex ) instead. "); return false; } @@ -441,11 +446,11 @@ bool ofLight::beginShadowDepthPass() { //------------------------------- bool ofLight::endShadowDepthPass() { - if(!shouldRenderShadowDepthPass()) { + if (!shouldRenderShadowDepthPass()) { return false; } shadow.endDepth(); - if( getNumShadowDepthPasses() > 1 ) { + if (getNumShadowDepthPasses() > 1) { ofLogWarning("ofLight :: endShadowDepthPass : shadow has more than one depth pass! Call endShadowDepthPass( GLenum aPassIndex ) instead. "); return false; } @@ -453,14 +458,14 @@ bool ofLight::endShadowDepthPass() { } //------------------------------- -bool ofLight::beginShadowDepthPass( GLenum aPassIndex ) { - if(!shouldRenderShadowDepthPass()) { +bool ofLight::beginShadowDepthPass(GLenum aPassIndex) { + if (!shouldRenderShadowDepthPass()) { return false; } - if( aPassIndex == 0 ) { + if (aPassIndex == 0) { shadow.update(*this); } - if( getNumShadowDepthPasses() < 2 ) { + if (getNumShadowDepthPasses() < 2) { shadow.beginDepth(); } else { shadow.beginDepth(aPassIndex); @@ -469,11 +474,11 @@ bool ofLight::beginShadowDepthPass( GLenum aPassIndex ) { } //------------------------------- -bool ofLight::endShadowDepthPass( GLenum aPassIndex ) { - if(!shouldRenderShadowDepthPass()) { +bool ofLight::endShadowDepthPass(GLenum aPassIndex) { + if (!shouldRenderShadowDepthPass()) { return false; } - if( getNumShadowDepthPasses() < 2 ) { + if (getNumShadowDepthPasses() < 2) { shadow.endDepth(); } else { shadow.endDepth(aPassIndex); diff --git a/libs/openFrameworks/gl/ofLight.h b/libs/openFrameworks/gl/ofLight.h index cbbb5150313..05e82c3eb14 100644 --- a/libs/openFrameworks/gl/ofLight.h +++ b/libs/openFrameworks/gl/ofLight.h @@ -12,13 +12,18 @@ #include "ofNode.h" #include "ofShadow.h" +template +class ofColor_; +typedef ofColor_ ofColor; +typedef ofColor_ ofFloatColor; +typedef ofColor_ ofShortColor; class ofBaseGLRenderer; enum ofLightType { - OF_LIGHT_POINT=0, - OF_LIGHT_DIRECTIONAL=1, - OF_LIGHT_SPOT=2, - OF_LIGHT_AREA=3 // Only programmable renderer + OF_LIGHT_POINT = 0, + OF_LIGHT_DIRECTIONAL = 1, + OF_LIGHT_SPOT = 2, + OF_LIGHT_AREA = 3 // Only programmable renderer }; void ofEnableLighting(); @@ -27,7 +32,7 @@ void ofEnableSeparateSpecularLight(); void ofDisableSeparateSpecularLight(); bool ofGetLightingEnabled(); void ofSetSmoothLighting(bool b); -void ofSetGlobalAmbientColor(const ofFloatColor& c); +void ofSetGlobalAmbientColor(const ofFloatColor & c); const ofFloatColor & ofGetGlobalAmbientColor(); //---------------------------------------- @@ -35,54 +40,54 @@ const ofFloatColor & ofGetGlobalAmbientColor(); class ofLight : public ofNode { public: ofLight(); - - void setup(); + + void setup(); void enable(); void disable(); - bool getIsEnabled() const; - + bool isEnabled() const; + [[deprecated("use isEnabled()")]] bool getIsEnabled() const; + void setDirectional(); bool getIsDirectional() const; - - void setSpotlight( float spotCutOff=45.f, float exponent=0.f ); + + void setSpotlight(float spotCutOff = 45.f, float exponent = 0.f); bool getIsSpotlight() const; - void setSpotlightCutOff( float spotCutOff ); - float getSpotlightCutOff() const; - void setSpotConcentration( float exponent ); - float getSpotConcentration() const; - + void setSpotlightCutOff(float spotCutOff); + float getSpotlightCutOff() const; + void setSpotConcentration(float exponent); + float getSpotConcentration() const; + void setPointLight(); bool getIsPointLight() const; - void setAttenuation( float constant=1.f, float linear=0.f, float quadratic=0.f ); - float getAttenuationConstant() const; - float getAttenuationLinear() const; - float getAttenuationQuadratic() const; - - void setAreaLight(float width, float height); - bool getIsAreaLight() const; - + void setAttenuation(float constant = 1.f, float linear = 0.f, float quadratic = 0.f); + float getAttenuationConstant() const; + float getAttenuationLinear() const; + float getAttenuationQuadratic() const; + + void setAreaLight(float width, float height); + bool getIsAreaLight() const; + int getType() const; - - void setAmbientColor(const ofFloatColor& c); - void setDiffuseColor(const ofFloatColor& c); - void setSpecularColor(const ofFloatColor& c); - + + void setAmbientColor(const ofFloatColor & c); + void setDiffuseColor(const ofFloatColor & c); + void setSpecularColor(const ofFloatColor & c); + ofFloatColor getAmbientColor() const; ofFloatColor getDiffuseColor() const; ofFloatColor getSpecularColor() const; - + int getLightID() const; - + bool shouldRenderShadowDepthPass(); int getNumShadowDepthPasses(); bool beginShadowDepthPass(); bool endShadowDepthPass(); - bool beginShadowDepthPass( GLenum aPassIndex ); - bool endShadowDepthPass( GLenum aPassIndex ); - + bool beginShadowDepthPass(GLenum aPassIndex); + bool endShadowDepthPass(GLenum aPassIndex); ofShadow & getShadow() { return shadow; } - class Data{ + class Data { public: Data(); ~Data(); @@ -91,38 +96,37 @@ class ofLight : public ofNode { ofFloatColor diffuseColor; ofFloatColor specularColor; - float attenuation_constant; - float attenuation_linear; - float attenuation_quadratic; + float attenuation_constant; + float attenuation_linear; + float attenuation_quadratic; ofLightType lightType; int glIndex; int isEnabled; - float spotCutOff; - float exponent; + float spotCutOff; + float exponent; glm::vec4 position; glm::vec3 direction; - float width; - float height; + float width; + float height; glm::vec3 up; glm::vec3 right; /// weak link back to renderer for which this light was created/setup std::weak_ptr rendererP; }; - + protected: ofShadow shadow; - + private: void customDraw(const ofBaseRenderer * renderer) const; std::shared_ptr data; - // update opengl light + // update opengl light // this method overrides ofNode to catch the changes and update glLightv(GL_POSITION) virtual void onPositionChanged(); virtual void onOrientationChanged(); }; - -std::vector > & ofLightsData(); +std::vector> & ofLightsData(); diff --git a/libs/openFrameworks/gl/ofShadow.cpp b/libs/openFrameworks/gl/ofShadow.cpp index 59236b78138..3725cd3174d 100644 --- a/libs/openFrameworks/gl/ofShadow.cpp +++ b/libs/openFrameworks/gl/ofShadow.cpp @@ -5,11 +5,14 @@ // Created by Nick Hardeman on 10/3/22. // -#include "ofShadow.h" +#include "ofConstants.h" + #include "of3dUtils.h" #include "ofGLBaseTypes.h" +#include "ofGLProgrammableRenderer.h" #include "ofGLUtils.h" #include "ofLight.h" +#include "ofShadow.h" #include "ofGLProgrammableRenderer.h" // MARK: ofConstants Targets #include "ofConstants.h" @@ -19,34 +22,33 @@ #include #include -using std::weak_ptr; -using std::vector; using std::shared_ptr; - +using std::vector; +using std::weak_ptr; //---------------------------------------- -vector > & ofShadowsData(){ - static vector > * shadowsActive = ofIsGLProgrammableRenderer()?new vector >:new vector >(8); +vector> & ofShadowsData() { + static vector> * shadowsActive = ofIsGLProgrammableRenderer() ? new vector> : new vector>(8); return *shadowsActive; } //-------------------------------------------------------------- -static std::map< int, ofShadow::GLData > & getGLDatas(){ - static std::map< int,ofShadow::GLData > * idsFB = new std::map< int,ofShadow::GLData >; +static std::map & getGLDatas() { + static std::map * idsFB = new std::map; return *idsFB; } //-------------------------------------------------------------- -static ofShadow::GLData& getGLData( int aLightType ) { - if( getGLDatas().count(aLightType) < 1 ) { +static ofShadow::GLData & getGLData(int aLightType) { + if (getGLDatas().count(aLightType) < 1) { getGLDatas()[aLightType] = ofShadow::GLData(); } return getGLDatas()[aLightType]; } //-------------------------------------------------------------- -static void retainFBO(int aLightType){ - if( !getGLData(aLightType).bAllocated ) { +static void retainFBO(int aLightType) { + if (!getGLData(aLightType).bAllocated) { ofLogVerbose("ofShadow :: retainFBO : for light ") << aLightType << " | " << ofGetFrameNum(); getGLData(aLightType).bAllocated = true; glGenFramebuffers(1, &getGLDatas()[aLightType].fboId); @@ -55,35 +57,35 @@ static void retainFBO(int aLightType){ } //-------------------------------------------------------------- -static GLuint getFBOId( int aLightType ) { +static GLuint getFBOId(int aLightType) { retainFBO(aLightType); return getGLData(aLightType).fboId; } //-------------------------------------------------------------- -static GLuint getFBODepthTexId( int aLightType ) { +static GLuint getFBODepthTexId(int aLightType) { retainFBO(aLightType); return getGLData(aLightType).texId; } //-------------------------------------------------------------- -static void releaseFBO(int aLightType){ - if( getGLData(aLightType).bAllocated ){ +static void releaseFBO(int aLightType) { + if (getGLData(aLightType).bAllocated) { ofLogVerbose("ofShadow :: releaseFBO : for light ") << aLightType << " | " << ofGetFrameNum(); - glDeleteTextures(1, &getGLDatas()[aLightType].texId ); - glDeleteFramebuffers(1, &getGLDatas()[aLightType].fboId ); + glDeleteTextures(1, &getGLDatas()[aLightType].texId); + glDeleteFramebuffers(1, &getGLDatas()[aLightType].fboId); getGLDatas()[aLightType].bAllocated = false; getGLDatas()[aLightType].bFboAllocated = false; } } //---------------------------------------- -int ofShadow::getNumTotalPossibleShadows( int aLightType ) { - - GLenum texTarget = getTextureTarget( aLightType ); - if( texTarget == GL_TEXTURE_CUBE_MAP) { +int ofShadow::getNumTotalPossibleShadows(int aLightType) { + + GLenum texTarget = getTextureTarget(aLightType); + if (texTarget == GL_TEXTURE_CUBE_MAP) { return 1; } - if( texTarget == GL_TEXTURE_2D ) { + if (texTarget == GL_TEXTURE_2D) { return 1; } // a bit of an arbitrary selection here @@ -91,52 +93,52 @@ int ofShadow::getNumTotalPossibleShadows( int aLightType ) { } //---------------------------------------- -GLenum ofShadow::getTextureTarget( int aLightType ) { - -// #if !defined(TARGET_OPENGLES) - if( aLightType == OF_LIGHT_POINT ) { - #if !defined(TARGET_OPENGLES) - if( ofGetGLRenderer() && ofGetGLRenderer()->getGLVersionMajor() < 4 ) { +GLenum ofShadow::getTextureTarget(int aLightType) { + + // #if !defined(TARGET_OPENGLES) + if (aLightType == OF_LIGHT_POINT) { +#if !defined(TARGET_OPENGLES) + if (ofGetGLRenderer() && ofGetGLRenderer()->getGLVersionMajor() < 4) { // does not support cube map arrays in openGL < 4 glsl shader return GL_TEXTURE_CUBE_MAP; } - #else +#else return GL_TEXTURE_CUBE_MAP; - #endif +#endif } -// #endif - - if( aLightType == OF_LIGHT_POINT ) { - #ifdef GL_TEXTURE_CUBE_MAP_ARRAY - #ifdef glTexImage3D + // #endif + + if (aLightType == OF_LIGHT_POINT) { +#ifdef GL_TEXTURE_CUBE_MAP_ARRAY + #ifdef glTexImage3D return GL_TEXTURE_CUBE_MAP_ARRAY; - #endif - #endif + #endif +#endif return GL_TEXTURE_CUBE_MAP; } - #ifdef GL_TEXTURE_2D_ARRAY +#ifdef GL_TEXTURE_2D_ARRAY #ifdef glTexImage3D return GL_TEXTURE_2D_ARRAY; #endif - #endif +#endif return GL_TEXTURE_2D; } //-------------------------------------------------------------- -void ofShadow::setDepthMapResolution( int aLightType, int ares ) { - setDepthMapResolution( aLightType, ares, ares ); +void ofShadow::setDepthMapResolution(int aLightType, int ares) { + setDepthMapResolution(aLightType, ares, ares); } //-------------------------------------------------------------- -void ofShadow::setDepthMapResolution( int aLightType, int awidth, int aheight ) { - if( aLightType == OF_LIGHT_POINT ) { +void ofShadow::setDepthMapResolution(int aLightType, int awidth, int aheight) { + if (aLightType == OF_LIGHT_POINT) { // rendering to a cube, so needs to be the same aheight = awidth; } - - ofLogVerbose("ofShadow :: setDepthMapResolution : incoming: " ) << awidth << " x " << aheight << " current: " << getDepthMapWidth(aLightType) << " x " << getDepthMapHeight(aLightType) << " | " << ofGetFrameNum(); - - if( awidth != getDepthMapWidth(aLightType) || aheight != getDepthMapHeight(aLightType) ) { + + ofLogVerbose("ofShadow :: setDepthMapResolution : incoming: ") << awidth << " x " << aheight << " current: " << getDepthMapWidth(aLightType) << " x " << getDepthMapHeight(aLightType) << " | " << ofGetFrameNum(); + + if (awidth != getDepthMapWidth(aLightType) || aheight != getDepthMapHeight(aLightType)) { getGLData(aLightType).width = awidth; getGLData(aLightType).height = aheight; releaseFBO(aLightType); @@ -178,27 +180,27 @@ GLuint ofShadow::getAreaTexId() { } //-------------------------------------------------------------- -std::string ofShadow::getShadowTypeAsString( ofShadowType atype ) { - switch( atype ) { - case OF_SHADOW_TYPE_HARD: - return "Hard"; - case OF_SHADOW_TYPE_PCF_LOW: - return "PCF Low"; - case OF_SHADOW_TYPE_PCF_MED: - return "PCF Medium"; - case OF_SHADOW_TYPE_PCF_HIGH: - return "PCF High"; - case OF_SHADOW_TYPE_TOTAL: - return "Total"; +std::string ofShadow::getShadowTypeAsString(ofShadowType atype) { + switch (atype) { + case OF_SHADOW_TYPE_HARD: + return "Hard"; + case OF_SHADOW_TYPE_PCF_LOW: + return "PCF Low"; + case OF_SHADOW_TYPE_PCF_MED: + return "PCF Medium"; + case OF_SHADOW_TYPE_PCF_HIGH: + return "PCF High"; + case OF_SHADOW_TYPE_TOTAL: + return "Total"; } return "Default"; } //-------------------------------------------------------------- bool ofShadow::hasActiveShadows() { - for(size_t i=0;i< ofShadowsData().size();i++){ + for (size_t i = 0; i < ofShadowsData().size(); i++) { std::shared_ptr shadow = ofShadowsData()[i].lock(); - if(shadow && shadow->isEnabled && shadow->index > -1 ){ + if (shadow && shadow->isEnabled && shadow->index > -1) { return true; break; } @@ -208,14 +210,14 @@ bool ofShadow::hasActiveShadows() { //-------------------------------------------------------------- void ofShadow::enableAllShadows() { - if( !areShadowsSupported() ) { + if (!areShadowsSupported()) { ofLogWarning("ofShadow :: enableAllShadows : only works with programmable renderer."); return; } - - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->isEnabled = true; @@ -224,9 +226,9 @@ void ofShadow::enableAllShadows() { //-------------------------------------------------------------- void ofShadow::disableAllShadows() { - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->isEnabled = false; @@ -234,14 +236,14 @@ void ofShadow::disableAllShadows() { } //-------------------------------------------------------------- -void ofShadow::setAllShadowTypes( ofShadowType atype ) { - if( !ofIsGLProgrammableRenderer() ) { +void ofShadow::setAllShadowTypes(ofShadowType atype) { + if (!ofIsGLProgrammableRenderer()) { ofLogWarning("ofShadow :: setAllShadowTypes : only works with programmable renderer."); return; } - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->shadowType = atype; @@ -249,26 +251,26 @@ void ofShadow::setAllShadowTypes( ofShadowType atype ) { } //-------------------------------------------------------------- -void ofShadow::setAllShadowDepthResolutions(int awidth, int aheight ) { - if( !ofIsGLProgrammableRenderer() ) { +void ofShadow::setAllShadowDepthResolutions(int awidth, int aheight) { + if (!ofIsGLProgrammableRenderer()) { ofLogWarning("ofShadow :: setAllShadowDepthResolutions : only works with programmable renderer."); return; } - setDepthMapResolution( OF_LIGHT_POINT, awidth, aheight ); - setDepthMapResolution( OF_LIGHT_DIRECTIONAL, awidth, aheight ); - setDepthMapResolution( OF_LIGHT_SPOT, awidth, aheight ); - setDepthMapResolution( OF_LIGHT_AREA, awidth, aheight ); + setDepthMapResolution(OF_LIGHT_POINT, awidth, aheight); + setDepthMapResolution(OF_LIGHT_DIRECTIONAL, awidth, aheight); + setDepthMapResolution(OF_LIGHT_SPOT, awidth, aheight); + setDepthMapResolution(OF_LIGHT_AREA, awidth, aheight); } //-------------------------------------------------------------- -void ofShadow::setAllShadowBias( float bias ) { - if( !ofIsGLProgrammableRenderer() ) { +void ofShadow::setAllShadowBias(float bias) { + if (!ofIsGLProgrammableRenderer()) { ofLogWarning("ofShadow :: setAllShadowBias : only works with programmable renderer."); return; } - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->bias = bias; @@ -276,14 +278,14 @@ void ofShadow::setAllShadowBias( float bias ) { } //-------------------------------------------------------------- -void ofShadow::setAllShadowNormalBias( float normalBias ) { - if( !ofIsGLProgrammableRenderer() ) { +void ofShadow::setAllShadowNormalBias(float normalBias) { + if (!ofIsGLProgrammableRenderer()) { ofLogWarning("ofShadow :: setAllShadowNormalBias : only works with programmable renderer."); return; } - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->normalBias = normalBias; @@ -291,14 +293,14 @@ void ofShadow::setAllShadowNormalBias( float normalBias ) { } //-------------------------------------------------------------- -void ofShadow::setAllShadowSampleRadius( float sampleRadius ) { - if( !ofIsGLProgrammableRenderer() ) { +void ofShadow::setAllShadowSampleRadius(float sampleRadius) { + if (!ofIsGLProgrammableRenderer()) { ofLogWarning("ofShadow :: enableAllShadows : only works with programmable renderer."); return; } - for(size_t i=0;i shadow = ofShadowsData()[i].lock(); - if(!shadow || shadow->index < 0 ){ + if (!shadow || shadow->index < 0) { continue; } shadow->sampleRadius = sampleRadius; @@ -308,16 +310,16 @@ void ofShadow::setAllShadowSampleRadius( float sampleRadius ) { //-------------------------------------------------------------- std::string ofShadow::getShaderDefinesAsString() { std::string definesString = ""; - if( areShadowsSupported() ) { - if( ofShadowsData().size() > 0 && ofLightsData().size() > 0) { + if (areShadowsSupported()) { + if (ofShadowsData().size() > 0 && ofLightsData().size() > 0) { definesString += "#define HAS_SHADOWS 1\n"; } - - if( ofShadow::getTextureTarget( OF_LIGHT_POINT ) != GL_TEXTURE_CUBE_MAP ) { + + if (ofShadow::getTextureTarget(OF_LIGHT_POINT) != GL_TEXTURE_CUBE_MAP) { definesString += "#define SHADOWS_USE_CUBE_MAP_ARRAY 1\n"; } - - if( ofShadow::getTextureTarget( OF_LIGHT_DIRECTIONAL ) != GL_TEXTURE_2D ) { + + if (ofShadow::getTextureTarget(OF_LIGHT_DIRECTIONAL) != GL_TEXTURE_2D) { definesString += "#define SHADOWS_USE_TEXTURE_ARRAY 1\n"; } } @@ -326,11 +328,11 @@ std::string ofShadow::getShaderDefinesAsString() { //-------------------------------------------------------------- bool ofShadow::areShadowsSupported() { - #if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) +#if defined(TARGET_OPENGLES) && !defined(TARGET_EMSCRIPTEN) return false; - #endif - - if(!ofIsGLProgrammableRenderer() ) { +#endif + + if (!ofIsGLProgrammableRenderer()) { return false; } return true; @@ -339,18 +341,18 @@ bool ofShadow::areShadowsSupported() { //-------------------------------------------------------------- void ofShadow::_updateTexDataIds() { std::map texIdMap; - - for(size_t i=0;i< ofShadowsData().size();i++){ + + for (size_t i = 0; i < ofShadowsData().size(); i++) { std::shared_ptr shadow = ofShadowsData()[i].lock(); - if(!shadow || !shadow->isEnabled || shadow->index < 0 ){ + if (!shadow || !shadow->isEnabled || shadow->index < 0) { continue; } - - if( texIdMap.count((int)shadow->lightType) < 0 ) { + + if (texIdMap.count((int)shadow->lightType) < 0) { texIdMap[(int)shadow->lightType] = 0; } shadow->texIndex = texIdMap[(int)shadow->lightType]; - + texIdMap[(int)shadow->lightType]++; } } @@ -372,104 +374,103 @@ ofShadow::~ofShadow() { } //-------------------------------------------------------------- -void ofShadow::setLightType( int atype ) { - - if( (ofLightType)atype != data->lightType ) { +void ofShadow::setLightType(int atype) { + + if ((ofLightType)atype != data->lightType) { clear(); } data->lightType = atype; data->numDepthPasses = getNumShadowDepthPasses(); - if( getIsEnabled() ) { + if (isEnabled()) { _checkFbos(); _allocate(); } } //-------------------------------------------------------------- -void ofShadow::update( const ofLight& alight ) { - - if( !data->isEnabled ) { +void ofShadow::update(const ofLight & alight) { + + if (!data->isEnabled) { return; } - + glm::quat rq = alight.getGlobalOrientation(); - glm::vec3 lookAtDir(glm::normalize( rq * glm::vec4(0.f,0.f,-1.f, 1.f))); - - setLightType( (ofLightType)alight.getType() ); - + glm::vec3 lookAtDir(glm::normalize(rq * glm::vec4(0.f, 0.f, -1.f, 1.f))); + + setLightType((ofLightType)alight.getType()); + data->position = alight.getGlobalPosition(); data->direction = glm::normalize(lookAtDir); - data->up = rq * glm::vec3(0.0,1.0,0.0); - data->right = rq * glm::vec3(1.0,0.0,0.0); - + data->up = rq * glm::vec3(0.0, 1.0, 0.0); + data->right = rq * glm::vec3(1.0, 0.0, 0.0); + unsigned int targetNumMatrices = 1; - if(data->lightType == OF_LIGHT_POINT) { + if (data->lightType == OF_LIGHT_POINT) { targetNumMatrices = 6; } - - if( mLookAtMats.size() != targetNumMatrices ) { + + if (mLookAtMats.size() != targetNumMatrices) { mLookAtMats.clear(); - mLookAtMats.assign(targetNumMatrices, glm::mat4(1.0) ); + mLookAtMats.assign(targetNumMatrices, glm::mat4(1.0)); } - if( mViewProjMats.size() != targetNumMatrices ) { + if (mViewProjMats.size() != targetNumMatrices) { mViewProjMats.clear(); - mViewProjMats.assign( targetNumMatrices, glm::mat4(1.0) ); + mViewProjMats.assign(targetNumMatrices, glm::mat4(1.0)); } - - if( data->lightType == OF_LIGHT_SPOT || data->lightType == OF_LIGHT_AREA ) { - if(data->lightType == OF_LIGHT_SPOT) { + + if (data->lightType == OF_LIGHT_SPOT || data->lightType == OF_LIGHT_AREA) { + if (data->lightType == OF_LIGHT_SPOT) { mFov = alight.getSpotlightCutOff() * 2.0f; } float aspectRatio = (float)getDepthMapWidth() / (float)getDepthMapHeight(); - if( data->lightType == OF_LIGHT_AREA ) { + if (data->lightType == OF_LIGHT_AREA) { mFov = 90; aspectRatio = mAreaLightWidth / mAreaLightHeight; } - + mShadowProjection = glm::perspective(glm::radians(mFov), aspectRatio, getNearClip(), getFarClip()); - mLookAtMats[0] = glm::lookAt( data->position, data->position + data->direction, glm::vec3(0.0, 1.0, 0.0) ); + mLookAtMats[0] = glm::lookAt(data->position, data->position + data->direction, glm::vec3(0.0, 1.0, 0.0)); mViewProjMats[0] = mShadowProjection * mLookAtMats[0]; data->shadowMatrix = biasMatrix * mViewProjMats[0]; - } else if( data->lightType == OF_LIGHT_DIRECTIONAL ) { - + } else if (data->lightType == OF_LIGHT_DIRECTIONAL) { + mOrthoScaleX = 1.0; - if( mDirectionalBoundsWidth > -1 ) { + if (mDirectionalBoundsWidth > -1) { mOrthoScaleX = mDirectionalBoundsWidth / (float)getDepthMapWidth(); } - + mOrthoScaleY = 1.0; - if( mDirectionalBoundsHeight > -1 ) { + if (mDirectionalBoundsHeight > -1) { mOrthoScaleY = mDirectionalBoundsHeight / (float)getDepthMapHeight(); } - + float viewWidth = getGLData(data->lightType).width; - float viewHeight = getGLData(data->lightType).height;// + float viewHeight = getGLData(data->lightType).height; // mShadowProjection = glm::ortho( - - viewWidth/2 * mOrthoScaleX, - + viewWidth/2 * mOrthoScaleX, - - viewHeight/2 * mOrthoScaleY, - + viewHeight/2 * mOrthoScaleY, - getNearClip(), - getFarClip() - ); - mLookAtMats[0] = glm::lookAt( data->position, data->position + data->direction, glm::vec3(0.0, 1.0, 0.0) ); + -viewWidth / 2 * mOrthoScaleX, + +viewWidth / 2 * mOrthoScaleX, + -viewHeight / 2 * mOrthoScaleY, + +viewHeight / 2 * mOrthoScaleY, + getNearClip(), + getFarClip()); + mLookAtMats[0] = glm::lookAt(data->position, data->position + data->direction, glm::vec3(0.0, 1.0, 0.0)); mViewProjMats[0] = mShadowProjection * mLookAtMats[0]; data->shadowMatrix = biasMatrix * mViewProjMats[0]; - - } else if( data->lightType == OF_LIGHT_POINT ) { + + } else if (data->lightType == OF_LIGHT_POINT) { mFov = 90.f; // aspect is 1.0 since width and height should be the same - mShadowProjection = glm::perspective(glm::radians(mFov), 1.0f, getNearClip(), getFarClip() ); + mShadowProjection = glm::perspective(glm::radians(mFov), 1.0f, getNearClip(), getFarClip()); // eye, target and up vector // +x, -x, +y, -y, +z and -z direction - mLookAtMats[0] = glm::lookAt( data->position, data->position + glm::vec3(1,0,0), glm::vec3(0, -1, 0) ); - mLookAtMats[1] = glm::lookAt( data->position, data->position + glm::vec3(-1,0,0), glm::vec3(0, -1, 0) ); - mLookAtMats[2] = glm::lookAt( data->position, data->position + glm::vec3(0,1,0), glm::vec3(0, 0, 1) ); - mLookAtMats[3] = glm::lookAt( data->position, data->position + glm::vec3(0,-1,0), glm::vec3(0, 0, -1) ); - mLookAtMats[4] = glm::lookAt( data->position, data->position + glm::vec3(0,0,1), glm::vec3(0, -1, 0) ); - mLookAtMats[5] = glm::lookAt( data->position, data->position + glm::vec3(0,0,-1), glm::vec3(0, -1, 0) ); - - for( size_t i = 0; i < 6; i++ ) { + mLookAtMats[0] = glm::lookAt(data->position, data->position + glm::vec3(1, 0, 0), glm::vec3(0, -1, 0)); + mLookAtMats[1] = glm::lookAt(data->position, data->position + glm::vec3(-1, 0, 0), glm::vec3(0, -1, 0)); + mLookAtMats[2] = glm::lookAt(data->position, data->position + glm::vec3(0, 1, 0), glm::vec3(0, 0, 1)); + mLookAtMats[3] = glm::lookAt(data->position, data->position + glm::vec3(0, -1, 0), glm::vec3(0, 0, -1)); + mLookAtMats[4] = glm::lookAt(data->position, data->position + glm::vec3(0, 0, 1), glm::vec3(0, -1, 0)); + mLookAtMats[5] = glm::lookAt(data->position, data->position + glm::vec3(0, 0, -1), glm::vec3(0, -1, 0)); + + for (size_t i = 0; i < 6; i++) { mViewProjMats[i] = mShadowProjection * mLookAtMats[i]; } } @@ -477,64 +478,64 @@ void ofShadow::update( const ofLight& alight ) { //---------------------------------------------------- bool ofShadow::beginDepth() { - - if( !areShadowsSupported() ) { + + if (!areShadowsSupported()) { ofLogWarning("ofShadow :: beginDepth() : shadows only work with programmable renderer."); setEnabled(false); } - - if( !getIsEnabled() ) { + + if (!isEnabled()) { return false; } - + _allocateFbo(); - + auto glRenderer = ofGetGLRenderer(); - if(!glRenderer){ + if (!glRenderer) { return false; } - - if( data->lightType == OF_LIGHT_POINT ) { - if( !isSingleOmniPass() ) { + + if (data->lightType == OF_LIGHT_POINT) { + if (!isSingleOmniPass()) { ofLogWarning("ofShadow :: beginDepth : must call beginDepth(cubeFace) when using point light without single pass."); return false; } } - - if( data->texIndex+1 > getNumTotalPossibleShadows(data->lightType) ) { - ofLogWarning( "ofShadow :: too many shadows detected for light type " ) << data->lightType<<". Total supported for light type: " << getNumTotalPossibleShadows(data->lightType); + + if (data->texIndex + 1 > getNumTotalPossibleShadows(data->lightType)) { + ofLogWarning("ofShadow :: too many shadows detected for light type ") << data->lightType << ". Total supported for light type: " << getNumTotalPossibleShadows(data->lightType); } - -// - - glBindFramebuffer( GL_FRAMEBUFFER, getDepthMapFboId() ); - if( data->lightType == OF_LIGHT_POINT ) { + + // + + glBindFramebuffer(GL_FRAMEBUFFER, getDepthMapFboId()); + if (data->lightType == OF_LIGHT_POINT) { // handled in the depthCubeGeom shader -// glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0, (data->texIndex * 6)); + // glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0, (data->texIndex * 6)); } else { - #ifdef glFramebufferTextureLayer - glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0, data->texIndex ); - #else - - auto texTarget = getTextureTarget( data->lightType ); - if( texTarget == GL_TEXTURE_2D ) { +#ifdef glFramebufferTextureLayer + glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0, data->texIndex); +#else + + auto texTarget = getTextureTarget(data->lightType); + if (texTarget == GL_TEXTURE_2D) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, getDepthMapTexId(), 0); } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, data->texIndex, getDepthMapTexId(), 0); } - - //glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, data->texIndex, getDepthMapTexId(), 0); - #endif + +//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, data->texIndex, getDepthMapTexId(), 0); +#endif } - + ofPushView(); ofViewport(0, 0, getDepthMapWidth(), getDepthMapHeight(), false); - + glClear(GL_DEPTH_BUFFER_BIT); - + glRenderer->bind(*this); - - if( isGlCullingEnabled() ) { + + if (isGlCullingEnabled()) { glEnable(GL_CULL_FACE); // enables face culling glFrontFace(mGlFrontFaceWindingOrder); glCullFace(GL_FRONT); // tells OpenGL to cull front faces @@ -544,18 +545,18 @@ bool ofShadow::beginDepth() { //-------------------------------------------------------------- bool ofShadow::endDepth() { - if( !getIsEnabled() || !areShadowsSupported() ) { + if (!isEnabled() || !areShadowsSupported()) { return false; } - if( isGlCullingEnabled() ) { + if (isGlCullingEnabled()) { glDisable(GL_CULL_FACE); } - + auto glRenderer = ofGetGLRenderer(); - if(glRenderer){ + if (glRenderer) { glRenderer->unbind(*this); } - + glBindFramebuffer(GL_FRAMEBUFFER, 0); ofPopView(); return true; @@ -563,57 +564,57 @@ bool ofShadow::endDepth() { //-------------------------------------------------------------- bool ofShadow::beginDepth(GLenum aCubeFace) { - if( !areShadowsSupported() ) { + if (!areShadowsSupported()) { ofLogWarning("ofShadow :: beginDepth(cubeFace) : shadows are only available with programmable renderer."); setEnabled(false); } - - if( !getIsEnabled() ) { + + if (!isEnabled()) { return false; } - + _allocateFbo(); - - if( data->lightType != OF_LIGHT_POINT ) { + + if (data->lightType != OF_LIGHT_POINT) { ofLogWarning("ofShadow :: beginDepth(cubeFace) called from a light that does not use cube map. Use beginDepth() instead."); return false; } - if( isSingleOmniPass() ) { + if (isSingleOmniPass()) { ofLogWarning("ofShadow :: beginDepth(cubeFace) called using single pass, should be calling beginDepth()."); return false; } - - if( data->texIndex+1 > getNumTotalPossibleShadows(data->lightType) ) { - ofLogWarning( "ofShadow :: too many shadows detected for light type " ) << data->lightType<<". Total supported for light type: " << getNumTotalPossibleShadows(data->lightType); + + if (data->texIndex + 1 > getNumTotalPossibleShadows(data->lightType)) { + ofLogWarning("ofShadow :: too many shadows detected for light type ") << data->lightType << ". Total supported for light type: " << getNumTotalPossibleShadows(data->lightType); } - -// if( data->lightType == OF_LIGHT_POINT ) { -// glEnable(GL_TEXTURE_CUBE_MAP_ARRAY); -// } - + + // if( data->lightType == OF_LIGHT_POINT ) { + // glEnable(GL_TEXTURE_CUBE_MAP_ARRAY); + // } + const auto glRenderer = ofGetGLRenderer(); - if(!glRenderer){ + if (!glRenderer) { return false; } - + glBindFramebuffer(GL_FRAMEBUFFER, getDepthMapFboId()); - if( getTextureTarget(OF_LIGHT_POINT) != GL_TEXTURE_CUBE_MAP ){ - #ifdef glFramebufferTextureLayer + if (getTextureTarget(OF_LIGHT_POINT) != GL_TEXTURE_CUBE_MAP) { +#ifdef glFramebufferTextureLayer glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0, (data->texIndex * 6) + aCubeFace); - #else +#else ofLogWarning("ofShadow::beginDepth(GLenum aCubeFace) point light texture target needs to be GL_TEXTURE_CUBE_MAP"); - #endif +#endif } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + aCubeFace, getDepthMapTexId(), 0); } -// glViewport(0, 0, getDepthMapWidth(), getDepthMapHeight() ); + // glViewport(0, 0, getDepthMapWidth(), getDepthMapHeight() ); ofPushView(); ofViewport(0, 0, getDepthMapWidth(), getDepthMapHeight(), false); glClear(GL_DEPTH_BUFFER_BIT); - - glRenderer->bind(*this,aCubeFace); - - if( isGlCullingEnabled() ) { + + glRenderer->bind(*this, aCubeFace); + + if (isGlCullingEnabled()) { glEnable(GL_CULL_FACE); // enables face culling glFrontFace(mGlFrontFaceWindingOrder); glCullFace(GL_FRONT); // tells OpenGL to cull back faces (the sane default setting) @@ -629,28 +630,27 @@ bool ofShadow::endDepth(GLenum aCubeFace) { //-------------------------------------------------------------- void ofShadow::clear() { _checkFbos(); - + mLookAtMats.clear(); mViewProjMats.clear(); - } //-------------------------------------------------------------- -void ofShadow::setEnabled( bool ab ) { - if( !areShadowsSupported() ) { +void ofShadow::setEnabled(bool ab) { + if (!areShadowsSupported()) { ofLogWarning("ofShadow :: setEnabled : shadows only work with programmable renderer"); ab = false; } - + data->isEnabled = ab; - if( data->isEnabled ) { + if (data->isEnabled) { _allocate(); } } //-------------------------------------------------------------- -bool ofShadow::isMultiCubeFacePass() const { - if( data->lightType == OF_LIGHT_POINT ) { +const bool ofShadow::isMultiCubeFacePass() const { + if (data->lightType == OF_LIGHT_POINT) { return !isSingleOmniPass(); } return false; @@ -662,26 +662,26 @@ bool ofShadow::isSingleOmniPass() const { } //-------------------------------------------------------------- -int ofShadow::getNumShadowDepthPasses() const { - if(isMultiCubeFacePass()) { +const int ofShadow::getNumShadowDepthPasses() const { + if (isMultiCubeFacePass()) { return 6; } return 1; } //-------------------------------------------------------------- -void ofShadow::setSingleOmniPass( bool ab ) { - - if( ofGetGLRenderer() && ofGetGLRenderer()->getGLVersionMajor() < 4 ) { +void ofShadow::setSingleOmniPass(bool ab) { + + if (ofGetGLRenderer() && ofGetGLRenderer()->getGLVersionMajor() < 4) { ab = false; } - + #ifdef TARGET_OPENGLES // setting to false because the single pass uses a geometry shader ab = false; #endif - - if(mBSinglePass != ab ) { + + if (mBSinglePass != ab) { clear(); } @@ -691,16 +691,16 @@ void ofShadow::setSingleOmniPass( bool ab ) { //-------------------------------------------------------------- int ofShadow::getDepthMapWidth() { - return getDepthMapWidth( data->lightType ); + return getDepthMapWidth(data->lightType); } //-------------------------------------------------------------- int ofShadow::getDepthMapHeight() { - return getDepthMapHeight( data->lightType ); + return getDepthMapHeight(data->lightType); } //-------------------------------------------------------------- -void ofShadow::setDirectionalBounds( float aWorldWidth, float aWorldHeight ) { +void ofShadow::setDirectionalBounds(float aWorldWidth, float aWorldHeight) { mDirectionalBoundsWidth = aWorldWidth; mDirectionalBoundsHeight = aWorldHeight; } @@ -717,136 +717,133 @@ GLuint ofShadow::getDepthMapTexId() { //-------------------------------------------------------------- void ofShadow::drawFrustum() { - if( data->lightType == OF_LIGHT_POINT ) { - _drawFrustum( data->up, data->right, data->direction ); - _drawFrustum( data->up, data->right, -data->direction ); - _drawFrustum( data->up, data->direction, data->right ); - _drawFrustum( data->up, data->direction, -data->right ); + if (data->lightType == OF_LIGHT_POINT) { + _drawFrustum(data->up, data->right, data->direction); + _drawFrustum(data->up, data->right, -data->direction); + _drawFrustum(data->up, data->direction, data->right); + _drawFrustum(data->up, data->direction, -data->right); } else { - _drawFrustum( data->up, data->right, data->direction ); + _drawFrustum(data->up, data->right, data->direction); } } //-------------------------------------------------------------- -void ofShadow::_drawFrustum( const glm::vec3& aup, const glm::vec3& aright, const glm::vec3& afwd ) { - auto corners = getFrustumCorners(aup, aright, afwd ); - +void ofShadow::_drawFrustum(const glm::vec3 & aup, const glm::vec3 & aright, const glm::vec3 & afwd) { + auto corners = getFrustumCorners(aup, aright, afwd); + ofPushStyle(); - ofSetColor( ofColor::green ); - ofDrawArrow( data->position, data->position+data->up * 100.0, 10.0); - ofSetColor( ofColor::red ); - ofDrawArrow( data->position, data->position+data->right * 100.0, 10.0); - ofSetColor( ofColor::blue ); - ofDrawArrow( data->position, data->position+data->direction * 100.0, 10.0); - + ofSetColor(ofColor::green); + ofDrawArrow(data->position, data->position + data->up * 100.0, 10.0); + ofSetColor(ofColor::red); + ofDrawArrow(data->position, data->position + data->right * 100.0, 10.0); + ofSetColor(ofColor::blue); + ofDrawArrow(data->position, data->position + data->direction * 100.0, 10.0); + vector colors; - + ofMesh mesh; mesh.setMode(OF_PRIMITIVE_LINES); - - for( int i = 0; i < 4; i++ ) { - mesh.addVertex( corners[i] ); - if( i == 3 ) { + + for (int i = 0; i < 4; i++) { + mesh.addVertex(corners[i]); + if (i == 3) { mesh.addVertex(corners[0]); } else { - mesh.addVertex(corners[i+1]); + mesh.addVertex(corners[i + 1]); } } - - colors.assign( 8, ofColor(220, 90, 190) ); + + colors.assign(8, ofColor(220, 90, 190)); mesh.addColors(colors); - - for( int i = 0; i < 4; i++ ) { - mesh.addVertex( corners[i+4] ); - if( i == 3 ) { + + for (int i = 0; i < 4; i++) { + mesh.addVertex(corners[i + 4]); + if (i == 3) { mesh.addVertex(corners[4]); } else { - mesh.addVertex(corners[i+4+1]); + mesh.addVertex(corners[i + 4 + 1]); } } - - colors.assign( 8, ofColor(220, 220, 90) ); + + colors.assign(8, ofColor(220, 220, 90)); mesh.addColors(colors); - - - for( int i = 0; i < 4; i++ ) { - if( data->lightType == OF_LIGHT_SPOT || data->lightType == OF_LIGHT_AREA) { + + for (int i = 0; i < 4; i++) { + if (data->lightType == OF_LIGHT_SPOT || data->lightType == OF_LIGHT_AREA) { mesh.addVertex(data->position); } else { - mesh.addVertex(corners[i+4]); + mesh.addVertex(corners[i + 4]); } mesh.addVertex(corners[i]); } - colors.assign( 8, ofColor(220) ); + colors.assign(8, ofColor(220)); mesh.addColors(colors); - - if( data->lightType == OF_LIGHT_DIRECTIONAL ) { - for( int i = 0; i < 4; i++ ) { + + if (data->lightType == OF_LIGHT_DIRECTIONAL) { + for (int i = 0; i < 4; i++) { mesh.addVertex(data->position); - mesh.addVertex(corners[i+4]); + mesh.addVertex(corners[i + 4]); } - colors.assign( 8, ofColor(220) ); + colors.assign(8, ofColor(220)); mesh.addColors(colors); } - - + mesh.draw(); - + ofPopStyle(); } //-------------------------------------------------------------- -std::vector ofShadow::getFrustumCorners( const glm::vec3& aup, const glm::vec3& aright, const glm::vec3& afwd ) { - - if( data->lightType == OF_LIGHT_DIRECTIONAL) { - +std::vector ofShadow::getFrustumCorners(const glm::vec3 & aup, const glm::vec3 & aright, const glm::vec3 & afwd) { + + if (data->lightType == OF_LIGHT_DIRECTIONAL) { + glm::vec3 fc = data->position + afwd * getFarClip(); glm::vec3 nc = data->position + afwd * getNearClip(); - + float viewWidth = getGLData(data->lightType).width; float viewHeight = getGLData(data->lightType).height; - if( mDirectionalBoundsWidth > 0 ) { + if (mDirectionalBoundsWidth > 0) { viewWidth = mDirectionalBoundsWidth; } - if( mDirectionalBoundsHeight > 0 ) { + if (mDirectionalBoundsHeight > 0) { viewHeight = mDirectionalBoundsHeight; } - + float hw = 0.5f * viewWidth; float hh = 0.5f * viewHeight; - + glm::vec3 X = glm::normalize(aright); glm::vec3 Y = glm::normalize(aup); - + std::vector corners(8); // ftl, ftr, fbl, fbr - corners[0] = fc + (Y*hh) - (X*hw); - corners[1] = fc + (Y*hh) + (X*hw); - corners[2] = fc + (-Y*hh) + (X*hw); - corners[3] = fc + (-Y*hh) - (X*hw); - - corners[4] = nc + (Y*hh) - (X*hw); - corners[5] = nc + (Y*hh) + (X*hw); - corners[6] = nc + (-Y*hh) + (X*hw); - corners[7] = nc + (-Y*hh) - (X*hw); - + corners[0] = fc + (Y * hh) - (X * hw); + corners[1] = fc + (Y * hh) + (X * hw); + corners[2] = fc + (-Y * hh) + (X * hw); + corners[3] = fc + (-Y * hh) - (X * hw); + + corners[4] = nc + (Y * hh) - (X * hw); + corners[5] = nc + (Y * hh) + (X * hw); + corners[6] = nc + (-Y * hh) + (X * hw); + corners[7] = nc + (-Y * hh) - (X * hw); + return corners; - } - + glm::vec3 Z = glm::normalize(afwd); glm::vec3 X = glm::normalize(aright); glm::vec3 Y = glm::normalize(aup); - + glm::vec3 p = data->position; - + glm::vec3 nc = p + Z * getNearClip(); glm::vec3 fc = p + Z * getFarClip(); - + float ratio = (float)getDepthMapWidth() / (float)getDepthMapHeight(); - - if( data->lightType == OF_LIGHT_AREA ) { + + if (data->lightType == OF_LIGHT_AREA) { ratio = mAreaLightWidth / mAreaLightHeight; } @@ -855,23 +852,21 @@ std::vector ofShadow::getFrustumCorners( const glm::vec3& aup, const float Hfar = 2.f * std::tan( glm::radians( mFov ) / 2.f ) * getFarClip(); float Wfar = Hfar * ratio; - + std::vector corners(8); - - corners[0] = fc + ( Y * Hfar/2) - ( X * Wfar/2.f); // ftl - corners[1] = fc + ( Y * Hfar/2) + ( X * Wfar/2); // ftr - corners[2] = fc - ( Y * Hfar/2) + ( X * Wfar/2); // fbl - corners[3] = fc - ( Y * Hfar/2) - ( X * Wfar/2); // fbr - - corners[4] = nc + ( Y * Hnear/2) - ( X * Wnear/2); // ntl - corners[5] = nc + ( Y * Hnear/2) + ( X * Wnear/2); // ntr - corners[6] = nc - ( Y * Hnear/2) + ( X * Wnear/2); // nbl - corners[7] = nc - ( Y * Hnear/2) - ( X * Wnear/2); // nbr - - return corners; -} + corners[0] = fc + (Y * Hfar / 2) - (X * Wfar / 2.f); // ftl + corners[1] = fc + (Y * Hfar / 2) + (X * Wfar / 2); // ftr + corners[2] = fc - (Y * Hfar / 2) + (X * Wfar / 2); // fbl + corners[3] = fc - (Y * Hfar / 2) - (X * Wfar / 2); // fbr + corners[4] = nc + (Y * Hnear / 2) - (X * Wnear / 2); // ntl + corners[5] = nc + (Y * Hnear / 2) + (X * Wnear / 2); // ntr + corners[6] = nc - (Y * Hnear / 2) + (X * Wnear / 2); // nbl + corners[7] = nc - (Y * Hnear / 2) - (X * Wnear / 2); // nbr + + return corners; +} //-------------------------------------------------------------- std::string ofShadow::getShadowTypeAsString() { @@ -880,18 +875,18 @@ std::string ofShadow::getShadowTypeAsString() { //-------------------------------------------------------------- const ofShader & ofShadow::getDepthShader(ofGLProgrammableRenderer & renderer) const { - initShaders( renderer ); - if( data->lightType == OF_LIGHT_POINT ) { - #ifndef TARGET_OPENGLES - if(isSingleOmniPass()) { + initShaders(renderer); + if (data->lightType == OF_LIGHT_POINT) { +#ifndef TARGET_OPENGLES + if (isSingleOmniPass()) { return shaders[&renderer]->depthCube; } else { return shaders[&renderer]->depthCubeMultiPass; } - #else +#else return shaders[&renderer]->depthCubeMultiPass; - #endif - } else if( data->lightType == OF_LIGHT_AREA ) { +#endif + } else if (data->lightType == OF_LIGHT_AREA) { return shaders[&renderer]->depth; } else { return shaders[&renderer]->depth; @@ -899,47 +894,47 @@ const ofShader & ofShadow::getDepthShader(ofGLProgrammableRenderer & renderer) c } //-------------------------------------------------------------- -void ofShadow::updateDepth(const ofShader & shader,ofGLProgrammableRenderer & renderer) const { - shader.setUniform3f("uLightPos", data->position ); - shader.setUniform1f("uNearPlane", data->nearClip ); - shader.setUniform1f("uFarPlane", data->farClip ); - - if( data->lightType == OF_LIGHT_POINT ) { - if( isSingleOmniPass() ) { - for( unsigned int i = 0; i < 6; i++ ) { - shader.setUniformMatrix4f("light["+ std::to_string(i) +"].viewProjectionMatrix", mViewProjMats[i]); +void ofShadow::updateDepth(const ofShader & shader, ofGLProgrammableRenderer & renderer) const { + shader.setUniform3f("uLightPos", data->position); + shader.setUniform1f("uNearPlane", data->nearClip); + shader.setUniform1f("uFarPlane", data->farClip); + + if (data->lightType == OF_LIGHT_POINT) { + if (isSingleOmniPass()) { + for (unsigned int i = 0; i < 6; i++) { + shader.setUniformMatrix4f("light[" + std::to_string(i) + "].viewProjectionMatrix", mViewProjMats[i]); } - shader.setUniform1i("uStartLayer", data->texIndex ); + shader.setUniform1i("uStartLayer", data->texIndex); } else { ofLogWarning("Must call beginDepth(cubeFace) to render to point light in multiple passes"); } } else { // just in case // - if(mViewProjMats.size() > 0 ) { + if (mViewProjMats.size() > 0) { shader.setUniformMatrix4f("lightsViewProjectionMatrix", mViewProjMats[0]); } } } //-------------------------------------------------------------- -void ofShadow::updateDepth(const ofShader & shader,GLenum aCubeFace,ofGLProgrammableRenderer & renderer) const { -// shader.begin(); - shader.setUniform3f("uLightPos", data->position ); - shader.setUniform1f("uNearPlane", data->nearClip ); - shader.setUniform1f("uFarPlane", data->farClip ); - - if( aCubeFace < mViewProjMats.size() ) { - shader.setUniformMatrix4f("lightsViewProjectionMatrix", mViewProjMats[aCubeFace] ); +void ofShadow::updateDepth(const ofShader & shader, GLenum aCubeFace, ofGLProgrammableRenderer & renderer) const { + // shader.begin(); + shader.setUniform3f("uLightPos", data->position); + shader.setUniform1f("uNearPlane", data->nearClip); + shader.setUniform1f("uFarPlane", data->farClip); + + if (aCubeFace < mViewProjMats.size()) { + shader.setUniformMatrix4f("lightsViewProjectionMatrix", mViewProjMats[aCubeFace]); } } //-------------------------------------------------------------- void ofShadow::_checkSetup() { - if( data->index < 0 ) { + if (data->index < 0) { bool bShadowFound = false; // search for the first free block - for(size_t i=0; iindex = i; data->isEnabled = false; ofShadowsData()[i] = data; @@ -947,7 +942,7 @@ void ofShadow::_checkSetup() { break; } } - if(!bShadowFound && ofIsGLProgrammableRenderer()){ + if (!bShadowFound && ofIsGLProgrammableRenderer()) { ofShadowsData().push_back(data); data->index = ofShadowsData().size() - 1; data->isEnabled = false; @@ -965,12 +960,12 @@ void ofShadow::_allocate() { //-------------------------------------------------------------- void ofShadow::_allocateFbo() { - if(getGLData(data->lightType).bFboAllocated) { + if (getGLData(data->lightType).bFboAllocated) { return; } - + GLenum gl_read_status = GL_FRAMEBUFFER_UNSUPPORTED; - + GLenum textureTarget = getTextureTarget(data->lightType); #if !defined(TARGET_OPENGLES) int depthComponent = GL_DEPTH_COMPONENT32F; @@ -982,117 +977,115 @@ void ofShadow::_allocateFbo() { int depthComponent = GL_DEPTH_COMPONENT; int glType = GL_UNSIGNED_SHORT; #endif - - glBindTexture(textureTarget, getDepthMapTexId() ); - - if( data->lightType == OF_LIGHT_POINT ) { - // Create the cube map depth buffer - #if !defined(TARGET_OPENGLES) + + glBindTexture(textureTarget, getDepthMapTexId()); + + if (data->lightType == OF_LIGHT_POINT) { +// Create the cube map depth buffer +#if !defined(TARGET_OPENGLES) glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - #endif - +#endif + // OES_depth_texture_cube_map - - if( textureTarget == GL_TEXTURE_CUBE_MAP ) { - for (GLint i = 0 ; i < 6 ; i++) { + + if (textureTarget == GL_TEXTURE_CUBE_MAP) { + for (GLint i = 0; i < 6; i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, depthComponent, getDepthMapWidth(), getDepthMapWidth(), 0, GL_DEPTH_COMPONENT, glType, NULL); } } - + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - #ifdef GL_TEXTURE_WRAP_R +#ifdef GL_TEXTURE_WRAP_R glTexParameteri(textureTarget, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - #endif - #if defined( GL_TEXTURE_CUBE_MAP_ARRAY ) && defined(glTexImage3D) - if( textureTarget == GL_TEXTURE_CUBE_MAP_ARRAY ) { - +#endif +#if defined(GL_TEXTURE_CUBE_MAP_ARRAY) && defined(glTexImage3D) + if (textureTarget == GL_TEXTURE_CUBE_MAP_ARRAY) { + glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, depthComponent, getDepthMapWidth(), getDepthMapWidth(), getGLData(data->lightType).totalShadows * 6, 0, GL_DEPTH_COMPONENT, glType, NULL); } - #endif +#endif } else { - if( textureTarget == GL_TEXTURE_2D ) { + if (textureTarget == GL_TEXTURE_2D) { glTexImage2D(GL_TEXTURE_2D, 0, depthComponent, getDepthMapWidth(), getDepthMapHeight(), 0, GL_DEPTH_COMPONENT, glType, NULL); } - + glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - + //-- This is to allow usage of shadow2DProj function in the shader --// - if( data->lightType != OF_LIGHT_AREA ) { - #ifdef GL_TEXTURE_COMPARE_MODE + if (data->lightType != OF_LIGHT_AREA) { +#ifdef GL_TEXTURE_COMPARE_MODE glTexParameteri(textureTarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(textureTarget, GL_TEXTURE_COMPARE_FUNC, GL_LESS); - #endif +#endif } - //--! This is to allow usage of shadow2DProj function in the shader !--// - #ifdef GL_TEXTURE_2D_ARRAY - if( textureTarget == GL_TEXTURE_2D_ARRAY ) { - #ifdef GL_TEXTURE_WRAP_R +//--! This is to allow usage of shadow2DProj function in the shader !--// +#ifdef GL_TEXTURE_2D_ARRAY + if (textureTarget == GL_TEXTURE_2D_ARRAY) { + #ifdef GL_TEXTURE_WRAP_R glTexParameteri(textureTarget, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - #endif + #endif } - #endif - - #if defined(GL_CLAMP_TO_BORDER) && !defined(TARGET_EMSCRIPTEN) +#endif + +#if defined(GL_CLAMP_TO_BORDER) && !defined(TARGET_EMSCRIPTEN) glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; glTexParameterfv(textureTarget, GL_TEXTURE_BORDER_COLOR, borderColor); - #else +#else glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - #endif - - #ifdef GL_TEXTURE_2D_ARRAY - if( textureTarget == GL_TEXTURE_2D_ARRAY ) { - #ifdef glTexImage3D +#endif + +#ifdef GL_TEXTURE_2D_ARRAY + if (textureTarget == GL_TEXTURE_2D_ARRAY) { + #ifdef glTexImage3D glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, depthComponent, getDepthMapWidth(), getDepthMapHeight(), getGLData(data->lightType).totalShadows, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); - #endif + #endif } - #endif +#endif } glBindTexture(textureTarget, 0); - - + // Create the fbo - glBindFramebuffer(GL_FRAMEBUFFER, getDepthMapFboId() ); - #if defined(TARGET_OPENGLES) - - if( textureTarget == GL_TEXTURE_CUBE_MAP ) { + glBindFramebuffer(GL_FRAMEBUFFER, getDepthMapFboId()); +#if defined(TARGET_OPENGLES) + + if (textureTarget == GL_TEXTURE_CUBE_MAP) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, NULL, 0); - for(int c = 0; c < 6; c++) { - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X+c, getDepthMapTexId(), 0); + for (int c = 0; c < 6; c++) { + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + c, getDepthMapTexId(), 0); } } else { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, textureTarget, getDepthMapTexId(), 0); } - #else +#else glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, getDepthMapTexId(), 0); - #endif - - #ifndef TARGET_OPENGLES +#endif + +#ifndef TARGET_OPENGLES // Disable writes to the color buffer glDrawBuffer(GL_NONE); - + // Disable reads from the color buffer glReadBuffer(GL_NONE); - #endif - +#endif + gl_read_status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - + glBindFramebuffer(GL_FRAMEBUFFER, 0); - + if (gl_read_status != GL_FRAMEBUFFER_COMPLETE) { releaseFBO(data->lightType); ofLogError("ofShadow :: _allocateFbo : Frame buffer error, status") << gl_read_status; } else { getGLData(data->lightType).bFboAllocated = true; } - - + ofLogVerbose("xxxxx ofShadow::_allocateFbo xxxxxxxxxxxxxxxxxxxxxxxxx") << std::endl; } @@ -1105,52 +1098,52 @@ void ofShadow::_checkFbos() { preNumShadows[OF_LIGHT_SPOT] = getGLData(OF_LIGHT_SPOT).totalShadows; preNumShadows[OF_LIGHT_AREA] = getGLData(OF_LIGHT_AREA).totalShadows; _updateNumShadows(); - - if(getGLData(OF_LIGHT_POINT).totalShadows != preNumShadows[OF_LIGHT_POINT]) { + + if (getGLData(OF_LIGHT_POINT).totalShadows != preNumShadows[OF_LIGHT_POINT]) { releaseFBO((int)OF_LIGHT_POINT); } - if(getGLData(OF_LIGHT_DIRECTIONAL).totalShadows != preNumShadows[OF_LIGHT_DIRECTIONAL]) { + if (getGLData(OF_LIGHT_DIRECTIONAL).totalShadows != preNumShadows[OF_LIGHT_DIRECTIONAL]) { releaseFBO((int)OF_LIGHT_DIRECTIONAL); } - if(getGLData(OF_LIGHT_SPOT).totalShadows != preNumShadows[OF_LIGHT_SPOT]) { + if (getGLData(OF_LIGHT_SPOT).totalShadows != preNumShadows[OF_LIGHT_SPOT]) { releaseFBO((int)OF_LIGHT_SPOT); } - if(getGLData(OF_LIGHT_AREA).totalShadows != preNumShadows[OF_LIGHT_AREA]) { + if (getGLData(OF_LIGHT_AREA).totalShadows != preNumShadows[OF_LIGHT_AREA]) { releaseFBO((int)OF_LIGHT_AREA); } } //-------------------------------------------------------------- void ofShadow::_updateNumShadows() { - + getGLData(OF_LIGHT_POINT).totalShadows = 0; getGLData(OF_LIGHT_DIRECTIONAL).totalShadows = 0; getGLData(OF_LIGHT_SPOT).totalShadows = 0; getGLData(OF_LIGHT_AREA).totalShadows = 0; - - for(size_t i=0; i < ofShadowsData().size(); i++){ - if(!ofShadowsData()[i].expired()) { + + for (size_t i = 0; i < ofShadowsData().size(); i++) { + if (!ofShadowsData()[i].expired()) { auto shadow = ofShadowsData()[i].lock(); - if( shadow ) { + if (shadow) { getGLData(shadow->lightType).totalShadows++; } } } } -#include "shaders/shadowDepth.vert" #include "shaders/shadowDepth.frag" +#include "shaders/shadowDepth.vert" #include "shaders/shadowDepthCubeGeom.glsl" -bool ofShadow::setupShadowDepthShader(ofShader& ashader, const std::string aShaderMain) const { +bool ofShadow::setupShadowDepthShader(ofShader& ashader, const std::string aShaderMain) { return setupShadowDepthShader( ashader, data->lightType, aShaderMain, isSingleOmniPass() ); } -bool ofShadow::setupShadowDepthShader(ofShader& ashader, int aLightType, const std::string aShaderMain, bool abSinglePass) const { +bool ofShadow::setupShadowDepthShader(ofShader& ashader, int aLightType, const std::string aShaderMain, bool abSinglePass) { std::string gversion = "#version 150\n"; #ifdef TARGET_OPENGLES - gversion = "#version 300 es\n"; + gversion = "#version 300 es\nprecision highp float;\n"; #endif std::string nShaderMain = aShaderMain; @@ -1176,12 +1169,10 @@ bool ofShadow::setupShadowDepthShader(ofShader& ashader, int aLightType, const s #endif std::string tdefines = "#define SINGLE_PASS\n"; - bool bDepthCubeSinglePass = false; - - if( aLightType == OF_LIGHT_POINT ) { + if(aLightType == OF_LIGHT_POINT) { #ifndef TARGET_OPENGLES - if(abSinglePass) { + if(isSingleOmniPass()) { tdefines = "#define CUBE_MAP_SINGLE_PASS\n"; bDepthCubeSinglePass = true; } else { @@ -1195,49 +1186,44 @@ bool ofShadow::setupShadowDepthShader(ofShader& ashader, int aLightType, const s ashader.setupShaderFromSource(GL_VERTEX_SHADER,gversion+tdefines+depthVertexShaderSource+nShaderMain); ashader.setupShaderFromSource(GL_FRAGMENT_SHADER,gversion+tdefines+depthFragShaderSource); - #ifndef TARGET_OPENGLES - if(bDepthCubeSinglePass) { - ashader.setupShaderFromSource(GL_GEOMETRY_SHADER_EXT,depthCubeGeometryShaderSource); +#ifndef TARGET_OPENGLES + if (bDepthCubeSinglePass) { + ashader.setupShaderFromSource(GL_GEOMETRY_SHADER_EXT, depthCubeGeometryShaderSource); } - #endif +#endif ashader.bindDefaults(); return ashader.linkProgram(); } - -void ofShadow::initShaders(ofGLProgrammableRenderer & renderer) const{ +void ofShadow::initShaders(ofGLProgrammableRenderer & renderer) { auto rendererShaders = shaders.find(&renderer); - - if(rendererShaders == shaders.end() ){ + + if (rendererShaders == shaders.end()) { shaders[&renderer] = std::make_shared(); - + std::string gversion = "#version 150\n"; - #ifdef TARGET_OPENGLES +#ifdef TARGET_OPENGLES gversion = "#version 300 es\nprecision highp float;\n"; - #endif - - std::string vertString = depthVertexShaderSource+depthVertexShader_Main; - - shaders[&renderer]->depth.setupShaderFromSource(GL_VERTEX_SHADER,gversion+"#define SINGLE_PASS\n"+vertString); - shaders[&renderer]->depth.setupShaderFromSource(GL_FRAGMENT_SHADER,gversion+"#define SINGLE_PASS\n"+depthFragShaderSource); +#endif + + std::string vertString = depthVertexShaderSource + depthVertexShader_Main; + + shaders[&renderer]->depth.setupShaderFromSource(GL_VERTEX_SHADER, gversion + "#define SINGLE_PASS\n" + vertString); + shaders[&renderer]->depth.setupShaderFromSource(GL_FRAGMENT_SHADER, gversion + "#define SINGLE_PASS\n" + depthFragShaderSource); shaders[&renderer]->depth.bindDefaults(); shaders[&renderer]->depth.linkProgram(); - - #ifndef TARGET_OPENGLES - shaders[&renderer]->depthCube.setupShaderFromSource(GL_VERTEX_SHADER,gversion+"#define CUBE_MAP_SINGLE_PASS\n"+vertString); - shaders[&renderer]->depthCube.setupShaderFromSource(GL_FRAGMENT_SHADER,gversion+"#define CUBE_MAP_SINGLE_PASS\n"+depthFragShaderSource); - shaders[&renderer]->depthCube.setupShaderFromSource(GL_GEOMETRY_SHADER_EXT,depthCubeGeometryShaderSource); + +#ifndef TARGET_OPENGLES + shaders[&renderer]->depthCube.setupShaderFromSource(GL_VERTEX_SHADER, gversion + "#define CUBE_MAP_SINGLE_PASS\n" + vertString); + shaders[&renderer]->depthCube.setupShaderFromSource(GL_FRAGMENT_SHADER, gversion + "#define CUBE_MAP_SINGLE_PASS\n" + depthFragShaderSource); + shaders[&renderer]->depthCube.setupShaderFromSource(GL_GEOMETRY_SHADER_EXT, depthCubeGeometryShaderSource); shaders[&renderer]->depthCube.bindDefaults(); shaders[&renderer]->depthCube.linkProgram(); - #endif - shaders[&renderer]->depthCubeMultiPass.setupShaderFromSource(GL_VERTEX_SHADER,gversion+"#define CUBE_MAP_MULTI_PASS\n"+vertString); - shaders[&renderer]->depthCubeMultiPass.setupShaderFromSource(GL_FRAGMENT_SHADER,gversion+"#define CUBE_MAP_MULTI_PASS\n"+depthFragShaderSource); +#endif + shaders[&renderer]->depthCubeMultiPass.setupShaderFromSource(GL_VERTEX_SHADER, gversion + "#define CUBE_MAP_MULTI_PASS\n" + vertString); + shaders[&renderer]->depthCubeMultiPass.setupShaderFromSource(GL_FRAGMENT_SHADER, gversion + "#define CUBE_MAP_MULTI_PASS\n" + depthFragShaderSource); shaders[&renderer]->depthCubeMultiPass.bindDefaults(); shaders[&renderer]->depthCubeMultiPass.linkProgram(); - } - } - - diff --git a/libs/openFrameworks/gl/ofShadow.h b/libs/openFrameworks/gl/ofShadow.h index 55938fe3ad5..75072212f71 100644 --- a/libs/openFrameworks/gl/ofShadow.h +++ b/libs/openFrameworks/gl/ofShadow.h @@ -7,11 +7,11 @@ #pragma once -#include "ofShader.h" #include "ofNode.h" +#include "ofShader.h" enum ofShadowType { - OF_SHADOW_TYPE_HARD=0, + OF_SHADOW_TYPE_HARD = 0, OF_SHADOW_TYPE_PCF_LOW, OF_SHADOW_TYPE_PCF_MED, OF_SHADOW_TYPE_PCF_HIGH, @@ -23,13 +23,12 @@ class ofGLProgrammableRenderer; class ofShadow { public: - struct GLData { GLuint fboId = 0; GLuint texId = 0; bool bAllocated = false; bool bFboAllocated = false; - + #if defined(TARGET_OPENGLES) int width = 512; int height = 512; @@ -37,190 +36,192 @@ class ofShadow { int width = 1024; int height = 1024; #endif - + int totalShadows = 0; }; - - class Data{ + + class Data { public: - // position, direction, up and right are in world space - glm::vec3 position = {0,0,0}; - glm::vec3 direction = {1,0,0}; - - glm::vec3 up = {0,1,0}; - glm::vec3 right = {1,0,0}; - + // position, direction, up and right are in world space + glm::vec3 position = { 0, 0, 0 }; + glm::vec3 direction = { 1, 0, 0 }; + + glm::vec3 up = { 0, 1, 0 }; + glm::vec3 right = { 1, 0, 0 }; + int lightType = 0; #if defined(TARGET_OPENGLES) ofShadowType shadowType = OF_SHADOW_TYPE_HARD; #else ofShadowType shadowType = OF_SHADOW_TYPE_PCF_LOW; #endif - + glm::mat4 shadowMatrix; float strength = 0.5; - + int texIndex = 0; - + bool isEnabled = false; float bias = 0.005f; float normalBias = 0.0; - + int numDepthPasses = 1; - + int index = -1; float nearClip = 1; float farClip = 1500; float sampleRadius = 1.f; }; - - static GLenum getTextureTarget( int aLightType ); - static int getNumTotalPossibleShadows( int aLightType ); - - static void setDepthMapResolution( int aLightType, int ares ); - static void setDepthMapResolution( int aLightType, int awidth, int aheight ); - + + static GLenum getTextureTarget(int aLightType); + static int getNumTotalPossibleShadows(int aLightType); + + static void setDepthMapResolution(int aLightType, int ares); + static void setDepthMapResolution(int aLightType, int awidth, int aheight); + static int getDepthMapWidth(int aLightType); static int getDepthMapHeight(int aLightType); - + static GLuint getPointTexId(); static GLuint getDirectionalTexId(); static GLuint getSpotTexId(); static GLuint getAreaTexId(); - + static bool hasActiveShadows(); - static std::string getShadowTypeAsString( ofShadowType atype ); - + static std::string getShadowTypeAsString(ofShadowType atype); + static void enableAllShadows(); static void disableAllShadows(); - static void setAllShadowTypes( ofShadowType atype ); - static void setAllShadowDepthResolutions( int awidth, int aheight ); - static void setAllShadowBias( float bias ); - static void setAllShadowNormalBias( float normalBias ); - static void setAllShadowSampleRadius( float sampleRadius ); + static void setAllShadowTypes(ofShadowType atype); + static void setAllShadowDepthResolutions(int awidth, int aheight); + static void setAllShadowBias(float bias); + static void setAllShadowNormalBias(float normalBias); + static void setAllShadowSampleRadius(float sampleRadius); static std::string getShaderDefinesAsString(); - + static bool areShadowsSupported(); - ofShadow(); ~ofShadow(); - - void setLightType( int atype ); - - void update( const ofLight& alight ); - + + void setLightType(int atype); + + void update(const ofLight & alight); + bool beginDepth(); bool endDepth(); - + bool beginDepth(GLenum aCubeFace); bool endDepth(GLenum aCubeFace); - + void clear(); - - const std::shared_ptr& getData() const { return data; } - bool getIsEnabled() { return data->isEnabled; } - void setEnabled( bool ab ); - + + const std::shared_ptr & getData() const { return data; } + bool isEnabled() { return data->isEnabled; } + [[deprecated("use isEnabled()")]] bool getIsEnabled() { return isEnabled(); } + void setEnabled(bool ab); + float getNearClip() { return data->nearClip; } float getFarClip() { return data->farClip; } - void setNearClip( float anear ) { data->nearClip = anear; } - void setFarClip( float afar ) { data->farClip = afar; } - - bool isMultiCubeFacePass() const; - bool isSingleOmniPass() const; - int getNumShadowDepthPasses() const; - void setSingleOmniPass( bool ab ); + void setNearClip(float anear) { data->nearClip = anear; } + void setFarClip(float afar) { data->farClip = afar; } + + const bool isMultiCubeFacePass() const; + const bool isSingleOmniPass() const; + const int getNumShadowDepthPasses() const; + void setSingleOmniPass(bool ab); + int getDepthMapWidth(); int getDepthMapHeight(); - - void setDirectionalBounds( float aWorldWidth, float aWorldHeight ); - - void setShadowType(ofShadowType atype) {data->shadowType = atype;} - + + void setDirectionalBounds(float aWorldWidth, float aWorldHeight); + + void setShadowType(ofShadowType atype) { data->shadowType = atype; } + bool isGlCullingEnabled() { return mBEnableCulling; } - void setGlCullingEnabled(bool ab) { mBEnableCulling=ab;} + void setGlCullingEnabled(bool ab) { mBEnableCulling = ab; } GLenum getFrontFaceWindingOrder() { return mGlFrontFaceWindingOrder; } - void setFrontFaceWindingOrder( GLenum aw ) { mGlFrontFaceWindingOrder = aw; } - + void setFrontFaceWindingOrder(GLenum aw) { mGlFrontFaceWindingOrder = aw; } + GLuint getDepthMapFboId(); GLuint getDepthMapTexId(); - - const float& getStrength() { return data->strength; } + + const float & getStrength() { return data->strength; } void setStrength(float astrength) { data->strength = astrength; } - - float getBias() const { return data->bias; } - void setBias( float abias ) { data->bias = abias; } - - float getNormalBias() const { return data->normalBias; } - void setNormalBias( float abias ) { data->normalBias = abias; } - - float getSampleRadius() const { return data->sampleRadius; } - void setSampleRadius( float aradius ) { data->sampleRadius = aradius; } - - void setAreaLightSize( float awidth, float aheight ) {mAreaLightWidth=awidth;mAreaLightHeight=aheight;}; - + + const float getBias() { return data->bias; } + void setBias(float abias) { data->bias = abias; } + + const float getNormalBias() { return data->normalBias; } + void setNormalBias(float abias) { data->normalBias = abias; } + + const float getSampleRadius() { return data->sampleRadius; } + void setSampleRadius(float aradius) { data->sampleRadius = aradius; } + + void setAreaLightSize(float awidth, float aheight) { + mAreaLightWidth = awidth; + mAreaLightHeight = aheight; + }; + void drawFrustum(); - std::vector getFrustumCorners( const glm::vec3& aup, const glm::vec3& aright, const glm::vec3& afwd ); - + std::vector getFrustumCorners(const glm::vec3 & aup, const glm::vec3 & aright, const glm::vec3 & afwd); + std::string getShadowTypeAsString(); - + const ofShader & getDepthShader(ofGLProgrammableRenderer & renderer) const; - bool setupShadowDepthShader(ofShader& ashader, const std::string aShaderMain) const; - bool setupShadowDepthShader(ofShader& ashader, int aLightType, const std::string aShaderMain, bool abSinglePass) const; - void updateDepth(const ofShader & shader,ofGLProgrammableRenderer & renderer) const; - void updateDepth(const ofShader & shader,GLenum aCubeFace,ofGLProgrammableRenderer & renderer) const; - + bool setupShadowDepthShader(ofShader & ashader, const std::string aShaderMain); + bool setupShadowDepthShader(ofShader & ashader, int aLightType, const std::string aShaderMain); + void updateDepth(const ofShader & shader, ofGLProgrammableRenderer & renderer) const; + void updateDepth(const ofShader & shader, GLenum aCubeFace, ofGLProgrammableRenderer & renderer) const; + protected: - static void _updateTexDataIds(); - - void _drawFrustum( const glm::vec3& aup, const glm::vec3& aright, const glm::vec3& afwd ); - + + void _drawFrustum(const glm::vec3 & aup, const glm::vec3 & aright, const glm::vec3 & afwd); + void _allocate(); - + void _checkSetup(); void _allocateFbo(); void _checkFbos(); void _updateNumShadows(); - + std::shared_ptr data; - + bool mBSinglePass = true; - + glm::mat4 mShadowProjection = glm::mat4(1.0); - + std::vector mLookAtMats; std::vector mViewProjMats; - + float mOrthoScaleX = 1.0; float mOrthoScaleY = 1.0; float mDirectionalBoundsWidth = -1; float mDirectionalBoundsHeight = -1; - + float mAreaLightWidth = 100; float mAreaLightHeight = 50.0; - + float mFov = 90; - + bool mBEnableCulling = true; GLenum mGlFrontFaceWindingOrder = GL_CW; - + const glm::mat4 biasMatrix = glm::mat4( - 0.5, 0.0, 0.0, 0.0, - 0.0, 0.5, 0.0, 0.0, - 0.0, 0.0, 0.5, 0.0, - 0.5, 0.5, 0.5, 1.0 - ); - -private: - struct Shaders{ + 0.5, 0.0, 0.0, 0.0, + 0.0, 0.5, 0.0, 0.0, + 0.0, 0.0, 0.5, 0.0, + 0.5, 0.5, 0.5, 1.0); + +private: + struct Shaders { ofShader depth; ofShader depthCube; ofShader depthCubeMultiPass; }; - void initShaders(ofGLProgrammableRenderer & renderer) const; - - mutable std::map> shaders; + void initShaders(ofGLProgrammableRenderer & renderer); + + mutable std::map> shaders; }; -std::vector > & ofShadowsData(); +std::vector> & ofShadowsData();