From 244b91ee80217ed220338c7cb0e4e98cc9fe085a Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 4 Nov 2020 16:22:15 +0100 Subject: [PATCH] fixed boats for new renderer --- src/core/main.cpp | 22 +++--- src/render/Renderer.cpp | 144 ++++++++++++++++++++++++++++++---------- src/render/Renderer.h | 2 + src/vehicles/Boat.cpp | 20 ++++++ src/vehicles/Boat.h | 3 +- vendor/librw | 2 +- 6 files changed, 146 insertions(+), 47 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 @@ -355,6 +357,34 @@ struct BuildingInst 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) { @@ -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 @@ -773,6 +832,37 @@ CRenderer::RenderVehiclesAndPeds(void) // RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); } +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) { @@ -1540,6 +1630,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) { @@ -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); diff --git a/vendor/librw b/vendor/librw index 8c00f787..5ef54dcb 160000 --- a/vendor/librw +++ b/vendor/librw @@ -1 +1 @@ -Subproject commit 8c00f787cb8f53781c4335ecbc9d28fb9c664ba7 +Subproject commit 5ef54dcb78ea01171e2c0d690e5a64c2ed2ceb3b