00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "CaelumPrecompiled.h"
00022 #include "SkyDome.h"
00023 #include "GeometryFactory.h"
00024 #include "CaelumExceptions.h"
00025
00026 namespace caelum {
00027
00028 const Ogre::String SkyDome::SPHERIC_DOME_NAME = "CaelumSphericDome";
00029 const Ogre::String SkyDome::SKY_DOME_MATERIAL_NAME = "CaelumSkyDomeMaterial";
00030
00031 SkyDome::SkyDome (Ogre::SceneManager *sceneMgr, Ogre::SceneNode *caelumRootNode):
00032 mNode(NULL)
00033 {
00034
00035 mMaterial = Ogre::MaterialManager::getSingleton().getByName(SKY_DOME_MATERIAL_NAME);
00036 mMaterial = mMaterial->clone(SKY_DOME_MATERIAL_NAME + Ogre::StringConverter::toString((size_t)this));
00037 mMaterial->load ();
00038
00039
00040 mShadersEnabled = mMaterial->getBestTechnique()->getPass(0)->isProgrammable();
00041
00042
00043 mHazeEnabled = true;
00044 setHazeEnabled(false);
00045
00046 sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_SKYDOME)->setShadowsEnabled(false);
00047
00048
00049 GeometryFactory::generateSphericDome (SPHERIC_DOME_NAME, 32);
00050 Ogre::Entity *ent = sceneMgr->createEntity ("Dome", SPHERIC_DOME_NAME);
00051 ent->setMaterialName (mMaterial->getName());
00052 ent->setRenderQueueGroup (CAELUM_RENDER_QUEUE_SKYDOME);
00053 ent->setCastShadows (false);
00054
00055 mNode = caelumRootNode->createChildSceneNode ();
00056 mNode->attachObject (ent);
00057 }
00058
00059 SkyDome::~SkyDome () {
00060 if (mNode) {
00061
00062 Ogre::Entity *ent = static_cast<Ogre::Entity *>(mNode->detachObject ("Dome"));
00063 ent->_getManager ()->destroyEntity (ent);
00064
00065
00066 static_cast<Ogre::SceneNode *>(mNode->getParent ())->removeAndDestroyChild (mNode->getName ());
00067 mNode = 0;
00068
00069 Ogre::MaterialManager::getSingletonPtr()->remove(mMaterial->getHandle());
00070 }
00071 }
00072
00073 void SkyDome::notifyCameraChanged (Ogre::Camera *cam) {
00074 CameraBoundElement::notifyCameraChanged (cam);
00075 }
00076
00077 void SkyDome::setFarRadius (Ogre::Real radius) {
00078 CameraBoundElement::setFarRadius(radius);
00079 mNode->setScale (Ogre::Vector3::UNIT_SCALE * radius);
00080 }
00081
00082 void SkyDome::setSunDirection (Ogre::Vector3 sunDir) {
00083 float elevation = sunDir.dotProduct (Ogre::Vector3::UNIT_Y);
00084 elevation = elevation * 0.5 + 0.5;
00085 Ogre::Pass* pass = mMaterial->getBestTechnique()->getPass(0);
00086 if (mShadersEnabled) {
00087 Ogre::GpuProgramParametersSharedPtr vpParams = pass->getVertexProgramParameters();
00088 Ogre::GpuProgramParametersSharedPtr fpParams = pass->getFragmentProgramParameters();
00089 vpParams->setNamedConstant ("sunDirection", sunDir);
00090 fpParams->setNamedConstant ("offset", elevation);
00091 } else {
00092 Ogre::TextureUnitState* gradientsTus = pass->getTextureUnitState(0);
00093 gradientsTus->setTextureUScroll (elevation);
00094 }
00095 }
00096
00097 void SkyDome::setHazeColour (Ogre::ColourValue hazeColour) {
00098 if (mShadersEnabled && mHazeEnabled) {
00099 Ogre::GpuProgramParametersSharedPtr fpParams = mMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
00100 fpParams->setNamedConstant ("hazeColour", hazeColour);
00101 }
00102 }
00103
00104 void SkyDome::setLightAbsorption (float absorption) const {
00105 if (!mShadersEnabled)
00106 return;
00107
00108 if (absorption > 1) {
00109 absorption = 1;
00110 } else if (absorption < 0) {
00111 absorption = 0;
00112 }
00113
00114 Ogre::GpuProgramParametersSharedPtr vpParams =
00115 mMaterial->getBestTechnique()->getPass(0)->getVertexProgramParameters();
00116 vpParams->setNamedConstant ("lightAbsorption", absorption);
00117 }
00118
00119 void SkyDome::setLightScattering (float scattering) const {
00120 if(!mShadersEnabled)
00121 return;
00122
00123 if (scattering <= 0) {
00124 scattering = 0.00001;
00125 }
00126
00127 Ogre::GpuProgramParametersSharedPtr fpParams =
00128 mMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
00129 fpParams->setNamedConstant ("lightInvScattering", 1.0f / scattering);
00130 }
00131
00132 void SkyDome::setAtmosphereHeight (float height) const {
00133 if(!mShadersEnabled)
00134 return;
00135
00136 if (height <= 0) {
00137 height = 0.00001;
00138 } else if (height > 1) {
00139 height = 1;
00140 }
00141
00142 Ogre::GpuProgramParametersSharedPtr fpParams =
00143 mMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
00144 fpParams->setNamedConstant ("atmosphereInvHeight", 1.0f / height);
00145 }
00146
00147 void SkyDome::setSkyGradientsImage (const Ogre::String& gradients) {
00148 Ogre::TextureUnitState* gradientsTus =
00149 mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(0);
00150
00151 gradientsTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP);
00152
00153
00154 #if OGRE_VERSION < ((1 << 16) | (3 << 8))
00155 gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D, -1, true);
00156 #else
00157 gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D);
00158 gradientsTus->setIsAlpha (true);
00159 #endif
00160 }
00161
00162 void SkyDome::setAtmosphereDepthImage (const Ogre::String& atmosphereDepth) {
00163 if(!mShadersEnabled)
00164 return;
00165
00166 Ogre::TextureUnitState* atmosphereTus =
00167 mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(1);
00168
00169 atmosphereTus->setTextureName (atmosphereDepth, Ogre::TEX_TYPE_1D);
00170 atmosphereTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP, Ogre::TextureUnitState::TAM_WRAP, Ogre::TextureUnitState::TAM_WRAP);
00171 }
00172
00173 bool SkyDome::getHazeEnabled () const {
00174 return mHazeEnabled;
00175 }
00176
00177 void SkyDome::setHazeEnabled (bool value) {
00178 if (mHazeEnabled == value) {
00179 return;
00180 }
00181 mHazeEnabled = value;
00182
00183 if(!mShadersEnabled) {
00184 return;
00185 }
00186
00187 Ogre::Pass *pass = mMaterial->getTechnique (0)->getPass (0);
00188 if (value) {
00189 pass->setFragmentProgram("CaelumSkyDomeFP");
00190 } else {
00191 pass->setFragmentProgram("CaelumSkyDomeFP_NoHaze");
00192 }
00193 Ogre::GpuProgramParametersSharedPtr params = pass->getFragmentProgramParameters();
00194 params->setIgnoreMissingParams(true);
00195 }
00196
00197 }