summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/Frontend.cpp4
-rw-r--r--src/core/Streaming.cpp6
-rw-r--r--src/core/main.cpp11
-rw-r--r--src/core/re3.cpp1
-rw-r--r--src/entities/Entity.cpp26
-rw-r--r--src/entities/Entity.h8
-rw-r--r--src/render/Occlusion.cpp8
-rw-r--r--src/render/Occlusion.h7
-rw-r--r--src/render/Renderer.cpp226
-rw-r--r--src/render/Renderer.h5
-rw-r--r--src/rw/RwHelper.cpp10
-rw-r--r--src/rw/RwHelper.h2
-rw-r--r--src/rw/VisibilityPlugins.cpp54
-rw-r--r--src/rw/VisibilityPlugins.h3
-rw-r--r--src/vehicles/HandlingMgr.h1
15 files changed, 251 insertions, 121 deletions
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<uint32>(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<uint32>(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<uint32>(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();
@@ -232,27 +257,14 @@ CRenderer::RenderEverythingBarRoads(void)
}
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;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
+
for(node = gSortedVehiclesAndPeds.tail.prev;
node != &gSortedVehiclesAndPeds.head;
node = node->prev){
@@ -267,12 +279,22 @@ 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)
{
int i;
@@ -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;
}
+ }
+
+ // All sorts of Clumps
+ if(ent->m_rwObject == nil || !ent->bIsVisible)
+ return VIS_INVISIBLE;
+ if(!ent->GetIsOnScreen() || ent->IsEntityOccluded())
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;
+ if(ent->bDrawLast){
+ dist = (ent->GetPosition() - ms_vecCameraPosition).Magnitude();
+ CVisibilityPlugins::InsertEntityIntoSortedList(ent, dist);
+ ent->bDistanceFade = false;
+ return VIS_INVISIBLE;
}
- return VIS_INVISIBLE;
+ return VIS_VISIBLE;
}
-// TODO(MIAMI): this is different
- if(ent->IsObject() &&
- ((CObject*)ent)->ObjectCreatedBy == TEMP_OBJECT){
+ if(ent->m_flagE10){
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;
}
}
@@ -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