1 /* 2 * This file is part of the Colobot: Gold Edition source code 3 * Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam 4 * http://epsitec.ch; http://colobot.info; http://github.com/colobot 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14 * See the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see http://gnu.org/licenses 18 */ 19 20 /** 21 * \file graphics/engine/lightman.h 22 * \brief Dynamic light manager - CLightManager class 23 */ 24 25 #pragma once 26 27 #include "graphics/core/light.h" 28 29 #include "graphics/engine/engine.h" 30 31 #include "math/vector.h" 32 33 34 // Graphics module namespace 35 namespace Gfx 36 { 37 38 struct Color; 39 40 /** 41 * \struct LightProgression 42 * \brief Describes the progression of light parameters change 43 */ 44 struct LightProgression 45 { 46 //! Starting value 47 float starting; 48 //! Ending (destination) value 49 float ending; 50 //! Current value 51 float current; 52 //! Progress from start to end 53 float progress; 54 //! Speed of progression 55 float speed; 56 LightProgressionLightProgression57 LightProgression() 58 : starting(0.0f) 59 , ending(0.0f) 60 , current(0.0f) 61 , progress(0.0f) 62 , speed(0.0f) 63 {} 64 65 //! Initializes the progression 66 void Init(float value); 67 68 //! Updates the progression 69 void Update(float rTime); 70 71 //! Sets the new end value (starting is set to current) 72 void SetTarget(float value); 73 }; 74 75 /** 76 * \enum LightPriority 77 * \brief Priority in light assignment 78 */ 79 enum LightPriority 80 { 81 LIGHT_PRI_HIGHEST = 0, //!< always highest weight (always picked) 82 LIGHT_PRI_HIGH = 1, //!< high weight 83 LIGHT_PRI_LOW = 2 //!< low weight 84 }; 85 86 /** 87 * \struct DynamicLight 88 * \brief Dynamic light in 3D scene 89 * 90 * It is an extension over standard light properties. Added are dynamic progressions for light 91 * colors and intensity and types of objects included/excluded in lighting. 92 */ 93 struct DynamicLight 94 { 95 //! Rank (index) 96 int rank; 97 98 //! Whether the light is used 99 bool used; 100 //! Whether the light is turned on 101 bool enabled; 102 103 //! Priority in assignment 104 LightPriority priority; 105 106 //! Configuration of the light 107 Light light; 108 109 //! Progression of intensity [0, 1] 110 LightProgression intensity; 111 //! Progression of red diffuse color 112 LightProgression colorRed; 113 //! Progression of green diffuse color 114 LightProgression colorGreen; 115 //! Progression of blue diffuse color 116 LightProgression colorBlue; 117 118 //! Type of objects included in lighting with this light; if ENG_OBJTYPE_NULL is used, it is ignored 119 EngineObjectType includeType; 120 //! Type of objects excluded from lighting with this light; if ENG_OBJTYPE_NULL is used, it is ignored 121 EngineObjectType excludeType; 122 DynamicLightDynamicLight123 DynamicLight() 124 : rank(0) 125 , used(false) 126 , enabled(false) 127 , priority(LIGHT_PRI_LOW) 128 , includeType(ENG_OBJTYPE_NULL) 129 , excludeType(ENG_OBJTYPE_NULL) 130 {} 131 }; 132 133 /** 134 * \class CLightManager 135 * \brief Manager for dynamic lights in 3D scene 136 * 137 * The class is responsible for managing dynamic lights (struct DynamicLight) used in 3D scene. 138 * The dynamic lights are created, updated and deleted through the class' interface. 139 * 140 * Since there is a limit on total number of lights available in OpenGL (usually up to 8), the dynamic lights 141 * must be emulated by displaying only some of them. All functions normally operate only on DynamicLight structs, 142 * updating the models with new values, while only one function, UpdateDeviceLights(), performs the actual 143 * synchronization to the device. It allocates device's light slots as necessary, with two priority levels 144 * for lights. 145 */ 146 class CLightManager 147 { 148 public: 149 //! Constructor 150 CLightManager(CEngine* engine); 151 //! Destructor 152 virtual ~CLightManager(); 153 154 //! Sets the device to be used 155 void SetDevice(CDevice* device); 156 157 //! Prints debug info 158 void DebugDumpLights(); 159 160 //! Clears and disables all lights 161 void FlushLights(); 162 //! Creates a new dynamic light and returns its index (lightRank) 163 int CreateLight(LightPriority priority = LIGHT_PRI_LOW); 164 //! Deletes and disables the given dynamic light 165 bool DeleteLight(int lightRank); 166 //! Sets the light parameters for dynamic light 167 bool SetLight(int lightRank, const Light &light); 168 //! Returns the light parameters for given dynamic light 169 bool GetLight(int lightRank, Light &light); 170 //! Enables/disables the given dynamic light 171 bool SetLightEnabled(int lightRank, bool enabled); 172 //! Changes the light priority 173 bool SetLightPriority(int lightRank, LightPriority priority); 174 175 //! Sets what objects are included in given dynamic light 176 bool SetLightIncludeType(int lightRank, EngineObjectType type); 177 //! Sets what objects are excluded from given dynamic light 178 bool SetLightExcludeType(int lightRank, EngineObjectType type); 179 180 //! Sets the position of dynamic light 181 bool SetLightPos(int lightRank, const Math::Vector &pos); 182 //! Returns the position of dynamic light 183 Math::Vector GetLightPos(int lightRank); 184 185 //! Sets the direction of dynamic light 186 bool SetLightDir(int lightRank, const Math::Vector &dir); 187 //! Returns the direction of dynamic light 188 Math::Vector GetLightDir(int lightRank); 189 190 //! Sets the destination intensity for dynamic light's intensity progression 191 bool SetLightIntensity(int lightRank, float value); 192 //! Returns the current light intensity 193 float GetLightIntensity(int lightRank); 194 //! Sets the rate of change for dynamic light intensity 195 bool SetLightIntensitySpeed(int lightRank, float speed); 196 197 //! Adjusts the color of all dynamic lights 198 void AdaptLightColor(const Color &color, float factor); 199 200 //! Sets the destination color for dynamic light's color progression 201 bool SetLightColor(int lightRank, const Color &color); 202 //! Returns current light color 203 Color GetLightColor(int lightRank); 204 //! Sets the rate of change for dynamic light colors (RGB) 205 bool SetLightColorSpeed(int lightRank, float speed); 206 207 //! Updates progression of dynamic lights 208 void UpdateProgression(float rTime); 209 //! Updates (recalculates) all dynamic lights 210 void UpdateLights(); 211 //! Enables or disables dynamic lights affecting the given object type 212 void UpdateDeviceLights(EngineObjectType type); 213 214 protected: 215 class CLightsComparator 216 { 217 public: 218 CLightsComparator(Math::Vector eyePos, EngineObjectType objectType); 219 220 bool operator()(const DynamicLight& left, const DynamicLight& right); 221 222 private: 223 float GetLightWeight(const DynamicLight& dynLight); 224 225 Math::Vector m_eyePos; 226 EngineObjectType m_objectType; 227 }; 228 229 protected: 230 CEngine* m_engine; 231 CDevice* m_device; 232 233 //! Current time 234 float m_time; 235 //! List of dynamic lights 236 std::vector<DynamicLight> m_dynLights; 237 //! Map of current light allocation: graphics light -> dynamic light 238 std::vector<int> m_lightMap; 239 }; 240 241 } // namespace Gfx 242 243