123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- //---------------------------------------------------------------------------
- //
- // Clouds.cpp -- File contains class definitions for the Clouds
- //
- // MechCommander 2
- //
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //---------------------------------------------------------------------------
- // Include Files
- #ifndef CLOUDS_H
- #include "clouds.h"
- #endif
- #ifndef TXMMGR_H
- #include "txmmgr.h"
- #endif
- #ifndef CIDENT_H
- #include "cident.h"
- #endif
- #ifndef PATHS_H
- #include "paths.h"
- #endif
- #ifndef CAMERA_H
- #include "camera.h"
- #endif
- #ifndef CLIP_H
- #include "clip.h"
- #endif
- #ifndef TIMING_H
- #include "timing.h"
- #endif
- //---------------------------------------------------------------------------
- // Macro Definitions
- #define MAX_CLOUDS_ANGLE 45.0f
- #define MAX_CLOUDS_SIZE 4500.0f
- #define MAX_UV_REPEAT 4.0f
- #define CLOUD_START_U -2.0f
- #define CLOUD_START_V -2.0f
- #define CLOUD_ALTITUDE 200.0f
- #define SCROLL_U_FACTOR 0.01f;
- #define SCROLL_V_FACTOR 0.01f;
- //----------------------------------------
- // Externs
- extern bool useFog;
- extern bool hasGuardBand;
- //---------------------------------------------------------------------------
- // Class Clouds
- void Clouds::init (char *textureName, long gSize)
- {
- FullPathFileName cloudName;
- cloudName.init(texturePath,textureName,".tga");
-
- //-------------------------------------
- // Load Texture here.
- mcTextureNodeIndex = mcTextureManager->loadTexture(cloudName,gos_Texture_Alpha,/*gosHint_DisableMipmap |*/ gosHint_DontShrink);
-
- //-------------------------------------
- // Create the CloudVertices here.
- gridSize = gSize;
- long gridTotal = gridSize * gridSize;
- cloudVertices = (CloudVertexPtr)systemHeap->Malloc(sizeof(CloudVertex)*gridTotal);
- gosASSERT(cloudVertices != NULL);
-
- memset(cloudVertices,0,sizeof(CloudVertex)*gridTotal);
- }
-
- //---------------------------------------------------------------------------
- void Clouds::update (void)
- {
- renderClouds = false;
-
- scrollU += frameLength * SCROLL_U_FACTOR;
- scrollV += frameLength * SCROLL_V_FACTOR;
- if (scrollU > 1.0f)
- scrollU -= 1.0f;
-
- if (scrollV > 1.0f)
- scrollV -= 1.0f;
-
- if (scrollU < -1.0f)
- scrollU += 1.0f;
-
- if (scrollV < -1.0f)
- scrollV += 1.0f;
-
- //---------------------------------------------------------------------
- // If projectionAngle is less then some magic number, draw the clouds.
- // Otherwise, do not do anything!
- if (eye->active && eye->usePerspective && (eye->getProjectionAngle() < MAX_CLOUDS_ANGLE))
- {
- //renderClouds = true;
-
- //-------------------------------------------------------
- // Create the cloud grid based on camera CENTER position.
- Stuff::Vector3D centerPosition(eye->getPosition());
-
- //-------------------------------------------------------
- // Create a topLeft vertex
- float tLeftX = centerPosition.x + MAX_CLOUDS_SIZE;
- float tLeftY = centerPosition.y + MAX_CLOUDS_SIZE;
-
- //-------------------------------------------------------
- // Create the grid.
- long cloudInc = float2long(MAX_CLOUDS_SIZE * 2.0f / gridSize);
- float uvInc = MAX_UV_REPEAT / float(gridSize);
-
- for (long y=0;y<gridSize;y++)
- {
- for (long x=0;x<gridSize;x++)
- {
- cloudVertices[x + (y*gridSize)].vx = tLeftX - (cloudInc * x);
- cloudVertices[x + (y*gridSize)].vy = tLeftY - (cloudInc * y);
-
- cloudVertices[x + (y*gridSize)].pu = CLOUD_START_U + (uvInc * x);
- cloudVertices[x + (y*gridSize)].pv = CLOUD_START_V + (uvInc * y);
- }
- }
-
- //-------------------------------------------------------
- // Transform Grid
- long gridTotal = gridSize * gridSize;
- for (long i=0;i<gridTotal;i++)
- {
- //----------------------------------------------------------------------------------------
- // Figure out if we are in front of camera or not. Should be faster then actual project!
- // Should weed out VAST overwhelming majority of vertices!
- bool onScreen = true;
-
- //-----------------------------------------------------------------
- // Find angle between lookVector of Camera and vector from camPos
- // to Target. If angle is less then halfFOV, object is visible.
-
- //-------------------------------------------------------------------
- // Then figure out if FarClipped. Should weed out a boatload more!
- float hazeFactor = 0.0f;
- Stuff::Point3D Distance;
- Stuff::Point3D vPosition;
- Stuff::Point3D eyePosition(eye->getPosition());
- vPosition.x = cloudVertices[i].vx;;
- vPosition.y = cloudVertices[i].vy;
- vPosition.z = centerPosition.z;
-
- Distance.Subtract(eyePosition,vPosition);
- float eyeDistance = Distance.GetApproximateLength();
- if (eyeDistance > Camera::MaxClipDistance)
- {
- hazeFactor = 1.0f;
- //onScreen = false;
- }
- else if (eyeDistance > Camera::MinHazeDistance)
- {
- hazeFactor = (eyeDistance - Camera::MinHazeDistance) * Camera::DistanceFactor;
- }
- else
- {
- hazeFactor = 0.0f;
- }
-
- //------------------------------------------------------------
- // Calculate the HazeDWORD here
- if (hazeFactor != 0.0f)
- {
- float fogFactor = 1.0 - hazeFactor;
- DWORD distFog = float2long(fogFactor * 255.0f);
-
- cloudVertices[i].fogRGB = (distFog<<24) + (0xffffff);
- }
- else
- {
- cloudVertices[i].fogRGB = 0xffffffff;
- }
-
- if (onScreen)
- {
- Stuff::Vector3D Distance;
- Stuff::Point3D objPosition;
- Stuff::Point3D eyePosition(eye->getCameraOrigin());
- objPosition.x = -cloudVertices[i].vx;
- objPosition.y = CLOUD_ALTITUDE;
- objPosition.z = cloudVertices[i].vy;
-
- Distance.Subtract(objPosition,eyePosition);
- Distance.Normalize(Distance);
-
- float cosine = Distance * eye->getLookVector();
- if (cosine > eye->cosHalfFOV)
- onScreen = true;
- else
- onScreen = false;
- }
- else
- {
- hazeFactor = 1.0f;
- }
-
- Stuff::Vector3D vertex3D(cloudVertices[i].vx,cloudVertices[i].vy,(CLOUD_ALTITUDE+eye->getCameraOrigin().y));
- Stuff::Vector4D screenPos;
- bool inView = eye->projectZ(vertex3D,screenPos);
-
- cloudVertices[i].px = screenPos.x;
- cloudVertices[i].py = screenPos.y;
- cloudVertices[i].pz = screenPos.z;
- cloudVertices[i].pw = screenPos.w;
-
- //------------------------------------------------------------
- // Fix clip. Vertices can all be off screen and triangle
- // still needs to be drawn!
- cloudVertices[i].clipInfo = onScreen && inView;
-
- //------------------------------------------------------------
- // Still need to scrollUVs here!
- cloudVertices[i].pu += scrollU;
- cloudVertices[i].pv += scrollV;
- }
-
- for (y=0;y<(gridSize-1);y++)
- {
- for (long x=0;x<(gridSize-1);x++)
- {
- CloudVertexPtr cloudVertex0 = &(cloudVertices[x + (y *gridSize)]);
- CloudVertexPtr cloudVertex1 = &(cloudVertices[(x+1) + (y *gridSize)]);
- CloudVertexPtr cloudVertex2 = &(cloudVertices[(x+1) + ((y+1)*gridSize)]);
- CloudVertexPtr cloudVertex3 = &(cloudVertices[x + ((y+1)*gridSize)]);
-
- bool clipCheck = (cloudVertex0->clipInfo || cloudVertex1->clipInfo || cloudVertex2->clipInfo);
- if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
- (cloudVertex1->pz < 1.0f) && (cloudVertex1->pz > 0.0f) &&
- (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f)))
- {
- mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
- }
-
- clipCheck = (cloudVertex0->clipInfo || cloudVertex2->clipInfo || cloudVertex3->clipInfo);
- if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
- (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f) &&
- (cloudVertex3->pz < 1.0f) && (cloudVertex3->pz > 0.0f)))
- {
- mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
- }
- }
- }
- }
- }
- #define CLOUD_Z_VALUE 0.9900f
- //---------------------------------------------------------------------------
- void Clouds::render (void)
- {
- if (!renderClouds)
- return;
-
- for (long y=0;y<(gridSize-1);y++)
- {
- for (long x=0;x<(gridSize-1);x++)
- {
- CloudVertexPtr cloudVertex0 = &(cloudVertices[x + (y *gridSize)]);
- CloudVertexPtr cloudVertex1 = &(cloudVertices[(x+1) + (y *gridSize)]);
- CloudVertexPtr cloudVertex2 = &(cloudVertices[(x+1) + ((y+1)*gridSize)]);
- CloudVertexPtr cloudVertex3 = &(cloudVertices[x + ((y+1)*gridSize)]);
-
- gos_VERTEX gVertex[3];
- bool clipCheck = (cloudVertex0->clipInfo || cloudVertex1->clipInfo || cloudVertex2->clipInfo);
- if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
- (cloudVertex1->pz < 1.0f) && (cloudVertex1->pz > 0.0f) &&
- (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f)))
- {
- //--------------------------
- // Top Triangle
- gVertex[0].x = cloudVertex0->px;
- gVertex[0].y = cloudVertex0->py;
- gVertex[0].z = CLOUD_Z_VALUE;
- gVertex[0].rhw = cloudVertex0->pw;
- gVertex[0].u = cloudVertex0->pu;
- gVertex[0].v = cloudVertex0->pv;
- gVertex[0].argb = cloudVertex0->fogRGB;
- gVertex[0].frgb = 0xff000000;
-
- gVertex[1].x = cloudVertex1->px;
- gVertex[1].y = cloudVertex1->py;
- gVertex[1].z = CLOUD_Z_VALUE;
- gVertex[1].rhw = cloudVertex1->pw;
- gVertex[1].u = cloudVertex1->pu;
- gVertex[1].v = cloudVertex1->pv;
- gVertex[1].argb = cloudVertex1->fogRGB;
- gVertex[1].frgb = 0xff000000;
-
- gVertex[2].x = cloudVertex2->px;
- gVertex[2].y = cloudVertex2->py;
- gVertex[2].z = CLOUD_Z_VALUE;
- gVertex[2].rhw = cloudVertex2->pw;
- gVertex[2].u = cloudVertex2->pu;
- gVertex[2].v = cloudVertex2->pv;
- gVertex[2].argb = cloudVertex2->fogRGB;
- gVertex[2].frgb = 0xff000000;
-
- mcTextureManager->addVertices(mcTextureNodeIndex,gVertex,MC2_DRAWALPHA);
- }
- clipCheck = (cloudVertex0->clipInfo || cloudVertex2->clipInfo || cloudVertex3->clipInfo);
- if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
- (cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f) &&
- (cloudVertex3->pz < 1.0f) && (cloudVertex3->pz > 0.0f)))
- {
- //--------------------------
- //Bottom Triangle
- //
- // gVertex[0] same as above gVertex[0].
- // gVertex[1] is same as above gVertex[2].
- // gVertex[2] is calced from vertex[3].
- gVertex[0].x = cloudVertex0->px;
- gVertex[0].y = cloudVertex0->py;
- gVertex[0].z = CLOUD_Z_VALUE;
- gVertex[0].rhw = cloudVertex0->pw;
- gVertex[0].u = cloudVertex0->pu;
- gVertex[0].v = cloudVertex0->pv;
- gVertex[0].argb = cloudVertex0->fogRGB;
- gVertex[0].frgb = 0xff000000;
-
- gVertex[1].x = cloudVertex2->px;
- gVertex[1].y = cloudVertex2->py;
- gVertex[1].z = CLOUD_Z_VALUE;
- gVertex[1].rhw = cloudVertex2->pw;
- gVertex[1].u = cloudVertex2->pu;
- gVertex[1].v = cloudVertex2->pv;
- gVertex[1].argb = cloudVertex2->fogRGB;
- gVertex[1].frgb = 0xff000000;
-
- gVertex[2].x = cloudVertex3->px;
- gVertex[2].y = cloudVertex3->py;
- gVertex[2].z = CLOUD_Z_VALUE;
- gVertex[2].rhw = cloudVertex3->pw;
- gVertex[2].u = cloudVertex3->pu;
- gVertex[2].v = cloudVertex3->pv;
- gVertex[2].argb = cloudVertex3->fogRGB;
- gVertex[2].frgb = 0xff000000;
-
- mcTextureManager->addVertices(mcTextureNodeIndex,gVertex,MC2_DRAWALPHA);
- }
- }
- }
- }
- //---------------------------------------------------------------------------
- void Clouds::destroy (void)
- {
- systemHeap->Free(cloudVertices);
- cloudVertices = NULL;
- }
- //---------------------------------------------------------------------------
- //---------------------------------------------------------------------------
- //
- // Edit Log
- //
- //---------------------------------------------------------------------------
|