clouds.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. //---------------------------------------------------------------------------
  2. //
  3. // Clouds.cpp -- File contains class definitions for the Clouds
  4. //
  5. // MechCommander 2
  6. //
  7. //---------------------------------------------------------------------------//
  8. // Copyright (C) Microsoft Corporation. All rights reserved. //
  9. //===========================================================================//
  10. //---------------------------------------------------------------------------
  11. // Include Files
  12. #ifndef CLOUDS_H
  13. #include "clouds.h"
  14. #endif
  15. #ifndef TXMMGR_H
  16. #include "txmmgr.h"
  17. #endif
  18. #ifndef CIDENT_H
  19. #include "cident.h"
  20. #endif
  21. #ifndef PATHS_H
  22. #include "paths.h"
  23. #endif
  24. #ifndef CAMERA_H
  25. #include "camera.h"
  26. #endif
  27. #ifndef CLIP_H
  28. #include "clip.h"
  29. #endif
  30. #ifndef TIMING_H
  31. #include "timing.h"
  32. #endif
  33. //---------------------------------------------------------------------------
  34. // Macro Definitions
  35. #define MAX_CLOUDS_ANGLE 45.0f
  36. #define MAX_CLOUDS_SIZE 4500.0f
  37. #define MAX_UV_REPEAT 4.0f
  38. #define CLOUD_START_U -2.0f
  39. #define CLOUD_START_V -2.0f
  40. #define CLOUD_ALTITUDE 200.0f
  41. #define SCROLL_U_FACTOR 0.01f;
  42. #define SCROLL_V_FACTOR 0.01f;
  43. //----------------------------------------
  44. // Externs
  45. extern bool useFog;
  46. extern bool hasGuardBand;
  47. //---------------------------------------------------------------------------
  48. // Class Clouds
  49. void Clouds::init (char *textureName, long gSize)
  50. {
  51. FullPathFileName cloudName;
  52. cloudName.init(texturePath,textureName,".tga");
  53. //-------------------------------------
  54. // Load Texture here.
  55. mcTextureNodeIndex = mcTextureManager->loadTexture(cloudName,gos_Texture_Alpha,/*gosHint_DisableMipmap |*/ gosHint_DontShrink);
  56. //-------------------------------------
  57. // Create the CloudVertices here.
  58. gridSize = gSize;
  59. long gridTotal = gridSize * gridSize;
  60. cloudVertices = (CloudVertexPtr)systemHeap->Malloc(sizeof(CloudVertex)*gridTotal);
  61. gosASSERT(cloudVertices != NULL);
  62. memset(cloudVertices,0,sizeof(CloudVertex)*gridTotal);
  63. }
  64. //---------------------------------------------------------------------------
  65. void Clouds::update (void)
  66. {
  67. renderClouds = false;
  68. scrollU += frameLength * SCROLL_U_FACTOR;
  69. scrollV += frameLength * SCROLL_V_FACTOR;
  70. if (scrollU > 1.0f)
  71. scrollU -= 1.0f;
  72. if (scrollV > 1.0f)
  73. scrollV -= 1.0f;
  74. if (scrollU < -1.0f)
  75. scrollU += 1.0f;
  76. if (scrollV < -1.0f)
  77. scrollV += 1.0f;
  78. //---------------------------------------------------------------------
  79. // If projectionAngle is less then some magic number, draw the clouds.
  80. // Otherwise, do not do anything!
  81. if (eye->active && eye->usePerspective && (eye->getProjectionAngle() < MAX_CLOUDS_ANGLE))
  82. {
  83. //renderClouds = true;
  84. //-------------------------------------------------------
  85. // Create the cloud grid based on camera CENTER position.
  86. Stuff::Vector3D centerPosition(eye->getPosition());
  87. //-------------------------------------------------------
  88. // Create a topLeft vertex
  89. float tLeftX = centerPosition.x + MAX_CLOUDS_SIZE;
  90. float tLeftY = centerPosition.y + MAX_CLOUDS_SIZE;
  91. //-------------------------------------------------------
  92. // Create the grid.
  93. long cloudInc = float2long(MAX_CLOUDS_SIZE * 2.0f / gridSize);
  94. float uvInc = MAX_UV_REPEAT / float(gridSize);
  95. for (long y=0;y<gridSize;y++)
  96. {
  97. for (long x=0;x<gridSize;x++)
  98. {
  99. cloudVertices[x + (y*gridSize)].vx = tLeftX - (cloudInc * x);
  100. cloudVertices[x + (y*gridSize)].vy = tLeftY - (cloudInc * y);
  101. cloudVertices[x + (y*gridSize)].pu = CLOUD_START_U + (uvInc * x);
  102. cloudVertices[x + (y*gridSize)].pv = CLOUD_START_V + (uvInc * y);
  103. }
  104. }
  105. //-------------------------------------------------------
  106. // Transform Grid
  107. long gridTotal = gridSize * gridSize;
  108. for (long i=0;i<gridTotal;i++)
  109. {
  110. //----------------------------------------------------------------------------------------
  111. // Figure out if we are in front of camera or not. Should be faster then actual project!
  112. // Should weed out VAST overwhelming majority of vertices!
  113. bool onScreen = true;
  114. //-----------------------------------------------------------------
  115. // Find angle between lookVector of Camera and vector from camPos
  116. // to Target. If angle is less then halfFOV, object is visible.
  117. //-------------------------------------------------------------------
  118. // Then figure out if FarClipped. Should weed out a boatload more!
  119. float hazeFactor = 0.0f;
  120. Stuff::Point3D Distance;
  121. Stuff::Point3D vPosition;
  122. Stuff::Point3D eyePosition(eye->getPosition());
  123. vPosition.x = cloudVertices[i].vx;;
  124. vPosition.y = cloudVertices[i].vy;
  125. vPosition.z = centerPosition.z;
  126. Distance.Subtract(eyePosition,vPosition);
  127. float eyeDistance = Distance.GetApproximateLength();
  128. if (eyeDistance > Camera::MaxClipDistance)
  129. {
  130. hazeFactor = 1.0f;
  131. //onScreen = false;
  132. }
  133. else if (eyeDistance > Camera::MinHazeDistance)
  134. {
  135. hazeFactor = (eyeDistance - Camera::MinHazeDistance) * Camera::DistanceFactor;
  136. }
  137. else
  138. {
  139. hazeFactor = 0.0f;
  140. }
  141. //------------------------------------------------------------
  142. // Calculate the HazeDWORD here
  143. if (hazeFactor != 0.0f)
  144. {
  145. float fogFactor = 1.0 - hazeFactor;
  146. DWORD distFog = float2long(fogFactor * 255.0f);
  147. cloudVertices[i].fogRGB = (distFog<<24) + (0xffffff);
  148. }
  149. else
  150. {
  151. cloudVertices[i].fogRGB = 0xffffffff;
  152. }
  153. if (onScreen)
  154. {
  155. Stuff::Vector3D Distance;
  156. Stuff::Point3D objPosition;
  157. Stuff::Point3D eyePosition(eye->getCameraOrigin());
  158. objPosition.x = -cloudVertices[i].vx;
  159. objPosition.y = CLOUD_ALTITUDE;
  160. objPosition.z = cloudVertices[i].vy;
  161. Distance.Subtract(objPosition,eyePosition);
  162. Distance.Normalize(Distance);
  163. float cosine = Distance * eye->getLookVector();
  164. if (cosine > eye->cosHalfFOV)
  165. onScreen = true;
  166. else
  167. onScreen = false;
  168. }
  169. else
  170. {
  171. hazeFactor = 1.0f;
  172. }
  173. Stuff::Vector3D vertex3D(cloudVertices[i].vx,cloudVertices[i].vy,(CLOUD_ALTITUDE+eye->getCameraOrigin().y));
  174. Stuff::Vector4D screenPos;
  175. bool inView = eye->projectZ(vertex3D,screenPos);
  176. cloudVertices[i].px = screenPos.x;
  177. cloudVertices[i].py = screenPos.y;
  178. cloudVertices[i].pz = screenPos.z;
  179. cloudVertices[i].pw = screenPos.w;
  180. //------------------------------------------------------------
  181. // Fix clip. Vertices can all be off screen and triangle
  182. // still needs to be drawn!
  183. cloudVertices[i].clipInfo = onScreen && inView;
  184. //------------------------------------------------------------
  185. // Still need to scrollUVs here!
  186. cloudVertices[i].pu += scrollU;
  187. cloudVertices[i].pv += scrollV;
  188. }
  189. for (y=0;y<(gridSize-1);y++)
  190. {
  191. for (long x=0;x<(gridSize-1);x++)
  192. {
  193. CloudVertexPtr cloudVertex0 = &(cloudVertices[x + (y *gridSize)]);
  194. CloudVertexPtr cloudVertex1 = &(cloudVertices[(x+1) + (y *gridSize)]);
  195. CloudVertexPtr cloudVertex2 = &(cloudVertices[(x+1) + ((y+1)*gridSize)]);
  196. CloudVertexPtr cloudVertex3 = &(cloudVertices[x + ((y+1)*gridSize)]);
  197. bool clipCheck = (cloudVertex0->clipInfo || cloudVertex1->clipInfo || cloudVertex2->clipInfo);
  198. if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
  199. (cloudVertex1->pz < 1.0f) && (cloudVertex1->pz > 0.0f) &&
  200. (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f)))
  201. {
  202. mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
  203. }
  204. clipCheck = (cloudVertex0->clipInfo || cloudVertex2->clipInfo || cloudVertex3->clipInfo);
  205. if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
  206. (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f) &&
  207. (cloudVertex3->pz < 1.0f) && (cloudVertex3->pz > 0.0f)))
  208. {
  209. mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
  210. }
  211. }
  212. }
  213. }
  214. }
  215. #define CLOUD_Z_VALUE 0.9900f
  216. //---------------------------------------------------------------------------
  217. void Clouds::render (void)
  218. {
  219. if (!renderClouds)
  220. return;
  221. for (long y=0;y<(gridSize-1);y++)
  222. {
  223. for (long x=0;x<(gridSize-1);x++)
  224. {
  225. CloudVertexPtr cloudVertex0 = &(cloudVertices[x + (y *gridSize)]);
  226. CloudVertexPtr cloudVertex1 = &(cloudVertices[(x+1) + (y *gridSize)]);
  227. CloudVertexPtr cloudVertex2 = &(cloudVertices[(x+1) + ((y+1)*gridSize)]);
  228. CloudVertexPtr cloudVertex3 = &(cloudVertices[x + ((y+1)*gridSize)]);
  229. gos_VERTEX gVertex[3];
  230. bool clipCheck = (cloudVertex0->clipInfo || cloudVertex1->clipInfo || cloudVertex2->clipInfo);
  231. if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
  232. (cloudVertex1->pz < 1.0f) && (cloudVertex1->pz > 0.0f) &&
  233. (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f)))
  234. {
  235. //--------------------------
  236. // Top Triangle
  237. gVertex[0].x = cloudVertex0->px;
  238. gVertex[0].y = cloudVertex0->py;
  239. gVertex[0].z = CLOUD_Z_VALUE;
  240. gVertex[0].rhw = cloudVertex0->pw;
  241. gVertex[0].u = cloudVertex0->pu;
  242. gVertex[0].v = cloudVertex0->pv;
  243. gVertex[0].argb = cloudVertex0->fogRGB;
  244. gVertex[0].frgb = 0xff000000;
  245. gVertex[1].x = cloudVertex1->px;
  246. gVertex[1].y = cloudVertex1->py;
  247. gVertex[1].z = CLOUD_Z_VALUE;
  248. gVertex[1].rhw = cloudVertex1->pw;
  249. gVertex[1].u = cloudVertex1->pu;
  250. gVertex[1].v = cloudVertex1->pv;
  251. gVertex[1].argb = cloudVertex1->fogRGB;
  252. gVertex[1].frgb = 0xff000000;
  253. gVertex[2].x = cloudVertex2->px;
  254. gVertex[2].y = cloudVertex2->py;
  255. gVertex[2].z = CLOUD_Z_VALUE;
  256. gVertex[2].rhw = cloudVertex2->pw;
  257. gVertex[2].u = cloudVertex2->pu;
  258. gVertex[2].v = cloudVertex2->pv;
  259. gVertex[2].argb = cloudVertex2->fogRGB;
  260. gVertex[2].frgb = 0xff000000;
  261. mcTextureManager->addVertices(mcTextureNodeIndex,gVertex,MC2_DRAWALPHA);
  262. }
  263. clipCheck = (cloudVertex0->clipInfo || cloudVertex2->clipInfo || cloudVertex3->clipInfo);
  264. if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
  265. (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f) &&
  266. (cloudVertex3->pz < 1.0f) && (cloudVertex3->pz > 0.0f)))
  267. {
  268. //--------------------------
  269. //Bottom Triangle
  270. //
  271. // gVertex[0] same as above gVertex[0].
  272. // gVertex[1] is same as above gVertex[2].
  273. // gVertex[2] is calced from vertex[3].
  274. gVertex[0].x = cloudVertex0->px;
  275. gVertex[0].y = cloudVertex0->py;
  276. gVertex[0].z = CLOUD_Z_VALUE;
  277. gVertex[0].rhw = cloudVertex0->pw;
  278. gVertex[0].u = cloudVertex0->pu;
  279. gVertex[0].v = cloudVertex0->pv;
  280. gVertex[0].argb = cloudVertex0->fogRGB;
  281. gVertex[0].frgb = 0xff000000;
  282. gVertex[1].x = cloudVertex2->px;
  283. gVertex[1].y = cloudVertex2->py;
  284. gVertex[1].z = CLOUD_Z_VALUE;
  285. gVertex[1].rhw = cloudVertex2->pw;
  286. gVertex[1].u = cloudVertex2->pu;
  287. gVertex[1].v = cloudVertex2->pv;
  288. gVertex[1].argb = cloudVertex2->fogRGB;
  289. gVertex[1].frgb = 0xff000000;
  290. gVertex[2].x = cloudVertex3->px;
  291. gVertex[2].y = cloudVertex3->py;
  292. gVertex[2].z = CLOUD_Z_VALUE;
  293. gVertex[2].rhw = cloudVertex3->pw;
  294. gVertex[2].u = cloudVertex3->pu;
  295. gVertex[2].v = cloudVertex3->pv;
  296. gVertex[2].argb = cloudVertex3->fogRGB;
  297. gVertex[2].frgb = 0xff000000;
  298. mcTextureManager->addVertices(mcTextureNodeIndex,gVertex,MC2_DRAWALPHA);
  299. }
  300. }
  301. }
  302. }
  303. //---------------------------------------------------------------------------
  304. void Clouds::destroy (void)
  305. {
  306. systemHeap->Free(cloudVertices);
  307. cloudVertices = NULL;
  308. }
  309. //---------------------------------------------------------------------------
  310. //---------------------------------------------------------------------------
  311. //
  312. // Edit Log
  313. //
  314. //---------------------------------------------------------------------------