// setLighting: set renderer lights according to current position and sun // positions. Original lighting is passed back in oldLights, oldAmbient, and // should be reset after rendering with ModelBody::ResetLighting. void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::vector<Graphics::Light> &oldLights, Color &oldAmbient) { std::vector<Graphics::Light> newLights; double ambient, direct; CalcLighting(ambient, direct, camera); const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources(); for(size_t i = 0; i < lightSources.size(); i++) { Graphics::Light light(lightSources[i].GetLight()); oldLights.push_back(light); const float intensity = direct * camera->ShadowedIntensity(i, this); Color c = light.GetDiffuse(); Color cs = light.GetSpecular(); c.r*=float(intensity); c.g*=float(intensity); c.b*=float(intensity); cs.r*=float(intensity); cs.g*=float(intensity); cs.b*=float(intensity); light.SetDiffuse(c); light.SetSpecular(cs); newLights.push_back(light); } oldAmbient = r->GetAmbientColor(); r->SetAmbientColor(Color(ambient)); r->SetLights(newLights.size(), &newLights[0]); }
// setLighting: set renderer lights according to current position and sun // positions. Original lighting is passed back in oldLights, oldAmbient, and // should be reset after rendering with ModelBody::ResetLighting. void ModelBody::SetLighting(Graphics::Renderer *r, const Camera *camera, std::vector<Graphics::Light> &oldLights, Color &oldAmbient) { std::vector<Graphics::Light> newLights; double ambient, direct; CalcLighting(ambient, direct, camera); const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources(); newLights.reserve(lightSources.size()); oldLights.reserve(lightSources.size()); for(size_t i = 0; i < lightSources.size(); i++) { Graphics::Light light(lightSources[i].GetLight()); oldLights.push_back(light); const float intensity = direct * camera->ShadowedIntensity(i, this); Color c = light.GetDiffuse(); Color cs = light.GetSpecular(); c.r*=float(intensity); c.g*=float(intensity); c.b*=float(intensity); cs.r*=float(intensity); cs.g*=float(intensity); cs.b*=float(intensity); light.SetDiffuse(c); light.SetSpecular(cs); newLights.push_back(light); } if (newLights.empty()) { // no lights means we're somewhere weird (eg hyperspace, ObjectViewer). fake one newLights.push_back(Graphics::Light(Graphics::Light::LIGHT_DIRECTIONAL, vector3f(0.f), Color::WHITE, Color::WHITE)); } oldAmbient = r->GetAmbientColor(); r->SetAmbientColor(Color(ambient*255, ambient * 255, ambient * 255)); r->SetLights(newLights.size(), &newLights[0]); }
// Renders space station and adjacent city if applicable // For orbital starports: renders as normal // For surface starports: // Lighting: Calculates available light for model and splits light between directly and ambiently lit // Lighting is done by manipulating global lights or setting uniforms in atmospheric models shader void SpaceStation::Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { Body *b = GetFrame()->GetBody(); assert(b); if (!b->IsType(Object::PLANET)) { // orbital spaceport -- don't make city turds or change lighting based on atmosphere RenderModel(r, viewCoords, viewTransform); } else { Planet *planet = static_cast<Planet*>(b); // calculate lighting // available light is calculated and split between directly (diffusely/specularly) lit and ambiently lit const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources(); double ambient, intensity; CalcLighting(planet, ambient, intensity, lightSources); ambient = std::max(0.05, ambient); std::vector<Graphics::Light> origLights, newLights; for(size_t i = 0; i < lightSources.size(); i++) { Graphics::Light light(lightSources[i].GetLight()); origLights.push_back(light); Color c = light.GetDiffuse(); Color cs = light.GetSpecular(); c.r*=float(intensity); c.g*=float(intensity); c.b*=float(intensity); cs.r*=float(intensity); cs.g*=float(intensity); cs.b*=float(intensity); light.SetDiffuse(c); light.SetSpecular(cs); newLights.push_back(light); } const Color oldAmbient = r->GetAmbientColor(); r->SetAmbientColor(Color(ambient)); r->SetLights(newLights.size(), &newLights[0]); /* don't render city if too far away */ if (viewCoords.Length() < 1000000.0){ if (!m_adjacentCity) { m_adjacentCity = new CityOnPlanet(planet, this, m_sbody->seed); } m_adjacentCity->Render(r, camera, this, viewCoords, viewTransform); } RenderModel(r, viewCoords, viewTransform); // restore old lights & ambient r->SetLights(origLights.size(), &origLights[0]); r->SetAmbientColor(oldAmbient); } }
// Renders space station and adjacent city if applicable // For orbital starports: renders as normal // For surface starports: // Lighting: Calculates available light for model and splits light between directly and ambiently lit // Lighting is done by manipulating global lights or setting uniforms in atmospheric models shader // Adds an ambient light at close ranges if dark by manipulating the global ambient level void SpaceStation::Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) { LmrObjParams ¶ms = GetLmrObjParams(); params.label = GetLabel().c_str(); SetLmrTimeParams(); for (int i=0; i<MAX_DOCKING_PORTS; i++) { params.animStages[ANIM_DOCKING_BAY_1 + i] = m_shipDocking[i].stage; params.animValues[ANIM_DOCKING_BAY_1 + i] = m_shipDocking[i].stagePos; } Body *b = GetFrame()->m_astroBody; assert(b); if (!b->IsType(Object::PLANET)) { // orbital spaceport -- don't make city turds or change lighting based on atmosphere RenderLmrModel(r, viewCoords, viewTransform); } else { Planet *planet = static_cast<Planet*>(b); // calculate lighting // available light is calculated and split between directly (diffusely/specularly) lit and ambiently lit const std::vector<Camera::LightSource> &lightSources = camera->GetLightSources(); double ambient, intensity; CalcLighting(planet, ambient, intensity, lightSources); std::vector<Graphics::Light> origLights, newLights; for(size_t i = 0; i < lightSources.size(); i++) { Graphics::Light light(lightSources[i].GetLight()); origLights.push_back(light); Color c = light.GetDiffuse(); Color ca = light.GetAmbient(); Color cs = light.GetSpecular(); ca.r = c.r * float(ambient); ca.g = c.g * float(ambient); ca.b = c.b * float(ambient); c.r*=float(intensity); c.g*=float(intensity); c.b*=float(intensity); cs.r*=float(intensity); cs.g*=float(intensity); cs.b*=float(intensity); light.SetDiffuse(c); light.SetAmbient(ca); light.SetSpecular(cs); newLights.push_back(light); } r->SetLights(newLights.size(), &newLights[0]); double overallLighting = ambient+intensity; // turn off global ambient color const Color oldAmbient = r->GetAmbientColor(); r->SetAmbientColor(Color::BLACK); // as the camera gets close adjust scene ambient so that intensity+ambient = minIllumination double fadeInEnd, fadeInLength, minIllumination; if (Graphics::AreShadersEnabled()) { minIllumination = 0.125; fadeInEnd = 800.0; fadeInLength = 2000.0; } else { minIllumination = 0.25; fadeInEnd = 1500.0; fadeInLength = 3000.0; } /* don't render city if too far away */ if (viewCoords.Length() < 1000000.0){ r->SetAmbientColor(Color::BLACK); if (!m_adjacentCity) { m_adjacentCity = new CityOnPlanet(planet, this, m_sbody->seed); } m_adjacentCity->Render(r, camera, this, viewCoords, viewTransform, overallLighting, minIllumination); } r->SetAmbientColor(Color::BLACK); FadeInModelIfDark(r, GetCollMesh()->GetBoundingRadius(), viewCoords.Length(), fadeInEnd, fadeInLength, overallLighting, minIllumination); RenderLmrModel(r, viewCoords, viewTransform); // restore old lights r->SetLights(origLights.size(), &origLights[0]); // restore old ambient color r->SetAmbientColor(oldAmbient); } }