diff options
author | Sergeanur <s.anureev@yandex.ua> | 2021-07-15 17:19:32 +0200 |
---|---|---|
committer | Sergeanur <s.anureev@yandex.ua> | 2021-07-17 23:04:26 +0200 |
commit | d0404cbdb77bd82abf578ce28093990db94743f2 (patch) | |
tree | 1a7232c3dcdd6c371ab5fbde0fc6bf04c5bc7005 /src/render/Renderer.cpp | |
parent | Merge pull request #1217 from Nopey/master (diff) | |
download | re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar.gz re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar.bz2 re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar.lz re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar.xz re3-d0404cbdb77bd82abf578ce28093990db94743f2.tar.zst re3-d0404cbdb77bd82abf578ce28093990db94743f2.zip |
Diffstat (limited to 'src/render/Renderer.cpp')
-rw-r--r-- | src/render/Renderer.cpp | 1838 |
1 files changed, 0 insertions, 1838 deletions
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp deleted file mode 100644 index 1c0bd445..00000000 --- a/src/render/Renderer.cpp +++ /dev/null @@ -1,1838 +0,0 @@ -#define WITHD3D -#include "common.h" - -#include "main.h" -#include "Lights.h" -#include "ModelInfo.h" -#include "Treadable.h" -#include "Ped.h" -#include "Vehicle.h" -#include "Boat.h" -#include "Heli.h" -#include "Object.h" -#include "PathFind.h" -#include "Collision.h" -#include "VisibilityPlugins.h" -#include "Clock.h" -#include "World.h" -#include "Camera.h" -#include "ModelIndices.h" -#include "Streaming.h" -#include "Shadows.h" -#include "PointLights.h" -#include "Renderer.h" -#include "Frontend.h" -#include "custompipes.h" -#include "Debug.h" - -bool gbShowPedRoadGroups; -bool gbShowCarRoadGroups; -bool gbShowCollisionPolys; -bool gbShowCollisionLines; -bool gbShowCullZoneDebugStuff; -bool gbDisableZoneCull; // not original -bool gbBigWhiteDebugLightSwitchedOn; - -bool gbDontRenderBuildings; -bool gbDontRenderBigBuildings; -bool gbDontRenderPeds; -bool gbDontRenderObjects; -bool gbDontRenderVehicles; - -int32 EntitiesRendered; -int32 EntitiesNotRendered; -int32 RenderedBigBuildings; -int32 RenderedBuildings; -int32 RenderedCars; -int32 RenderedPeds; -int32 RenderedObjects; -int32 RenderedDummies; -int32 TestedBigBuildings; -int32 TestedBuildings; -int32 TestedCars; -int32 TestedPeds; -int32 TestedObjects; -int32 TestedDummies; - -// unused -int16 TestCloseThings; -int16 TestBigThings; - -struct EntityInfo -{ - CEntity *ent; - float sort; -}; - -CLinkList<EntityInfo> gSortedVehiclesAndPeds; - -int32 CRenderer::ms_nNoOfVisibleEntities; -CEntity *CRenderer::ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES]; -CEntity *CRenderer::ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES]; -int32 CRenderer::ms_nNoOfInVisibleEntities; -#ifdef NEW_RENDERER -int32 CRenderer::ms_nNoOfVisibleVehicles; -CEntity *CRenderer::ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES]; -int32 CRenderer::ms_nNoOfVisibleBuildings; -CEntity *CRenderer::ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES]; - -CLinkList<EntityInfo> gSortedBuildings; -#endif - -CVector CRenderer::ms_vecCameraPosition; -CVehicle *CRenderer::m_pFirstPersonVehicle; -bool CRenderer::m_loadingPriority; -float CRenderer::ms_lodDistScale = 1.2f; - -// unused -BlockedRange CRenderer::aBlockedRanges[16]; -BlockedRange *CRenderer::pFullBlockedRanges; -BlockedRange *CRenderer::pEmptyBlockedRanges; - -void -CRenderer::Init(void) -{ - gSortedVehiclesAndPeds.Init(40); - SortBIGBuildings(); -#ifdef NEW_RENDERER - gSortedBuildings.Init(NUMVISIBLEENTITIES); -#endif -} - -void -CRenderer::Shutdown(void) -{ - gSortedVehiclesAndPeds.Shutdown(); -#ifdef NEW_RENDERER - gSortedBuildings.Shutdown(); -#endif -} - -void -CRenderer::PreRender(void) -{ - int i; - CLink<CVisibilityPlugins::AlphaObjectInfo> *node; - - for(i = 0; i < ms_nNoOfVisibleEntities; i++) - ms_aVisibleEntityPtrs[i]->PreRender(); - -#ifdef NEW_RENDERER - if(gbNewRenderer){ - for(i = 0; i < ms_nNoOfVisibleVehicles; i++) - ms_aVisibleVehiclePtrs[i]->PreRender(); - // How is this done with cWorldStream? - //for(i = 0; i < ms_nNoOfVisibleBuildings; i++) - // ms_aVisibleBuildingPtrs[i]->PreRender(); - for(CLink<EntityInfo> *node = gSortedBuildings.head.next; - node != &gSortedBuildings.tail; - node = node->next) - ((CEntity*)node->item.ent)->PreRender(); - for(node = CVisibilityPlugins::m_alphaBuildingList.head.next; - node != &CVisibilityPlugins::m_alphaBuildingList.tail; - node = node->next) - ((CEntity*)node->item.entity)->PreRender(); - } -#endif - - for (i = 0; i < ms_nNoOfInVisibleEntities; i++) { -#ifdef SQUEEZE_PERFORMANCE - if (ms_aInVisibleEntityPtrs[i]->IsVehicle() && ((CVehicle*)ms_aInVisibleEntityPtrs[i])->IsHeli()) -#endif - ms_aInVisibleEntityPtrs[i]->PreRender(); - } - - for(node = CVisibilityPlugins::m_alphaEntityList.head.next; - node != &CVisibilityPlugins::m_alphaEntityList.tail; - node = node->next) - ((CEntity*)node->item.entity)->PreRender(); - - CHeli::SpecialHeliPreRender(); - CShadows::RenderExtraPlayerShadows(); -} - -void -CRenderer::RenderOneRoad(CEntity *e) -{ - if(gbDontRenderBuildings) - return; - if(gbShowCollisionPolys) - CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); - else{ -#ifdef EXTENDED_PIPELINES - CustomPipes::AttachGlossPipe(e->GetAtomic()); -#endif - PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName()); - -#ifdef EXTRA_MODEL_FLAGS - if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){ - BACKFACE_CULLING_OFF; - e->Render(); - BACKFACE_CULLING_ON; - }else -#endif - e->Render(); - - POP_RENDERGROUP(); - } -} - -void -CRenderer::RenderOneNonRoad(CEntity *e) -{ - CPed *ped; - CVehicle *veh; - int i; - bool resetLights; - -#ifndef MASTER - if(gbShowCollisionPolys){ - if(!e->IsVehicle()){ - CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex()); - return; - } - }else if(e->IsBuilding()){ - if(e->bIsBIGBuilding){ - if(gbDontRenderBigBuildings) - return; - }else{ - if(gbDontRenderBuildings) - return; - } - }else -#endif - if(e->IsPed()){ -#ifndef MASTER - if(gbDontRenderPeds) - return; -#endif - ped = (CPed*)e; - if(ped->m_nPedState == PED_DRIVING) - return; - } -#ifndef MASTER - else if(e->IsObject() || e->IsDummy()){ - if(gbDontRenderObjects) - return; - }else if(e->IsVehicle()){ - // re3 addition - if(gbDontRenderVehicles) - return; - } -#endif - - PUSH_RENDERGROUP(CModelInfo::GetModelInfo(e->GetModelIndex())->GetModelName()); - - resetLights = e->SetupLighting(); - - if(e->IsVehicle()) - CVisibilityPlugins::InitAlphaAtomicList(); - - // Render Peds in vehicle before vehicle itself - if(e->IsVehicle()){ - veh = (CVehicle*)e; - if(veh->pDriver && veh->pDriver->m_nPedState == PED_DRIVING) - veh->pDriver->Render(); - for(i = 0; i < 8; i++) - if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING) - veh->pPassengers[i]->Render(); - BACKFACE_CULLING_OFF; - } -#ifdef EXTRA_MODEL_FLAGS - if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){ - BACKFACE_CULLING_OFF; - e->Render(); - BACKFACE_CULLING_ON; - }else -#endif - e->Render(); - - if(e->IsVehicle()){ - BACKFACE_CULLING_OFF; - e->bImBeingRendered = true; - CVisibilityPlugins::RenderAlphaAtomics(); - e->bImBeingRendered = false; - BACKFACE_CULLING_ON; - } - - e->RemoveLighting(resetLights); - - POP_RENDERGROUP(); -} - -void -CRenderer::RenderFirstPersonVehicle(void) -{ - if(m_pFirstPersonVehicle == nil) - return; - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RenderOneNonRoad(m_pFirstPersonVehicle); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); -} - -inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable(); } - -void -CRenderer::RenderRoads(void) -{ - int i; - CTreadable *t; - - PUSH_RENDERGROUP("CRenderer::RenderRoads"); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; - DeActivateDirectional(); - SetAmbientColours(); - - for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - t = (CTreadable*)ms_aVisibleEntityPtrs[i]; - if(IsRoad(t)){ -#ifndef MASTER - if(gbShowCarRoadGroups || gbShowPedRoadGroups){ - int ind = 0; - if(gbShowCarRoadGroups) - ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_CAR][0]].group; - if(gbShowPedRoadGroups) - ind += ThePaths.m_pathNodes[t->m_nodeIndices[PATH_PED][0]].group; - SetAmbientColoursToIndicateRoadGroup(ind); - } -#endif - RenderOneRoad(t); -#ifndef MASTER - if(gbShowCarRoadGroups || gbShowPedRoadGroups) - ReSetAmbientAndDirectionalColours(); -#endif - } - } - POP_RENDERGROUP(); -} - -void -CRenderer::RenderEverythingBarRoads(void) -{ - int i; - CEntity *e; - CVector dist; - EntityInfo ei; - - PUSH_RENDERGROUP("CRenderer::RenderEverythingBarRoads"); - BACKFACE_CULLING_ON; - gSortedVehiclesAndPeds.Clear(); - - for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - e = ms_aVisibleEntityPtrs[i]; - - if(IsRoad(e)) - continue; - -#ifdef EXTENDED_PIPELINES - if(CustomPipes::bRenderingEnvMap && (e->IsPed() || e->IsVehicle())) - continue; -#endif - - if(e->IsVehicle() || - e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){ - if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){ - ei.ent = e; - dist = ms_vecCameraPosition - e->GetPosition(); - ei.sort = dist.MagnitudeSqr(); - gSortedVehiclesAndPeds.InsertSorted(ei); - }else{ - dist = ms_vecCameraPosition - e->GetPosition(); - if(!CVisibilityPlugins::InsertEntityIntoSortedList(e, dist.Magnitude())){ - printf("Ran out of space in alpha entity list"); - RenderOneNonRoad(e); - } - } - }else - RenderOneNonRoad(e); - } - POP_RENDERGROUP(); -} - -void -CRenderer::RenderVehiclesButNotBoats(void) -{ - // This function doesn't do anything - // because only boats are inserted into the list - CLink<EntityInfo> *node; - - for(node = gSortedVehiclesAndPeds.tail.prev; - node != &gSortedVehiclesAndPeds.head; - node = node->prev){ - // only boats in this list - CVehicle *v = (CVehicle*)node->item.ent; - if(!v->IsBoat()) - RenderOneNonRoad(v); - } -} - -void -CRenderer::RenderBoats(void) -{ - CLink<EntityInfo> *node; - - PUSH_RENDERGROUP("CRenderer::RenderBoats"); - BACKFACE_CULLING_ON; - - for(node = gSortedVehiclesAndPeds.tail.prev; - node != &gSortedVehiclesAndPeds.head; - node = node->prev){ - // only boats in this list - CVehicle *v = (CVehicle*)node->item.ent; - if(v->IsBoat()) - RenderOneNonRoad(v); - } - POP_RENDERGROUP(); -} - -#ifdef NEW_RENDERER -#ifndef LIBRW -#error "Need librw for EXTENDED_PIPELINES" -#endif -#include "WaterLevel.h" - -enum { - // blend passes - PASS_NOZ, // no z-write - PASS_ADD, // additive - PASS_BLEND // normal blend -}; - -static RwRGBAReal black; - -static void -SetStencilState(int state) -{ - switch(state){ - // disable stencil - case 0: - rw::SetRenderState(rw::STENCILENABLE, FALSE); - break; - // test against stencil - case 1: - rw::SetRenderState(rw::STENCILENABLE, TRUE); - rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILNOTEQUAL); - rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP); - rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP); - rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP); - rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFF); - rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF); - break; - // write to stencil - case 2: - rw::SetRenderState(rw::STENCILENABLE, TRUE); - rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS); - rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE); - rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF); - break; - } -} - -void -CRenderer::RenderOneBuilding(CEntity *ent, float camdist) -{ - if(ent->m_rwObject == nil) - return; - - ent->bImBeingRendered = true; // TODO: this seems wrong, but do we even need it? - - assert(RwObjectGetType(ent->m_rwObject) == rpATOMIC); - RpAtomic *atomic = (RpAtomic*)ent->m_rwObject; - CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->GetModelIndex()); - -#ifdef EXTRA_MODEL_FLAGS - bool resetCull = false; - if(!ent->IsBuilding() || mi->RenderDoubleSided()){ - resetCull = true; - BACKFACE_CULLING_OFF; - } -#endif - - int pass = PASS_BLEND; - if(mi->m_additive) // very questionable - pass = PASS_ADD; - if(mi->m_noZwrite) - pass = PASS_NOZ; - - if(ent->bDistanceFade){ - RpAtomic *lodatm; - float fadefactor; - uint32 alpha; - - lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE); - fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE; - if(fadefactor > 1.0f) - fadefactor = 1.0f; - alpha = mi->m_alpha * fadefactor; - - if(alpha == 255) - WorldRender::AtomicFirstPass(atomic, pass); - else{ - // not quite sure what this is about, do we have to do that? - RpGeometry *geo = RpAtomicGetGeometry(lodatm); - if(geo != RpAtomicGetGeometry(atomic)) - RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); - WorldRender::AtomicFullyTransparent(atomic, pass, alpha); - } - }else - WorldRender::AtomicFirstPass(atomic, pass); - -#ifdef EXTRA_MODEL_FLAGS - if(resetCull) - BACKFACE_CULLING_ON; -#endif - - ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it? -} - -void -CRenderer::RenderWorld(int pass) -{ - int i; - CEntity *e; - CLink<CVisibilityPlugins::AlphaObjectInfo> *node; - - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; - DeActivateDirectional(); - SetAmbientColours(); - - // Temporary...have to figure out sorting better - switch(pass){ - case 0: - // Roads - PUSH_RENDERGROUP("CRenderer::RenderWorld - Roads"); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); -/* - for(i = 0; i < ms_nNoOfVisibleBuildings; i++){ - e = ms_aVisibleBuildingPtrs[i]; - if(e->bIsBIGBuilding || IsRoad(e)) - RenderOneBuilding(e); - } -*/ - for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev; - node != &gSortedBuildings.head; - node = node->prev){ - e = node->item.ent; - if(e->bIsBIGBuilding || IsRoad(e)) - RenderOneBuilding(e); - } - for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev; - node != &CVisibilityPlugins::m_alphaBuildingList.head; - node = node->prev){ - e = node->item.entity; - if(e->bIsBIGBuilding || IsRoad(e)) - RenderOneBuilding(e, node->item.sort); - } - - // KLUDGE for road puddles which have to be rendered at road-time - // only very temporary, there are more rendering issues - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - WorldRender::RenderBlendPass(PASS_BLEND); - WorldRender::numBlendInsts[PASS_BLEND] = 0; - POP_RENDERGROUP(); - break; - case 1: - // Opaque - PUSH_RENDERGROUP("CRenderer::RenderWorld - Opaque"); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE); -/* - for(i = 0; i < ms_nNoOfVisibleBuildings; i++){ - e = ms_aVisibleBuildingPtrs[i]; - if(!(e->bIsBIGBuilding || IsRoad(e))) - RenderOneBuilding(e); - } -*/ - for(CLink<EntityInfo> *node = gSortedBuildings.tail.prev; - node != &gSortedBuildings.head; - node = node->prev){ - e = node->item.ent; - if(!(e->bIsBIGBuilding || IsRoad(e))) - RenderOneBuilding(e); - } - for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev; - node != &CVisibilityPlugins::m_alphaBuildingList.head; - node = node->prev){ - e = node->item.entity; - if(!(e->bIsBIGBuilding || IsRoad(e))) - RenderOneBuilding(e, node->item.sort); - } - // Now we have iterated through all visible buildings (unsorted and sorted) - // and the transparency list is done. - - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); - WorldRender::RenderBlendPass(PASS_NOZ); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); - POP_RENDERGROUP(); - break; - case 2: - // Transparent - PUSH_RENDERGROUP("CRenderer::RenderWorld - Transparent"); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - WorldRender::RenderBlendPass(PASS_ADD); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - WorldRender::RenderBlendPass(PASS_BLEND); - POP_RENDERGROUP(); - break; - } -} - -void -CRenderer::RenderPeds(void) -{ - int i; - CEntity *e; - - PUSH_RENDERGROUP("CRenderer::RenderPeds"); - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(e->IsPed()) - RenderOneNonRoad(e); - } - POP_RENDERGROUP(); -} - -void -CRenderer::RenderVehicles(void) -{ - int i; - CEntity *e; - EntityInfo ei; - CLink<EntityInfo> *node; - - PUSH_RENDERGROUP("CRenderer::RenderVehicles"); - // not the real thing - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(!e->IsVehicle()) - continue; -// if(PutIntoSortedVehicleList((CVehicle*)e)) -// continue; // boats handled elsewhere - ei.ent = e; - ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr(); - gSortedVehiclesAndPeds.InsertSorted(ei); - } - - for(node = gSortedVehiclesAndPeds.tail.prev; - node != &gSortedVehiclesAndPeds.head; - node = node->prev) - RenderOneNonRoad(node->item.ent); - POP_RENDERGROUP(); -} - -void -CRenderer::RenderWater(void) -{ - int i; - CEntity *e; - - PUSH_RENDERGROUP("CRenderer::RenderWater"); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil); - RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); - SetStencilState(2); - - for(i = 0; i < ms_nNoOfVisibleVehicles; i++){ - e = ms_aVisibleVehiclePtrs[i]; - if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()) - ((CBoat*)e)->RenderWaterOutPolys(); - } - - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); - SetStencilState(1); - - CWaterLevel::RenderWater(); - - SetStencilState(0); - POP_RENDERGROUP(); -} - -void -CRenderer::ClearForFrame(void) -{ - ms_nNoOfVisibleEntities = 0; - ms_nNoOfVisibleVehicles = 0; - ms_nNoOfVisibleBuildings = 0; - ms_nNoOfInVisibleEntities = 0; - gSortedVehiclesAndPeds.Clear(); - gSortedBuildings.Clear(); - - WorldRender::numBlendInsts[PASS_NOZ] = 0; - WorldRender::numBlendInsts[PASS_ADD] = 0; - WorldRender::numBlendInsts[PASS_BLEND] = 0; -} -#endif - -void -CRenderer::RenderFadingInEntities(void) -{ - PUSH_RENDERGROUP("CRenderer::RenderFadingInEntities"); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); - BACKFACE_CULLING_ON; - DeActivateDirectional(); - SetAmbientColours(); - CVisibilityPlugins::RenderFadingEntities(); - POP_RENDERGROUP(); -} - -void -CRenderer::RenderCollisionLines(void) -{ - int i; - - // game doesn't draw fading in entities - // this should probably be fixed - for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - CEntity *e = ms_aVisibleEntityPtrs[i]; - if(Abs(e->GetPosition().x - ms_vecCameraPosition.x) < 100.0f && - Abs(e->GetPosition().y - ms_vecCameraPosition.y) < 100.0f) - CCollision::DrawColModel(e->GetMatrix(), *e->GetColModel()); - } -} - -// unused -void -CRenderer::RenderBlockBuildingLines(void) -{ - for(BlockedRange *br = pFullBlockedRanges; br; br = br->next) - printf("Blocked: %f %f\n", br->a, br->b); -} - -enum Visbility -{ - VIS_INVISIBLE, - VIS_VISIBLE, - VIS_OFFSCREEN, - VIS_STREAMME -}; - -// Time Objects can be time culled if -// other == -1 || CModelInfo::GetModelInfo(other)->GetRwObject() -// i.e. we have to draw even at the wrong time if -// other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject() == nil - -#define OTHERUNAVAILABLE (other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject() == nil) -#define CANTIMECULL (!OTHERUNAVAILABLE) - -int32 -CRenderer::SetupEntityVisibility(CEntity *ent) -{ - CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->m_modelIndex); - CTimeModelInfo *ti; - int32 other; - float dist; - - bool request = true; - if (mi->GetModelType() == MITYPE_TIME) { - ti = (CTimeModelInfo*)mi; - other = ti->GetOtherTimeModel(); - if(CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())){ - // don't fade in, or between time objects - if(CANTIMECULL) - ti->m_alpha = 255; - }else{ - // Hide if possible - if(CANTIMECULL) - return VIS_INVISIBLE; - // can't cull, so we'll try to draw this one, but don't request - // it since what we really want is the other one. - request = false; - } - }else{ - if (mi->GetModelType() != MITYPE_SIMPLE) { - if(FindPlayerVehicle() == ent && - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ - // Player's vehicle in first person mode - if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD || - ent->GetModelIndex() == MI_RHINO || - ent->GetModelIndex() == MI_COACH || - TheCamera.m_bInATunnelAndABigVehicle){ - ent->bNoBrightHeadLights = true; - }else{ - m_pFirstPersonVehicle = (CVehicle*)ent; - ent->bNoBrightHeadLights = false; - } - return VIS_OFFSCREEN; - } - // All sorts of Clumps - if(ent->m_rwObject == nil || !ent->bIsVisible) - return VIS_INVISIBLE; - if(!ent->GetIsOnScreen()) - return VIS_OFFSCREEN; - if(ent->bDrawLast){ - dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = false; - return VIS_INVISIBLE; - } - return VIS_VISIBLE; - } - if(ent->IsObject() && - ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){ - if(ent->m_rwObject == nil || !ent->bIsVisible) - return VIS_INVISIBLE; - return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN; - } - } - - // Simple ModelInfo - - dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); - - // This can only happen with multi-atomic models (e.g. railtracks) - // but why do we bump up the distance? can only be fading... - if(LOD_DISTANCE + STREAM_DISTANCE < dist && dist < mi->GetLargestLodDistance()) - dist = mi->GetLargestLodDistance(); - - if(ent->IsObject() && ent->bRenderDamaged) - mi->m_isDamaged = true; - - RpAtomic *a = mi->GetAtomicFromDistance(dist); - if(a){ - mi->m_isDamaged = false; - if(ent->m_rwObject == nil) - ent->CreateRwObject(); - assert(ent->m_rwObject); - RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; - // Make sure our atomic uses the right geometry and not - // that of an atomic for another draw distance. - if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) - RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - mi->IncreaseAlpha(); - if(ent->m_rwObject == nil || !ent->bIsVisible) - return VIS_INVISIBLE; - - if(!ent->GetIsOnScreen()){ - mi->m_alpha = 255; - return VIS_OFFSCREEN; - } - - if(mi->m_alpha != 255){ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = true; - return VIS_INVISIBLE; - } - - if(mi->m_drawLast || ent->bDrawLast){ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = false; - return VIS_INVISIBLE; - } - return VIS_VISIBLE; - } - - // Object is not loaded, figure out what to do - - if(mi->m_noFade){ - mi->m_isDamaged = false; - // request model - if(dist - STREAM_DISTANCE < mi->GetLargestLodDistance() && request) - return VIS_STREAMME; - return VIS_INVISIBLE; - } - - // We might be fading - - a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); - mi->m_isDamaged = false; - if(a == nil){ - // request model - if(dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance() && request) - return VIS_STREAMME; - return VIS_INVISIBLE; - } - - if(ent->m_rwObject == nil) - ent->CreateRwObject(); - assert(ent->m_rwObject); - RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; - if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) - RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - mi->IncreaseAlpha(); - if(ent->m_rwObject == nil || !ent->bIsVisible) - return VIS_INVISIBLE; - - if(!ent->GetIsOnScreen()){ - mi->m_alpha = 255; - return VIS_OFFSCREEN; - }else{ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = true; - return VIS_OFFSCREEN; // Why this? - } -} - -int32 -CRenderer::SetupBigBuildingVisibility(CEntity *ent) -{ - CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); - CTimeModelInfo *ti; - int32 other; - - if (mi->GetModelType() == MITYPE_TIME) { - ti = (CTimeModelInfo*)mi; - other = ti->GetOtherTimeModel(); - // Hide objects not in time range if possible - if(CANTIMECULL) - if(!CClock::GetIsTimeInRange(ti->GetTimeOn(), ti->GetTimeOff())) - return VIS_INVISIBLE; - // Draw like normal - } else if (mi->GetModelType() == MITYPE_VEHICLE) - return ent->IsVisible() ? VIS_VISIBLE : VIS_INVISIBLE; - - float dist = (ms_vecCameraPosition-ent->GetPosition()).Magnitude(); - CSimpleModelInfo *nonLOD = mi->GetRelatedModel(); - - // Find out whether to draw below near distance. - // This is only the case if there is a non-LOD which is either not - // loaded or not completely faded in yet. - if(dist < mi->GetNearDistance() && dist < LOD_DISTANCE + STREAM_DISTANCE){ - // No non-LOD or non-LOD is completely visible. - if(nonLOD == nil || - nonLOD->GetRwObject() && nonLOD->m_alpha == 255) - return VIS_INVISIBLE; - - // But if it is a time object, we'd rather draw the wrong - // non-LOD than the right LOD. - if (nonLOD->GetModelType() == MITYPE_TIME) { - ti = (CTimeModelInfo*)nonLOD; - other = ti->GetOtherTimeModel(); - if(other != -1 && CModelInfo::GetModelInfo(other)->GetRwObject()) - return VIS_INVISIBLE; - } - } - - RpAtomic *a = mi->GetAtomicFromDistance(dist); - if(a){ - if(ent->m_rwObject == nil) - ent->CreateRwObject(); - assert(ent->m_rwObject); - RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; - - // Make sure our atomic uses the right geometry and not - // that of an atomic for another draw distance. - if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) - RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - if (!ent->IsVisible() || !ent->GetIsOnScreenComplex()) - return VIS_INVISIBLE; - if(mi->m_drawLast){ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = false; - return VIS_INVISIBLE; - } - return VIS_VISIBLE; - } - - if(mi->m_noFade){ - ent->DeleteRwObject(); - return VIS_INVISIBLE; - } - - - // get faded atomic - a = mi->GetAtomicFromDistance(dist - FADE_DISTANCE); - if(a == nil){ - ent->DeleteRwObject(); - return VIS_INVISIBLE; - } - - // Fade... - if(ent->m_rwObject == nil) - ent->CreateRwObject(); - assert(ent->m_rwObject); - RpAtomic *rwobj = (RpAtomic*)ent->m_rwObject; - if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) - RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - if (ent->IsVisible() && ent->GetIsOnScreenComplex()) - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - return VIS_INVISIBLE; -} - -void -CRenderer::ConstructRenderList(void) -{ -#ifdef NEW_RENDERER - if(!gbNewRenderer) -#endif -{ - ms_nNoOfVisibleEntities = 0; - ms_nNoOfInVisibleEntities = 0; -} - ms_vecCameraPosition = TheCamera.GetPosition(); - - // unused - pFullBlockedRanges = nil; - pEmptyBlockedRanges = aBlockedRanges; - for(int i = 0; i < 16; i++){ - aBlockedRanges[i].prev = &aBlockedRanges[i-1]; - aBlockedRanges[i].next = &aBlockedRanges[i+1]; - } - aBlockedRanges[0].prev = nil; - aBlockedRanges[15].next = nil; - - // unused - TestCloseThings = 0; - TestBigThings = 0; - - ScanWorld(); -} - -void -LimitFrustumVector(CVector &vec1, const CVector &vec2, float l) -{ - float f; - f = (l - vec2.z) / (vec1.z - vec2.z); - vec1.x = f*(vec1.x - vec2.x) + vec2.x; - vec1.y = f*(vec1.y - vec2.y) + vec2.y; - vec1.z = f*(vec1.z - vec2.z) + vec2.z; -} - -enum Corners -{ - CORNER_CAM = 0, - CORNER_FAR_TOPLEFT, - CORNER_FAR_TOPRIGHT, - CORNER_FAR_BOTRIGHT, - CORNER_FAR_BOTLEFT, - CORNER_LOD_LEFT, - CORNER_LOD_RIGHT, - CORNER_PRIO_LEFT, - CORNER_PRIO_RIGHT, -}; - -void -CRenderer::ScanWorld(void) -{ - float f = RwCameraGetFarClipPlane(TheCamera.m_pRwCamera); - RwV2d vw = *RwCameraGetViewWindow(TheCamera.m_pRwCamera); - CVector vectors[9]; - RwMatrix *cammatrix; - RwV2d poly[3]; - -#ifndef MASTER - // missing in game but has to be done somewhere - EntitiesRendered = 0; - EntitiesNotRendered = 0; - RenderedBigBuildings = 0; - RenderedBuildings = 0; - RenderedCars = 0; - RenderedPeds = 0; - RenderedObjects = 0; - RenderedDummies = 0; - TestedBigBuildings = 0; - TestedBuildings = 0; - TestedCars = 0; - TestedPeds = 0; - TestedObjects = 0; - TestedDummies = 0; -#endif - - memset(vectors, 0, sizeof(vectors)); - vectors[CORNER_FAR_TOPLEFT].x = -vw.x * f; - vectors[CORNER_FAR_TOPLEFT].y = vw.y * f; - vectors[CORNER_FAR_TOPLEFT].z = f; - vectors[CORNER_FAR_TOPRIGHT].x = vw.x * f; - vectors[CORNER_FAR_TOPRIGHT].y = vw.y * f; - vectors[CORNER_FAR_TOPRIGHT].z = f; - vectors[CORNER_FAR_BOTRIGHT].x = vw.x * f; - vectors[CORNER_FAR_BOTRIGHT].y = -vw.y * f; - vectors[CORNER_FAR_BOTRIGHT].z = f; - vectors[CORNER_FAR_BOTLEFT].x = -vw.x * f; - vectors[CORNER_FAR_BOTLEFT].y = -vw.y * f; - vectors[CORNER_FAR_BOTLEFT].z = f; - - cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - - m_pFirstPersonVehicle = nil; - CVisibilityPlugins::InitAlphaEntityList(); - CWorld::AdvanceCurrentScanCode(); - - if(cammatrix->at.z > 0.0f){ - // looking up, bottom corners are further away - vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f; - vectors[CORNER_LOD_RIGHT] = vectors[CORNER_FAR_BOTRIGHT] * LOD_DISTANCE/f; - }else{ - // looking down, top corners are further away - vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_TOPLEFT] * LOD_DISTANCE/f; - vectors[CORNER_LOD_RIGHT] = vectors[CORNER_FAR_TOPRIGHT] * LOD_DISTANCE/f; - } - vectors[CORNER_PRIO_LEFT].x = vectors[CORNER_LOD_LEFT].x * 0.2f; - vectors[CORNER_PRIO_LEFT].y = vectors[CORNER_LOD_LEFT].y * 0.2f; - vectors[CORNER_PRIO_LEFT].z = vectors[CORNER_LOD_LEFT].z; - vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; - vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; - vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints(vectors, vectors, 9, cammatrix); - - m_loadingPriority = false; - if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || -#ifdef FIX_BUGS - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_GTACLASSIC || -#endif - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED){ - CRect rect; - int x1, x2, y1, y2; - LimitFrustumVector(vectors[CORNER_FAR_TOPLEFT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_TOPLEFT]); - LimitFrustumVector(vectors[CORNER_FAR_TOPRIGHT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_TOPRIGHT]); - LimitFrustumVector(vectors[CORNER_FAR_BOTRIGHT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_BOTRIGHT]); - LimitFrustumVector(vectors[CORNER_FAR_BOTLEFT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_BOTLEFT]); - x1 = CWorld::GetSectorIndexX(rect.left); - if(x1 < 0) x1 = 0; - x2 = CWorld::GetSectorIndexX(rect.right); - if(x2 >= NUMSECTORS_X-1) x2 = NUMSECTORS_X-1; - y1 = CWorld::GetSectorIndexY(rect.top); - if(y1 < 0) y1 = 0; - y2 = CWorld::GetSectorIndexY(rect.bottom); - if(y2 >= NUMSECTORS_Y-1) y2 = NUMSECTORS_Y-1; - for(; x1 <= x2; x1++) - for(int y = y1; y <= y2; y++) - ScanSectorList(CWorld::GetSector(x1, y)->m_lists); - }else{ - CVehicle *train = FindPlayerTrain(); - if(train && train->GetPosition().z < 0.0f){ - poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); - poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); - poly[1].x = CWorld::GetSectorX(vectors[CORNER_LOD_LEFT].x); - poly[1].y = CWorld::GetSectorY(vectors[CORNER_LOD_LEFT].y); - poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x); - poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y); - ScanSectorPoly(poly, 3, ScanSectorList_Subway); - }else{ - if(f > LOD_DISTANCE){ - // priority - poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); - poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); - poly[1].x = CWorld::GetSectorX(vectors[CORNER_PRIO_LEFT].x); - poly[1].y = CWorld::GetSectorY(vectors[CORNER_PRIO_LEFT].y); - poly[2].x = CWorld::GetSectorX(vectors[CORNER_PRIO_RIGHT].x); - poly[2].y = CWorld::GetSectorY(vectors[CORNER_PRIO_RIGHT].y); - ScanSectorPoly(poly, 3, ScanSectorList_Priority); - - // below LOD - poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); - poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); - poly[1].x = CWorld::GetSectorX(vectors[CORNER_LOD_LEFT].x); - poly[1].y = CWorld::GetSectorY(vectors[CORNER_LOD_LEFT].y); - poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x); - poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y); - ScanSectorPoly(poly, 3, ScanSectorList); - }else{ - poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); - poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); - poly[1].x = CWorld::GetSectorX(vectors[CORNER_FAR_TOPLEFT].x); - poly[1].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPLEFT].y); - poly[2].x = CWorld::GetSectorX(vectors[CORNER_FAR_TOPRIGHT].x); - poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y); - ScanSectorPoly(poly, 3, ScanSectorList); - } -#ifdef NO_ISLAND_LOADING - if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) { - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_INDUSTRIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_COMMERCIAL)); - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_SUBURBAN)); - } else -#endif - { - #ifdef FIX_BUGS - if (CCollision::ms_collisionInMemory != LEVEL_GENERIC) - #endif - ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory)); - } - ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC)); - } - } - -#ifndef MASTER - if(gbShowCullZoneDebugStuff){ - sprintf(gString, "Rejected: %d/%d.", EntitiesNotRendered, EntitiesNotRendered + EntitiesRendered); - CDebug::PrintAt(gString, 10, 10); - sprintf(gString, "Tested:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d", - TestedBigBuildings, TestedBuildings, TestedPeds, TestedCars, TestedObjects, TestedDummies); - CDebug::PrintAt(gString, 10, 11); - sprintf(gString, "Rendered:BBuild:%d Build:%d Peds:%d Cars:%d Obj:%d Dummies:%d", - RenderedBigBuildings, RenderedBuildings, RenderedPeds, RenderedCars, RenderedObjects, RenderedDummies); - CDebug::PrintAt(gString, 10, 12); - } -#endif -} - -void -CRenderer::RequestObjectsInFrustum(void) -{ - float f = RwCameraGetFarClipPlane(TheCamera.m_pRwCamera); - RwV2d vw = *RwCameraGetViewWindow(TheCamera.m_pRwCamera); - CVector vectors[9]; - RwMatrix *cammatrix; - RwV2d poly[3]; - - memset(vectors, 0, sizeof(vectors)); - vectors[CORNER_FAR_TOPLEFT].x = -vw.x * f; - vectors[CORNER_FAR_TOPLEFT].y = vw.y * f; - vectors[CORNER_FAR_TOPLEFT].z = f; - vectors[CORNER_FAR_TOPRIGHT].x = vw.x * f; - vectors[CORNER_FAR_TOPRIGHT].y = vw.y * f; - vectors[CORNER_FAR_TOPRIGHT].z = f; - vectors[CORNER_FAR_BOTRIGHT].x = vw.x * f; - vectors[CORNER_FAR_BOTRIGHT].y = -vw.y * f; - vectors[CORNER_FAR_BOTRIGHT].z = f; - vectors[CORNER_FAR_BOTLEFT].x = -vw.x * f; - vectors[CORNER_FAR_BOTLEFT].y = -vw.y * f; - vectors[CORNER_FAR_BOTLEFT].z = f; - - cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); - - CWorld::AdvanceCurrentScanCode(); - - if(cammatrix->at.z > 0.0f){ - // looking up, bottom corners are further away - vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f; - vectors[CORNER_LOD_RIGHT] = vectors[CORNER_FAR_BOTRIGHT] * LOD_DISTANCE/f; - }else{ - // looking down, top corners are further away - vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_TOPLEFT] * LOD_DISTANCE/f; - vectors[CORNER_LOD_RIGHT] = vectors[CORNER_FAR_TOPRIGHT] * LOD_DISTANCE/f; - } - vectors[CORNER_PRIO_LEFT].x = vectors[CORNER_LOD_LEFT].x * 0.2f; - vectors[CORNER_PRIO_LEFT].y = vectors[CORNER_LOD_LEFT].y * 0.2f; - vectors[CORNER_PRIO_LEFT].z = vectors[CORNER_LOD_LEFT].z; - vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f; - vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f; - vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z; - RwV3dTransformPoints(vectors, vectors, 9, cammatrix); - - if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN || -#ifdef FIX_BUGS - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_GTACLASSIC || -#endif - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOP_DOWN_PED){ - CRect rect; - int x1, x2, y1, y2; - LimitFrustumVector(vectors[CORNER_FAR_TOPLEFT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_TOPLEFT]); - LimitFrustumVector(vectors[CORNER_FAR_TOPRIGHT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_TOPRIGHT]); - LimitFrustumVector(vectors[CORNER_FAR_BOTRIGHT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_BOTRIGHT]); - LimitFrustumVector(vectors[CORNER_FAR_BOTLEFT], vectors[CORNER_CAM], -100.0f); - rect.ContainPoint(vectors[CORNER_FAR_BOTLEFT]); - x1 = CWorld::GetSectorIndexX(rect.left); - if(x1 < 0) x1 = 0; - x2 = CWorld::GetSectorIndexX(rect.right); - if(x2 >= NUMSECTORS_X-1) x2 = NUMSECTORS_X-1; - y1 = CWorld::GetSectorIndexY(rect.top); - if(y1 < 0) y1 = 0; - y2 = CWorld::GetSectorIndexY(rect.bottom); - if(y2 >= NUMSECTORS_Y-1) y2 = NUMSECTORS_Y-1; - for(; x1 <= x2; x1++) - for(int y = y1; y <= y2; y++) - ScanSectorList_RequestModels(CWorld::GetSector(x1, y)->m_lists); - }else{ - poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); - poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); - poly[1].x = CWorld::GetSectorX(vectors[CORNER_LOD_LEFT].x); - poly[1].y = CWorld::GetSectorY(vectors[CORNER_LOD_LEFT].y); - poly[2].x = CWorld::GetSectorX(vectors[CORNER_LOD_RIGHT].x); - poly[2].y = CWorld::GetSectorY(vectors[CORNER_LOD_RIGHT].y); - ScanSectorPoly(poly, 3, ScanSectorList_RequestModels); - } -} - -bool -CEntity::SetupLighting(void) -{ - DeActivateDirectional(); - SetAmbientColours(); - return false; -} - -void -CEntity::RemoveLighting(bool) -{ -} - -bool -CPed::SetupLighting(void) -{ - ActivateDirectional(); - SetAmbientColoursForPedsCarsAndObjects(); - -#ifndef MASTER - // Originally this was being called through iteration of Sectors, but putting it here is better. - if (GetDebugDisplay() != 0 && !IsPlayer()) - DebugRenderOnePedText(); -#endif - - if (bRenderScorched) { - WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f); - } else { - // Note that this lightMult is only affected by LIGHT_DARKEN. If there's no LIGHT_DARKEN, it will be 1.0. - float lightMult = CPointLights::GenerateLightsAffectingObject(&GetPosition()); - if (!bHasBlip && lightMult != 1.0f) { - SetAmbientAndDirectionalColours(lightMult); - return true; - } - } - return false; -} - -void -CPed::RemoveLighting(bool reset) -{ - CRenderer::RemoveVehiclePedLights(this, reset); -} - -float -CalcNewDelta(RwV2d *a, RwV2d *b) -{ - return (b->x - a->x) / (b->y - a->y); -} - -#ifdef FIX_BUGS -#define TOINT(x) ((int)Floor(x)) -#else -#define TOINT(x) ((int)(x)) -#endif - -void -CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrList *)) -{ - float miny, maxy; - int y, yend; - int x, xstart, xend; - int i; - int a1, a2, b1, b2; - float deltaA, deltaB; - float xA, xB; - - miny = poly[0].y; - maxy = poly[0].y; - a2 = 0; - xstart = 9999; - xend = -9999; - - for(i = 1; i < numVertices; i++){ - if(poly[i].y > maxy) - maxy = poly[i].y; - if(poly[i].y < miny){ - miny = poly[i].y; - a2 = i; - } - } - y = TOINT(miny); - yend = TOINT(maxy); - - // Go left in poly to find first edge b - b2 = a2; - for(i = 0; i < numVertices; i++){ - b1 = b2--; - if(b2 < 0) b2 = numVertices-1; - if(poly[b1].x < xstart) - xstart = TOINT(poly[b1].x); - if(TOINT(poly[b1].y) != TOINT(poly[b2].y)) - break; - } - // Go right to find first edge a - for(i = 0; i < numVertices; i++){ - a1 = a2++; - if(a2 == numVertices) a2 = 0; - if(poly[a1].x > xend) - xend = TOINT(poly[a1].x); - if(TOINT(poly[a1].y) != TOINT(poly[a2].y)) - break; - } - - // prestep x1 and x2 to next integer y - deltaA = CalcNewDelta(&poly[a1], &poly[a2]); - xA = deltaA * (Ceil(poly[a1].y) - poly[a1].y) + poly[a1].x; - deltaB = CalcNewDelta(&poly[b1], &poly[b2]); - xB = deltaB * (Ceil(poly[b1].y) - poly[b1].y) + poly[b1].x; - - if(y != yend){ - if(deltaB < 0.0f && TOINT(xB) < xstart) - xstart = TOINT(xB); - if(deltaA >= 0.0f && TOINT(xA) > xend) - xend = TOINT(xA); - } - - while(y <= yend && y < NUMSECTORS_Y){ - // scan one x-line - if(y >= 0 && xstart < NUMSECTORS_X) - for(x = xstart; x <= xend && x != NUMSECTORS_X; x++) - if(x >= 0) - scanfunc(CWorld::GetSector(x, y)->m_lists); - - // advance one scan line - y++; - xA += deltaA; - xB += deltaB; - - // update left side - if(y == TOINT(poly[b2].y)){ - // reached end of edge - if(y == yend){ - if(deltaB < 0.0f){ - do{ - xstart = TOINT(poly[b2--].x); - if(b2 < 0) b2 = numVertices-1; - }while(xstart > TOINT(poly[b2].x)); - }else - xstart = TOINT(xB - deltaB); - }else{ - // switch edges - if(deltaB < 0.0f) - xstart = TOINT(poly[b2].x); - else - xstart = TOINT(xB - deltaB); - do{ - b1 = b2--; - if(b2 < 0) b2 = numVertices-1; - if(TOINT(poly[b1].x) < xstart) - xstart = TOINT(poly[b1].x); - }while(y == TOINT(poly[b2].y)); - deltaB = CalcNewDelta(&poly[b1], &poly[b2]); - xB = deltaB * (Ceil(poly[b1].y) - poly[b1].y) + poly[b1].x; - if(deltaB < 0.0f && TOINT(xB) < xstart) - xstart = TOINT(xB); - } - }else{ - if(deltaB < 0.0f) - xstart = TOINT(xB); - else - xstart = TOINT(xB - deltaB); - } - - // update right side - if(y == TOINT(poly[a2].y)){ - // reached end of edge - if(y == yend){ - if(deltaA < 0.0f) - xend = TOINT(xA - deltaA); - else{ - do{ - xend = TOINT(poly[a2++].x); - if(a2 == numVertices) a2 = 0; - }while(xend < TOINT(poly[a2].x)); - } - }else{ - // switch edges - if(deltaA < 0.0f) - xend = TOINT(xA - deltaA); - else - xend = TOINT(poly[a2].x); - do{ - a1 = a2++; - if(a2 == numVertices) a2 = 0; - if(TOINT(poly[a1].x) > xend) - xend = TOINT(poly[a1].x); - }while(y == TOINT(poly[a2].y)); - deltaA = CalcNewDelta(&poly[a1], &poly[a2]); - xA = deltaA * (Ceil(poly[a1].y) - poly[a1].y) + poly[a1].x; - if(deltaA >= 0.0f && TOINT(xA) > xend) - xend = TOINT(xA); - } - }else{ - if(deltaA < 0.0f) - xend = TOINT(xA - deltaA); - else - xend = TOINT(xA); - } - } -} - -void -CRenderer::InsertEntityIntoList(CEntity *ent) -{ -#ifdef FIX_BUGS - if (!ent->m_rwObject) return; -#endif - -#ifdef NEW_RENDERER - // TODO: there are more flags being checked here - if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed())) - ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent; - else if(gbNewRenderer && ent->IsBuilding()){ - EntityInfo info; - info.ent = ent; - info.sort = -(ent->GetPosition() - ms_vecCameraPosition).MagnitudeSqr(); - gSortedBuildings.InsertSorted(info); -// ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent; - }else -#endif - ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; -} - -void -CRenderer::ScanBigBuildingList(CPtrList &list) -{ - CPtrNode *node; - CEntity *ent; - - for(node = list.first; node; node = node->next){ - ent = (CEntity*)node->item; -#ifndef MASTER - // all missing from game actually - TestedBigBuildings++; -#endif - if(!ent->bZoneCulled || gbDisableZoneCull){ - if(SetupBigBuildingVisibility(ent) == VIS_VISIBLE) - InsertEntityIntoList(ent); -#ifndef MASTER - EntitiesRendered++; - RenderedBigBuildings++; - }else{ - EntitiesNotRendered++; -#endif - } - } -} - -void -CRenderer::ScanSectorList(CPtrList *lists) -{ - CPtrNode *node; - CPtrList *list; - CEntity *ent; - int i; - float dx, dy; - - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ - list = &lists[i]; - for(node = list->first; node; node = node->next){ - ent = (CEntity*)node->item; - if(ent->m_scanCode == CWorld::GetCurrentScanCode()) - continue; // already seen - ent->m_scanCode = CWorld::GetCurrentScanCode(); - - if(IsEntityCullZoneVisible(ent)){ - switch(SetupEntityVisibility(ent)){ - case VIS_VISIBLE: - InsertEntityIntoList(ent); - break; - case VIS_INVISIBLE: - if(!IsGlass(ent->GetModelIndex())) - break; - // fall through - case VIS_OFFSCREEN: - dx = ms_vecCameraPosition.x - ent->GetPosition().x; - dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && - ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) - ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; - break; - case VIS_STREAMME: - if(!CStreaming::ms_disableStreaming) - if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) - CStreaming::RequestModel(ent->GetModelIndex(), 0); - break; - } -#ifndef MASTER - EntitiesRendered++; - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - RenderedBigBuildings++; - else - RenderedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - RenderedCars++; - break; - case ENTITY_TYPE_PED: - RenderedPeds++; - break; - case ENTITY_TYPE_OBJECT: - RenderedObjects++; - break; - case ENTITY_TYPE_DUMMY: - RenderedDummies++; - break; - } -#endif - }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){ - if(SetupEntityVisibility(ent) == VIS_STREAMME) - if(!m_loadingPriority || CStreaming::ms_numModelsRequested < 10) - CStreaming::RequestModel(ent->GetModelIndex(), 0); - }else{ -#ifndef MASTER - EntitiesNotRendered++; -#endif - } - } - } -} - -void -CRenderer::ScanSectorList_Priority(CPtrList *lists) -{ - CPtrNode *node; - CPtrList *list; - CEntity *ent; - int i; - float dx, dy; - - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ - list = &lists[i]; - for(node = list->first; node; node = node->next){ - ent = (CEntity*)node->item; - if(ent->m_scanCode == CWorld::GetCurrentScanCode()) - continue; // already seen - ent->m_scanCode = CWorld::GetCurrentScanCode(); - - if(IsEntityCullZoneVisible(ent)){ - switch(SetupEntityVisibility(ent)){ - case VIS_VISIBLE: - InsertEntityIntoList(ent); - break; - case VIS_INVISIBLE: - if(!IsGlass(ent->GetModelIndex())) - break; - // fall through - case VIS_OFFSCREEN: - dx = ms_vecCameraPosition.x - ent->GetPosition().x; - dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && - ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) - ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; - break; - case VIS_STREAMME: - if(!CStreaming::ms_disableStreaming){ - CStreaming::RequestModel(ent->GetModelIndex(), 0); - if(CStreaming::ms_aInfoForModel[ent->GetModelIndex()].m_loadState != STREAMSTATE_LOADED) - m_loadingPriority = true; - } - break; - } -#ifndef MASTER - // actually missing in game - EntitiesRendered++; - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - RenderedBigBuildings++; - else - RenderedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - RenderedCars++; - break; - case ENTITY_TYPE_PED: - RenderedPeds++; - break; - case ENTITY_TYPE_OBJECT: - RenderedObjects++; - break; - case ENTITY_TYPE_DUMMY: - RenderedDummies++; - break; - } -#endif - }else if(IsRoad(ent) && !CStreaming::ms_disableStreaming){ - if(SetupEntityVisibility(ent) == VIS_STREAMME) - CStreaming::RequestModel(ent->GetModelIndex(), 0); - }else{ -#ifndef MASTER - // actually missing in game - EntitiesNotRendered++; -#endif - } - } - } -} - -void -CRenderer::ScanSectorList_Subway(CPtrList *lists) -{ - CPtrNode *node; - CPtrList *list; - CEntity *ent; - int i; - float dx, dy; - - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ - list = &lists[i]; - for(node = list->first; node; node = node->next){ - ent = (CEntity*)node->item; - if(ent->m_scanCode == CWorld::GetCurrentScanCode()) - continue; // already seen - ent->m_scanCode = CWorld::GetCurrentScanCode(); - switch(SetupEntityVisibility(ent)){ - case VIS_VISIBLE: - InsertEntityIntoList(ent); - break; - case VIS_OFFSCREEN: - dx = ms_vecCameraPosition.x - ent->GetPosition().x; - dy = ms_vecCameraPosition.y - ent->GetPosition().y; - if(dx > -65.0f && dx < 65.0f && - dy > -65.0f && dy < 65.0f && - ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) - ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; - break; - } - } - } -} - -void -CRenderer::ScanSectorList_RequestModels(CPtrList *lists) -{ - CPtrNode *node; - CPtrList *list; - CEntity *ent; - int i; - - for(i = 0; i < NUMSECTORENTITYLISTS; i++){ - list = &lists[i]; - for(node = list->first; node; node = node->next){ - ent = (CEntity*)node->item; - if(ent->m_scanCode == CWorld::GetCurrentScanCode()) - continue; // already seen - ent->m_scanCode = CWorld::GetCurrentScanCode(); - if(IsEntityCullZoneVisible(ent)) - if(ShouldModelBeStreamed(ent)) - CStreaming::RequestModel(ent->GetModelIndex(), 0); - } - } -} - -// Put big buildings in front -// This seems pointless because the sector lists shouldn't have big buildings in the first place -void -CRenderer::SortBIGBuildings(void) -{ - int x, y; - for(y = 0; y < NUMSECTORS_Y; y++) - for(x = 0; x < NUMSECTORS_X; x++){ - SortBIGBuildingsForSectorList(&CWorld::GetSector(x, y)->m_lists[ENTITYLIST_BUILDINGS]); - SortBIGBuildingsForSectorList(&CWorld::GetSector(x, y)->m_lists[ENTITYLIST_BUILDINGS_OVERLAP]); - } -} - -void -CRenderer::SortBIGBuildingsForSectorList(CPtrList *list) -{ - CPtrNode *node; - CEntity *ent; - - for(node = list->first; node; node = node->next){ - ent = (CEntity*)node->item; - if(ent->bIsBIGBuilding){ - list->RemoveNode(node); - list->InsertNode(node); - } - } -} - -bool -CRenderer::ShouldModelBeStreamed(CEntity *ent) -{ - CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); - float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); - if(mi->m_noFade) - return dist - STREAM_DISTANCE < mi->GetLargestLodDistance(); - else - return dist - FADE_DISTANCE - STREAM_DISTANCE < mi->GetLargestLodDistance(); -} - -bool -CRenderer::IsEntityCullZoneVisible(CEntity *ent) -{ - CPed *ped; - CObject *obj; - - if(gbDisableZoneCull) return true; - -#ifndef MASTER - switch(ent->GetType()){ - case ENTITY_TYPE_BUILDING: - if(ent->bIsBIGBuilding) - TestedBigBuildings++; - else - TestedBuildings++; - break; - case ENTITY_TYPE_VEHICLE: - TestedCars++; - break; - case ENTITY_TYPE_PED: - TestedPeds++; - break; - case ENTITY_TYPE_OBJECT: - TestedObjects++; - break; - case ENTITY_TYPE_DUMMY: - TestedDummies++; - break; - } -#endif - if(ent->bZoneCulled) - return false; - - - switch(ent->GetType()){ - case ENTITY_TYPE_VEHICLE: - return IsVehicleCullZoneVisible(ent); - case ENTITY_TYPE_PED: - ped = (CPed*)ent; - if (ped->bInVehicle) { - if (ped->m_pMyVehicle) - return IsVehicleCullZoneVisible(ped->m_pMyVehicle); - else - return true; - } - return !(ped->m_pCurSurface && ped->m_pCurSurface->bZoneCulled2); - case ENTITY_TYPE_OBJECT: - obj = (CObject*)ent; - if(!obj->GetIsStatic()) - return true; - return !(obj->m_pCurSurface && obj->m_pCurSurface->bZoneCulled2); - default: break; - } - return true; -} - -bool -CRenderer::IsVehicleCullZoneVisible(CEntity *ent) -{ - CVehicle *v = (CVehicle*)ent; - switch(v->GetStatus()) { - case STATUS_SIMPLE: - case STATUS_PHYSICS: - case STATUS_ABANDONED: - case STATUS_WRECKED: - return !(v->m_pCurGroundEntity && v->m_pCurGroundEntity->bZoneCulled2); - default: break; - } - return true; -} - -void -CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) -{ - if(ent->bRenderScorched){ - WorldReplaceScorchedLightsWithNormal(Scene.world); - return; - } - CPointLights::RemoveLightsAffectingObject(); - if(reset) - ReSetAmbientAndDirectionalColours(); -} |