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.
Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.