123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625 |
- //---------------------------------------------------------------------------
- //
- // GameCam.h -- File contains the Game camera class definitions
- //
- // MechCommander 2
- //
- //---------------------------------------------------------------------------//
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- //===========================================================================//
- //---------------------------------------------------------------------------
- // Include Files
- #ifndef GAMECAM_H
- #include "gamecam.h"
- #endif
- #ifndef OBJMGR_H
- #include "objmgr.h"
- #endif
- #ifndef MOVER_H
- #include "mover.h"
- #endif
- #ifndef MISSION_H
- #include "mission.h"
- #endif
- #ifndef TEAM_H
- #include "team.h"
- #endif
- #ifndef COMNDR_H
- #include "comndr.h"
- #endif
- #ifndef WEATHER_H
- #include "weather.h"
- #endif
- #include <MLR\MLR.hpp>
- //---------------------------------------------------------------------------
- CameraPtr eye = NULL;
- extern bool useShadows;
- extern bool useFog;
- extern bool DisplayCameraAngle;
- extern MidLevelRenderer::MLRClipper * theClipper;
- #define MAX_SHADOW_PITCH_CHANGE (5.0f)
- extern bool drawOldWay;
- extern bool useNonWeaponEffects;
- GenericAppearance *theSky = NULL;
- //---------------------------------------------------------------------------
- void GameCamera::destroy (void)
- {
- if (theSky)
- {
- delete theSky;
- theSky = NULL;
- }
- if (compass)
- {
- delete compass;
- compass = NULL;
- }
- Camera::destroy();
- }
- //---------------------------------------------------------------------------
- void GameCamera::render (void)
- {
- //------------------------------------------------------
- // At present, these actually draw. Later they will
- // add elements to the draw list and sort and draw.
- // The later time has arrived. We begin sorting immediately.
- // NO LONGER NEED TO SORT!
- // ZBuffer time has arrived. Share and Enjoy!
- // Everything SIMPLY draws at the execution point into the zBuffer
- // at the correct depth. Miracles occur at that point!
- // Big code change but it removes a WHOLE bunch of code and memory!
-
- //--------------------------------------------------------
- // Get new viewport values to scale stuff. No longer uses
- // VFX stuff for this. ALL GOS NOW!
- gos_GetViewport(&viewMulX, &viewMulY, &viewAddX, &viewAddY);
- MidLevelRenderer::MLRState default_state;
- default_state.SetBackFaceOn();
- default_state.SetDitherOn();
- default_state.SetTextureCorrectionOn();
- default_state.SetZBufferCompareOn();
- default_state.SetZBufferWriteOn();
- default_state.SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode);
- float z = 1.0f;
- Stuff::RGBAColor fColor;
- fColor.red = ((fogColor >> 16) & 0xff);
- fColor.green = ((fogColor >> 8) & 0xff);
- fColor.blue = ((fogColor) & 0xff);
- //--------------------------------------------------------
- // Get new viewport values to scale stuff. No longer uses
- // VFX stuff for this. ALL GOS NOW!
- screenResolution.x = viewMulX;
- screenResolution.y = viewMulY;
- calculateProjectionConstants();
- TG_Shape::SetViewport(viewMulX,viewMulY,viewAddX,viewAddY);
- userInput->setViewport(viewMulX,viewMulY,viewAddX,viewAddY);
- gos_TextSetRegion(viewAddX,viewAddY,viewMulX,viewMulY);
- //--------------------------------------------------------
- // Get new viewport values to scale stuff. No longer uses
- // VFX stuff for this. ALL GOS NOW!
- screenResolution.x = viewMulX;
- screenResolution.y = viewMulY;
- calculateProjectionConstants();
- globalScaleFactor = getScaleFactor();
- globalScaleFactor *= viewMulX / 640.0; //Scale Mechs to ScreenRES
-
- //-----------------------------------------------
- // Set Ambient for this pass of rendering
- DWORD lightRGB = (ambientRed<<16)+(ambientGreen<<8)+ambientBlue;
-
- eye->setLightColor(1,lightRGB);
- eye->setLightIntensity(1,1.0);
- MidLevelRenderer::PerspectiveMode = usePerspective;
- theClipper->StartDraw(cameraOrigin, cameraToClip, fColor, &fColor, default_state, &z);
- MidLevelRenderer::GOSVertex::farClipReciprocal = (1.0f-cameraToClip(2, 2))/cameraToClip(3, 2);
- if (active && turn > 1)
- {
- //----------------------------------------------------------
- // Turn stuff on line by line until perspective is working.
-
- if (Environment.Renderer != 3)
- theSky->render(1);
-
- land->render(); //render the Terrain
- if (Environment.Renderer != 3)
- craterManager->render(); //render the craters and footprints
-
- ObjectManager->render(true, true, true); //render all other objects
- land->renderWater(); //Draw Water Last!
- if (useShadows && Environment.Renderer != 3)
- ObjectManager->renderShadows(true, true, true);
- if (mission && mission->missionInterface)
- mission->missionInterface->drawVTOL();
-
- if (!drawOldWay && !inMovieMode)
- {
- if (compass && (turn > 3) && drawCompass)
- compass->render(-1); //Force this to zBuffer in front of everything
- }
-
- if (!drawOldWay)
- mcTextureManager->renderLists(); //This sends triangles down to the card. All "rendering" to this point has been setting up tri lists
- if (drawOldWay)
- {
- //Last thing drawn were shadows which are not Gouraud Shaded!!!
- // MLR to be "efficient" doesn't set this state by default at startup!
- gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
- }
- theClipper->RenderNow(); //Draw the FX
- if (useNonWeaponEffects)
- weather->render(); //Draw the weather
- }
- if (drawOldWay && !inMovieMode)
- {
- gos_SetRenderState( gos_State_ZCompare, 0);
- gos_SetRenderState( gos_State_ZWrite, 0);
- gos_SetRenderState( gos_State_Perspective, 1);
- if (compass && (turn > 3) && drawCompass)
- compass->render();
- }
-
- //---------------------------------------------------------
- //Check if we are inMovieMode and should be letterboxed.
- // draw letterboxes here.
- if (inMovieMode && (letterBoxPos != 0.0f))
- {
- //Figure out the two faces we need to draw based on letterBox Pos and Alpha
- float barTopX = screenResolution.y * letterBoxPos;
- float barBotX = screenResolution.y - barTopX;
- gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha);
- gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
- gos_SetRenderState( gos_State_MonoEnable, 0);
- gos_SetRenderState( gos_State_Perspective, 0);
- gos_SetRenderState( gos_State_Clipping, 1);
- gos_SetRenderState( gos_State_AlphaTest, 1);
- gos_SetRenderState( gos_State_Specular, 0);
- gos_SetRenderState( gos_State_Dither, 1);
- gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
- gos_SetRenderState( gos_State_Filter, gos_FilterNone);
- gos_SetRenderState( gos_State_TextureAddress, gos_TextureClamp );
- gos_SetRenderState( gos_State_ZCompare, 0);
- gos_SetRenderState( gos_State_ZWrite, 0);
- gos_SetRenderState( gos_State_Texture, 0);
-
- //------------------------------------
- gos_VERTEX gVertex[4];
- gVertex[0].x = 0.0f;
- gVertex[0].y = 0.0f;
- gVertex[0].z = 0.00001f;
- gVertex[0].rhw = 0.00001f;
- gVertex[0].u = 0.0f;
- gVertex[0].v = 0.0f;
- gVertex[0].argb = (letterBoxAlpha << 24);
- gVertex[0].frgb = 0xff000000;
- gVertex[1].x = 0.0f;
- gVertex[1].y = barTopX;
- gVertex[1].z = 0.00001f;
- gVertex[1].rhw = 0.00001f;
- gVertex[1].u = 0.0f;
- gVertex[1].v = 0.0f;
- gVertex[1].argb = (letterBoxAlpha << 24);
- gVertex[1].frgb = 0xff000000;
- gVertex[2].x = screenResolution.x;
- gVertex[2].y = barTopX;
- gVertex[2].z = 0.00001f;
- gVertex[2].rhw = 0.00001f;
- gVertex[2].u = 0.0f;
- gVertex[2].v = 0.0f;
- gVertex[2].argb = (letterBoxAlpha << 24);
- gVertex[2].frgb = 0xff000000;
- gVertex[3].x = screenResolution.x;
- gVertex[3].y = 0.0f;
- gVertex[3].z = 0.00001f;
- gVertex[3].rhw = 0.00001f;
- gVertex[3].u = 0.0f;
- gVertex[3].v = 0.0f;
- gVertex[3].argb = (letterBoxAlpha << 24);
- gVertex[3].frgb = 0xff000000;
-
- gos_DrawQuads(gVertex, 4);
-
- gVertex[0].x = 0.0f;
- gVertex[0].y = barBotX;
- gVertex[0].z = 0.00001f;
- gVertex[0].rhw = 0.00001f;
- gVertex[0].u = 0.0f;
- gVertex[0].v = 0.0f;
- gVertex[0].argb = (letterBoxAlpha << 24);
- gVertex[0].frgb = 0xff000000;
- gVertex[1].x = screenResolution.x;
- gVertex[1].y = barBotX;
- gVertex[1].z = 0.00001f;
- gVertex[1].rhw = 0.00001f;
- gVertex[1].u = 0.0f;
- gVertex[1].v = 0.0f;
- gVertex[1].argb = (letterBoxAlpha << 24);
- gVertex[1].frgb = 0xff000000;
- gVertex[2].x = screenResolution.x;
- gVertex[2].y = screenResolution.y;
- gVertex[2].z = 0.00001f;
- gVertex[2].rhw = 0.00001f;
- gVertex[2].u = 0.0f;
- gVertex[2].v = 0.0f;
- gVertex[2].argb = (letterBoxAlpha << 24);
- gVertex[2].frgb = 0xff000000;
- gVertex[3].x = 0.0f;
- gVertex[3].y = screenResolution.y;
- gVertex[3].z = 0.00001f;
- gVertex[3].rhw = 0.00001f;
- gVertex[3].u = 0.0f;
- gVertex[3].v = 0.0f;
- gVertex[3].argb = (letterBoxAlpha << 24);
- gVertex[3].frgb = 0xff000000;
-
- gos_DrawQuads(gVertex, 4);
- }
- if (inMovieMode && (fadeAlpha != 0x0))
- {
- //We are fading to something other then clear screen.
- gos_SetRenderState( gos_State_AlphaMode, gos_Alpha_AlphaInvAlpha);
- gos_SetRenderState( gos_State_ShadeMode, gos_ShadeGouraud);
- gos_SetRenderState( gos_State_MonoEnable, 0);
- gos_SetRenderState( gos_State_Perspective, 0);
- gos_SetRenderState( gos_State_Clipping, 1);
- gos_SetRenderState( gos_State_AlphaTest, 1);
- gos_SetRenderState( gos_State_Specular, 0);
- gos_SetRenderState( gos_State_Dither, 1);
- gos_SetRenderState( gos_State_TextureMapBlend, gos_BlendModulate);
- gos_SetRenderState( gos_State_Filter, gos_FilterNone);
- gos_SetRenderState( gos_State_TextureAddress, gos_TextureClamp );
- gos_SetRenderState( gos_State_ZCompare, 0);
- gos_SetRenderState( gos_State_ZWrite, 0);
- gos_SetRenderState( gos_State_Texture, 0);
-
- //------------------------------------
- gos_VERTEX gVertex[4];
- gVertex[0].x = 0.0f;
- gVertex[0].y = 0.0f;
- gVertex[0].z = 0.00001f;
- gVertex[0].rhw = 0.00001f;
- gVertex[0].u = 0.0f;
- gVertex[0].v = 0.0f;
- gVertex[0].argb = (fadeAlpha << 24) + (fadeColor & 0x00ffffff);
- gVertex[0].frgb = 0xff000000;
- gVertex[1].x = 0.0f;
- gVertex[1].y = screenResolution.y;
- gVertex[1].z = 0.00001f;
- gVertex[1].rhw = 0.00001f;
- gVertex[1].u = 0.0f;
- gVertex[1].v = 0.0f;
- gVertex[1].argb = (fadeAlpha << 24) + (fadeColor & 0x00ffffff);
- gVertex[1].frgb = 0xff000000;
- gVertex[2].x = screenResolution.x;
- gVertex[2].y = screenResolution.y;
- gVertex[2].z = 0.00001f;
- gVertex[2].rhw = 0.00001f;
- gVertex[2].u = 0.0f;
- gVertex[2].v = 0.0f;
- gVertex[2].argb = (fadeAlpha << 24) + (fadeColor & 0x00ffffff);
- gVertex[2].frgb = 0xff000000;
- gVertex[3].x = screenResolution.x;
- gVertex[3].y = 0.0f;
- gVertex[3].z = 0.00001f;
- gVertex[3].rhw = 0.00001f;
- gVertex[3].u = 0.0f;
- gVertex[3].v = 0.0f;
- gVertex[3].argb = (fadeAlpha << 24) + (fadeColor & 0x00ffffff);
- gVertex[3].frgb = 0xff000000;
-
- gos_DrawQuads(gVertex, 4);
- }
-
- //-----------------------------------------------------
- }
- //---------------------------------------------------------------------------
- long GameCamera::activate (void)
- {
- //------------------------------------------
- // If camera is already active, just return
- if (ready && active)
- return(NO_ERR);
-
- //---------------------------------------------------------
- // Camera always starts pointing at first mover in lists
- // CANNOT be infinite because we don't allow missions without at least 1 player mech!!
- MoverPtr firstMover = NULL;
- if (ObjectManager->getNumMovers() > 0) {
- long i = 0;
- firstMover = ObjectManager->getMover(i);
- while (firstMover && ((firstMover->getCommander()->getId() != Commander::home->getId()) || !firstMover->isOnGUI()))
- {
- i++;
- if (i == ObjectManager->getNumMovers())
- break;
- firstMover = ObjectManager->getMover(i);
- }
- }
-
- if (firstMover)
- {
- Stuff::Vector3D newPosition(firstMover->getPosition());
- setPosition(newPosition);
- }
- if (land)
- {
- land->update();
- }
-
- allNormal();
-
- //updateDaylight(true);
-
- lastShadowLightPitch = lightPitch;
-
- //Startup the SKYBox
- long appearanceType = (GENERIC_APPR_TYPE << 24);
- AppearanceTypePtr genericAppearanceType = NULL;
- genericAppearanceType = appearanceTypeList->getAppearance(appearanceType,"skybox");
- if (!genericAppearanceType)
- {
- char msg[1024];
- sprintf(msg,"No Generic Appearance Named %s","skybox");
- Fatal(0,msg);
- }
-
- theSky = new GenericAppearance;
- gosASSERT(theSky != NULL);
- //--------------------------------------------------------------
- gosASSERT(genericAppearanceType->getAppearanceClass() == GENERIC_APPR_TYPE);
- theSky->init((GenericAppearanceType*)genericAppearanceType, NULL);
-
- theSky->setSkyNumber(mission->theSkyNumber);
-
- return NO_ERR;
- }
- inline GameObjectPtr getCamObject (long partId, bool existsOnly)
- {
- GameObjectPtr obj = NULL;
- if (partId == -1)
- obj = NULL;
- else
- obj = ObjectManager->findByPartId(partId);
- if (existsOnly)
- {
- if (obj &&
- obj->getExists() &&
- (obj->getCommanderId() == Commander::home->getId()) ||
- (Team::home->teamLineOfSight(obj->getLOSPosition(),0.0f)))
- return(obj);
- return(NULL);
- }
- return(obj);
- }
- long cameraLineChanged = 0;
- bool useLOSAngle = true;
- //---------------------------------------------------------------------------
- long GameCamera::update (void)
- {
- if (lookTargetObject != -1)
- targetObject = getCamObject(lookTargetObject,true);
-
- if (targetObject &&
- targetObject->getExists() &&
- ((targetObject->getCommanderId() == Commander::home->getId()) ||
- !targetObject->isMover() ||
- (targetObject->isMover() && ((Mover *)targetObject)->conStat >= CONTACT_SENSOR_QUALITY_1) ))
- {
- setPosition(targetObject->getPosition(),false);
- }
- else
- {
- targetObject = NULL;
- }
- //Force CameraAltitude to be less than max based on angle. This keeps poly load relatively even
- float anglePercent = (projectionAngle - MIN_PERSPECTIVE) / (MAX_PERSPECTIVE - MIN_PERSPECTIVE);
- float testMax = Camera::AltitudeMaximumLo + ((Camera::AltitudeMaximumHi - Camera::AltitudeMaximumLo) * anglePercent);
-
- if (cameraAltitude > testMax)
- cameraAltitude = testMax;
- if ((cameraAltitude < testMax) && (cameraAltitudeDesired > testMax))
- cameraAltitude = testMax;
-
- // calculate new near and far plane distance based on
- // Current altitude above terrain.
- float altitudePercent = (cameraAltitude - AltitudeMinimum) / (testMax - AltitudeMinimum);
- Camera::NearPlaneDistance = MinNearPlane + ((MaxNearPlane - MinNearPlane) * altitudePercent);
- Camera::FarPlaneDistance = MinFarPlane + ((MaxFarPlane - MinFarPlane) * altitudePercent);
-
- if (userInput->getKeyDown(KEY_LBRACKET) && userInput->ctrl() && userInput->alt() && !userInput->shift())
- {
- useLOSAngle ^= true;
- }
- #ifdef DEBUG_CAMERA
- if (userInput->getKeyDown(KEY_RBRACKET) && userInput->ctrl() && userInput->alt() && !userInput->shift())
- {
- Camera::NearPlaneDistance += 10.0f;
- }
- if (userInput->getKeyDown(KEY_APOSTROPHE) && userInput->ctrl() && userInput->alt() && !userInput->shift())
- {
- Camera::FarPlaneDistance -= 1005.00f;
- }
- if (userInput->getKeyDown(KEY_SEMICOLON) && userInput->ctrl() && userInput->alt() && !userInput->shift())
- {
- Camera::FarPlaneDistance += 1005.0f;
- }
- char text[1024];
- sprintf(text,"Near Plane: %f Far Plane: %f",Camera::NearPlaneDistance,Camera::FarPlaneDistance);
- DWORD width, height;
- Stuff::Vector4D moveHere;
- moveHere.x = 10.0f;
- moveHere.y = 10.0f;
- gos_TextSetAttributes (gosFontHandle, 0, gosFontScale, false, true, false, false);
- gos_TextStringLength(&width,&height,text);
- moveHere.z = width;
- moveHere.w = height;
- globalFloatHelp[currentFloatHelp].setHelpText(text);
- globalFloatHelp[currentFloatHelp].setScreenPos(moveHere);
- globalFloatHelp[currentFloatHelp].setForegroundColor(SD_GREEN);
- globalFloatHelp[currentFloatHelp].setBackgroundColor(SD_BLACK);
- globalFloatHelp[currentFloatHelp].setScale(1.0f);
- globalFloatHelp[currentFloatHelp].setProportional(true);
- globalFloatHelp[currentFloatHelp].setBold(false);
- globalFloatHelp[currentFloatHelp].setItalic(false);
- globalFloatHelp[currentFloatHelp].setWordWrap(false);
- currentFloatHelp++;
- gosASSERT(currentFloatHelp < MAX_FLOAT_HELPS);
- #endif
- if (DisplayCameraAngle)
- {
- char text[1024];
- sprintf(text,"Camera Angle: %f degrees Camera Altitude: %f CameraPosition: X=%f Y=%f Z=%f CameraRotation: %f",projectionAngle,cameraAltitude,position.x,position.y,position.z,cameraRotation);
-
- DWORD width, height;
- Stuff::Vector4D moveHere;
- moveHere.x = 10.0f;
- moveHere.y = 10.0f;
- gos_TextSetAttributes (gosFontHandle, 0, gosFontScale, false, true, false, false);
- gos_TextStringLength(&width,&height,text);
- moveHere.z = width;
- moveHere.w = height;
- globalFloatHelp->setFloatHelp(text,moveHere,SD_GREEN,SD_BLACK,1.0f,true,false,false,false);
- }
- if (!compass) //Create it!
- {
- AppearanceType* appearanceType = appearanceTypeList->getAppearance( BLDG_TYPE << 24, "compass" );
- compass = new BldgAppearance;
- compass->init( appearanceType );
- }
- long result = Camera::update();
-
- // if ((day2NightTransitionTime > 0.0f) && !getIsNight() && (fabs(lastShadowLightPitch-lightPitch) > MAX_SHADOW_PITCH_CHANGE))
- // {
- // forceShadowRecalc = true;
- // lastShadowLightPitch = lightPitch;
- // }
- // else
- // {
- // forceShadowRecalc = false;
- // }
-
- //Always TRUE for right now. Debugging....
- //-fs
- //forceShadowRecalc = true;
-
- bool oldFog = useFog;
- bool oldShadows = useShadows;
- useFog = false;
- useShadows = false;
-
- if (compass && (turn > 3))
- {
-
- compass->setObjectParameters(getPosition(),0.0f,false,0,0);
- compass->setMoverParameters(0.0f);
- compass->setGesture(0);
- compass->setObjStatus(OBJECT_STATUS_DESTROYED);
- compass->setInView(true);
- compass->setVisibility(true,true);
- compass->setFilterState(true);
- compass->setIsHudElement();
- compass->update(); //Force it to try and draw or stuff will not work!
- }
- if (theSky)
- {
- Stuff::Vector3D pos = getPosition();
-
- theSky->setObjectParameters(pos,0.0f,false,0,0);
- theSky->setMoverParameters(0.0f);
- theSky->setGesture(0);
- theSky->setObjStatus(OBJECT_STATUS_NORMAL);
- theSky->setInView(true);
- theSky->setVisibility(true,true);
- theSky->setFilterState(true);
- theSky->setIsHudElement();
- theSky->update(); //Force it to try and draw or stuff will not work!
- }
-
- useFog = oldFog;
- useShadows = oldShadows;
-
- return result;
- }
- //---------------------------------------------------------------------------
- //
- // Edit log
- //
- //---------------------------------------------------------------------------
|