pointlights done

This commit is contained in:
aap 2020-08-09 15:45:38 +02:00
parent 951439486f
commit 6514bc6b39
3 changed files with 64 additions and 14 deletions

View File

@ -7,6 +7,7 @@
#include "Camera.h" #include "Camera.h"
#include "Sprite.h" #include "Sprite.h"
#include "Coronas.h" #include "Coronas.h"
#include "PointLights.h"
#include "Rubbish.h" #include "Rubbish.h"
#include "Timecycle.h" #include "Timecycle.h"
#include "General.h" #include "General.h"
@ -391,7 +392,7 @@ void CMovingThings::Init()
CPlaneTrails::Init(); CPlaneTrails::Init();
CSmokeTrails::Init(); CSmokeTrails::Init();
CPlaneBanners::Init(); CPlaneBanners::Init();
CEscalators::Init(); CPointLights::Init();
StartCloseList.m_pNext = &CMovingThings::EndCloseList; StartCloseList.m_pNext = &CMovingThings::EndCloseList;
StartCloseList.m_pPrev = nil; StartCloseList.m_pPrev = nil;
@ -399,6 +400,8 @@ void CMovingThings::Init()
EndCloseList.m_pPrev = &CMovingThings::StartCloseList; EndCloseList.m_pPrev = &CMovingThings::StartCloseList;
Num = 0; Num = 0;
CEscalators::Init();
#ifndef MIAMI // something is still used here actually #ifndef MIAMI // something is still used here actually
// Initialize scroll bars // Initialize scroll bars
aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f); aScrollBars[0].Init(CVector( 228.3f, -669.0f, 39.0f ), SCROLL_BUSINESS, 0.0f, 0.5f, 0.5f, 255, 128, 0, 0.3f);

View File

@ -1,6 +1,7 @@
#include "common.h" #include "common.h"
#include "main.h" #include "main.h"
#include "CutsceneMgr.h"
#include "Lights.h" #include "Lights.h"
#include "Camera.h" #include "Camera.h"
#include "Weather.h" #include "Weather.h"
@ -10,8 +11,23 @@
#include "Timer.h" #include "Timer.h"
#include "PointLights.h" #include "PointLights.h"
//--MIAMI: file done
int16 CPointLights::NumLights; int16 CPointLights::NumLights;
CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS]; CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
CVector CPointLights::aCachedMapReads[32];
float CPointLights::aCachedMapReadResults[32];
int32 CPointLights::NextCachedValue;
void
CPointLights::Init(void)
{
for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++){
aCachedMapReads[i] = CVector(0.0f, 0.0f, 0.0f);
aCachedMapReadResults[i] = 0.0f;
}
NextCachedValue = 0;
}
void void
CPointLights::InitPerFrame(void) CPointLights::InitPerFrame(void)
@ -86,12 +102,11 @@ CPointLights::GenerateLightsAffectingObject(Const CVector *objCoors)
ret *= distNorm; ret *= distNorm;
}else{ }else{
float intensity; float intensity;
// distance fade
if(distNorm < 0.5f) if(distNorm < 0.5f)
// near enough
intensity = 1.0f; intensity = 1.0f;
else else
// attenuate intensity = 1.0f - (distNorm - 0.5f)/(1.0f - 0.5f);
intensity = 1.0f - (distNorm - 0.5f)*2.0f;
if(distance != 0.0f){ if(distance != 0.0f){
CVector dir = dist / distance; CVector dir = dist / distance;
@ -143,17 +158,22 @@ CPointLights::RenderFogEffect(void)
CVector spriteCoors; CVector spriteCoors;
float spritew, spriteh; float spritew, spriteh;
if(CCutsceneMgr::IsRunning())
return;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster); RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster);
CSprite::InitSpriteBuffer();
for(i = 0; i < NumLights; i++){ for(i = 0; i < NumLights; i++){
if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS) if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS)
continue; continue;
fogginess = aLights[i].fogType == FOG_ALWAYS ? 1.0f : CWeather::Foggyness; fogginess = aLights[i].fogType == FOG_NORMAL ? CWeather::Foggyness : 1.0f;
if(fogginess == 0.0f) if(fogginess == 0.0f)
continue; continue;
@ -198,7 +218,7 @@ CPointLights::RenderFogEffect(void)
float distsq = sq(dx) + sq(dy); float distsq = sq(dx) + sq(dy);
float linedistsq = distsq - sq(dot); float linedistsq = distsq - sq(dot);
if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){ if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){
CVector fogcoors(xi, yi, aLights[i].coors.z + 1.0f); CVector fogcoors(xi, yi, aLights[i].coors.z + 10.0f);
if(CWorld::ProcessVerticalLine(fogcoors, fogcoors.z - 20.0f, if(CWorld::ProcessVerticalLine(fogcoors, fogcoors.z - 20.0f,
point, entity, true, false, false, false, true, false, nil)){ point, entity, true, false, false, false, true, false, nil)){
// Now same check again in xyz // Now same check again in xyz
@ -220,9 +240,9 @@ CPointLights::RenderFogEffect(void)
intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH); intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x1FFF; float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000;
float size = FogSizes[r>>1]; float size = FogSizes[r>>1];
CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size, spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity, aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255); intensity, 1/spriteCoors.z, rotation, 255);
@ -234,9 +254,8 @@ CPointLights::RenderFogEffect(void)
} }
}else if(aLights[i].type == LIGHT_POINT || aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS){ }else if(aLights[i].type == LIGHT_POINT || aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS){
if(CWorld::ProcessVerticalLine(aLights[i].coors, aLights[i].coors.z - 20.0f, float groundZ;
point, entity, true, false, false, false, true, false, nil)){ if(ProcessVerticalLineUsingCache(aLights[i].coors, &groundZ)){
xmin = aLights[i].coors.x - FOG_AREA_RADIUS; xmin = aLights[i].coors.x - FOG_AREA_RADIUS;
ymin = aLights[i].coors.y - FOG_AREA_RADIUS; ymin = aLights[i].coors.y - FOG_AREA_RADIUS;
xmax = aLights[i].coors.x + FOG_AREA_RADIUS; xmax = aLights[i].coors.x + FOG_AREA_RADIUS;
@ -267,11 +286,11 @@ CPointLights::RenderFogEffect(void)
// more intensity the closer to light source // more intensity the closer to light source
intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS); intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
CVector fogcoors(xi, yi, point.point.z + 1.6f); CVector fogcoors(xi, yi, groundZ + 1.6f);
if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){ if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x3FFF; float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
float size = FogSizes[r>>1]; float size = FogSizes[r>>1];
CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z, CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
spritew * size, spriteh * size, spritew * size, spriteh * size,
aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity, aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
intensity, 1/spriteCoors.z, rotation, 255); intensity, 1/spriteCoors.z, rotation, 255);
@ -283,4 +302,27 @@ CPointLights::RenderFogEffect(void)
} }
} }
} }
CSprite::FlushSpriteBuffer();
}
bool
CPointLights::ProcessVerticalLineUsingCache(CVector coors, float *groundZ)
{
for(int i = 0; i < ARRAY_SIZE(aCachedMapReads); i++)
if(aCachedMapReads[i] == coors){
*groundZ = aCachedMapReadResults[i];
return true;
}
CColPoint point;
CEntity *entity;
if(CWorld::ProcessVerticalLine(coors, coors.z - 20.0f, point, entity, true, false, false, false, true, false, nil)){
aCachedMapReads[NextCachedValue] = coors;
aCachedMapReadResults[NextCachedValue] = point.point.z;
NextCachedValue = (NextCachedValue+1) % ARRAY_SIZE(aCachedMapReads);
*groundZ = point.point.z;
return true;
}
return false;
} }

View File

@ -20,6 +20,9 @@ class CPointLights
public: public:
static int16 NumLights; static int16 NumLights;
static CRegisteredPointLight aLights[NUMPOINTLIGHTS]; static CRegisteredPointLight aLights[NUMPOINTLIGHTS];
static CVector aCachedMapReads[32];
static float aCachedMapReadResults[32];
static int32 NextCachedValue;
enum { enum {
LIGHT_POINT, LIGHT_POINT,
@ -37,9 +40,11 @@ public:
FOG_ALWAYS FOG_ALWAYS
}; };
static void Init(void);
static void InitPerFrame(void); static void InitPerFrame(void);
static void AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows); static void AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows);
static float GenerateLightsAffectingObject(Const CVector *objCoors); static float GenerateLightsAffectingObject(Const CVector *objCoors);
static void RemoveLightsAffectingObject(void); static void RemoveLightsAffectingObject(void);
static void RenderFogEffect(void); static void RenderFogEffect(void);
static bool ProcessVerticalLineUsingCache(CVector coors, float *groundZ);
}; };