MLRPointLight.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "MLRHeaders.hpp"
  5. //#############################################################################
  6. //########################### MLRPointLight #############################
  7. //#############################################################################
  8. MLRPointLight::ClassData*
  9. MLRPointLight::DefaultData = NULL;
  10. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  11. //
  12. void
  13. MLRPointLight::InitializeClass()
  14. {
  15. Verify(!DefaultData);
  16. Verify(gos_GetCurrentHeap() == StaticHeap);
  17. DefaultData =
  18. new ClassData(
  19. MLRPointLightClassID,
  20. "MidLevelRenderer::MLRPointLight",
  21. MLRInfiniteLightWithFalloff::DefaultData
  22. );
  23. Register_Object(DefaultData);
  24. }
  25. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  26. //
  27. void
  28. MLRPointLight::TerminateClass()
  29. {
  30. Unregister_Object(DefaultData);
  31. delete DefaultData;
  32. DefaultData = NULL;
  33. }
  34. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  35. //
  36. MLRPointLight::MLRPointLight() :
  37. MLRInfiniteLightWithFalloff(DefaultData)
  38. {
  39. Verify(gos_GetCurrentHeap() == Heap);
  40. lightMap = NULL;
  41. }
  42. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  43. //
  44. MLRPointLight::MLRPointLight(
  45. Stuff::MemoryStream *stream,
  46. int version
  47. ) :
  48. MLRInfiniteLightWithFalloff(DefaultData, stream, version)
  49. {
  50. Check_Object(stream);
  51. Verify(gos_GetCurrentHeap() == Heap);
  52. lightMap = NULL;
  53. if (version > 7)
  54. {
  55. MString name;
  56. *stream >> name;
  57. if (name.GetLength() > 0)
  58. {
  59. Check_Object(MLRTexturePool::Instance);
  60. MLRTexture *texture = (*MLRTexturePool::Instance)(name, 0);
  61. if (!texture)
  62. texture = MLRTexturePool::Instance->Add(name, 0);
  63. Check_Object(texture);
  64. lightMap = new MLRLightMap(texture);
  65. Check_Object(lightMap);
  66. lightMask |= MLRState::LightMapLightingMode;
  67. }
  68. }
  69. }
  70. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  71. //
  72. MLRPointLight::MLRPointLight(Stuff::Page *page):
  73. MLRInfiniteLightWithFalloff(DefaultData, page)
  74. {
  75. Check_Object(page);
  76. Verify(gos_GetCurrentHeap() == Heap);
  77. lightMap = NULL;
  78. const char* lightmap;
  79. if (page->GetEntry("LightMap", &lightmap))
  80. {
  81. Check_Pointer(lightmap);
  82. Check_Object(MLRTexturePool::Instance);
  83. MLRTexture *texture = (*MLRTexturePool::Instance)(lightmap, 0);
  84. if (!texture)
  85. texture = MLRTexturePool::Instance->Add(lightmap, 0);
  86. Check_Object(texture);
  87. lightMap = new MLRLightMap(texture);
  88. Check_Object(lightMap);
  89. lightMask |= MLRState::LightMapLightingMode;
  90. }
  91. }
  92. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  93. //
  94. MLRPointLight::~MLRPointLight()
  95. {
  96. if (lightMap)
  97. {
  98. Check_Object(lightMap);
  99. delete lightMap;
  100. }
  101. }
  102. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  103. //
  104. void
  105. MLRPointLight::Save(Stuff::MemoryStream *stream)
  106. {
  107. Check_Object(this);
  108. Check_Object(stream);
  109. MLRInfiniteLightWithFalloff::Save(stream);
  110. if (lightMap)
  111. {
  112. Check_Object(lightMap);
  113. unsigned handle = lightMap->GetState().GetTextureHandle();
  114. MLRTexture *texture = (*MLRTexturePool::Instance)[handle];
  115. Check_Object(texture);
  116. MString name = texture->GetTextureName();
  117. *stream << name;
  118. }
  119. else
  120. *stream << MString("");
  121. }
  122. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  123. //
  124. void
  125. MLRPointLight::Write(Stuff::Page *page)
  126. {
  127. Check_Object(this);
  128. Check_Object(page);
  129. MLRInfiniteLightWithFalloff::Write(page);
  130. if (lightMap)
  131. {
  132. Check_Object(lightMap);
  133. unsigned handle = lightMap->GetState().GetTextureHandle();
  134. MLRTexture *texture = (*MLRTexturePool::Instance)[handle];
  135. Check_Object(texture);
  136. page->SetEntry("LightMap", texture->GetTextureName());
  137. }
  138. }
  139. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  140. //
  141. void
  142. MLRPointLight::TestInstance()
  143. {
  144. Verify(IsDerivedFrom(DefaultData));
  145. }
  146. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. //
  148. void
  149. MLRPointLight::LightVertex(const MLRVertexData& vertexData)
  150. {
  151. UnitVector3D light_z;
  152. RGBColor light_color(color);
  153. Point3D vertex_to_light;
  154. Verify(GetFalloffDistance(vertex_to_light.x, vertex_to_light.y));
  155. GetInShapePosition(vertex_to_light);
  156. vertex_to_light -= *vertexData.point;
  157. //
  158. //--------------------------------------------------------------
  159. // If the distance to the vertex is zero, the light will not
  160. // contribute to the vertex coloration. Otherwise, decrease the
  161. // light level as appropriate to the distance
  162. //--------------------------------------------------------------
  163. //
  164. Scalar length = vertex_to_light.GetApproximateLength();
  165. Scalar falloff = 1.0f;
  166. if(GetFalloff(length, falloff))
  167. {
  168. light_color.red *= falloff;
  169. light_color.green *= falloff;
  170. light_color.blue *= falloff;
  171. }
  172. else
  173. {
  174. return;
  175. }
  176. length = -1.0f / length;
  177. light_z.Vector3D::Multiply(vertex_to_light, length);
  178. //
  179. //-------------------------------------------------------------------
  180. // Now we reduce the light level falling on the vertex based upon the
  181. // cosine of the angle between light and normal
  182. //-------------------------------------------------------------------
  183. //
  184. Scalar cosine = -(light_z * (*vertexData.normal)) * intensity;
  185. #if COLOR_AS_DWORD
  186. #else
  187. if (cosine > SMALL)
  188. {
  189. light_color.red *= cosine;
  190. light_color.green *= cosine;
  191. light_color.blue *= cosine;
  192. vertexData.color->red += light_color.red;
  193. vertexData.color->green += light_color.green;
  194. vertexData.color->blue += light_color.blue;
  195. }
  196. #endif
  197. }
  198. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  199. //
  200. void
  201. MLRPointLight::SetLightMap(MLRLightMap *light_map)
  202. {
  203. Check_Object(this);
  204. if (lightMap)
  205. {
  206. Check_Object(lightMap);
  207. delete lightMap;
  208. }
  209. lightMap = light_map;
  210. if (lightMap == NULL)
  211. {
  212. lightMask &= ~MLRState::LightMapLightingMode;
  213. }
  214. else
  215. {
  216. Check_Object(light_map);
  217. lightMask |= MLRState::LightMapLightingMode;
  218. }
  219. }