summaryrefslogtreecommitdiff
path: root/src/render/PointLights.cpp
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2021-07-15 18:19:32 +0300
committerSergeanur <s.anureev@yandex.ua>2021-07-18 00:04:26 +0300
commitd0404cbdb77bd82abf578ce28093990db94743f2 (patch)
tree1a7232c3dcdd6c371ab5fbde0fc6bf04c5bc7005 /src/render/PointLights.cpp
parent8018e40ebf2e7033e1929b4ed638afb3de7da692 (diff)
render -> renderer (original name)
Diffstat (limited to 'src/render/PointLights.cpp')
-rw-r--r--src/render/PointLights.cpp289
1 files changed, 0 insertions, 289 deletions
diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp
deleted file mode 100644
index 84ac4ab2..00000000
--- a/src/render/PointLights.cpp
+++ /dev/null
@@ -1,289 +0,0 @@
-#include "common.h"
-
-#include "main.h"
-#include "Lights.h"
-#include "Camera.h"
-#include "Weather.h"
-#include "World.h"
-#include "Collision.h"
-#include "Sprite.h"
-#include "Timer.h"
-#include "PointLights.h"
-
-int16 CPointLights::NumLights;
-CRegisteredPointLight CPointLights::aLights[NUMPOINTLIGHTS];
-
-void
-CPointLights::InitPerFrame(void)
-{
- NumLights = 0;
-}
-
-#define MAX_DIST 22.0f
-
-void
-CPointLights::AddLight(uint8 type, CVector coors, CVector dir, float radius, float red, float green, float blue, uint8 fogType, bool castExtraShadows)
-{
- CVector dist;
- float distance;
-
- // The check is done in some weird way in the game
- // we're doing it a bit better here
- if(NumLights >= NUMPOINTLIGHTS)
- return;
-
- dist = coors - TheCamera.GetPosition();
- if(Abs(dist.x) < MAX_DIST && Abs(dist.y) < MAX_DIST){
- distance = dist.Magnitude();
- if(distance < MAX_DIST){
- aLights[NumLights].type = type;
- aLights[NumLights].fogType = fogType;
- aLights[NumLights].coors = coors;
- aLights[NumLights].dir = dir;
- aLights[NumLights].radius = radius;
- aLights[NumLights].castExtraShadows = castExtraShadows;
- if(distance < MAX_DIST*0.75f){
- aLights[NumLights].red = red;
- aLights[NumLights].green = green;
- aLights[NumLights].blue = blue;
- }else{
- float fade = 1.0f - (distance/MAX_DIST - 0.75f)*4.0f;
- aLights[NumLights].red = red * fade;
- aLights[NumLights].green = green * fade;
- aLights[NumLights].blue = blue * fade;
- }
- NumLights++;
- }
- }
-}
-
-float
-CPointLights::GenerateLightsAffectingObject(Const CVector *objCoors)
-{
- int i;
- float ret;
- CVector dist;
- float radius, distance;
-
- ret = 1.0f;
- for(i = 0; i < NumLights; i++){
- if(aLights[i].type == LIGHT_FOGONLY || aLights[i].type == LIGHT_FOGONLY_ALWAYS)
- continue;
-
- // same weird distance calculation. simplified here
- dist = aLights[i].coors - *objCoors;
- radius = aLights[i].radius;
- if(Abs(dist.x) < radius &&
- Abs(dist.y) < radius &&
- Abs(dist.z) < radius){
-
- distance = dist.Magnitude();
- if(distance < radius){
-
- float distNorm = distance/radius;
- if(aLights[i].type == LIGHT_DARKEN){
- // darken the object the closer it is
- ret *= distNorm;
- }else{
- float intensity;
- // distance fade
- if(distNorm < 0.5f)
- intensity = 1.0f;
- else
- intensity = 1.0f - (distNorm - 0.5f)/(1.0f - 0.5f);
-
- if(distance != 0.0f){
- CVector dir = dist / distance;
-
- if(aLights[i].type == LIGHT_DIRECTIONAL){
- float dot = -DotProduct(dir, aLights[i].dir);
- intensity *= Max((dot-0.5f)*2.0f, 0.0f);
- }
-
- if(intensity > 0.0f)
- AddAnExtraDirectionalLight(Scene.world,
- dir.x, dir.y, dir.z,
- aLights[i].red*intensity, aLights[i].green*intensity, aLights[i].blue*intensity);
- }
- }
- }
- }
- }
-
- return ret;
-}
-
-extern RwRaster *gpPointlightRaster;
-
-void
-CPointLights::RemoveLightsAffectingObject(void)
-{
- RemoveExtraDirectionalLights(Scene.world);
-}
-
-// for directional fog
-#define FOG_AREA_LENGTH 12.0f
-#define FOG_AREA_WIDTH 5.0f
-// for pointlight fog
-#define FOG_AREA_RADIUS 9.0f
-
-float FogSizes[8] = { 1.3f, 2.0f, 1.7f, 2.0f, 1.4f, 2.1f, 1.5f, 2.3f };
-
-void
-CPointLights::RenderFogEffect(void)
-{
- int i;
- float fogginess;
- CColPoint point;
- CEntity *entity;
- float xmin, ymin;
- float xmax, ymax;
- int16 xi, yi;
- CVector spriteCoors;
- float spritew, spriteh;
-
- PUSH_RENDERGROUP("CPointLights::RenderFogEffect");
-
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpPointlightRaster);
-
- for(i = 0; i < NumLights; i++){
- if(aLights[i].fogType != FOG_NORMAL && aLights[i].fogType != FOG_ALWAYS)
- continue;
-
- fogginess = aLights[i].fogType == FOG_NORMAL ? CWeather::Foggyness : 1.0f;
- if(fogginess == 0.0f)
- continue;
-
- if(aLights[i].type == LIGHT_DIRECTIONAL){
-
- // TODO: test this. haven't found directional fog so far
-
- float coors2X = aLights[i].coors.x + FOG_AREA_LENGTH*aLights[i].dir.x;
- float coors2Y = aLights[i].coors.y + FOG_AREA_LENGTH*aLights[i].dir.y;
-
- if(coors2X < aLights[i].coors.x){
- xmin = coors2X;
- xmax = aLights[i].coors.x;
- }else{
- xmax = coors2X;
- xmin = aLights[i].coors.x;
- }
- if(coors2Y < aLights[i].coors.y){
- ymin = coors2Y;
- ymax = aLights[i].coors.y;
- }else{
- ymax = coors2Y;
- ymin = aLights[i].coors.y;
- }
-
- xmin -= 5.0f;
- ymin -= 5.0f;
- xmax += 5.0f;
- ymax += 5.0f;
-
- for(xi = (int16)xmin - (int16)xmin % 4; xi <= (int16)xmax + 4; xi += 4){
- for(yi = (int16)ymin - (int16)ymin % 4; yi <= (int16)ymax + 4; yi += 4){
- // Some kind of pseudo random number?
- int r = (xi ^ yi)>>2 & 0xF;
- if((r & 1) == 0)
- continue;
-
- // Check if fog effect is close enough to directional line in x and y
- float dx = xi - aLights[i].coors.x;
- float dy = yi - aLights[i].coors.y;
- float dot = dx*aLights[i].dir.x + dy*aLights[i].dir.y;
- float distsq = sq(dx) + sq(dy);
- float linedistsq = distsq - sq(dot);
- if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){
- CVector fogcoors(xi, yi, aLights[i].coors.z + 10.0f);
- if(CWorld::ProcessVerticalLine(fogcoors, fogcoors.z - 20.0f,
- point, entity, true, false, false, false, true, false, nil)){
- // Now same check again in xyz
- fogcoors.z = point.point.z + 1.3f;
- // actually we don't have to recalculate x and y, but the game does it that way
- dx = xi - aLights[i].coors.x;
- dy = yi - aLights[i].coors.y;
- float dz = fogcoors.z - aLights[i].coors.z;
- dot = dx*aLights[i].dir.x + dy*aLights[i].dir.y + dz*aLights[i].dir.z;
- distsq = sq(dx) + sq(dy) + sq(dz);
- linedistsq = distsq - sq(dot);
- if(dot > 0.0f && dot < FOG_AREA_LENGTH && linedistsq < sq(FOG_AREA_WIDTH)){
- float intensity = 158.0f * fogginess;
- // more intensity the smaller the angle
- intensity *= dot/Sqrt(distsq);
- // more intensity the closer to light source
- intensity *= 1.0f - sq(dot/FOG_AREA_LENGTH);
- // more intensity the closer to line
- intensity *= 1.0f - sq(Sqrt(linedistsq) / FOG_AREA_WIDTH);
-
- if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){
- float rotation = (CTimer::GetTimeInMilliseconds()&0x1FFF) * 2*3.14f / 0x2000;
- float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
- spritew * size, spriteh * size,
- aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
- intensity, 1/spriteCoors.z, rotation, 255);
- }
- }
- }
- }
- }
- }
-
- }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,
- point, entity, true, false, false, false, true, false, nil)){
-
- xmin = aLights[i].coors.x - FOG_AREA_RADIUS;
- ymin = aLights[i].coors.y - FOG_AREA_RADIUS;
- xmax = aLights[i].coors.x + FOG_AREA_RADIUS;
- ymax = aLights[i].coors.y + FOG_AREA_RADIUS;
-
- for(xi = (int16)xmin - (int16)xmin % 2; xi <= (int16)xmax + 2; xi += 2){
- for(yi = (int16)ymin - (int16)ymin % 2; yi <= (int16)ymax + 2; yi += 2){
- // Some kind of pseudo random number?
- int r = (xi ^ yi)>>1 & 0xF;
- if((r & 1) == 0)
- continue;
-
- float dx = xi - aLights[i].coors.x;
- float dy = yi - aLights[i].coors.y;
- float lightdist = Sqrt(sq(dx) + sq(dy));
- if(lightdist < FOG_AREA_RADIUS){
- dx = xi - TheCamera.GetPosition().x;
- dy = yi - TheCamera.GetPosition().y;
- float camdist = Sqrt(sq(dx) + sq(dy));
- if(camdist < MAX_DIST){
- float intensity;
- // distance fade
- if(camdist < MAX_DIST/2)
- intensity = 1.0f;
- else
- intensity = 1.0f - (camdist - MAX_DIST/2) / (MAX_DIST/2);
- intensity *= 132.0f * fogginess;
- // more intensity the closer to light source
- intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
-
- CVector fogcoors(xi, yi, point.point.z + 1.6f);
- if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)){
- float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
- float size = FogSizes[r>>1];
- CSprite::RenderOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
- spritew * size, spriteh * size,
- aLights[i].red * intensity, aLights[i].green * intensity, aLights[i].blue * intensity,
- intensity, 1/spriteCoors.z, rotation, 255);
- }
- }
- }
- }
- }
- }
- }
- }
-
- POP_RENDERGROUP();
-}