Changeset 9448
- Timestamp:
- Nov 14, 2012, 9:16:18 PM (12 years ago)
- Location:
- code/branches/shaders/src/orxonox
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/shaders/src/orxonox/RenderQueueListener.cc
r9420 r9448 37 37 #include <OgreRoot.h> 38 38 #include <OgreRenderQueueListener.h> 39 #include <OgreHardwareOcclusionQuery.h> 39 40 40 41 namespace orxonox 41 42 { 43 RenderQueueListener::RenderQueueListener() : pixelCount_(0), pixelState_(RenderQueueListener::READY_FOR_RENDER) 44 { 45 hardwareOcclusionQuery_ = Ogre::Root::getSingleton().getRenderSystem()->createHardwareOcclusionQuery(); //create a new HOQ for the scene this listener is used in 46 } 47 48 RenderQueueListener::~RenderQueueListener() 49 { 50 Ogre::Root::getSingleton().getRenderSystem()->destroyHardwareOcclusionQuery(hardwareOcclusionQuery_); //destroy the created HOQ 51 } 52 53 /** 54 @brief 55 This function is returning the current pixel count and resets the pixel state if we're ready to do another Hardware Occlusion Query 56 57 @return 58 current pixel count taken from the last Hardware Occlusion Query 59 */ 60 unsigned int RenderQueueListener::getPixelCount() 61 { 62 if(this->pixelState_==RenderQueueListener::READY_FOR_ACCESS) 63 { 64 this->hardwareOcclusionQuery_->pullOcclusionQuery(&(this->pixelCount_)); 65 this->pixelState_=RenderQueueListener::READY_FOR_RENDER; 66 } 67 return this->pixelCount_; 68 } 69 42 70 /** 43 71 @brief 44 72 This function is called just before a RenderQueueGroup is rendered, this function is called by Ogre automatically with the correct parameters. 45 73 46 In this case we use it to set the stencil buffer parameters of the render system 74 In this case we use it to set the stencil buffer parameters of the render system and issue a Hardware Occlusion Query 47 75 */ 48 76 void RenderQueueListener::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation) … … 60 88 if (queueGroupId == RENDER_QUEUE_STENCIL_GLOW) 61 89 { 62 Ogre::RenderSystem * renderSystem = Ogre::Root::getSingleton().getRenderSystem(); 63 renderSystem->setStencilCheckEnabled(true); 64 renderSystem->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL, 65 STENCIL_VALUE_FOR_GLOW, STENCIL_FULL_MASK, 66 Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false); 90 Ogre::RenderSystem * renderSystem = Ogre::Root::getSingleton().getRenderSystem(); 91 renderSystem->setStencilCheckEnabled(true); 92 renderSystem->setStencilBufferParams(Ogre::CMPF_NOT_EQUAL, 93 STENCIL_VALUE_FOR_GLOW, STENCIL_FULL_MASK, 94 Ogre::SOP_KEEP,Ogre::SOP_KEEP,Ogre::SOP_REPLACE,false); 95 } 96 if (queueGroupId == RENDER_QUEUE_HOQ && this->pixelState_==RenderQueueListener::READY_FOR_RENDER) 97 { 98 this->hardwareOcclusionQuery_->beginOcclusionQuery(); 99 this->pixelState_=RenderQueueListener::QUERY_STARTED; 100 //TODO: Skip this rendering step altogheter if we haven't requested the pixel count yet, not sure if this is possible without a custom SceneManager 67 101 } 68 102 } … … 82 116 renderSystem->setStencilBufferParams(); 83 117 } 118 if (queueGroupId == RENDER_QUEUE_HOQ && this->pixelState_==RenderQueueListener::QUERY_STARTED) 119 { 120 this->hardwareOcclusionQuery_->endOcclusionQuery(); 121 this->pixelState_=RenderQueueListener::READY_FOR_ACCESS; 122 } 84 123 } 85 124 } -
code/branches/shaders/src/orxonox/RenderQueueListener.h
r9419 r9448 39 39 40 40 #include <OgreRenderQueueListener.h> 41 #include <OgreHardwareOcclusionQuery.h> 41 42 42 43 namespace orxonox … … 47 48 RENDER_QUEUE_STENCIL_OBJECTS = RENDER_QUEUE_MAIN+1, 48 49 RENDER_QUEUE_STENCIL_GLOW = RENDER_QUEUE_MAIN+2, 49 RENDER_QUEUE_STENCIL_LAST = RENDER_QUEUE_STENCIL_GLOW //this is a reference to the last render queue to be affected by stencil glow effects 50 RENDER_QUEUE_STENCIL_LAST = RENDER_QUEUE_STENCIL_GLOW, //this is a reference to the last render queue to be affected by stencil glow effects 51 RENDER_QUEUE_HOQ = RENDER_QUEUE_STENCIL_LAST+1 //this is where we render the objects for occlusion queries (use transparent material) 50 52 }; 51 53 … … 65 67 { 66 68 public: 69 RenderQueueListener(); 70 ~RenderQueueListener(); 71 72 /** 73 @brief 74 This function is returning the current pixel count and resets the pixel state if we're ready to do another Hardware Occlusion Query 75 76 @return 77 current pixel count taken from the last Hardware Occlusion Query 78 */ 79 unsigned int getPixelCount(); 80 67 81 /** 68 82 @brief … … 79 93 */ 80 94 virtual void renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation); 95 96 private: 97 Ogre::HardwareOcclusionQuery* hardwareOcclusionQuery_; //!< this stores the current instance of the HOQ used in the render system 98 unsigned int pixelCount_; //!< this stores the last pixel count returned by the last HOQ in the corresponding render group 99 100 enum PixelState //!< enum to distinguish the several HOQ pixel count states 101 { 102 READY_FOR_RENDER, 103 QUERY_STARTED, 104 READY_FOR_ACCESS 105 }; 106 107 PixelState pixelState_; //!< this stores the current state of the Hardware Occlusion Query 81 108 }; 82 109 } -
code/branches/shaders/src/orxonox/Scene.cc
r9420 r9448 78 78 this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); 79 79 this->rootSceneNode_ = this->sceneManager_->getRootSceneNode(); 80 RenderQueueListener* renderQueueListener= new RenderQueueListener();81 this->sceneManager_->addRenderQueueListener( renderQueueListener);//add our own renderQueueListener80 this->renderQueueListener_ = new RenderQueueListener(); 81 this->sceneManager_->addRenderQueueListener(this->renderQueueListener_);//add our own renderQueueListener 82 82 83 83 this->radar_ = new Radar(); -
code/branches/shaders/src/orxonox/Scene.h
r9420 r9448 69 69 inline Ogre::SceneNode* getRootSceneNode() const 70 70 { return this->rootSceneNode_; } 71 inline RenderQueueListener* getRenderQueueListener() const 72 { return this->renderQueueListener_; } 71 73 72 74 void setSkybox(const std::string& skybox); … … 107 109 Ogre::SceneManager* sceneManager_; //!< This is a pointer to the Ogre SceneManager we're using to render the Scene 108 110 Ogre::SceneNode* rootSceneNode_; //!< This is a pointer to the root node of the Scene tree 111 RenderQueueListener* renderQueueListener_; //!< this is a pointer to the RenderQueueListener we're using for this Scene 109 112 110 113 std::string skybox_; //!< This string holds information about the skybox we're using -
code/branches/shaders/src/orxonox/graphics/Billboard.cc
r8706 r9448 171 171 } 172 172 } 173 174 void Billboard::setRenderQueueGroup(unsigned char groupID) 175 { 176 Ogre::BillboardSet* bSet = this->billboard_.getBillboardSet(); 177 if( bSet != NULL ) 178 { 179 bSet->setRenderQueueGroup(groupID); 180 } 181 } 173 182 } -
code/branches/shaders/src/orxonox/graphics/Billboard.h
r8706 r9448 81 81 82 82 void setDefaultDimensions(float width, float height); 83 84 void setRenderQueueGroup(unsigned char groupID); 83 85 84 86 -
code/branches/shaders/src/orxonox/graphics/LensFlare.cc
r9445 r9448 38 38 #include "graphics/Billboard.h" 39 39 #include "CameraManager.h" 40 #include "RenderQueueListener.h" 41 42 #include <OgreSphere.h> 43 #include <OgreRenderWindow.h> 40 44 41 45 namespace orxonox … … 43 47 CreateFactory(LensFlare); 44 48 45 LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator) 49 LensFlare::LensFlare(BaseObject* creator) : StaticEntity(creator), scale_(1.0f) 46 50 { 47 51 RegisterObject(LensFlare); … … 59 63 { 60 64 SUPER(LensFlare, XMLPort, xmlelement, mode); 65 XMLPortParam(LensFlare, "scale", setScale, getScale, xmlelement, mode).defaultValues(1.0f); 61 66 } 62 67 63 68 void LensFlare::registerVariables() 64 69 { 65 70 registerVariable(this->scale_, VariableDirection::ToClient, new NetworkCallback<LensFlare>(this, &LensFlare::updateBillboardPositions)); 66 71 } 67 72 68 73 void LensFlare::createBillboards() 69 74 { 75 this->occlusionBillboard_ = new Billboard(this); 76 this->occlusionBillboard_->setMaterial("lensflare/hoq"); 77 this->occlusionBillboard_->setPosition(this->getPosition()); 78 this->occlusionBillboard_->setVisible(false); 79 this->occlusionBillboard_->setRenderQueueGroup(RENDER_QUEUE_HOQ); 80 this->attach(this->occlusionBillboard_); 81 70 82 Billboard* burst = new Billboard(this); 71 83 burst->setMaterial("lensflare/burst"); … … 79 91 Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); //get active Ogre Camera Instance, so we can check whether the light source is visible 80 92 bool lightIsVisible=camera->isVisible(this->getPosition()); //is the light source visible from our point of view? 81 int scale=camera->getPosition().distance(this->getPosition()); 93 this->cameraDistance_=camera->getPosition().distance(this->getPosition()); 94 unsigned int dimension=this->cameraDistance_*this->scale_; 82 95 83 Billboard* burst=static_cast<Billboard*>(getAttachedObject(0)); 96 this->occlusionBillboard_->setPosition(this->getPosition()); 97 this->occlusionBillboard_->setVisible(lightIsVisible); 98 this->occlusionBillboard_->setDefaultDimensions(dimension,dimension); 99 100 Billboard* burst=static_cast<Billboard*>(getAttachedObject(1)); 84 101 burst->setPosition(this->getPosition()); 85 102 burst->setVisible(lightIsVisible); 86 burst->setDefaultDimensions( scale,scale);103 burst->setDefaultDimensions(dimension,dimension); 87 104 } 88 105 … … 92 109 { 93 110 updateBillboardPositions(); 111 if(this->occlusionBillboard_->isVisible()) { 112 unsigned int dimension=this->cameraDistance_*this->scale_; 113 Ogre::Sphere* sphere=new Ogre::Sphere(this->getPosition(),dimension*0.25); 114 Ogre::Camera* camera=CameraManager::getInstance().getActiveCamera()->getOgreCamera(); 115 float left, right, top, bottom; 116 camera->projectSphere(*sphere,&left,&top,&right,&bottom);//approximate maximum pixel count of billboard with a sphere 117 delete sphere; 118 119 Ogre::RenderWindow* window = GraphicsManager::getInstance().getRenderWindow(); 120 float maxCount=(right-left)*(top-bottom)*window->getWidth()*window->getHeight()*0.25; 121 float pixelCount=this->getScene()->getRenderQueueListener()->getPixelCount();//get pixel count 122 float ratio=pixelCount/maxCount; 123 //orxout() << "maxCount: " << maxCount << " HOQ: " << pixelCount << " ratio: " << ratio << std::endl; 124 ColourValue* colour = new ColourValue(1.0f,1.0f,1.0f,ratio); //adjust alpha of billboard 125 126 Billboard* burst=static_cast<Billboard*>(getAttachedObject(1)); 127 burst->setColour(*colour); 128 delete colour; 129 } 94 130 } 95 131 } -
code/branches/shaders/src/orxonox/graphics/LensFlare.h
r9445 r9448 40 40 #include "OgreBillboardSet.h" 41 41 42 #include "core/GraphicsManager.h" 42 43 #include "util/Math.h" 43 44 #include "worldentities/StaticEntity.h" … … 54 55 David 'davidsa' Salvisberg 55 56 */ 57 //TODO: The Hardware Occlusion only works properly for a single Flare on the screen, 58 // if we have multiple strong lights it'll become way more complicated to determine how much of every object is occluded individually 59 // 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 60 // 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 56 61 class _OrxonoxExport LensFlare : public StaticEntity, public Tickable 57 62 { … … 59 64 LensFlare(BaseObject* creator); 60 65 virtual ~LensFlare(); 66 67 inline void setScale(float scale) 68 { this->scale_=scale; } 69 inline float getScale() 70 { return this->scale_; } 61 71 62 72 virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); … … 72 82 73 83 void updateBillboardPositions(); 84 85 Billboard* occlusionBillboard_; 86 unsigned int cameraDistance_; 87 float scale_; 74 88 }; 75 89 }
Note: See TracChangeset
for help on using the changeset viewer.