Lighting.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright © 2010 James Legg.
00006     This program is free software: you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation, either version 3 of the License, or
00009     (at your option) any later version.
00010 */
00011 
00012 #include "Lighting.h"
00013 
00014 #include <GL/gl.h>
00015 
00016 #include "stream_loader.h"
00017 #include "FormErrors.h"
00018 
00019 namespace Track
00020 {
00021 
00022 const unsigned int lighting_newest_version = 1;
00023 const unsigned int fog_settings_newest_version = 1;
00024 const unsigned int light_settings_newest_version = 1;
00025 
00026 FogSettings::FogSettings()
00027     :   density(0.004)
00028     ,   enabled(true)
00029 {
00030     const float default_fog_colour[4] = {0.3, 0.0, 0.1, 1.0};
00031     for (int i = 0; i < 4; i++)
00032     {
00033         colour[i] = default_fog_colour[i];
00034     }
00035 }
00036 
00037 FogSettings::FogSettings(std::istream & in)
00038 {
00039     unsigned int file_version;
00040     in >> file_version;
00041     if (file_version == 0) throw CorruptedError();
00042     if (file_version > fog_settings_newest_version) throw NewVersionError();
00043     in >> density >>
00044           colour[0] >> colour[1] >> colour[2] >> colour[3] >>
00045           enabled;
00046 }
00047 
00048 bool FogSettings::operator != (const FogSettings & other) const
00049 {
00050     if (enabled != other.enabled) return true;
00051     if (density != other.density) return true;
00052     for (int i = 0; i < 4; i++)
00053     {
00054         if (colour[i] != other.colour[i]) return true;
00055     }
00056     return false;
00057 }
00058 
00059 std::ostream & operator<<(std::ostream & dest, const FogSettings & fog)
00060 {
00061     dest << fog_settings_newest_version << ' ' <<
00062             fog.density << ' ' <<
00063             fog.colour[0] << ' ' << fog.colour[1] << ' ' <<
00064             fog.colour[2] << ' ' << fog.colour[3] << ' ' <<
00065             fog.enabled;
00066     return dest;
00067 }
00068 
00069 LightSettings::LightSettings()
00070 {
00071 }
00072 
00073 LightSettings::LightSettings(std::istream & in)
00074 {
00075     unsigned int file_version;
00076     in >> file_version;
00077     if (file_version == 0) throw CorruptedError();
00078     if (file_version > light_settings_newest_version) throw NewVersionError();
00079     in >> position[0] >> position[1] >> position[2] >> position[3] >>
00080           colour[0] >> colour[1] >> colour[2] >> colour[3];
00081 }
00082 
00083 bool LightSettings::operator == (const LightSettings & other) const
00084 {
00085     for (int i = 0; i < 4; i++)
00086     {
00087         if (position[i] != other.position[i]) return false;
00088         if (colour[i] != other.colour[i]) return false;
00089     }
00090     return true;
00091 }
00092 
00093 std::ostream & operator<<(std::ostream & dest, const LightSettings & ls)
00094 {
00095     dest << light_settings_newest_version << ' ' <<
00096             ls.position[0] << ' ' << ls.position[1] << ' ' <<
00097             ls.position[2] << ' ' << ls.position[3] << ' ' <<
00098             ls.colour[0]   << ' ' << ls.colour[1]   << ' ' <<
00099             ls.colour[2]   << ' ' << ls.colour[3];
00100     return dest;
00101 }
00102 
00103 Lighting::Lighting()
00104 {
00105     m_lights.resize(2);
00106     const float l0p[4] = {0.0, 0.0, 1.0, 0.0};
00107     const float l0c[4] = {0.4, 0.4, 0.4, 1.0};
00108     const float l1p[4] = {1.0, 0.0, 0.0, 0.0};
00109     const float l1c[4] = {0.4, 0.2, 0.1, 1.0};
00110     const float amb[4] = {0.6, 0.6, 0.6, 1.0};
00111     for (int i = 0; i < 4; i++)
00112     {
00113         m_lights[0].position[i] = l0p[i];
00114         m_lights[0].colour[i] = l0c[i];
00115         m_lights[1].position[i] = l1p[i];
00116         m_lights[1].colour[i] = l1c[i];
00117         m_ambient_light[i] = amb[i];
00118     }
00119     
00120 }
00121 
00122 Lighting::Lighting(std::istream & in)
00123 {
00124     unsigned int file_version;
00125     in >> file_version;
00126     if (file_version == 0) throw CorruptedError();
00127     if (file_version > lighting_newest_version) throw NewVersionError();
00128     m_fog = FogSettings(in);
00129     in >> m_ambient_light[0] >> m_ambient_light[1] >>
00130           m_ambient_light[2] >> m_ambient_light[3];
00131     unsigned int m_num_lights;
00132     in >> m_num_lights;
00133     if (m_num_lights > 8) throw CorruptedError();
00134     m_lights.resize(m_num_lights);
00135     for (int i = 0; i < m_num_lights; i++)
00136     {
00137         m_lights[i]= LightSettings(in);
00138     }
00139 }
00140 
00141 void Lighting::initalise() const
00142 {
00143     // lights
00144     for (unsigned int i = 0; i < m_lights.size(); i++)
00145     {
00146         glEnable(GL_LIGHT0 + i);
00147         glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, m_lights[i].colour);
00148     }
00149     // disable unused lights that could have activated from a previous game.
00150     for (unsigned int i = m_lights.size(); i < 8; i++)
00151     {
00152         glDisable(GL_LIGHT0+i);
00153     }
00154     // ambient light
00155     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, m_ambient_light);
00156     // only reflects a fith of the ambient light and 4 fiths of diffuse light
00157     // by default. Use all light.
00158     GLfloat light_scale[4] = {1.0, 1.0, 1.0, 1.0};
00159     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, light_scale);
00160     
00161     // fog
00162     glFogf(GL_FOG_MODE, GL_EXP2);
00163     glFogf(GL_FOG_DENSITY, m_fog.density);
00164     glFogfv(GL_FOG_COLOR, m_fog.colour);
00165     if (m_fog.enabled) glEnable(GL_FOG); else
00166                      glDisable(GL_FOG);
00167 }
00168 
00169 void Lighting::prepare_render() const
00170 {
00171     glEnable(GL_LIGHTING);
00172     if (m_fog.enabled) glEnable(GL_FOG); else
00173                      glDisable(GL_FOG);
00174     for (unsigned int i = 0; i < m_lights.size(); i++)
00175     {
00176         glLightfv(GL_LIGHT0 + i, GL_POSITION, m_lights[i].position);
00177     }
00178 }
00179 
00180 void Lighting::set_lights(const std::vector<LightSettings> & lights)
00181 {
00182     m_lights = lights;
00183 }
00184 
00185 const std::vector<LightSettings> & Lighting::get_lights() const
00186 {
00187     return m_lights;
00188 }
00189 
00190 void Lighting::set_ambient(float colour[4])
00191 {
00192     for (int i = 0; i < 4; i++)
00193     {
00194         m_ambient_light[i] = colour[i];
00195     }
00196 }
00197 
00198 const float * Lighting::get_ambient_light() const
00199 {
00200     return m_ambient_light;
00201 }
00202 
00203 void Lighting::set_fog(const FogSettings & fog)
00204 {
00205     m_fog = fog;
00206 }
00207 
00208 const FogSettings & Lighting::get_fog() const
00209 {
00210     return m_fog;
00211 }
00212 
00213 bool Lighting::operator!=(const Lighting & other) const
00214 {
00215     if (m_lights != other.m_lights) return true;
00216     if (m_fog != other.m_fog) return true;
00217     for (int i = 0; i < 4; i++)
00218     {
00219         if (m_ambient_light[i] != other.m_ambient_light[i]) return true;
00220     }
00221     return false;
00222 }
00223 
00224 std::ostream & operator<<(std::ostream & dest, const Lighting & lighting)
00225 {
00226     const float * amb = lighting.get_ambient_light();
00227     dest << lighting_newest_version << ' ' <<
00228             lighting.get_fog() << ' ' <<
00229             amb[0] << ' ' << amb[1] << ' ' << amb[2] << ' ' << amb[3] << ' ';
00230     const std::vector<LightSettings> & lights = lighting.get_lights();
00231     dest << lights.size();
00232     for (int i = 0; i < lights.size(); i++)
00233     {
00234         dest << ' ' << lights[i];
00235     }
00236     return dest;
00237 }
00238 
00239 } // namespace Track.

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.