summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/main.cpp22
-rw-r--r--src/render/Renderer.cpp144
-rw-r--r--src/render/Renderer.h2
-rw-r--r--src/vehicles/Boat.cpp20
-rw-r--r--src/vehicles/Boat.h3
5 files changed, 145 insertions, 46 deletions
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 0b3bb549..a057e55b 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -109,6 +109,9 @@ void DebugMenuPopulate(void);
#ifdef NEW_RENDERER
bool gbNewRenderer;
+#define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL)
+#else
+#define CLEARMODE (rwCAMERACLEARZ)
#endif
void
@@ -155,7 +158,7 @@ DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomR
CDraw::CalculateAspectRatio();
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &TopColor.rwRGBA, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &TopColor.rwRGBA, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
@@ -174,7 +177,7 @@ DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16
CDraw::CalculateAspectRatio();
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
@@ -873,7 +876,7 @@ MattRenderScene(void)
// CMattRenderer::ResetRenderStates
CRenderer::ClearForFrame();
// CClock::CalcEnvMapTimeMultiplicator
-if(gbRenderWater)
+//if(gbRenderWater)
CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater
// CClock::ms_EnvMapTimeMultiplicator = 1.0f;
// cWorldStream::ClearDynamics
@@ -889,10 +892,12 @@ if(gbRenderRoads)
CRenderer::RenderRoads();
// not sure where to put these since LCS has no underwater entities
+if(gbRenderBoats)
+ CRenderer::RenderBoats();
if(gbRenderFadingInUnderwaterEntities)
CRenderer::RenderFadingInUnderwaterEntities();
if(gbRenderWater)
- CWaterLevel::RenderTransparentWater();
+ CRenderer::RenderTransparentWater();
if(gbRenderEverythingBarRoads)
CRenderer::RenderEverythingBarRoads();
@@ -910,8 +915,7 @@ RenderScene_new(void)
MattRenderScene();
DefinedState();
// CMattRenderer::ResetRenderStates
-if(gbRenderBoats)
- CRenderer::RenderBoats();
+ // moved CRenderer::RenderBoats to before transparent water
}
// TODO
@@ -1259,7 +1263,7 @@ Idle(void *arg)
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
#endif
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return;
}
@@ -1308,7 +1312,7 @@ FrontendIdle(void)
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return;
@@ -1584,7 +1588,7 @@ void TheGame(void)
{
CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if (!RsCameraBeginUpdate(Scene.camera))
break;
}
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 5ff5aa22..01600c0d 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -7,6 +7,7 @@
#include "Treadable.h"
#include "Ped.h"
#include "Vehicle.h"
+#include "Boat.h"
#include "Heli.h"
#include "Bike.h"
#include "Object.h"
@@ -334,6 +335,7 @@ CRenderer::RenderBoats(void)
#ifndef LIBRW
#error "Need librw for EXTENDED_PIPELINES"
#endif
+#include "WaterLevel.h"
enum {
// blend passes
@@ -356,6 +358,34 @@ static BuildingInst blendInsts[3][2000];
static int numBlendInsts[3];
static void
+SetStencilState(int state)
+{
+ switch(state){
+ // disable stencil
+ case 0:
+ rw::d3d::setRenderState(D3DRS_STENCILENABLE, FALSE);
+ break;
+ // test against stencil
+ case 1:
+ rw::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE);
+ rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);
+ rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+ rw::d3d::setRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ rw::d3d::setRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ rw::d3d::setRenderState(D3DRS_STENCILMASK, 0xFF);
+ rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF);
+ break;
+ // write to stencil
+ case 2:
+ rw::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE);
+ rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+ rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF);
+ break;
+ }
+}
+
+static void
SetMatrix(BuildingInst *building, rw::Matrix *worldMat)
{
using namespace rw;
@@ -448,6 +478,7 @@ AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
assert(building->instHeader != nil);
assert(building->instHeader->platform == PLATFORM_D3D9);
building->fadeAlpha = fadeAlpha;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
SetMatrix(building, atomic->getFrame()->getLTM());
numBlendInsts[pass]++;
}
@@ -506,6 +537,30 @@ struct BuildingInst
static BuildingInst blendInsts[3][2000];
static int numBlendInsts[3];
+static void
+SetStencilState(int state)
+{
+ switch(state){
+ // disable stencil
+ case 0:
+ glDisable(GL_STENCIL_TEST);
+ break;
+ // test against stencil
+ case 1:
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_NOTEQUAL, 0xFF, 0xFF);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ glStencilMask(0xFF);
+ break;
+ // write to stencil
+ case 2:
+ glEnable(GL_STENCIL_TEST);
+ glStencilFunc(GL_ALWAYS, 0xFF, 0xFF);
+ glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ break;
+ }
+}
+
static bool
IsTextureTransparent(RwTexture *tex)
{
@@ -595,6 +650,7 @@ AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
assert(building->instHeader != nil);
assert(building->instHeader->platform == PLATFORM_GL3);
building->fadeAlpha = fadeAlpha;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
building->matrix = *atomic->getFrame()->getLTM();
numBlendInsts[pass]++;
}
@@ -643,6 +699,9 @@ RenderBlendPass(int pass)
drawInst(building->instHeader, inst);
}
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs);
+#endif
}
}
#endif
@@ -774,6 +833,37 @@ CRenderer::RenderVehiclesAndPeds(void)
}
void
+CRenderer::RenderTransparentWater(void)
+{
+ int i;
+ CEntity *e;
+
+ 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::RenderTransparentWater();
+
+ SetStencilState(0);
+}
+
+void
CRenderer::ClearForFrame(void)
{
ms_nNoOfVisibleEntities = 0;
@@ -1541,6 +1631,20 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
}
void
+CRenderer::InsertEntityIntoList(CEntity *ent)
+{
+#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())
+ ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
+ else
+#endif
+ ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+}
+
+void
CRenderer::ScanBigBuildingList(CPtrList &list)
{
CPtrNode *node;
@@ -1557,15 +1661,7 @@ CRenderer::ScanBigBuildingList(CPtrList &list)
vis = VIS_VISIBLE;
switch(vis){
case VIS_VISIBLE:
-#ifdef NEW_RENDERER
- // TODO: this isn't quite right...
- if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
- ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
- else if(gbNewRenderer && ent->IsBuilding())
- ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
- else
-#endif
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ InsertEntityIntoList(ent);
ent->bOffscreen = false;
break;
case VIS_STREAMME:
@@ -1596,15 +1692,7 @@ CRenderer::ScanSectorList(CPtrList *lists)
switch(SetupEntityVisibility(ent)){
case VIS_VISIBLE:
-#ifdef NEW_RENDERER
- // TODO: this isn't quite right...
- if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
- ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
- else if(gbNewRenderer && ent->IsBuilding())
- ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
- else
-#endif
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ InsertEntityIntoList(ent);
break;
case VIS_INVISIBLE:
if(!IsGlass(ent->GetModelIndex()))
@@ -1649,15 +1737,7 @@ CRenderer::ScanSectorList_Priority(CPtrList *lists)
switch(SetupEntityVisibility(ent)){
case VIS_VISIBLE:
-#ifdef NEW_RENDERER
- // TODO: this isn't quite right...
- if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
- ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
- else if(gbNewRenderer && ent->IsBuilding())
- ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
- else
-#endif
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ InsertEntityIntoList(ent);
break;
case VIS_INVISIBLE:
if(!IsGlass(ent->GetModelIndex()))
@@ -1704,15 +1784,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
ent->bOffscreen = false;
switch(SetupEntityVisibility(ent)){
case VIS_VISIBLE:
-#ifdef NEW_RENDERER
- // TODO: this isn't quite right...
- if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
- ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
- else if(gbNewRenderer && ent->IsBuilding())
- ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
- else
-#endif
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ InsertEntityIntoList(ent);
break;
case VIS_OFFSCREEN:
ent->bOffscreen = true;
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index 814d3105..ec9d9023 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -77,5 +77,7 @@ public:
static void RenderVehiclesAndPeds(void); // just called RenderVehicles in LCS
static void RenderOneBuilding(CEntity *ent, float camdist = 0.0f);
static void RenderWorld(int pass); // like cWorldStream::Render(int)
+ static void RenderTransparentWater(void); // keep-out polys and transparent water
#endif
+ static void InsertEntityIntoList(CEntity *ent);
};
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 8b5de929..bf42f2a8 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+#include "main.h"
#include "General.h"
#include "Timecycle.h"
#include "Weather.h"
@@ -1100,6 +1101,15 @@ CBoat::Render()
m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 3000;
if (!CVehicle::bWheelsOnlyCheat)
CEntity::Render();
+#ifdef NEW_RENDERER
+ if(!gbNewRenderer)
+#endif
+ RenderWaterOutPolys(); // not separate function in VC
+}
+
+void
+CBoat::RenderWaterOutPolys(void)
+{
if(GetModelIndex() == MI_SKIMMER)
return;
KeepWaterOutIndices[0] = 0;
@@ -1178,11 +1188,16 @@ CBoat::Render()
KeepWaterOutVertices[2].v = 1.0f;
KeepWaterOutVertices[3].u = 1.0f;
KeepWaterOutVertices[3].v = 1.0f;
+#ifdef NEW_RENDERER
+ if(!gbNewRenderer)
+#endif
+{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpWaterRaster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+}
if (!CVehicle::bWheelsOnlyCheat && RwIm3DTransform(KeepWaterOutVertices, 4, GetMatrix().m_attachment, rwIM3D_VERTEXUV)) {
RwIm3DRenderIndexedPrimitive(rwPRIMTYPETRILIST, KeepWaterOutIndices, 6);
RwIm3DEnd();
@@ -1209,10 +1224,15 @@ CBoat::Render()
RwIm3DEnd();
}
}
+#ifdef NEW_RENDERER
+ if(!gbNewRenderer)
+#endif
+{
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
+}
void
CBoat::Teleport(CVector v)
diff --git a/src/vehicles/Boat.h b/src/vehicles/Boat.h
index 5f8cc8a8..5d866c48 100644
--- a/src/vehicles/Boat.h
+++ b/src/vehicles/Boat.h
@@ -62,7 +62,8 @@ public:
virtual void GetComponentWorldPosition(int32 component, CVector &pos);
virtual bool IsComponentPresent(int32 component) { return true; }
virtual void BlowUpCar(CEntity *ent);
-
+
+ void RenderWaterOutPolys(void);
void ApplyWaterResistance(void);
void SetupModelNodes();
void PruneWakeTrail(void);