#include "sky.h" #include "IVideoDriver.h" #include "ISceneManager.h" #include "ICameraSceneNode.h" #include "S3DVertex.h" #include "tile.h" // getTexturePath #include "noise.h" // easeCurve #include "main.h" // g_profiler #include "profiler.h" #include "util/numeric.h" // MYMIN //! constructor Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id): scene::ISceneNode(parent, mgr, id), m_first_update(true), m_brightness(0.5), m_cloud_brightness(0.5), m_bgcolor_bright_f(1,1,1,1), m_skycolor_bright_f(1,1,1,1), m_cloudcolor_bright_f(1,1,1,1) { setAutomaticCulling(scene::EAC_OFF); Box.MaxEdge.set(0,0,0); Box.MinEdge.set(0,0,0); // create material video::SMaterial mat; mat.Lighting = false; mat.ZBuffer = video::ECFN_NEVER; mat.ZWriteEnable = false; mat.AntiAliasing=0; mat.TextureLayer[0].TextureWrapU = video::ETC_CLAMP_TO_EDGE; mat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE; mat.BackfaceCulling = false; m_materials[0] = mat; m_materials[1] = mat; //m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; m_materials[1].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; m_materials[2] = mat; m_materials[2].setTexture(0, mgr->getVideoDriver()->getTexture( getTexturePath("sunrisebg.png").c_str())); m_materials[2].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; //m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; for(u32 i=0; iregisterNodeForRendering(this, scene::ESNRP_SKY_BOX); scene::ISceneNode::OnRegisterSceneNode(); } const core::aabbox3d& Sky::getBoundingBox() const { return Box; } //! renders the node. void Sky::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); scene::ICameraSceneNode* camera = SceneManager->getActiveCamera(); if (!camera || !driver) return; ScopeProfiler sp(g_profiler, "Sky::render()", SPT_AVG); // draw perspective skybox core::matrix4 translate(AbsoluteTransformation); translate.setTranslation(camera->getAbsolutePosition()); // Draw the sky box between the near and far clip plane const f32 viewDistance = (camera->getNearValue() + camera->getFarValue()) * 0.5f; core::matrix4 scale; scale.setScale(core::vector3df(viewDistance, viewDistance, viewDistance)); driver->setTransform(video::ETS_WORLD, translate * scale); if(m_sunlight_seen) { float sunsize = 0.07; video::SColorf suncolor_f(1, 1, 0, 1); suncolor_f.r = 1; suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.7+m_time_brightness*(0.5))); suncolor_f.b = MYMAX(0.0, m_brightness*0.95); video::SColorf suncolor2_f(1, 1, 1, 1); suncolor_f.r = 1; suncolor_f.g = MYMAX(0.3, MYMIN(1.0, 0.85+m_time_brightness*(0.5))); suncolor_f.b = MYMAX(0.0, m_brightness); float moonsize = 0.04; video::SColorf mooncolor_f(0.50, 0.57, 0.65, 1); video::SColorf mooncolor2_f(0.85, 0.875, 0.9, 1); float nightlength = 0.415; float wn = nightlength / 2; float wicked_time_of_day = 0; if(m_time_of_day > wn && m_time_of_day < 1.0 - wn) wicked_time_of_day = (m_time_of_day - wn)/(1.0-wn*2)*0.5 + 0.25; else if(m_time_of_day < 0.5) wicked_time_of_day = m_time_of_day / wn * 0.25; else wicked_time_of_day = 1.0 - ((1.0-m_time_of_day) / wn * 0.25); /*std::cerr<<"time_of_day="< " <<"wicked_time_of_day="<setMaterial(m_materials[1]); //video::SColor cloudyfogcolor(255,255,255,255); video::SColor cloudyfogcolor = m_bgcolor; //video::SColor cloudyfogcolor = m_bgcolor.getInterpolated(m_skycolor, 0.5); // Draw far cloudy fog thing for(u32 j=0; j<4; j++) { video::SColor c = cloudyfogcolor.getInterpolated(m_skycolor, 0.45); vertices[0] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, t); vertices[1] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, t); vertices[2] = video::S3DVertex( 1, 0.12,-1, 0,0,1, c, o, o); vertices[3] = video::S3DVertex(-1, 0.12,-1, 0,0,1, c, t, o); for(u32 i=0; i<4; i++){ if(j==0) // Don't switch {} else if(j==1) // Switch from -Z (south) to +X (east) vertices[i].Pos.rotateXZBy(90); else if(j==2) // Switch from -Z (south) to -X (west) vertices[i].Pos.rotateXZBy(-90); else // Switch from -Z (south) to -Z (north) vertices[i].Pos.rotateXZBy(-180); } driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); } for(u32 j=0; j<4; j++) { video::SColor c = cloudyfogcolor; vertices[0] = video::S3DVertex(-1,-1.0,-1, 0,0,1, c, t, t); vertices[1] = video::S3DVertex( 1,-1.0,-1, 0,0,1, c, o, t); vertices[2] = video::S3DVertex( 1, 0.08,-1, 0,0,1, c, o, o); vertices[3] = video::S3DVertex(-1, 0.08,-1, 0,0,1, c, t, o); for(u32 i=0; i<4; i++){ if(j==0) // Don't switch {} else if(j==1) // Switch from -Z (south) to +X (east) vertices[i].Pos.rotateXZBy(90); else if(j==2) // Switch from -Z (south) to -X (west) vertices[i].Pos.rotateXZBy(-90); else // Switch from -Z (south) to -Z (north) vertices[i].Pos.rotateXZBy(-180); } driver->drawIndexedTriangleFan(&vertices[0], 4, indices, 2); } driver->setMaterial(m_materials[2]); { float mid1 = 0.25; float mid = (wicked_time_of_day < 0.5 ? mid1 : (1.0 - mid1)); float a_ = 1.0 - fabs(wicked_time_of_day - mid) * 35.0; float a = easeCurve(MYMAX(0, MYMIN(1, a_))); //std::cerr<<"a_="<