[Orxonox-commit 4792] r9461 - code/branches/shaders/src/orxonox/graphics
davidsa at orxonox.net
davidsa at orxonox.net
Tue Nov 20 18:46:04 CET 2012
Author: davidsa
Date: 2012-11-20 18:46:03 +0100 (Tue, 20 Nov 2012)
New Revision: 9461
Modified:
code/branches/shaders/src/orxonox/graphics/Billboard.cc
code/branches/shaders/src/orxonox/graphics/Billboard.h
code/branches/shaders/src/orxonox/graphics/LensFlare.cc
code/branches/shaders/src/orxonox/graphics/LensFlare.h
Log:
Updated orxonox::Billboard so you can disable FrustumCulling. Also improved orxonox::LensFlare and added documentation.
Modified: code/branches/shaders/src/orxonox/graphics/Billboard.cc
===================================================================
--- code/branches/shaders/src/orxonox/graphics/Billboard.cc 2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/Billboard.cc 2012-11-20 17:46:03 UTC (rev 9461)
@@ -179,4 +179,13 @@
bSet->setRenderQueueGroup(groupID);
}
}
+
+ void Billboard::disableFrustumCulling()
+ {
+ Ogre::BillboardSet* bSet = this->billboard_.getBillboardSet();
+ if( bSet != NULL )
+ {
+ bSet->setBounds(Ogre::AxisAlignedBox(Ogre::AxisAlignedBox::EXTENT_INFINITE),0);
+ }
+ }
}
Modified: code/branches/shaders/src/orxonox/graphics/Billboard.h
===================================================================
--- code/branches/shaders/src/orxonox/graphics/Billboard.h 2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/Billboard.h 2012-11-20 17:46:03 UTC (rev 9461)
@@ -82,6 +82,8 @@
void setDefaultDimensions(float width, float height);
void setRenderQueueGroup(unsigned char groupID);
+
+ void disableFrustumCulling();
protected:
Modified: code/branches/shaders/src/orxonox/graphics/LensFlare.cc
===================================================================
--- code/branches/shaders/src/orxonox/graphics/LensFlare.cc 2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/LensFlare.cc 2012-11-20 17:46:03 UTC (rev 9461)
@@ -46,7 +46,7 @@
{
CreateFactory(LensFlare);
- LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f)
+ LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f), fadeOnViewBorder_(true), fadeResolution_(7), fadeExponent_(2.0f)
{
RegisterObject(LensFlare);
@@ -63,55 +63,122 @@
{
SUPER(LensFlare, XMLPort, xmlelement, mode);
XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f);
+ XMLPortParam(LensFlare, "fadeOnViewBorder", setFadeOnViewBorder, isFadeOnViewBorder, xmlelement, mode).defaultValues(true);
+ XMLPortParam(LensFlare, "fadeResolution", setFadeResolution, getFadeResolution, xmlelement, mode).defaultValues(7);
+ XMLPortParam(LensFlare, "fadeExponent", setFadeExponent, getFadeExponent, xmlelement, mode).defaultValues(2.0f);
}
void LensFlare::registerVariables()
{
- registerVariable(this->scale_, VariableDirection::ToClient, new NetworkCallback<LensFlare>(this, &LensFlare::updateBillboardPositions));
+ registerVariable(this->scale_, VariableDirection::ToClient);
+ registerVariable(this->fadeOnViewBorder_, VariableDirection::ToClient);
+ registerVariable(this->fadeResolution_, VariableDirection::ToClient);
}
-
+
+ /**
+ @brief
+ This function creates all the billboards needed for the flare effect
+ */
void LensFlare::createBillboards()
{
+ //TODO: add more billboards, possibly do some cleaning up, by using a loop
this->occlusionBillboard_ = new Billboard(this);
this->occlusionBillboard_->setMaterial("lensflare/hoq");
this->occlusionBillboard_->setPosition(this->getPosition());
this->occlusionBillboard_->setVisible(false);
+ this->occlusionBillboard_->disableFrustumCulling();
this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ);
this->attach(this->occlusionBillboard_);
Billboard* burst = new Billboard(this);
burst->setMaterial("lensflare/burst");
burst->setPosition(this->getPosition());
- burst->setVisible(false);
+ burst->disableFrustumCulling();
+ burst->setVisible(true);
this->attach(burst);
}
+
+ /**
+ @brief
+ This function updates the states of all the billboards, i.e. their positions, visibilty and dimensions
+ @param dimension
+ the current dimension of the main billboard, we're always using square billboards
+ */
+ void LensFlare::updateBillboardStates(unsigned int dimension, bool lightIsVisible)
+ {
+ //TODO: position and dimensions need to be calculated for everything but the main burst of the flare
+ for(std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++) {
+ Billboard* billboard=static_cast<Billboard*>(*it);
+ billboard->setPosition(this->getPosition());
+ billboard->setVisible(lightIsVisible);
+ billboard->setDefaultDimensions(dimension,dimension);
+ }
+ }
+
+ /**
+ @brief
+ This function updates the alpha values for all billboards except for the one used for Hardware Occlusion Querying
+ @param alpha
+ the new alpha value all visible billboards should use
+ */
+ void LensFlare::updateBillboardAlphas(float alpha)
+ {
+ ColourValue* colour = new ColourValue(1.0f,1.0f,1.0f,alpha);
+ std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin();
+ it++;
+ for(;it!=this->getAttachedObjects().end(); it++) {
+ Billboard* billboard=static_cast<Billboard*>(*it);
+ billboard->setColour(*colour);
+ }
+ delete colour;
+ }
- void LensFlare::updateBillboardPositions()
+ /**
+ @brief
+ This function generates point samples of the main burst billboard according to the fadeResolution and returns how many of them are in the view port
+ @param dimension
+ the current dimension of the main billboard, we're always using square billboards
+ @return
+ the absolute amount of point samples that are currently captured by the camera of the view port
+ */
+ unsigned int LensFlare::getPointCount(unsigned int dimension) const
{
- Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
- bool lightIsVisible=camera->isVisible(this->getPosition()); //is the light source visible from our point of view?
- this->cameraDistance_=camera->getPosition().distance(this->getPosition());
- unsigned int dimension=this->cameraDistance_*this->scale_;
-
- this->occlusionBillboard_->setPosition(this->getPosition());
- this->occlusionBillboard_->setVisible(lightIsVisible);
- this->occlusionBillboard_->setDefaultDimensions(dimension,dimension);
-
- Billboard* burst=static_cast<Billboard*>(getAttachedObject(1));
- burst->setPosition(this->getPosition());
- burst->setVisible(lightIsVisible);
- burst->setDefaultDimensions(dimension,dimension);
+ Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
+ Vector3 position = this->getPosition();
+ Vector3 nX = camera->getOrientation().xAxis().normalisedCopy();
+ Vector3 nY = camera->getOrientation().yAxis().normalisedCopy();
+ int halfRes=fadeResolution_/2;
+ int resDim=dimension/fadeResolution_;
+ unsigned int count=0;
+ for(int i=-halfRes;i<=halfRes;i++)
+ {
+ for(int j=-halfRes;j<=halfRes;j++)
+ {
+ Vector3 point=position+(i*resDim)*nX+(j*resDim)*nY;//generate point samples
+ if(camera->isVisible(point))
+ {
+ count++;
+ }
+ }
+ }
+ return count;
}
void LensFlare::tick(float dt)
{
if(this->isVisible())
{
- updateBillboardPositions();
- if(this->occlusionBillboard_->isVisible()) {
- unsigned int dimension=this->cameraDistance_*this->scale_;
+ Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible
+ this->cameraDistance_=camera->getPosition().distance(this->getPosition());
+ unsigned int dimension=this->cameraDistance_*this->scale_;
+ if(!this->fadeOnViewBorder_)
+ {
+ this->fadeResolution_=3;//this is so we can still determine when the billboard has left the screen
+ }
+ unsigned int pointCount=this->getPointCount(dimension);
+ updateBillboardStates(dimension,pointCount>0);
+ if(pointCount>0) {
Ogre::Sphere* sphere=new Ogre::Sphere(this->getPosition(),dimension*0.25);
- Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera();
float left, right, top, bottom;
camera->projectSphere(*sphere,&left,&top,&right,&bottom);//approximate maximum pixel count of billboard with a sphere
delete sphere;
@@ -119,18 +186,21 @@
Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow();
float maxCount=(right-left)*(top-bottom)*window->getWidth()*window->getHeight()*0.25;
float pixelCount=this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count
- float ratio=pixelCount/maxCount;
- //orxout() << "maxCount: " << maxCount << " HOQ: " << pixelCount << " ratio: " << ratio << std::endl;
- ColourValue* colour = new ColourValue(1.0f,1.0f,1.0f,ratio); //adjust alpha of billboard
+ float ratio=(maxCount==0)?0:(pixelCount/maxCount);//prevent division by zero
+ float borderRatio=1.0f;
+ if(this->fadeOnViewBorder_)
+ {
+ borderRatio=((float) pointCount)/(((float) fadeResolution_)*((float) fadeResolution_));//ratio for the border fade
+ }
- Billboard* burst=static_cast<Billboard*>(getAttachedObject(1));
- burst->setColour(*colour);
- delete colour;
+ //update alpha values of all billboards except the HOQ billboard
+ this->updateBillboardAlphas(std::min(1.0f,std::pow(std::min(ratio,borderRatio),2.0f)));
}
}
}
void LensFlare::changedVisibility()
{
+
}
}
\ No newline at end of file
Modified: code/branches/shaders/src/orxonox/graphics/LensFlare.h
===================================================================
--- code/branches/shaders/src/orxonox/graphics/LensFlare.h 2012-11-19 15:25:11 UTC (rev 9460)
+++ code/branches/shaders/src/orxonox/graphics/LensFlare.h 2012-11-20 17:46:03 UTC (rev 9461)
@@ -57,7 +57,7 @@
//TODO: The Hardware Occlusion only works properly for a single Flare on the screen,
// if we have multiple strong lights it'll become way more complicated to determine how much of every object is occluded individually
// there's below a 100 render queue groups, so maybe we should take turns for each object to be tested, so we only have one of the objects rendered at a time
- // obviously we shouldn't use too much of these effects anyways, since they use a lot of performance, so not sure whether it's worth implementing a solution that works for multiple lens flares on screen
+ // obviously we shouldn't use too many of these effects anyways, since they use a lot of processing power, so not sure whether it's worth implementing a solution that works for multiple lens flares on screen
class _OrxonoxExport LensFlare : public StaticEntity, public Tickable
{
public:
@@ -66,8 +66,62 @@
inline void setScale(float scale)
{ this->scale_=scale; }
- inline float getScale()
+ inline float getScale() const
{ return this->scale_; }
+
+ /**
+ @brief
+ This sets the resolution of the out-of-screen-fade-effect
+
+ the higher the resolution, the smoother the transition, but it will also have a greater impact on the performance
+ this happens with O(n^2) since it's a two dimensional operation.
+ @param fadeResolution
+ how many point samples should be used per axis
+
+ note: this will always be an odd number, so the center point is included in the samples
+ */
+ inline void setFadeResolution(unsigned int fadeResolution)
+ { this->fadeResolution_=fadeResolution>0?fadeResolution:1; }
+ /**
+ @brief
+ This returns the resolution of the out-of-screen-fade-effect
+ @return how many point samples are being used per axis
+ */
+ inline unsigned int getFadeResolution() const
+ { return this->fadeResolution_; }
+
+ /**
+ @brief
+ This sets the exponent of the fade-out function
+ @param exponent
+ how strong should the fade-out effect be
+ */
+ inline void setFadeExponent(float exponent)
+ { this->fadeExponent_=exponent; }
+ /**
+ @brief
+ This returns the exponent of the fade-out function
+ @return the exponent of the fade-out function
+ */
+ inline float getFadeExponent() const
+ { return this->fadeExponent_; }
+
+ /**
+ @brief
+ Turn the out-of-screen-fade-effect on or off
+ @param fadeOnViewBorder
+ true to turn the effect on, false to turn it off
+ */
+ inline void setFadeOnViewBorder(bool fadeOnViewBorder)
+ { this->fadeOnViewBorder_=fadeOnViewBorder; }
+ /**
+ @brief
+ Determine whether the out-of-screen-fade-effect is on or off
+ @return
+ true if the effect is on, false if it is off
+ */
+ inline bool isFadeOnViewBorder() const
+ { return this->fadeOnViewBorder_; }
virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
@@ -80,11 +134,18 @@
void createBillboards();
- void updateBillboardPositions();
+ void updateBillboardStates(unsigned int dimension, bool isLightVisible);
- Billboard* occlusionBillboard_;
- unsigned int cameraDistance_;
- float scale_;
+ void updateBillboardAlphas(float alpha);
+
+ unsigned int getPointCount(unsigned int dimension) const;
+
+ Billboard* occlusionBillboard_;//!< this is a transparent billboard used solely for the Hardware Occlusion Query
+ unsigned int cameraDistance_;//!< current distance of the lensflare center from the camera
+ float scale_;//!< this factor is used to scale the billboard to the desired size
+ bool fadeOnViewBorder_;//!< should the effect fade out on the border of the view?
+ unsigned int fadeResolution_;//!< how many points should be sampled per axis for the screen border fade. High number => smooth fade, but uses more processing power
+ float fadeExponent_;//!< this determines how fast the flare fades away as it gets obstructed
};
}
More information about the Orxonox-commit
mailing list