diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index a8787675..e6a10267 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -4539,6 +4539,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient Rotating = false; } + if(TheCamera.m_bUseTransitionBeta) + Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); Front = CVector(Cos(Alpha) * Cos(Beta), Cos(Alpha) * Sin(Beta), Sin(Alpha)); Source = TargetCoors - Front*CamDist; diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp index 06b9a151..5663b9ab 100644 --- a/src/core/Frontend.cpp +++ b/src/core/Frontend.cpp @@ -1088,7 +1088,7 @@ CMenuManager::Draw() rightText = TheText.Get(gbShowCollisionPolys ? "FEM_ON" : "FEM_OFF"); break; case MENUACTION_SHOWCULL: - rightText = TheText.Get(gbShowCullZoneDebugStuff ? "FEM_ON" : "FEM_OFF"); + // REMOVED(MIAMI) break; case MENUACTION_SHOWHEADBOB: rightText = TheText.Get(TheCamera.m_bHeadBob ? "FEM_ON" : "FEM_OFF"); @@ -4464,7 +4464,7 @@ CMenuManager::ProcessButtonPresses(void) CGame::ReloadIPLs(); break; case MENUACTION_SHOWCULL: - gbShowCullZoneDebugStuff = !gbShowCullZoneDebugStuff; + // REMOVED(MIAMI) break; case MENUACTION_MEMCARDSAVECONFIRM: return; diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 4d6ac215..c1f0be5d 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -234,7 +234,7 @@ CStreaming::Init(void) } } #else - CStreaming::Init(); + CStreaming::Init2(); #endif } @@ -725,7 +725,7 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos) b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding && b->m_level == level) if(b->bStreamBIGBuilding){ - if(CRenderer::ShouldModelBeStreamed(b)) + if(CRenderer::ShouldModelBeStreamed(b, pos)) RequestModel(b->GetModelIndex(), 0); }else RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS); @@ -745,7 +745,7 @@ CStreaming::InstanceBigBuildings(eLevelName level, const CVector &pos) b = CPools::GetBuildingPool()->GetSlot(i); if(b && b->bIsBIGBuilding && b->m_level == level && b->bStreamBIGBuilding && b->m_rwObject == nil) - if(CRenderer::ShouldModelBeStreamed(b)) + if(CRenderer::ShouldModelBeStreamed(b, pos)) b->CreateRwObject(); } } diff --git a/src/core/main.cpp b/src/core/main.cpp index 6bf8228d..00ae3774 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -778,14 +778,17 @@ RenderScene(void) DoRWRenderHorizon(); CRenderer::RenderRoads(); CCoronas::RenderReflections(); - RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); CRenderer::RenderEverythingBarRoads(); - CRenderer::RenderBoats(); - DefinedState(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWaterLevel::RenderWater(); + CRenderer::RenderBoats(); + CRenderer::RenderFadingInUnderwaterEntities(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); + // CWaterLevel::RenderTransparentWater(); CRenderer::RenderFadingInEntities(); - CRenderer::RenderVehiclesButNotBoats(); + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); CWeather::RenderRainStreaks(); + // CCoronas::RenderSunReflection } void diff --git a/src/core/re3.cpp b/src/core/re3.cpp index 8ed27eef..1915e135 100644 --- a/src/core/re3.cpp +++ b/src/core/re3.cpp @@ -329,6 +329,7 @@ DebugMenuPopulate(void) DebugMenuAddCmd("Spawn", "Spawn Predator", [](){ SpawnCar(MI_PREDATOR); }); DebugMenuAddVarBool8("Render", "Draw hud", &CHud::m_Wants_To_Draw_Hud, nil); + DebugMenuAddVarBool8("Render", "Backface Culling", &gBackfaceCulling, nil); #ifdef LIBRW DebugMenuAddVarBool8("Render", "PS2 Alpha test Emu", &gPS2alphaTest, nil); #endif diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp index e3ecf50f..1e00b129 100644 --- a/src/entities/Entity.cpp +++ b/src/entities/Entity.cpp @@ -53,16 +53,16 @@ CEntity::CEntity(void) bHasBlip = false; bIsBIGBuilding = false; bStreamBIGBuilding = false; - bRenderDamaged = false; + bRenderDamaged = false; bBulletProof = false; bFireProof = false; bCollisionProof = false; bMeleeProof = false; bOnlyDamagedByPlayer = false; bStreamingDontDelete = false; - bRemoveFromWorld = false; + bHasHitWall = false; bImBeingRendered = false; bTouchingWater = false; @@ -70,11 +70,15 @@ CEntity::CEntity(void) bDrawLast = false; bNoBrightHeadLights = false; bDoNotRender = false; - bDistanceFade = false; - m_flagE2 = false; + m_flagE1 = false; + m_flagE2 = false; + bOffscreen = false; bIsStaticWaitingForCollision = false; + m_flagE10 = false; + m_flagE20 = false; + m_flagE40 = false; m_scanCode = 0; m_modelIndex = -1; @@ -924,6 +928,7 @@ CEntity::AddSteamsFromGround(CPtrList& list) } #ifdef COMPATIBLE_SAVES +// TODO(MIAMI) void CEntity::SaveEntityFlags(uint8*& buf) { @@ -955,26 +960,27 @@ CEntity::SaveEntityFlags(uint8*& buf) if (bMeleeProof) tmp |= BIT(27); if (bOnlyDamagedByPlayer) tmp |= BIT(28); if (bStreamingDontDelete) tmp |= BIT(29); + if (bRemoveFromWorld) tmp |= BIT(0); + if (bHasHitWall) tmp |= BIT(1); WriteSaveBuf(buf, tmp); tmp = 0; - if (bRemoveFromWorld) tmp |= BIT(0); - if (bHasHitWall) tmp |= BIT(1); if (bImBeingRendered) tmp |= BIT(2); if (bTouchingWater) tmp |= BIT(3); if (bIsSubway) tmp |= BIT(4); if (bDrawLast) tmp |= BIT(5); if (bNoBrightHeadLights) tmp |= BIT(6); if (bDoNotRender) tmp |= BIT(7); - if (bDistanceFade) tmp |= BIT(8); + if (m_flagE2) tmp |= BIT(9); WriteSaveBuf(buf, tmp); } +// TODO(MIAMI) void CEntity::LoadEntityFlags(uint8*& buf) { @@ -1006,19 +1012,19 @@ CEntity::LoadEntityFlags(uint8*& buf) bMeleeProof = !!(tmp & BIT(27)); bOnlyDamagedByPlayer = !!(tmp & BIT(28)); bStreamingDontDelete = !!(tmp & BIT(29)); + bRemoveFromWorld = !!(tmp & BIT(0)); + bHasHitWall = !!(tmp & BIT(1)); tmp = ReadSaveBuf(buf); - bRemoveFromWorld = !!(tmp & BIT(0)); - bHasHitWall = !!(tmp & BIT(1)); bImBeingRendered = !!(tmp & BIT(2)); bTouchingWater = !!(tmp & BIT(3)); bIsSubway = !!(tmp & BIT(4)); bDrawLast = !!(tmp & BIT(5)); bNoBrightHeadLights = !!(tmp & BIT(6)); bDoNotRender = !!(tmp & BIT(7)); - bDistanceFade = !!(tmp & BIT(8)); + m_flagE2 = !!(tmp & BIT(9)); } diff --git a/src/entities/Entity.h b/src/entities/Entity.h index 2e2c64c0..b8f8c80c 100644 --- a/src/entities/Entity.h +++ b/src/entities/Entity.h @@ -82,9 +82,13 @@ public: uint32 bDistanceFade : 1; // Fade entity because it is far away // flagsE + uint32 m_flagE1 : 1; uint32 m_flagE2 : 1; - // TODO(MIAMI) + uint32 bOffscreen : 1; // offscreen flag. This can only be trusted when it is set to true uint32 bIsStaticWaitingForCollision : 1; // this is used by script created entities - they are static until the collision is loaded below them + uint32 m_flagE10 : 1; + uint32 m_flagE20 : 1; + uint32 m_flagE40 : 1; uint16 m_scanCode; uint16 m_randomSeed; @@ -151,6 +155,8 @@ public: bool GetIsOnScreenComplex(void); bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); } bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); } +// TODO(MIAMI): + bool IsEntityOccluded(void) { return false; } int16 GetModelIndex(void) const { return m_modelIndex; } void UpdateRwFrame(void); void SetupBigBuilding(void); diff --git a/src/render/Occlusion.cpp b/src/render/Occlusion.cpp new file mode 100644 index 00000000..b33b1d01 --- /dev/null +++ b/src/render/Occlusion.cpp @@ -0,0 +1,8 @@ +#include "common.h" + +#include "Occlusion.h" + +void +COcclusion::ProcessBeforeRendering(void) +{ +} diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h new file mode 100644 index 00000000..977649b8 --- /dev/null +++ b/src/render/Occlusion.h @@ -0,0 +1,7 @@ +#pragma once + +class COcclusion +{ +public: + static void ProcessBeforeRendering(void); +}; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index ac501919..406edc9f 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -18,11 +18,13 @@ #include "Streaming.h" #include "Shadows.h" #include "PointLights.h" +#include "Occlusion.h" #include "Renderer.h" +//--MIAMI: file almost done, just one bike flag left + bool gbShowCollisionPolys; bool gbShowCollisionLines; -bool gbShowCullZoneDebugStuff; bool gbBigWhiteDebugLightSwitchedOn; bool gbDontRenderBuildings; @@ -140,8 +142,10 @@ CRenderer::RenderOneNonRoad(CEntity *e) resetLights = e->SetupLighting(); - if(e->IsVehicle()) + if(e->IsVehicle()){ + CVisibilityPlugins::SetupVehicleVariables(e->GetClump()); CVisibilityPlugins::InitAlphaAtomicList(); + } // Render Peds in vehicle before vehicle itself if(e->IsVehicle()){ @@ -151,6 +155,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) for(i = 0; i < 8; i++) if(veh->pPassengers[i] && veh->pPassengers[i]->m_nPedState == PED_DRIVING) veh->pPassengers[i]->Render(); + SetCullMode(rwCULLMODECULLNONE); } e->Render(); @@ -158,6 +163,7 @@ CRenderer::RenderOneNonRoad(CEntity *e) e->bImBeingRendered = true; CVisibilityPlugins::RenderAlphaAtomics(); e->bImBeingRendered = false; + SetCullMode(rwCULLMODECULLBACK); } e->RemoveLighting(resetLights); @@ -178,24 +184,40 @@ CRenderer::RenderFirstPersonVehicle(void) RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); } +inline bool IsRoad(CEntity *e) { return e->IsBuilding() && ((CSimpleModelInfo*)CModelInfo::GetModelInfo(e->GetModelIndex()))->m_wetRoadReflection; } + void CRenderer::RenderRoads(void) { int i; - CTreadable *t; + CEntity *e; RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ - t = (CTreadable*)ms_aVisibleEntityPtrs[i]; - if(t->IsBuilding() && t->GetIsATreadable()){ - RenderOneRoad(t); - } + e = ms_aVisibleEntityPtrs[i]; + if(IsRoad(e)) + RenderOneRoad(e); } } +inline bool PutIntoSortedVehicleList(CVehicle *veh) +{ + if(veh->IsBoat()){ + int mode = TheCamera.Cams[TheCamera.ActiveCam].Mode; + if(mode == CCam::MODE_WHEELCAM || + mode == CCam::MODE_1STPERSON && TheCamera.GetLookDirection() != LOOKING_FORWARD && TheCamera.GetLookDirection() != LOOKING_BEHIND || + CVisibilityPlugins::GetClumpAlpha(veh->GetClump()) != 255) + return false; + return true; + }else + return veh->bTouchingWater; +} + void CRenderer::RenderEverythingBarRoads(void) { @@ -204,17 +226,20 @@ CRenderer::RenderEverythingBarRoads(void) CVector dist; EntityInfo ei; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); gSortedVehiclesAndPeds.Clear(); for(i = 0; i < ms_nNoOfVisibleEntities; i++){ e = ms_aVisibleEntityPtrs[i]; - if(e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable()) + if(IsRoad(e)) continue; if(e->IsVehicle() || e->IsPed() && CVisibilityPlugins::GetClumpAlpha((RpClump*)e->m_rwObject) != 255){ - if(e->IsVehicle() && ((CVehicle*)e)->IsBoat()){ + if(e->IsVehicle() && PutIntoSortedVehicleList((CVehicle*)e)){ ei.ent = e; dist = ms_vecCameraPosition - e->GetPosition(); ei.sort = dist.MagnitudeSqr(); @@ -231,28 +256,15 @@ CRenderer::RenderEverythingBarRoads(void) } } -void -CRenderer::RenderVehiclesButNotBoats(void) -{ - // This function doesn't do anything - // because only boats are inserted into the list - CLink *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 *node; + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); + for(node = gSortedVehiclesAndPeds.tail.prev; node != &gSortedVehiclesAndPeds.head; node = node->prev){ @@ -267,11 +279,21 @@ void CRenderer::RenderFadingInEntities(void) { RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE); + RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); + SetCullMode(rwCULLMODECULLBACK); DeActivateDirectional(); SetAmbientColours(); CVisibilityPlugins::RenderFadingEntities(); } +void +CRenderer::RenderFadingInUnderwaterEntities(void) +{ + DeActivateDirectional(); + SetAmbientColours(); + CVisibilityPlugins::RenderFadingUnderwaterEntities(); +} + void CRenderer::RenderCollisionLines(void) { @@ -332,44 +354,57 @@ CRenderer::SetupEntityVisibility(CEntity *ent) request = false; } }else{ -// TODO(MIAMI): weapon - if(mi->GetModelType() != MITYPE_SIMPLE){ + if(mi->GetModelType() != MITYPE_SIMPLE && mi->GetModelType() != MITYPE_WEAPON){ if(FindPlayerVehicle() == ent && - TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){ + TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON && +//TODO(MIAMI): that bike flag + (!FindPlayerVehicle()->IsBike() || true)){ // Player's vehicle in first person mode - if(TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_FORWARD || + CVehicle *veh = (CVehicle*)ent; + int model = veh->GetModelIndex(); + int direction = TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking; + if(direction == LOOKING_FORWARD || ent->GetModelIndex() == MI_RHINO || ent->GetModelIndex() == MI_COACH || - TheCamera.m_bInATunnelAndABigVehicle){ + TheCamera.m_bInATunnelAndABigVehicle || + direction == LOOKING_BEHIND && veh->pHandling->Flags & HANDLING_UNKNOWN){ ent->bNoBrightHeadLights = true; - }else{ + return VIS_OFFSCREEN; + } + + if(direction != LOOKING_BEHIND || + !veh->IsBoat() || model == MI_REEFER || model == MI_TROPIC || model == MI_PREDATOR || model == MI_SKIMMER){ m_pFirstPersonVehicle = (CVehicle*)ent; ent->bNoBrightHeadLights = false; - } - return VIS_OFFSCREEN; - }else{ - // All sorts of Clumps - if(ent->m_rwObject == nil || !ent->bIsVisible) - return VIS_INVISIBLE; -// TODO(MIAMI): occlusion - 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; - }else - return VIS_VISIBLE; + } } - return VIS_INVISIBLE; - } -// TODO(MIAMI): this is different - if(ent->IsObject() && - ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){ + + // All sorts of Clumps if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - return ent->GetIsOnScreen() ? VIS_VISIBLE : VIS_OFFSCREEN; + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()) + 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->m_flagE10){ + if(ent->m_rwObject == nil || !ent->bIsVisible) + return VIS_INVISIBLE; + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()) + 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; } } @@ -380,8 +415,14 @@ CRenderer::SetupEntityVisibility(CEntity *ent) dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); +#ifndef FIX_BUGS + // Whatever this is supposed to do, it breaks fading for objects + // whose draw dist is > LOD_DISTANCE-FADE_DISTANCE, i.e. 280 + // because decreasing dist here makes the object visible above LOD_DISTANCE + // before fading normally once below LOD_DISTANCE. if(LOD_DISTANCE < dist && dist < mi->GetLargestLodDistance() + FADE_DISTANCE) - dist += mi->GetLargestLodDistance() - 300.0f; + dist += mi->GetLargestLodDistance() - LOD_DISTANCE; +#endif if(ent->IsObject() && ent->bRenderDamaged) mi->m_isDamaged = true; @@ -401,7 +442,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; - if(!ent->GetIsOnScreen()){ + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){ mi->m_alpha = 255; return VIS_OFFSCREEN; } @@ -452,8 +493,7 @@ CRenderer::SetupEntityVisibility(CEntity *ent) if(ent->m_rwObject == nil || !ent->bIsVisible) return VIS_INVISIBLE; -// TODO(MIAMI): occlusion - if(!ent->GetIsOnScreen()){ + if(!ent->GetIsOnScreen() || ent->IsEntityOccluded()){ mi->m_alpha = 255; return VIS_OFFSCREEN; }else{ @@ -528,8 +568,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) mi->IncreaseAlpha(); -// TODO(MIAMI): occlusion - if(!ent->IsVisibleComplex()){ + if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){ mi->m_alpha = 255; return VIS_INVISIBLE; } @@ -573,18 +612,20 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent) if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj)) RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) mi->IncreaseAlpha(); -// TODO(MIAMI): occlusion - if(ent->IsVisibleComplex()){ - CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); - ent->bDistanceFade = true; - }else + if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){ mi->m_alpha = 255; + return VIS_INVISIBLE; + } + CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist); + ent->bDistanceFade = true; return VIS_INVISIBLE; } void CRenderer::ConstructRenderList(void) { + COcclusion::ProcessBeforeRendering(); + ms_nNoOfVisibleEntities = 0; ms_nNoOfInVisibleEntities = 0; ms_vecCameraPosition = TheCamera.GetPosition(); @@ -644,6 +685,15 @@ CRenderer::ScanWorld(void) CVisibilityPlugins::InitAlphaEntityList(); CWorld::AdvanceCurrentScanCode(); + // unused + static CVector prevPos; + static CVector prevFwd; + static bool smallMovement; + smallMovement = (TheCamera.GetPosition() - prevPos).MagnitudeSqr() < SQR(4.0f) && + DotProduct(TheCamera.GetForward(), prevFwd) > 0.98f; + prevPos = TheCamera.GetPosition(); + prevFwd = TheCamera.GetForward(); + if(cammatrix->at.z > 0.0f){ // looking up, bottom corners are further away vectors[CORNER_LOD_LEFT] = vectors[CORNER_FAR_BOTLEFT] * LOD_DISTANCE/f; @@ -689,6 +739,7 @@ CRenderer::ScanWorld(void) for(int y = y1; y <= y2; y++) ScanSectorList(CWorld::GetSector(x1, y)->m_lists); }else{ +#ifdef GTA_TRAIN CVehicle *train = FindPlayerTrain(); if(train && train->GetPosition().z < 0.0f){ poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); @@ -698,7 +749,9 @@ CRenderer::ScanWorld(void) 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{ + }else +#endif + { if(f <= LOD_DISTANCE){ poly[0].x = CWorld::GetSectorX(vectors[CORNER_CAM].x); poly[0].y = CWorld::GetSectorY(vectors[CORNER_CAM].y); @@ -758,6 +811,7 @@ CRenderer::RequestObjectsInFrustum(void) cammatrix = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)); CWorld::AdvanceCurrentScanCode(); + ms_vecCameraPosition = TheCamera.GetPosition(); if(cammatrix->at.z > 0.0f){ // looking up, bottom corners are further away @@ -970,13 +1024,20 @@ CRenderer::ScanBigBuildingList(CPtrList &list) { CPtrNode *node; CEntity *ent; + int vis; - // TODO(MIAMI): some flags and such + int f = CTimer::GetFrameCounter() & 3; for(node = list.first; node; node = node->next){ ent = (CEntity*)node->item; - switch(SetupBigBuildingVisibility(ent)){ + if(ent->bOffscreen || (ent->m_randomSeed&3) != f){ + ent->bOffscreen = true; + vis = SetupBigBuildingVisibility(ent); + }else + vis = VIS_VISIBLE; + switch(vis){ case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; + ent->bOffscreen = false; break; case VIS_STREAMME: if(!CStreaming::ms_disableStreaming) @@ -1002,6 +1063,7 @@ CRenderer::ScanSectorList(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: @@ -1012,10 +1074,11 @@ CRenderer::ScanSectorList(CPtrList *lists) break; // fall through case VIS_OFFSCREEN: + ent->bOffscreen = true; 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 && + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; break; @@ -1045,6 +1108,7 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: @@ -1055,10 +1119,11 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) break; // fall through case VIS_OFFSCREEN: + ent->bOffscreen = true; 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 && + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; break; @@ -1074,6 +1139,7 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists) } } +#ifdef GTA_TRAIN void CRenderer::ScanSectorList_Subway(CPtrList *lists) { @@ -1090,15 +1156,17 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); + ent->bOffscreen = false; switch(SetupEntityVisibility(ent)){ case VIS_VISIBLE: ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent; break; case VIS_OFFSCREEN: + ent->bOffscreen = true; 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 && + if(dx > -30.0f && dx < 30.0f && + dy > -30.0f && dy < 30.0f && ms_nNoOfInVisibleEntities < NUMINVISIBLEENTITIES - 1) ms_aInVisibleEntityPtrs[ms_nNoOfInVisibleEntities++] = ent; break; @@ -1106,6 +1174,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists) } } } +#endif void CRenderer::ScanSectorList_RequestModels(CPtrList *lists) @@ -1122,7 +1191,7 @@ CRenderer::ScanSectorList_RequestModels(CPtrList *lists) if(ent->m_scanCode == CWorld::GetCurrentScanCode()) continue; // already seen ent->m_scanCode = CWorld::GetCurrentScanCode(); - if(ShouldModelBeStreamed(ent)) + if(ShouldModelBeStreamed(ent, ms_vecCameraPosition)) CStreaming::RequestModel(ent->GetModelIndex(), 0); } } @@ -1157,10 +1226,15 @@ CRenderer::SortBIGBuildingsForSectorList(CPtrList *list) } bool -CRenderer::ShouldModelBeStreamed(CEntity *ent) +CRenderer::ShouldModelBeStreamed(CEntity *ent, const CVector &campos) { - CSimpleModelInfo *mi = (CSimpleModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); - float dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude(); + if(!IsAreaVisible(ent->m_area)) + return false; + CTimeModelInfo *mi = (CTimeModelInfo *)CModelInfo::GetModelInfo(ent->GetModelIndex()); + if(mi->GetModelType() == MITYPE_TIME) + if(!CClock::GetIsTimeInRange(mi->GetTimeOn(), mi->GetTimeOff())) + return false; + float dist = (ent->GetPosition() - campos).Magnitude(); if(mi->m_noFade) return dist - STREAM_DISTANCE < mi->GetLargestLodDistance(); else @@ -1171,7 +1245,7 @@ void CRenderer::RemoveVehiclePedLights(CEntity *ent, bool reset) { if(ent->bRenderScorched) - WorldReplaceScorchedLightsWithNormal(Scene.world); + return; CPointLights::RemoveLightsAffectingObject(); if(reset) ReSetAmbientAndDirectionalColours(); diff --git a/src/render/Renderer.h b/src/render/Renderer.h index dc643722..e9f82078 100644 --- a/src/render/Renderer.h +++ b/src/render/Renderer.h @@ -4,7 +4,6 @@ class CEntity; extern bool gbShowCollisionPolys; extern bool gbShowCollisionLines; -extern bool gbShowCullZoneDebugStuff; extern bool gbBigWhiteDebugLightSwitchedOn; extern bool gbDontRenderBuildings; @@ -36,8 +35,8 @@ public: static void RenderRoads(void); static void RenderFadingInEntities(void); + static void RenderFadingInUnderwaterEntities(void); static void RenderEverythingBarRoads(void); - static void RenderVehiclesButNotBoats(void); static void RenderBoats(void); static void RenderOneRoad(CEntity *); static void RenderOneNonRoad(CEntity *); @@ -61,7 +60,7 @@ public: static void SortBIGBuildings(void); static void SortBIGBuildingsForSectorList(CPtrList *list); - static bool ShouldModelBeStreamed(CEntity *ent); + static bool ShouldModelBeStreamed(CEntity *ent, const CVector &campos); static void RemoveVehiclePedLights(CEntity *ent, bool reset); }; diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index cb1d4ab5..525c2910 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -12,6 +12,7 @@ RtCharset *debugCharset; #endif bool gPS2alphaTest = 1; +bool gBackfaceCulling; #ifndef FINAL static bool charsetOpen; @@ -116,6 +117,15 @@ DefinedState(void) #endif } +void +SetCullMode(uint32 mode) +{ + if(gBackfaceCulling) + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)mode); + else + RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE); +} + RwFrame* GetFirstFrameCallback(RwFrame *child, void *data) { diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index a751ee39..993acd89 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -1,6 +1,7 @@ #pragma once extern bool gPS2alphaTest; +extern bool gBackfaceCulling; void *RwMallocAlign(RwUInt32 size, RwUInt32 align); void RwFreeAlign(void *mem); @@ -11,6 +12,7 @@ void DestroyDebugFont(); void ObrsPrintfString(const char *str, short x, short y); void FlushObrsPrintfs(); void DefinedState(void); +void SetCullMode(uint32 mode); RwFrame *GetFirstChild(RwFrame *frame); RwObject *GetFirstObject(RwFrame *frame); RpAtomic *GetFirstAtomic(RpClump *clump); diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp index c24677e0..fe2ad06f 100644 --- a/src/rw/VisibilityPlugins.cpp +++ b/src/rw/VisibilityPlugins.cpp @@ -111,6 +111,11 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera) ms_pedFadeDist = sq(70.0f * TheCamera.LODDistMultiplier); } +void +CVisibilityPlugins::SetupVehicleVariables(RpClump *vehicle) +{ +} + RpMaterial* SetAlphaCB(RpMaterial *material, void *data) { @@ -164,6 +169,11 @@ CVisibilityPlugins::RenderFadingEntities(void) } } +void +CVisibilityPlugins::RenderFadingUnderwaterEntities(void) +{ +} + RpAtomic* CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic) { @@ -237,6 +247,7 @@ CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic) return atomic; } +//--MIAMI: done RpAtomic* CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) { @@ -247,29 +258,30 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist) mi = GetAtomicModelInfo(atomic); lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE); - if(mi->m_additive){ - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + if(mi->m_additive) AtomicDefaultRenderCallBack(atomic); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - }else{ - fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE; - if(fadefactor > 1.0f) - fadefactor = 1.0f; - alpha = mi->m_alpha * fadefactor; - if(alpha == 255) - AtomicDefaultRenderCallBack(atomic); - else{ - RpGeometry *geo = RpAtomicGetGeometry(lodatm); - uint32 flags = RpGeometryGetFlags(geo); - RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR); - RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); - if(geo != RpAtomicGetGeometry(atomic)) - RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) - AtomicDefaultRenderCallBack(atomic); - RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); - RpGeometrySetFlags(geo, flags); - } + + fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE; + if(fadefactor > 1.0f) + fadefactor = 1.0f; + alpha = mi->m_alpha * fadefactor; + if(alpha == 255) + AtomicDefaultRenderCallBack(atomic); + else{ + RpGeometry *geo = RpAtomicGetGeometry(lodatm); + uint32 flags = RpGeometryGetFlags(geo); + RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha); + if(geo != RpAtomicGetGeometry(atomic)) + RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?) + AtomicDefaultRenderCallBack(atomic); + RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255); + RpGeometrySetFlags(geo, flags); } + + if(mi->m_additive) + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + return atomic; } diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h index 3f20044f..d21562b6 100644 --- a/src/rw/VisibilityPlugins.h +++ b/src/rw/VisibilityPlugins.h @@ -42,6 +42,7 @@ public: static bool InsertAtomicIntoSortedList(RpAtomic *a, float dist); static void SetRenderWareCamera(RwCamera *camera); + static void SetupVehicleVariables(RpClump *vehicle); static RpAtomic *RenderWheelAtomicCB(RpAtomic *atomic); static RpAtomic *RenderObjNormalAtomic(RpAtomic *atomic); @@ -70,11 +71,11 @@ public: static void RenderAlphaAtomics(void); static void RenderFadingEntities(void); + static void RenderFadingUnderwaterEntities(void); // All actually unused static bool DefaultVisibilityCB(RpClump *clump); static bool FrustumSphereCB(RpClump *clump); - static bool MloVisibilityCB(RpClump *clump); static bool VehicleVisibilityCB(RpClump *clump); static bool VehicleVisibilityCB_BigVehicle(RpClump *clump); diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h index b6afd81d..e629d885 100644 --- a/src/vehicles/HandlingMgr.h +++ b/src/vehicles/HandlingMgr.h @@ -141,6 +141,7 @@ enum HANDLING_FAT_REARW = 0x1000000, HANDLING_NARROW_FRONTW = 0x2000000, HANDLING_GOOD_INSAND = 0x4000000, + HANDLING_UNKNOWN = 0x8000000, // something for helis and planes }; struct tHandlingData