miami shadows

This commit is contained in:
Fire-Head 2020-07-29 12:17:53 +03:00
parent 4c65ec28d6
commit 1803dcc873
19 changed files with 2174 additions and 264 deletions

View File

@ -3958,7 +3958,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
128, 128, 128, 128, 1000.0f, false, 1.0f);
128, 128, 128, 128, 1000.0f, false, 1.0f, NULL, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];
@ -4103,7 +4103,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
if(CPad::GetPad(1)->GetLeftShockJustDown() && gbBigWhiteDebugLightSwitchedOn)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &Source,
12.0f, 0.0f, 0.0f, -12.0f,
128, 128, 128, 128, 1000.0f, false, 1.0f);
128, 128, 128, 128, 1000.0f, false, 1.0f, NULL, false);
if(CHud::m_Wants_To_Draw_Hud){
char str[256];

View File

@ -74,6 +74,9 @@ struct CColTrianglePlane
void Set(const CVector *v, CColTriangle &tri);
void GetNormal(CVector &n) const { n = normal; }
float GetNormalX() const { return normal.x; }
float GetNormalY() const { return normal.y; }
float GetNormalZ() const { return normal.z; }
float CalcPoint(const CVector &v) const { return DotProduct(normal, v) - dist; };
};

View File

@ -444,7 +444,7 @@ CEntity::PreRender(void)
gpShadowExplosionTex, &pos,
8.0f, 0.0f, 0.0f, -8.0f,
255, 200.0f*flicker, 160.0f*flicker, 120.0f*flicker,
20.0f, false, 1.0f);
20.0f, false, 1.0f, NULL, false);
CPointLights::AddLight(CPointLights::LIGHT_POINT,
pos, CVector(0.0f, 0.0f, 0.0f),
8.0f,
@ -482,7 +482,7 @@ CEntity::PreRender(void)
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
CTimeCycle::GetShadowStrength(),
20.0f, false, 1.0f);
20.0f, false, 1.0f, NULL, false);
}
// fall through
case ENTITY_TYPE_DUMMY:

View File

@ -29,6 +29,15 @@ public:
if(m_hasRwMatrix && m_attachment)
RwMatrixDestroy(m_attachment);
}
#ifdef RWCORE_H
operator RwMatrix (void) const {
return m_matrix;
}
operator RwMatrix *(void) {
return &m_matrix;
}
#endif
void Attach(RwMatrix *matrix, bool owner = false){
#ifdef FIX_BUGS
if(m_attachment && m_hasRwMatrix)
@ -240,6 +249,15 @@ public:
void CopyOnlyMatrix(CMatrix *other){
m_matrix = other->m_matrix;
}
void CopyRwMatrix(RwMatrix *matrix){
m_matrix = *matrix;
}
void CopyToRwMatrix(RwMatrix *matrix){
*matrix = m_matrix;
RwMatrixUpdate(matrix);
}
void SetUnity(void) {
m_matrix.right.x = 1.0f;
m_matrix.right.y = 0.0f;

View File

@ -11,7 +11,11 @@
#include "ModelIndices.h"
#include "Shadows.h"
#include "Timecycle.h"
#include "CutsceneShadow.h"
#include "CutsceneObject.h"
#include "ModelIndices.h"
#include "RpAnimBlend.h"
CCutsceneObject::CCutsceneObject(void)
{
@ -21,6 +25,19 @@ CCutsceneObject::CCutsceneObject(void)
ObjectCreatedBy = CUTSCENE_OBJECT;
m_fMass = 1.0f;
m_fTurnMass = 1.0f;
m_pAttachTo = NULL;
m_pAttachmentObject = NULL;
m_pShadow = NULL;
}
CCutsceneObject::~CCutsceneObject(void)
{
if ( m_pShadow )
{
delete m_pShadow;
m_pShadow = NULL;
}
}
void
@ -33,22 +50,38 @@ CCutsceneObject::SetModelIndex(uint32 id)
(*RPANIMBLENDCLUMPDATA(m_rwObject))->frames[0].flag |= AnimBlendFrameData::VELOCITY_EXTRACTION_3D;
}
void
CCutsceneObject::CreateShadow(void)
{
if ( IsPedModel(GetModelIndex()) )
{
m_pShadow = new CCutsceneShadow();
if (!m_pShadow->IsInitialized())
m_pShadow->Create(m_rwObject, 6, true, 4, true);
}
}
void
CCutsceneObject::ProcessControl(void)
{
CPhysical::ProcessControl();
if ( m_pAttachTo )
{
if ( m_pAttachmentObject )
GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
else
GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
}
else
{
if(CTimer::GetTimeStep() < 1/100.0f)
m_vecMoveSpeed *= 100.0f;
else
m_vecMoveSpeed *= 1.0f/CTimer::GetTimeStep();
ApplyMoveSpeed();
#ifdef PED_SKIN
if(IsClumpSkinned(GetClump()))
UpdateRpHAnim();
#endif
}
}
static RpMaterial*
@ -61,7 +94,30 @@ MaterialSetAlpha(RpMaterial *material, void *data)
void
CCutsceneObject::PreRender(void)
{
if(IsPedModel(GetModelIndex())){
if ( m_pAttachTo )
{
if ( m_pAttachmentObject )
{
m_pAttachmentObject->UpdateRpHAnim();
GetMatrix() = CMatrix((RwMatrix*)m_pAttachTo);
}
else
GetMatrix() = CMatrix(RwFrameGetLTM((RwFrame*)m_pAttachTo));
if ( RwObjectGetType(m_rwObject) == rpCLUMP && IsClumpSkinned(GetClump()) )
{
RpAtomic *atomic = GetFirstAtomic(GetClump());
atomic->boundingSphere.center = (*RPANIMBLENDCLUMPDATA(GetClump()))->frames[0].hanimFrame->t;
}
}
if ( RwObjectGetType(m_rwObject) == rpCLUMP )
UpdateRpHAnim();
if(IsPedModel(GetModelIndex()))
{
if ( m_pShadow == NULL )
{
CShadows::StoreShadowForPedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
@ -69,6 +125,21 @@ CCutsceneObject::PreRender(void)
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
}
else
{
if ( m_pShadow->IsInitialized() )
m_pShadow->UpdateForCutscene();
CShadows::StoreShadowForCutscenePedObject(this,
CTimeCycle::m_fShadowDisplacementX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowDisplacementY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
}
// For some reason xbox/android limbs are transparent here...
RpGeometry *geometry = RpAtomicGetGeometry(GetFirstAtomic(GetClump()));
RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
@ -79,7 +150,9 @@ CCutsceneObject::PreRender(void)
void
CCutsceneObject::Render(void)
{
RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLNONE);
CObject::Render();
RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLBACK);
}
bool
@ -93,7 +166,7 @@ CCutsceneObject::SetupLighting(void)
}else{
CVector coors = GetPosition();
float lighting = CPointLights::GenerateLightsAffectingObject(&coors);
if(!bHasBlip && lighting != 1.0f){
if(lighting != 1.0f){
SetAmbientAndDirectionalColours(lighting);
return true;
}

View File

@ -2,12 +2,20 @@
#include "Object.h"
class CCutsceneShadow;
class CCutsceneObject : public CObject
{
public:
CCutsceneShadow *m_pShadow;
void *m_pAttachTo;
CObject *m_pAttachmentObject;
CCutsceneObject(void);
~CCutsceneObject(void);
void SetModelIndex(uint32 id);
void CreateShadow(void);
void ProcessControl(void);
void PreRender(void);
void Render(void);

View File

@ -63,6 +63,7 @@
#include "Debug.h"
#include "GameLogic.h"
#include "Bike.h"
#include "CutsceneShadow.h"
#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
@ -146,6 +147,9 @@ void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((
// --MIAMI: Done
CPed::~CPed(void)
{
#if 1
if ( m_pRTShadow ) delete m_pRTShadow;
#endif
CWorld::Remove(this);
if (m_attractor)
GetPedAttractorManager()->DeRegisterPed(this, m_attractor);
@ -203,6 +207,9 @@ CPed::FlagToDestroyWhenNextProcessed(void)
CPed::CPed(uint32 pedType) : m_pedIK(this)
{
#if 1
m_pRTShadow = NULL;
#endif
m_type = ENTITY_TYPE_PED;
bPedPhysics = true;
bUseCollisionRecords = true;
@ -2672,6 +2679,13 @@ CPed::SetModelIndex(uint32 mi)
if (IsClumpSkinned(GetClump())) // condition isn't there in VC
UpdateRpHAnim();
#endif
#if 1
if (!m_pRTShadow)
{
m_pRTShadow = new CCutsceneShadow;
m_pRTShadow->Create(m_rwObject, 10, 1, 1, 1);
}
#endif
}
void

View File

@ -357,6 +357,9 @@ class CVehicle;
class CPed : public CPhysical
{
public:
#if 1
class CCutsceneShadow *m_pRTShadow;
#endif
// 0x128
CStoredCollPoly m_collPoly;
float m_fCollisionSpeed;

View File

@ -0,0 +1,267 @@
#include "common.h"
#include "main.h"
#include "rwcore.h"
#include "rwplcore.h"
#include "CutsceneShadow.h"
#include "RwHelper.h"
#define DLIGHT_VALUE 0.8f /* Directional light intensity */
CCutsceneShadow::CCutsceneShadow()
{
m_pAtomic = NULL;
m_nRwObjectType = -1;
m_pLight = NULL;
m_nBlurPasses = 0;
m_bResample = false;
m_bGradient = false;
}
CCutsceneShadow::~CCutsceneShadow()
{
Destroy();
}
bool
CCutsceneShadow::Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient)
{
RwRGBAReal color;
RwFrame *frame;
if (!object)
return false;
m_pLight = RpLightCreate(rpLIGHTDIRECTIONAL);
if (!m_pLight)
return false;
color.red = color.green = color.blue = DLIGHT_VALUE;
color.alpha = 0.0f;
RpLightSetColor(m_pLight, &color);
frame = RwFrameCreate();
RpLightSetFrame(m_pLight, frame);
SetLightProperties(180.0f, 90.0f, false);
m_pObject = object;
m_nRwObjectType = RwObjectGetType(m_pObject);
switch ( m_nRwObjectType )
{
case rpCLUMP:
{
RpClumpGetBoundingSphere(m_pClump, &m_BoundingSphere, 1);
m_BaseSphere.radius = m_BoundingSphere.radius;
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
break;
}
case rpATOMIC:
{
m_BoundingSphere = *RpAtomicGetBoundingSphere(m_pAtomic);
m_BaseSphere.radius = m_BoundingSphere.radius;
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
break;
}
default:
{
Destroy();
return false;
break;
}
}
if ( !m_Camera.Create(rasterSize) )
{
Destroy();
return false;
}
m_nBlurPasses = blurPasses;
m_bResample = resample;
m_bGradient = gradient;
if ( m_bResample && !m_ResampleCamera.Create(rasterSize - 1) )
{
Destroy();
return false;
}
if ( m_nBlurPasses != 0 )
{
if ( !m_BlurCamera.Create(resample ? rasterSize - 1 : rasterSize) )
{
Destroy();
return false;
}
}
if ( m_bGradient )
{
if ( !m_GradientCamera.Create(resample ? rasterSize - 1 : rasterSize) )
{
Destroy();
return false;
}
m_GradientCamera.MakeGradientRaster();
}
m_Camera.SetLight(m_pLight);
switch ( m_nRwObjectType )
{
case rpATOMIC:
m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
break;
case rpCLUMP:
m_Camera.SetFrustum(1.1f * m_BoundingSphere.radius);
break;
}
m_Camera.SetCenter(&m_BaseSphere.center);
return true;
}
RwFrame *
CCutsceneShadow::SetLightProperties(float angleY, float angleX, bool setLight)
{
RwFrame *frame;
static RwV3d Xaxis = { 1.0f, 0.0f, 0.0f };
static RwV3d Yaxis = { 0.0f, 1.0f, 0.0f };
frame = RpLightGetFrame(m_pLight);
if ( !frame )
return NULL;
RwFrameRotate(frame, &Yaxis, angleY, rwCOMBINEREPLACE);
RwFrameRotate(frame, &Xaxis, angleX, rwCOMBINEPOSTCONCAT);
if ( setLight )
m_Camera.SetLight(m_pLight);
return frame;
}
bool
CCutsceneShadow::IsInitialized()
{
return m_pObject != NULL;
}
void
CCutsceneShadow::Destroy()
{
m_Camera.Destroy();
m_ResampleCamera.Destroy();
m_BlurCamera.Destroy();
m_GradientCamera.Destroy();
m_pAtomic = NULL;
m_nRwObjectType = -1;
if (m_pLight)
{
RwFrame *frame = RpLightGetFrame(m_pLight);
RpLightSetFrame(m_pLight, NULL);
RwFrameDestroy(frame);
RpLightDestroy(m_pLight);
m_pLight = NULL;
}
}
RwRaster *
CCutsceneShadow::Update()
{
switch ( m_nRwObjectType )
{
case rpCLUMP:
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpClumpGetFrame(m_pClump)));
break;
case rpATOMIC:
RwV3dTransformPoints(&m_BaseSphere.center, &m_BoundingSphere.center, 1, RwFrameGetMatrix(RpAtomicGetFrame(m_pAtomic)));
break;
}
m_Camera.SetCenter(&m_BaseSphere.center);
switch ( m_nRwObjectType )
{
case rpCLUMP:
m_Camera.Update(m_pClump);
break;
case rpATOMIC:
m_Camera.Update(m_pAtomic);
break;
}
RwRaster *raster = m_Camera.GetRwRenderRaster();
if ( m_bResample )
return m_ResampleCamera.RasterResample(raster);
if ( m_nBlurPasses )
return m_BlurCamera.RasterBlur(raster, m_nBlurPasses);
if ( m_bGradient )
return m_GradientCamera.RasterGradient(raster);
return raster;
}
RwTexture *
CCutsceneShadow::UpdateForCutscene()
{
Update();
return GetShadowRwTexture();
}
CShadowCamera *
CCutsceneShadow::GetShadowCamera(int32 camType)
{
switch ( camType )
{
case RESAMPLE:
return &m_ResampleCamera;
break;
case BLUR:
return &m_BlurCamera;
break;
case GRADIENT:
return &m_GradientCamera;
break;
default:
return &m_Camera;
break;
}
}
RwTexture *
CCutsceneShadow::GetShadowRwTexture()
{
if ( m_bResample )
return m_ResampleCamera.GetRwRenderTexture();
else
return m_Camera.GetRwRenderTexture();
}
void
CCutsceneShadow::DrawBorderAroundTexture(RwRGBA const& color)
{
if ( m_bResample )
m_ResampleCamera.DrawOutlineBorder(color);
else
m_Camera.DrawOutlineBorder(color);
}

View File

@ -0,0 +1,54 @@
#pragma once
#include "ShadowCamera.h"
class CCutsceneShadow
{
public:
enum
{
RASTER = 0,
RESAMPLE,
BLUR,
GRADIENT,
};
CShadowCamera m_Camera;
bool m_bResample;
char _pad0[3];
CShadowCamera m_ResampleCamera;
int32 m_nBlurPasses;
CShadowCamera m_BlurCamera;
bool m_bGradient;
char _pad1[3];
CShadowCamera m_GradientCamera;
union
{
RwObject *m_pObject;
RpAtomic *m_pAtomic;
RpClump *m_pClump;
};
int m_nRwObjectType;
RpLight *m_pLight;
RwSphere m_BoundingSphere;
RwSphere m_BaseSphere;
CCutsceneShadow();
~CCutsceneShadow();
RwSphere &GetBaseSphere()
{
return m_BaseSphere;
}
bool Create(RwObject *object, int32 rasterSize, bool resample, int32 blurPasses, bool gradient);
RwFrame *SetLightProperties(float angleY, float angleX, bool setLight);
bool IsInitialized();
void Destroy();
RwRaster *Update();
RwTexture *UpdateForCutscene();
CShadowCamera *GetShadowCamera(int32 camType = RASTER);
RwTexture *GetShadowRwTexture();
void DrawBorderAroundTexture(RwRGBA const& color);
};

551
src/render/ShadowCamera.cpp Normal file
View File

@ -0,0 +1,551 @@
#include "common.h"
#include "rwcore.h"
#include "ShadowCamera.h"
#include "RwHelper.h"
#define TEXELOFFSET 0.5f
RpAtomic *ShadowRenderCallBack(RpAtomic *atomic, void *data)
{
RpAtomicCallBackRender savedCB = RpAtomicGetRenderCallBack(atomic);
RpAtomicSetRenderCallBack(atomic, AtomicDefaultRenderCallBack);
RpAtomicRender(atomic);
RpAtomicSetRenderCallBack(atomic, savedCB);
return atomic;
}
CShadowCamera::CShadowCamera()
{
m_pCamera = NULL;
m_pTexture = NULL;
}
CShadowCamera::~CShadowCamera()
{
Destroy();
}
void
CShadowCamera::Destroy()
{
if ( m_pCamera )
{
RwRaster *raster;
RwFrame *frame;
frame = RwCameraGetFrame(m_pCamera);
if ( frame )
{
RwCameraSetFrame(m_pCamera, NULL);
RwFrameDestroy(frame);
}
raster = RwCameraGetZRaster(m_pCamera);
if ( raster )
{
RwCameraSetZRaster(m_pCamera, NULL);
RwRasterDestroy(raster);
}
raster = RwCameraGetRaster(m_pCamera);
if ( raster )
{
RwCameraSetRaster(m_pCamera, NULL);
RwRasterDestroy(raster);
}
if ( m_pTexture )
{
RwTextureSetRaster(m_pTexture, NULL);
RwTextureDestroy(m_pTexture);
m_pTexture = NULL;
}
RwCameraDestroy(m_pCamera);
m_pCamera = NULL;
}
return;
}
RwCamera *
CShadowCamera::Create(int32 rasterSize)
{
int32 size = 1 << rasterSize;
m_pCamera = RwCameraCreate();
ASSERT(m_pCamera != NULL);
if ( m_pCamera )
{
RwCameraSetFrame(m_pCamera, RwFrameCreate());
if( RwCameraGetFrame(m_pCamera) )
{
RwRaster *zRaster = RwRasterCreate(size, size, 0, rwRASTERTYPEZBUFFER);
ASSERT(zRaster != NULL);
if ( zRaster )
{
RwCameraSetZRaster(m_pCamera, zRaster);
RwRaster *raster = RwRasterCreate(size, size, 0, rwRASTERTYPECAMERATEXTURE);
ASSERT(raster != NULL);
if ( raster )
{
RwCameraSetRaster(m_pCamera, raster);
m_pTexture = RwTextureCreate(raster);
ASSERT(m_pTexture != NULL);
if ( m_pTexture )
{
RwTextureSetAddressing(m_pTexture, rwTEXTUREADDRESSCLAMP);
RwTextureSetFilterMode(m_pTexture, rwFILTERLINEAR);
RwCameraSetProjection(m_pCamera, rwPARALLEL);
return (m_pCamera);
}
}
}
}
}
Destroy();
return (NULL);
}
RwCamera *
CShadowCamera::SetFrustum(float objectRadius)
{
ASSERT(m_pCamera != NULL);
RwV2d vw;
RwCameraSetFarClipPlane (m_pCamera, 2.0f * objectRadius);
RwCameraSetNearClipPlane(m_pCamera, 0.001f * objectRadius);
vw.x = objectRadius;
vw.y = objectRadius;
RwCameraSetViewWindow(m_pCamera, &vw);
return m_pCamera;
}
RwCamera *
CShadowCamera::SetLight(RpLight *light)
{
ASSERT(light != NULL);
ASSERT(m_pCamera != NULL);
RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
RwFrame *lightFrame = RpLightGetFrame(light);
RwMatrix *lightMatrix = RwFrameGetMatrix(lightFrame);
*RwMatrixGetRight(camMatrix) = *RwMatrixGetRight(lightMatrix);
*RwMatrixGetUp(camMatrix) = *RwMatrixGetUp(lightMatrix);
*RwMatrixGetAt(camMatrix) = *RwMatrixGetAt(lightMatrix);
//RwMatrixCopy(RwFrameGetMatrix(camFrame), RwFrameGetMatrix(lightFrame));
RwMatrixUpdate(RwFrameGetMatrix(camFrame));
RwFrameUpdateObjects(camFrame);
return m_pCamera;
}
RwCamera *
CShadowCamera::SetCenter(RwV3d *center)
{
ASSERT(center != NULL);
ASSERT(m_pCamera != NULL);
RwFrame *camFrame = RwCameraGetFrame(m_pCamera);
RwMatrix *camMatrix = RwFrameGetMatrix(camFrame);
*RwMatrixGetPos(camMatrix) = *center;
RwV3dIncrementScaled(RwMatrixGetPos(camMatrix), RwMatrixGetAt(camMatrix), -0.5f * RwCameraGetFarClipPlane(m_pCamera));
RwMatrixUpdate(camMatrix);
RwFrameUpdateObjects(camFrame);
RwFrameOrthoNormalize(camFrame);
return m_pCamera;
}
RwCamera *
CShadowCamera::Update(RpClump *clump)
{
ASSERT(clump != NULL);
ASSERT(m_pCamera != NULL);
RwUInt32 flags;
RpGeometry *geometry;
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
{
geometry = GetFirstAtomic(clump)->geometry;
ASSERT(geometry != NULL);
flags = RpGeometryGetFlags(geometry);
RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
|rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR));
RpClumpForAllAtomics(clump, ShadowRenderCallBack, NULL);
RpGeometrySetFlags(geometry, flags);
InvertRaster();
RwCameraEndUpdate(m_pCamera);
}
return m_pCamera;
}
RwCamera *
CShadowCamera::Update(RpAtomic *atomic)
{
ASSERT(atomic != NULL);
ASSERT(m_pCamera != NULL);
RwUInt32 flags;
RpGeometry *geometry;
RwRGBA bgColor = { 255, 255, 255, 0 };
RwCameraClear(m_pCamera, &bgColor, rwCAMERACLEARZ | rwCAMERACLEARIMAGE);
if ( RwCameraBeginUpdate(m_pCamera) )
{
geometry = RpAtomicGetGeometry(atomic);
ASSERT(geometry != NULL);
flags = RpGeometryGetFlags(geometry);
RpGeometrySetFlags(geometry, flags & ~(rpGEOMETRYPRELIT|rpGEOMETRYLIGHT
|rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2|rpGEOMETRYMODULATEMATERIALCOLOR|rpGEOMETRYNORMALS));
ShadowRenderCallBack(atomic, NULL);
RpGeometrySetFlags(geometry, flags);
InvertRaster();
RwCameraEndUpdate(m_pCamera);
}
return m_pCamera;
}
void
CShadowCamera::InvertRaster()
{
ASSERT(m_pCamera != NULL);
RwIm2DVertex vx[4];
float crw, crh;
RwRaster *raster;
float recipZ;
raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
crw = (float)RwRasterGetWidth(raster);
crh = (float)RwRasterGetHeight(raster);
recipZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], 0.0f);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[0], recipZ);
RwIm2DVertexSetIntRGBA (&vx[0], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[1], 0.0f);
RwIm2DVertexSetScreenY (&vx[1], crh);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[1], recipZ);
RwIm2DVertexSetIntRGBA (&vx[1], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[2], crw);
RwIm2DVertexSetScreenY (&vx[2], 0.0f);
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[2], recipZ);
RwIm2DVertexSetIntRGBA (&vx[2], 255, 255, 255, 255);
RwIm2DVertexSetScreenX (&vx[3], crw);
RwIm2DVertexSetScreenY (&vx[3], crh);
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[3], recipZ);
RwIm2DVertexSetIntRGBA (&vx[3], 255, 255, 255, 255);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)NULL);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
}
RwRaster *
CShadowCamera::MakeGradientRaster()
{
ASSERT(m_pCamera != NULL);
RwIm2DVertex vx[2];
if ( !m_pCamera )
return NULL;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
float width = (float)RwRasterGetWidth(raster);
float height = (float)RwRasterGetHeight(raster);
if ( height < 1 )
return NULL;
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)rwFILTERNAFILTERMODE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDINVDESTCOLOR);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEFLAT);
float color = 255.0f;
float step = (-191.0f / height);
for ( int32 i = 0; i < height; i++ )
{
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], i);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetIntRGBA (&vx[0], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
RwIm2DVertexSetScreenX (&vx[1], width - 1);
RwIm2DVertexSetScreenY (&vx[1], i);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetIntRGBA (&vx[1], (uint32)color, (uint32)color, (uint32)color, (uint32)color);
RwIm2DRenderLine(vx, 2, 0, 1);
color += step;
}
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATESHADEMODE, (void *)rwSHADEMODEGOURAUD);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}
RwRaster *
CShadowCamera::RasterResample(RwRaster *dstRaster)
{
ASSERT(dstRaster != NULL);
ASSERT(m_pCamera != NULL);
if ( !m_pCamera )
return NULL;
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
float size = (float) RwRasterGetWidth(raster);
float uvOffset = TEXELOFFSET / size;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, uvOffset);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}
RwRaster *
CShadowCamera::RasterBlur(RwRaster *dstRaster, int32 numPasses)
{
ASSERT(dstRaster != NULL);
ASSERT(m_pCamera != NULL);
if ( !m_pCamera )
return NULL;
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
float size = (float) RwRasterGetWidth(dstRaster);
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
for (int i = 0; i < numPasses; i++ )
{
RwCameraSetRaster(m_pCamera, raster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
if ( i == 0 )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDONE);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
}
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)dstRaster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 1.0f / size);
RwCameraEndUpdate(m_pCamera);
}
RwCameraSetRaster(m_pCamera, dstRaster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
Im2DRenderQuad(0.0f, 0.0f, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
if ( i == numPasses - 1 )
{
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
}
RwCameraEndUpdate(m_pCamera);
}
}
RwCameraSetRaster(m_pCamera, raster);
return dstRaster;
}
RwRaster *
CShadowCamera::RasterGradient(RwRaster *dstRaster)
{
ASSERT(dstRaster != NULL);
ASSERT(m_pCamera != NULL);
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
float size = (float)RwRasterGetWidth(dstRaster);
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwCameraSetRaster(m_pCamera, dstRaster);
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDSRCCOLOR);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void *)rwFILTERLINEAR);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)raster);
Im2DRenderQuad(0, 0, size, size, RwIm2DGetNearScreenZ(), recipCamZ, 0);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void *)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVSRCALPHA);
RwCameraEndUpdate(m_pCamera);
}
RwCameraSetRaster(m_pCamera, raster);
return dstRaster;
}
RwRaster *CShadowCamera::DrawOutlineBorder(RwRGBA const& color)
{
ASSERT(m_pCamera != NULL);
RwIm2DVertex vx[4];
RwImVertexIndex ix[5];
RwRaster *raster = RwCameraGetRaster(m_pCamera);
ASSERT(raster != NULL);
float size = (float)RwRasterGetWidth(raster) - 1.0f;
float recipCamZ = 1.0f / RwCameraGetNearClipPlane(m_pCamera);
RwIm2DVertexSetScreenX (&vx[0], 0.0f);
RwIm2DVertexSetScreenY (&vx[0], 0.0f);
RwIm2DVertexSetScreenZ (&vx[0], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[0], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetScreenX (&vx[1], size);
RwIm2DVertexSetScreenY (&vx[1], 0.0f);
RwIm2DVertexSetScreenZ (&vx[1], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[1], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetScreenX (&vx[2], size);
RwIm2DVertexSetScreenY (&vx[2], size);
RwIm2DVertexSetScreenZ (&vx[2], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[2], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
RwIm2DVertexSetScreenX (&vx[3], 0.0f);
RwIm2DVertexSetScreenY (&vx[3], size);
RwIm2DVertexSetScreenZ (&vx[3], RwIm2DGetNearScreenZ());
RwIm2DVertexSetIntRGBA (&vx[3], color.red, color.green, color.blue, color.alpha);
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
ix[0] = 0;
ix[4] = 0;
ix[1] = 1;
ix[2] = 2;
ix[3] = 3;
if ( RwCameraBeginUpdate(m_pCamera) )
{
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)NULL);
RwIm2DRenderIndexedPrimitive(rwPRIMTYPEPOLYLINE, vx, 4, ix, 5);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
RwCameraEndUpdate(m_pCamera);
}
return raster;
}

54
src/render/ShadowCamera.h Normal file
View File

@ -0,0 +1,54 @@
#pragma once
class CShadowCamera
{
public:
RwCamera *m_pCamera;
RwTexture *m_pTexture;
CShadowCamera();
~CShadowCamera();
RwCamera *Create(int32 rasterSize);
void Destroy();
RwCamera *SetFrustum(float objectRadius);
RwCamera *SetLight(RpLight *light);
RwCamera *SetCenter(RwV3d *center);
RwCamera *Update(RpClump *clump);
RwCamera *Update(RpAtomic *atomic);
void InvertRaster();
RwRaster* GetRwRenderRaster()
{
return RwCameraGetRaster(m_pCamera);
}
// ShadowRasterRender(RwV2d *)
// ApplyAlphaMapToRaster(void)
RwRaster *MakeGradientRaster();
RwTexture *GetRwRenderTexture()
{
return m_pTexture;
}
RwRaster* GetRwZRaster()
{
return RwCameraGetZRaster(m_pCamera);
}
RwRaster *RasterResample(RwRaster *dstRaster);
RwRaster *RasterBlur(RwRaster *dstRaster, int32 numPasses);
RwRaster *RasterGradient(RwRaster *dstRaster);
RwRaster *DrawOutlineBorder(RwRGBA const& color);
RwCamera *GetRwCamera()
{
return m_pCamera;
}
};

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,19 @@
#pragma once
#define MAX_STOREDSHADOWS 48
#define MAX_POLYBUNCHES 300
#define MAX_STATICSHADOWS 64
#define MAX_POLYBUNCHES 380
#define MAX_STATICSHADOWS 48
#define MAX_PERMAMENTSHADOWS 48
class CEntity;
class CPtrList;
class CAutomobile;
class CVehicle;
class CPed;
class CCutsceneShadow;
class CCutsceneObject;
enum eShadowType
{
@ -27,6 +34,16 @@ enum eShadowTextureType
SHADOWTEX_BLOOD
};
enum VEH_SHD_TYPE
{
VEH_SHD_TYPE_CAR = 0,
VEH_SHD_TYPE_BIKE,
VEH_SHD_TYPE_HELI,
VEH_SHD_TYPE_SEAPLANE,
VEH_SHD_TYPE_RCPLANE,
};
class CStoredShadow
{
public:
@ -35,6 +52,8 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
RwTexture *m_pTexture;
CCutsceneShadow *m_pCutsceneShadow;
int16 m_nIntensity;
uint8 m_ShadowType;
uint8 m_nRed;
@ -44,9 +63,9 @@ public:
{
uint8 bDrawOnWater : 1;
uint8 bRendered : 1;
//uint8 bDrawOnBuildings : 1;
uint8 bDrawOnBuildings : 1;
} m_nFlags;
RwTexture *m_pTexture;
CStoredShadow()
{ }
@ -57,11 +76,11 @@ VALIDATE_SIZE(CStoredShadow, 0x30);
class CPolyBunch
{
public:
int16 m_nNumVerts;
CVector m_aVerts[7];
CPolyBunch *m_pNext;
int16 m_nNumVerts;
uint8 m_aU[7];
uint8 m_aV[7];
CPolyBunch *m_pNext;
CPolyBunch()
{ }
@ -80,15 +99,16 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
uint8 m_nType;
RwTexture *m_pTexture;
int16 m_nIntensity; // unsigned ?
uint8 m_nType;
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
bool m_bJustCreated;
bool m_bRendered;
bool m_bTemp;
RwTexture *m_pTexture;
CStaticShadow()
{ }
@ -106,14 +126,14 @@ public:
CVector2D m_vecSide;
float m_fZDistance;
float m_fScale;
uint32 m_nTimeCreated;
uint32 m_nLifeTime;
RwTexture *m_pTexture;
int16 m_nIntensity;
uint8 m_nType; // eShadowType
uint8 m_nRed;
uint8 m_nGreen;
uint8 m_nBlue;
uint32 m_nTimeCreated;
uint32 m_nLifeTime;
RwTexture *m_pTexture;
CPermanentShadow()
{ }
@ -121,49 +141,49 @@ public:
VALIDATE_SIZE(CPermanentShadow, 0x38);
class CPtrList;
class CAutomobile;
class CPed;
class CShadows
{
public:
#if 1
static int16 ShadowsStoredToBeRendered;
static CStoredShadow asShadowsStored [MAX_STOREDSHADOWS];
static CPolyBunch aPolyBunches [MAX_POLYBUNCHES];
static CStaticShadow aStaticShadows [MAX_STATICSHADOWS];
static CPolyBunch *pEmptyBunchList;
static CPermanentShadow aPermanentShadows[MAX_PERMAMENTSHADOWS];
#else
static int16 &ShadowsStoredToBeRendered;
static CStoredShadow (&asShadowsStored) [MAX_STOREDSHADOWS];
static CPolyBunch (&aPolyBunches) [MAX_POLYBUNCHES];
static CStaticShadow (&aStaticShadows) [MAX_STATICSHADOWS];
static CPolyBunch *&pEmptyBunchList;
static CPermanentShadow (&aPermanentShadows)[MAX_PERMAMENTSHADOWS];
#endif
static void Init (void);
static void Shutdown (void);
static void AddPermanentShadow ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, uint32 nTime, float fScale);
static void StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
static bool StoreStaticShadow (uint32 nID, uint8 ShadowType, RwTexture *pTexture, Const CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, float fDrawDistance, bool bTempShadow, float fUpDistance);
static void StoreShadowToBeRendered ( uint8 ShadowType, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue);
static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale);
static void StoreShadowForCar (CAutomobile *pCar);
static void StoreShadowToBeRendered ( uint8 ShadowType, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, bool bDrawOnWater, float fScale, CCutsceneShadow *pShadow, bool bDrawOnBuildings);
static void StoreShadowForVehicle (CVehicle *pCar, VEH_SHD_TYPE type);
static void StoreCarLightShadow (CAutomobile *pCar, int32 nID, RwTexture *pTexture, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, uint8 nRed, uint8 nGreen, uint8 nBlue, float fMaxViewAngle);
static void StoreShadowForPed (CPed *pPed, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForPedObject (CEntity *pPedObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForCutscenePedObject(CCutsceneObject *pObject, float fDisplacementX, float fDisplacementY, float fFrontX, float fFrontY, float fSideX, float fSideY);
static void StoreShadowForTree (CEntity *pTree);
static void StoreShadowForPole (CEntity *pPole, float fOffsetX, float fOffsetY, float fOffsetZ, float fPoleHeight, float fPoleWidth, uint32 nID);
static void SetRenderModeForShadowType (uint8 ShadowType);
static void RenderStoredShadows (void);
static void RenderStaticShadows (void);
static void GeneratePolysForStaticShadow (int16 nStaticShadowID);
static void CastShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void CastShadowEntity (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
static void CastPlayerShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void CastCutsceneShadowSectorList (CPtrList &PtrList, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
static void CastShadowEntityXY (CEntity *pEntity, float fStartX, float fStartY, float fEndX, float fEndY,
CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch);
static void CastShadowEntityXYZ (CEntity *pEntity, CVector *pPosn, float fFrontX, float fFrontY, float fSideX, float fSideY, int16 nIntensity, uint8 nRed, uint8 nGreen, uint8 nBlue, float fZDistance, float fScale, CPolyBunch **ppPolyBunch, CCutsceneShadow *pShadow);
static void UpdateStaticShadows (void);
static void UpdatePermanentShadows (void);
static void CalcPedShadowValues (CVector vecLightDir, float *pfDisplacementX, float *pfDisplacementY, float *pfFrontX, float *pfFrontY, float *pfSideX, float *pfSideY);
@ -175,6 +195,8 @@ public:
extern RwTexture *gpShadowCarTex;
extern RwTexture *gpShadowPedTex;
extern RwTexture *gpShadowHeliTex;
extern RwTexture *gpShadowBikeTex;
extern RwTexture *gpShadowBaronTex;
extern RwTexture *gpShadowExplosionTex;
extern RwTexture *gpShadowHeadLightsTex;
extern RwTexture *gpOutline1Tex;
@ -182,7 +204,6 @@ extern RwTexture *gpOutline2Tex;
extern RwTexture *gpOutline3Tex;
extern RwTexture *gpBloodPoolTex;
extern RwTexture *gpReflectionTex;
extern RwTexture *gpGoalMarkerTex;
extern RwTexture *gpWalkDontTex;
extern RwTexture *gpCrackedGlassTex;
extern RwTexture *gpPostShadowTex;

View File

@ -395,6 +395,125 @@ RenderSkeleton(RpHAnimHierarchy *hier)
}
#endif
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset)
{
RwIm2DVertex vx[4];
/*
* Render an opaque white 2D quad at the given coordinates and
* spanning a whole texture.
*/
RwIm2DVertexSetScreenX(&vx[0], x1);
RwIm2DVertexSetScreenY(&vx[0], y1);
RwIm2DVertexSetScreenZ(&vx[0], z);
RwIm2DVertexSetIntRGBA(&vx[0], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[0], recipCamZ);
RwIm2DVertexSetU(&vx[0], uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[0], uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[1], x1);
RwIm2DVertexSetScreenY(&vx[1], y2);
RwIm2DVertexSetScreenZ(&vx[1], z);
RwIm2DVertexSetIntRGBA(&vx[1], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[1], recipCamZ);
RwIm2DVertexSetU(&vx[1], uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[1], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[2], x2);
RwIm2DVertexSetScreenY(&vx[2], y1);
RwIm2DVertexSetScreenZ(&vx[2], z);
RwIm2DVertexSetIntRGBA(&vx[2], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[2], recipCamZ);
RwIm2DVertexSetU(&vx[2], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[2], uvOffset, recipCamZ);
RwIm2DVertexSetScreenX(&vx[3], x2);
RwIm2DVertexSetScreenY(&vx[3], y2);
RwIm2DVertexSetScreenZ(&vx[3], z);
RwIm2DVertexSetIntRGBA(&vx[3], 255, 255, 255, 255);
RwIm2DVertexSetRecipCameraZ(&vx[3], recipCamZ);
RwIm2DVertexSetU(&vx[3], 1.0f + uvOffset, recipCamZ);
RwIm2DVertexSetV(&vx[3], 1.0f + uvOffset, recipCamZ);
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx, 4);
return TRUE;
}
bool b_cbsUseLTM = true;
RpAtomic *cbsCalcMeanBSphereRadiusCB(RpAtomic *atomic, void *data)
{
RwV3d atomicPos;
if ( b_cbsUseLTM )
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
else
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
RwV3d temp;
RwV3dSub(&temp, &atomicPos, &((RwSphere *)data)->center);
RwReal radius = RwV3dLength(&temp) + RpAtomicGetBoundingSphere(atomic)->radius;
if ( ((RwSphere *)data)->radius < radius )
((RwSphere *)data)->radius = radius;
return atomic;
}
RpAtomic *cbsCalcMeanBSphereCenterCB(RpAtomic *atomic, void *data)
{
RwV3d atomicPos;
if ( b_cbsUseLTM )
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetLTM(RpClumpGetFrame(atomic->clump)));
else
RwV3dTransformPoints(&atomicPos, &RpAtomicGetBoundingSphere(atomic)->center, 1, RwFrameGetMatrix(RpClumpGetFrame(atomic->clump)));
RwV3dAdd(&((RwSphere *)data)->center, &((RwSphere *)data)->center, &atomicPos);
return atomic;
}
RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM)
{
RwMatrix matrix;
RwSphere result = { 0.0f, 0.0f, 0.0f, 0.0f };
b_cbsUseLTM = useLTM;
if ( clump == NULL || sphere == NULL )
return NULL;
sphere->radius = 0.0f;
sphere->center.x = 0.0f;
sphere->center.y = 0.0f;
sphere->center.z = 0.0f;
RwInt32 numAtomics = RpClumpGetNumAtomics(clump);
if ( numAtomics < 1.0f )
return NULL;
RpClumpForAllAtomics(clump, cbsCalcMeanBSphereCenterCB, &result);
RwV3dScale(&result.center, &result.center, 1.0f/numAtomics);
RpClumpForAllAtomics(clump, cbsCalcMeanBSphereRadiusCB, &result);
if ( b_cbsUseLTM )
RwMatrixInvert(&matrix, RwFrameGetLTM(RpClumpGetFrame(clump)));
else
RwMatrixInvert(&matrix, RwFrameGetMatrix(RpClumpGetFrame(clump)));
RwV3dTransformPoints(&result.center, &result.center, 1, &matrix);
RwSphereAssign(sphere, &result);
return clump;
}
void
CameraSize(RwCamera * camera, RwRect * rect,
RwReal viewWindow, RwReal aspectRatio)

View File

@ -29,6 +29,9 @@ RpAtomic *AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data);
void RenderSkeleton(RpHAnimHierarchy *hier);
#endif
RwBool Im2DRenderQuad(RwReal x1, RwReal y1, RwReal x2, RwReal y2, RwReal z, RwReal recipCamZ, RwReal uvOffset);
RpClump *RpClumpGetBoundingSphere(RpClump *clump, RwSphere *sphere, bool useLTM);
RwTexDictionary *RwTexDictionaryGtaStreamRead(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead1(RwStream *stream);
RwTexDictionary *RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict);

View File

@ -2505,8 +2505,12 @@ CAutomobile::PreRender(void)
// end of lights
}
//TODO(MIAMI): StoreShadowForVehicle once we have it
CShadows::StoreShadowForCar(this);
if (IsRealHeli())
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
else if ( GetModelIndex() == MI_RCBARON)
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_RCPLANE);
else
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_CAR);
DoSunGlare();

View File

@ -1546,7 +1546,7 @@ CBike::PreRender(void)
}
AddDamagedVehicleParticles();
//TODO(MIAMI): StoreShadowForVehicle once we have it
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_BIKE);
CMatrix mat;
CVector pos;

View File

@ -560,6 +560,7 @@ CHeli::PreRender(void)
{
float radius = (GetPosition().z - FindPlayerCoors().z - 10.0f - 1.0f) * 0.3f + 10.0f;
HeliDustGenerate(this, radius, FindPlayerCoors().z, Max(16.0f - 4.0f*CTimer::GetTimeStep(), 2.0f));
CShadows::StoreShadowForVehicle(this, VEH_SHD_TYPE_HELI);
}
void
@ -595,7 +596,7 @@ CHeli::PreRenderAlways(void)
CShadows::StoreShadowToBeRendered(SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &shadowPos,
6.0f, 0.0f, 0.0f, -6.0f,
80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity, 80*m_fSearchLightIntensity,
50.0f, true, 1.0f);
50.0f, true, 1.0f, NULL, false);
CVector front = GetMatrix() * CVector(0.0f, 7.0f, 0.0f);
CVector toPlayer = FindPlayerCoors() - front;