mirror of
https://github.com/GTAmodding/re3.git
synced 2021-02-19 17:49:54 +01:00
commit
b9b7d5ac21
@ -312,7 +312,10 @@ project "reVC"
|
||||
linkoptions "/SAFESEH:NO"
|
||||
characterset ("MBCS")
|
||||
targetextension ".exe"
|
||||
if(_OPTIONS["with-librw"]) then
|
||||
-- external librw is dynamic
|
||||
staticruntime "on"
|
||||
end
|
||||
|
||||
filter "platforms:win*glfw*"
|
||||
staticruntime "off"
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "ColStore.h"
|
||||
#include "Automobile.h"
|
||||
#include "MBlur.h"
|
||||
#include "screendroplets.h"
|
||||
|
||||
uint8 CGameLogic::ActivePlayers;
|
||||
uint8 CGameLogic::ShortCutState;
|
||||
@ -153,6 +154,9 @@ CGameLogic::Update()
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Initialise();
|
||||
#endif
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
@ -259,6 +263,9 @@ CGameLogic::Update()
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Initialise();
|
||||
#endif
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
@ -311,6 +318,9 @@ CGameLogic::Update()
|
||||
}
|
||||
}
|
||||
CEventList::Initialise();
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Initialise();
|
||||
#endif
|
||||
CMessages::ClearMessages();
|
||||
CCarCtrl::ClearInterestingVehicleList();
|
||||
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
|
||||
|
@ -93,6 +93,7 @@
|
||||
#include "WaterCreatures.h"
|
||||
#include "postfx.h"
|
||||
#include "custompipes.h"
|
||||
#include "screendroplets.h"
|
||||
|
||||
eLevelName CGame::currLevel;
|
||||
int32 CGame::currArea;
|
||||
@ -401,6 +402,9 @@ bool CGame::Initialise(const char* datFile)
|
||||
CPed::Initialise();
|
||||
CRouteNode::Initialise();
|
||||
CEventList::Initialise();
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Initialise();
|
||||
#endif
|
||||
LoadingScreen("Loading the Game", "Find big buildings", nil);
|
||||
CRenderer::Init();
|
||||
LoadingScreen("Loading the Game", "Setup game variables", nil);
|
||||
@ -568,6 +572,9 @@ void CGame::ReInitGameObjectVariables(void)
|
||||
currArea = AREA_MAIN_MAP;
|
||||
CPed::Initialise();
|
||||
CEventList::Initialise();
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Initialise();
|
||||
#endif
|
||||
CWeapon::InitialiseWeapons();
|
||||
CPopulation::Initialise();
|
||||
|
||||
|
@ -246,10 +246,18 @@ enum Config {
|
||||
#ifdef LIBRW
|
||||
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
|
||||
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
|
||||
//#define SCREEN_DROPLETS // neo water droplets
|
||||
//#define NEW_RENDERER // leeds-like world rendering, needs librw
|
||||
#endif
|
||||
//#define MULTISAMPLING // adds MSAA option TODO
|
||||
|
||||
#ifndef EXTENDED_COLOURFILTER
|
||||
#undef SCREEN_DROPLETS // we need the front- (or back-)buffer for this effect
|
||||
#endif
|
||||
#ifndef EXTENDED_PIPELINES
|
||||
#undef SCREEN_DROPLETS // we need neo.txd
|
||||
#endif
|
||||
|
||||
#ifdef LIBRW
|
||||
// these are not supported with librw yet
|
||||
# undef MULTISAMPLING
|
||||
|
@ -68,7 +68,9 @@
|
||||
#include "Clock.h"
|
||||
#include "Occlusion.h"
|
||||
#include "Ropes.h"
|
||||
#include "postfx.h"
|
||||
#include "custompipes.h"
|
||||
#include "screendroplets.h"
|
||||
|
||||
GlobalScene Scene;
|
||||
|
||||
@ -401,6 +403,9 @@ Initialise3D(void *param)
|
||||
bool ret = CGame::InitialiseRenderWare();
|
||||
#ifdef EXTENDED_PIPELINES
|
||||
CustomPipes::CustomPipeInit(); // need Scene.world for this
|
||||
#endif
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::InitDraw();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@ -411,6 +416,9 @@ Initialise3D(void *param)
|
||||
static void
|
||||
Terminate3D(void)
|
||||
{
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::Shutdown();
|
||||
#endif
|
||||
#ifdef EXTENDED_PIPELINES
|
||||
CustomPipes::CustomPipeShutdown();
|
||||
#endif
|
||||
@ -1246,10 +1254,17 @@ Idle(void *arg)
|
||||
RenderDebugShit();
|
||||
RenderEffects();
|
||||
|
||||
tbStartTimer(0, "RenderMotionBlur");
|
||||
if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) &&
|
||||
TheCamera.m_ScreenReductionPercentage > 0.0f)
|
||||
TheCamera.SetMotionBlurAlpha(150);
|
||||
|
||||
#ifdef SCREEN_DROPLETS
|
||||
CPostFX::GetBackBuffer(Scene.camera);
|
||||
ScreenDroplets::Process();
|
||||
ScreenDroplets::Render();
|
||||
#endif
|
||||
|
||||
tbStartTimer(0, "RenderMotionBlur");
|
||||
TheCamera.RenderMotionBlur();
|
||||
tbEndTimer("RenderMotionBlur");
|
||||
|
||||
|
@ -44,7 +44,7 @@ CustomMatCopy(void *dst, void *src, int32, int32)
|
||||
|
||||
|
||||
|
||||
static rw::TexDictionary *neoTxd;
|
||||
rw::TexDictionary *neoTxd;
|
||||
|
||||
bool bRenderingEnvMap;
|
||||
int32 EnvMapSize = 128;
|
||||
|
@ -6,6 +6,7 @@
|
||||
namespace CustomPipes {
|
||||
|
||||
|
||||
extern rw::TexDictionary *neoTxd;
|
||||
|
||||
struct CustomMatExt
|
||||
{
|
||||
|
@ -132,6 +132,8 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
|
||||
inst++;
|
||||
}
|
||||
|
||||
d3d::setTexture(1, nil);
|
||||
|
||||
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,8 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
|
||||
inst++;
|
||||
}
|
||||
|
||||
setTexture(1, nil);
|
||||
|
||||
SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
|
@ -375,6 +375,14 @@ CPostFX::NeedFrontBuffer(int32 type)
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
CPostFX::GetBackBuffer(RwCamera *cam)
|
||||
{
|
||||
RwRasterPushContext(pBackBuffer);
|
||||
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
|
||||
RwRasterPopContext();
|
||||
}
|
||||
|
||||
void
|
||||
CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
|
||||
{
|
||||
@ -391,11 +399,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
|
||||
blur = AvgAlpha;
|
||||
}
|
||||
|
||||
if(NeedBackBuffer()){
|
||||
RwRasterPushContext(pBackBuffer);
|
||||
RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
|
||||
RwRasterPopContext();
|
||||
}
|
||||
if(NeedBackBuffer())
|
||||
GetBackBuffer(cam);
|
||||
|
||||
DefinedState();
|
||||
|
||||
|
@ -39,6 +39,7 @@ public:
|
||||
static void SmoothColor(uint32 red, uint32 green, uint32 blue, uint32 alpha);
|
||||
static bool NeedBackBuffer(void);
|
||||
static bool NeedFrontBuffer(int32 type);
|
||||
static void GetBackBuffer(RwCamera *cam);
|
||||
static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
|
||||
};
|
||||
|
||||
|
791
src/extras/screendroplets.cpp
Normal file
791
src/extras/screendroplets.cpp
Normal file
@ -0,0 +1,791 @@
|
||||
#define WITH_D3D
|
||||
#include "common.h"
|
||||
|
||||
#ifdef SCREEN_DROPLETS
|
||||
|
||||
#ifndef LIBRW
|
||||
#error "Need librw for SCREEN_DROPLETS"
|
||||
#endif
|
||||
|
||||
#include "General.h"
|
||||
#include "Main.h"
|
||||
#include "RwHelper.h"
|
||||
#include "Main.h"
|
||||
#include "Timer.h"
|
||||
#include "Camera.h"
|
||||
#include "ZoneCull.h"
|
||||
#include "Weather.h"
|
||||
#include "ParticleObject.h"
|
||||
#include "Pad.h"
|
||||
#include "RenderBuffer.h"
|
||||
#include "custompipes.h"
|
||||
#include "postfx.h"
|
||||
#include "screendroplets.h"
|
||||
|
||||
// for 640
|
||||
#define MAXSIZE 15
|
||||
#define MINSIZE 4
|
||||
|
||||
int ScreenDroplets::ms_initialised;
|
||||
RwTexture *ScreenDroplets::ms_maskTex;
|
||||
RwTexture *ScreenDroplets::ms_screenTex;
|
||||
|
||||
bool ScreenDroplets::ms_enabled = true;
|
||||
bool ScreenDroplets::ms_movingEnabled = true;
|
||||
|
||||
ScreenDroplets::ScreenDrop ScreenDroplets::ms_drops[ScreenDroplets::MAXDROPS];
|
||||
int ScreenDroplets::ms_numDrops;
|
||||
ScreenDroplets::ScreenDropMoving ScreenDroplets::ms_dropsMoving[ScreenDroplets::MAXDROPSMOVING];
|
||||
int ScreenDroplets::ms_numDropsMoving;
|
||||
|
||||
CVector ScreenDroplets::ms_prevCamUp;
|
||||
CVector ScreenDroplets::ms_prevCamPos;
|
||||
CVector ScreenDroplets::ms_camMoveDelta;
|
||||
float ScreenDroplets::ms_camMoveDist;
|
||||
CVector ScreenDroplets::ms_screenMoveDelta;
|
||||
float ScreenDroplets::ms_screenMoveDist;
|
||||
float ScreenDroplets::ms_camUpAngle;
|
||||
|
||||
int ScreenDroplets::ms_splashDuration;
|
||||
CParticleObject *ScreenDroplets::ms_splashObject;
|
||||
|
||||
struct Im2DVertexUV2 : rw::RWDEVICE::Im2DVertex
|
||||
{
|
||||
rw::float32 u2, v2;
|
||||
};
|
||||
|
||||
#ifdef RW_D3D9
|
||||
static void *screenDroplet_PS;
|
||||
#endif
|
||||
#ifdef RW_GL3
|
||||
static rw::gl3::Shader *screenDroplet;
|
||||
#endif
|
||||
|
||||
// platform specific
|
||||
static void openim2d_uv2(void);
|
||||
static void closeim2d_uv2(void);
|
||||
static void RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices);
|
||||
|
||||
static Im2DVertexUV2 VertexBuffer[TEMPBUFFERVERTSIZE];
|
||||
|
||||
void
|
||||
ScreenDroplets::Initialise(void)
|
||||
{
|
||||
Clear();
|
||||
ms_splashDuration = -1;
|
||||
ms_splashObject = nil;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::InitDraw(void)
|
||||
{
|
||||
if(CustomPipes::neoTxd)
|
||||
ms_maskTex = CustomPipes::neoTxd->find("dropmask");
|
||||
|
||||
ms_screenTex = RwTextureCreate(nil);
|
||||
RwTextureSetFilterMode(ms_screenTex, rwFILTERLINEAR);
|
||||
|
||||
openim2d_uv2();
|
||||
#ifdef RW_D3D9
|
||||
#include "shaders/screenDroplet_PS.inc"
|
||||
screenDroplet_PS = rw::d3d::createPixelShader(screenDroplet_PS_cso);
|
||||
#endif
|
||||
#ifdef RW_GL3
|
||||
using namespace rw::gl3;
|
||||
{
|
||||
#include "shaders/im2d_UV2_gl.inc"
|
||||
#include "shaders/screenDroplet_fs_gl.inc"
|
||||
const char *vs[] = { shaderDecl, header_vert_src, im2d_UV2_vert_src, nil };
|
||||
const char *fs[] = { shaderDecl, header_frag_src, screenDroplet_frag_src, nil };
|
||||
screenDroplet = Shader::create(vs, fs);
|
||||
assert(screenDroplet);
|
||||
}
|
||||
#endif
|
||||
|
||||
ms_initialised = 1;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::Shutdown(void)
|
||||
{
|
||||
if(ms_maskTex){
|
||||
RwTextureDestroy(ms_maskTex);
|
||||
ms_maskTex = nil;
|
||||
}
|
||||
if(ms_screenTex){
|
||||
RwTextureSetRaster(ms_screenTex, nil);
|
||||
RwTextureDestroy(ms_screenTex);
|
||||
ms_screenTex = nil;
|
||||
}
|
||||
#ifdef RW_D3D9
|
||||
if(screenDroplet_PS){
|
||||
rw::d3d::destroyPixelShader(screenDroplet_PS);
|
||||
screenDroplet_PS = nil;
|
||||
}
|
||||
#endif
|
||||
#ifdef RW_GL3
|
||||
if(screenDroplet){
|
||||
screenDroplet->destroy();
|
||||
screenDroplet = nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
closeim2d_uv2();
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::Process(void)
|
||||
{
|
||||
ProcessCameraMovement();
|
||||
SprayDrops();
|
||||
ProcessMoving();
|
||||
Fade();
|
||||
}
|
||||
|
||||
static void
|
||||
FlushBuffer(void)
|
||||
{
|
||||
if(TempBufferIndicesStored){
|
||||
RenderIndexedPrimitive_UV2(rwPRIMTYPETRILIST,
|
||||
VertexBuffer, TempBufferVerticesStored,
|
||||
TempBufferRenderIndexList, TempBufferIndicesStored);
|
||||
TempBufferVerticesStored = 0;
|
||||
TempBufferIndicesStored = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
StartStoring(int numIndices, int numVertices, RwImVertexIndex **indexStart, Im2DVertexUV2 **vertexStart)
|
||||
{
|
||||
if(TempBufferIndicesStored + numIndices >= TEMPBUFFERINDEXSIZE ||
|
||||
TempBufferVerticesStored + numVertices >= TEMPBUFFERVERTSIZE)
|
||||
FlushBuffer();
|
||||
*indexStart = &TempBufferRenderIndexList[TempBufferIndicesStored];
|
||||
*vertexStart = &VertexBuffer[TempBufferVerticesStored];
|
||||
int vertOffset = TempBufferVerticesStored;
|
||||
TempBufferIndicesStored += numIndices;
|
||||
TempBufferVerticesStored += numVertices;
|
||||
return vertOffset;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::Render(void)
|
||||
{
|
||||
ScreenDrop *drop;
|
||||
|
||||
DefinedState();
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(ms_maskTex));
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
|
||||
RwTextureSetRaster(ms_screenTex, CPostFX::pBackBuffer);
|
||||
#ifdef RW_D3D9
|
||||
rw::d3d::im2dOverridePS = screenDroplet_PS;
|
||||
rw::d3d::setTexture(1, ms_screenTex);
|
||||
#endif
|
||||
#ifdef RW_GL3
|
||||
rw::gl3::im2dOverrideShader = screenDroplet;
|
||||
rw::gl3::setTexture(1, ms_screenTex);
|
||||
#endif
|
||||
|
||||
RenderBuffer::ClearRenderBuffer();
|
||||
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||
if(drop->active)
|
||||
AddToRenderList(drop);
|
||||
FlushBuffer();
|
||||
|
||||
#ifdef RW_D3D9
|
||||
rw::d3d::im2dOverridePS = nil;
|
||||
rw::d3d::setTexture(1, nil);
|
||||
#endif
|
||||
#ifdef RW_GL3
|
||||
rw::gl3::im2dOverrideShader = nil;
|
||||
rw::gl3::setTexture(1, nil);
|
||||
#endif
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
|
||||
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::AddToRenderList(ScreenDroplets::ScreenDrop *drop)
|
||||
{
|
||||
static float xy[] = {
|
||||
-1.0f, -1.0f,
|
||||
-1.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, -1.0f
|
||||
};
|
||||
static float uv[] = {
|
||||
0.0f, 0.0f,
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f
|
||||
};
|
||||
|
||||
int i;
|
||||
RwImVertexIndex *indices;
|
||||
Im2DVertexUV2 *verts;
|
||||
int first = StartStoring(6, 4, &indices, &verts);
|
||||
|
||||
float scale = 0.5f*SCREEN_SCALE_X(drop->size);
|
||||
|
||||
float screenz = RwIm2DGetNearScreenZ();
|
||||
float z = RwCameraGetNearClipPlane(Scene.camera);
|
||||
float recipz = 1.0f/z;
|
||||
|
||||
float magSize = SCREEN_SCALE_Y(drop->magnification*(300.0f-40.0f) + 40.0f);
|
||||
float ul = drop->x - magSize;
|
||||
float vt = drop->y - magSize;
|
||||
float ur = drop->x + magSize;
|
||||
float vb = drop->y + magSize;
|
||||
ul = Max(ul, 0.0f)/RwRasterGetWidth(CPostFX::pBackBuffer);
|
||||
vt = Max(vt, 0.0f)/RwRasterGetHeight(CPostFX::pBackBuffer);
|
||||
ur = Min(ur, SCREEN_WIDTH)/RwRasterGetWidth(CPostFX::pBackBuffer);
|
||||
vb = Min(vb, SCREEN_HEIGHT)/RwRasterGetHeight(CPostFX::pBackBuffer);
|
||||
|
||||
for(i = 0; i < 4; i++){
|
||||
RwIm2DVertexSetScreenX(&verts[i], drop->x + xy[i*2]*scale);
|
||||
RwIm2DVertexSetScreenY(&verts[i], drop->y + xy[i*2+1]*scale);
|
||||
RwIm2DVertexSetScreenZ(&verts[i], screenz);
|
||||
RwIm2DVertexSetCameraZ(&verts[i], z);
|
||||
RwIm2DVertexSetRecipCameraZ(&verts[i], recipz);
|
||||
RwIm2DVertexSetIntRGBA(&verts[i], drop->color.r, drop->color.g, drop->color.b, drop->color.a);
|
||||
RwIm2DVertexSetU(&verts[i], uv[i*2], recipz);
|
||||
RwIm2DVertexSetV(&verts[i], uv[i*2+1], recipz);
|
||||
|
||||
verts[i].u2 = i < 2 ? ul : ur;
|
||||
verts[i].v2 = i % 3 ? vt : vb;
|
||||
}
|
||||
indices[0] = first + 0;
|
||||
indices[1] = first + 1;
|
||||
indices[2] = first + 2;
|
||||
indices[3] = first + 2;
|
||||
indices[4] = first + 3;
|
||||
indices[5] = first + 0;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::Clear(void)
|
||||
{
|
||||
ScreenDrop *drop;
|
||||
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||
drop->active = false;
|
||||
ms_numDrops = 0;
|
||||
}
|
||||
|
||||
ScreenDroplets::ScreenDrop*
|
||||
ScreenDroplets::NewDrop(float x, float y, float size, float lifetime, bool fades, int r, int g, int b)
|
||||
{
|
||||
ScreenDrop *drop;
|
||||
int i;
|
||||
|
||||
for(i = 0, drop = ms_drops; i < MAXDROPS; i++, drop++)
|
||||
if(!ms_drops[i].active)
|
||||
goto found;
|
||||
return nil;
|
||||
found:
|
||||
ms_numDrops++;
|
||||
drop->x = x;
|
||||
drop->y = y;
|
||||
drop->size = size;
|
||||
drop->magnification = (MAXSIZE - size + 1.0f) / (MAXSIZE - MINSIZE + 1.0f);
|
||||
drop->fades = fades;
|
||||
drop->active = true;
|
||||
drop->color.r = r;
|
||||
drop->color.g = g;
|
||||
drop->color.b = b;
|
||||
drop->color.a = 255;
|
||||
drop->time = 0.0f;
|
||||
drop->lifetime = lifetime;
|
||||
return drop;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::SetMoving(ScreenDroplets::ScreenDrop *drop)
|
||||
{
|
||||
ScreenDropMoving *moving;
|
||||
for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
|
||||
if(moving->drop == nil)
|
||||
goto found;
|
||||
return;
|
||||
found:
|
||||
ms_numDropsMoving++;
|
||||
moving->drop = drop;
|
||||
moving->dist = 0.0f;
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::FillScreen(int n)
|
||||
{
|
||||
float x, y, size;
|
||||
ScreenDrop *drop;
|
||||
|
||||
if(!ms_initialised)
|
||||
return;
|
||||
ms_numDrops = 0;
|
||||
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++){
|
||||
drop->active = false;
|
||||
if(drop < &ms_drops[n]){
|
||||
x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||
y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||
size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||
NewDrop(x, y, size, 2000.0f, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::FillScreenMoving(float amount, bool isBlood)
|
||||
{
|
||||
int n = (ms_screenMoveDelta.z > 5.0f ? 1.5f : 1.0f)*amount*20.0f;
|
||||
float x, y, size;
|
||||
ScreenDrop *drop;
|
||||
|
||||
while(n--)
|
||||
if(ms_numDrops < MAXDROPS && ms_numDropsMoving < MAXDROPSMOVING){
|
||||
x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||
y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||
size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||
drop = nil;
|
||||
if(isBlood)
|
||||
drop = NewDrop(x, y, size, 2000.0f, true, 255, 0, 0);
|
||||
else
|
||||
drop = NewDrop(x, y, size, 2000.0f, true);
|
||||
if(drop)
|
||||
SetMoving(drop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::RegisterSplash(CParticleObject *pobj)
|
||||
{
|
||||
CVector dist = pobj->GetPosition() - ms_prevCamPos;
|
||||
if(dist.MagnitudeSqr() < 20.0f){
|
||||
ms_splashDuration = 14;
|
||||
ms_splashObject = pobj;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::ProcessCameraMovement(void)
|
||||
{
|
||||
RwMatrix *camMat = RwFrameGetMatrix(RwCameraGetFrame(Scene.camera));
|
||||
CVector camPos = camMat->pos;
|
||||
CVector camUp = camMat->at;
|
||||
ms_camMoveDelta = camPos - ms_prevCamPos;
|
||||
ms_camMoveDist = ms_camMoveDelta.Magnitude();
|
||||
|
||||
ms_prevCamUp = camUp;
|
||||
ms_prevCamPos = camPos;
|
||||
|
||||
ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, (RwV3d*)&ms_camMoveDelta);
|
||||
ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, (RwV3d*)&ms_camMoveDelta);
|
||||
ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, (RwV3d*)&ms_camMoveDelta);
|
||||
ms_screenMoveDelta *= 10.0f;
|
||||
ms_screenMoveDist = ms_screenMoveDelta.Magnitude2D();
|
||||
|
||||
uint16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
|
||||
bool isTopDown = mode == CCam::MODE_TOPDOWN || mode == CCam::MODE_GTACLASSIC || mode == CCam::MODE_TOP_DOWN_PED;
|
||||
bool isLookingInDirection = CPad::GetPad(0)->GetLookBehindForCar() || CPad::GetPad(0)->GetLookLeft() || CPad::GetPad(0)->GetLookRight();
|
||||
ms_enabled = !isTopDown && !isLookingInDirection;
|
||||
ms_movingEnabled = !isTopDown && !isLookingInDirection;
|
||||
|
||||
// 0 when looking stright up, 180 when looking up or down
|
||||
ms_camUpAngle = RADTODEG(Acos(clamp(camUp.z, -1.0f, 1.0f)));
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::SprayDrops(void)
|
||||
{
|
||||
bool noRain = CCullZones::PlayerNoRain() || CCullZones::CamNoRain();
|
||||
if(!noRain && CWeather::Rain > 0.0f && ms_enabled){
|
||||
// 180 when looking stright up, 0 when looking up or down
|
||||
float angle = 180.0f - ms_camUpAngle;
|
||||
angle = Max(angle, 40.0f); // want at least some rain
|
||||
FillScreenMoving((angle - 40.0f) / 150.0f * CWeather::Rain * 0.5f);
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0; i < MAX_AUDIOHYDRANTS; i++){
|
||||
CAudioHydrant *hyd = CAudioHydrant::Get(i);
|
||||
if (hyd->pParticleObject){
|
||||
CVector dist = hyd->pParticleObject->GetPosition() - ms_prevCamPos;
|
||||
if(dist.MagnitudeSqr() > 40.0f ||
|
||||
DotProduct(dist, ms_prevCamUp) < 0.0f) continue;
|
||||
|
||||
FillScreenMoving(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
static int ndrops[] = {
|
||||
125, 250, 500, 1000, 1000,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
if(ms_splashDuration >= 0){
|
||||
if(ms_numDrops < MAXDROPS) {
|
||||
float numDropMult = 1.0f;
|
||||
if(ms_splashObject){
|
||||
float dist = (ms_splashObject->GetPosition() - ms_prevCamPos).Magnitude();
|
||||
numDropMult = 1.0f - (dist - 5.0f)/15.0f;
|
||||
if(numDropMult < 0) numDropMult = 0.0f; // fix
|
||||
}
|
||||
int n = ndrops[ms_splashDuration] * numDropMult;
|
||||
while(n--)
|
||||
if(ms_numDrops < MAXDROPS){
|
||||
float x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
|
||||
float y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
|
||||
float size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
|
||||
NewDrop(x, y, size, 10000.0f, false);
|
||||
}
|
||||
}
|
||||
ms_splashDuration--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::NewTrace(ScreenDroplets::ScreenDropMoving *moving)
|
||||
{
|
||||
if(ms_numDrops < MAXDROPS){
|
||||
moving->dist = 0.0f;
|
||||
NewDrop(moving->drop->x, moving->drop->y, MINSIZE, 500.0f, true,
|
||||
moving->drop->color.r, moving->drop->color.g, moving->drop->color.b);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::MoveDrop(ScreenDroplets::ScreenDropMoving *moving)
|
||||
{
|
||||
ScreenDrop *drop = moving->drop;
|
||||
if(!ms_movingEnabled)
|
||||
return;
|
||||
if(!drop->active){
|
||||
moving->drop = nil;
|
||||
ms_numDropsMoving--;
|
||||
return;
|
||||
}
|
||||
if(ms_screenMoveDelta.z > 0.0f && ms_camMoveDist > 0.3f){
|
||||
if(ms_screenMoveDist > 0.5f && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
|
||||
// movement when camera turns
|
||||
moving->dist += ms_screenMoveDist;
|
||||
if(moving->dist > 20.0f && drop->color.a > 100)
|
||||
NewTrace(moving);
|
||||
|
||||
drop->x -= ms_screenMoveDelta.x;
|
||||
drop->y += ms_screenMoveDelta.y;
|
||||
}else{
|
||||
// movement out of center
|
||||
float d = ms_screenMoveDelta.z*0.2f;
|
||||
float dx, dy, sum;
|
||||
dx = drop->x - SCREEN_WIDTH*0.5f + ms_screenMoveDelta.x;
|
||||
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON)
|
||||
dy = drop->y - SCREEN_HEIGHT*1.2f - ms_screenMoveDelta.y;
|
||||
else
|
||||
dy = drop->y - SCREEN_HEIGHT*0.5f - ms_screenMoveDelta.y;
|
||||
sum = fabs(dx) + fabs(dy);
|
||||
if(sum > 0.001f){
|
||||
dx /= sum;
|
||||
dy /= sum;
|
||||
}
|
||||
moving->dist += d;
|
||||
if(moving->dist > 20.0f && drop->color.a > 100)
|
||||
NewTrace(moving);
|
||||
drop->x += dx * d;
|
||||
drop->y += dy * d;
|
||||
}
|
||||
|
||||
if(drop->x < 0.0f || drop->y < 0.0f ||
|
||||
drop->x > SCREEN_WIDTH || drop->y > SCREEN_HEIGHT){
|
||||
moving->drop = nil;
|
||||
ms_numDropsMoving--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::ProcessMoving(void)
|
||||
{
|
||||
ScreenDropMoving *moving;
|
||||
if(!ms_movingEnabled)
|
||||
return;
|
||||
for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
|
||||
if(moving->drop)
|
||||
MoveDrop(moving);
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::Fade(void)
|
||||
{
|
||||
ScreenDrop *drop;
|
||||
for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
|
||||
if(drop->active)
|
||||
drop->Fade();
|
||||
}
|
||||
|
||||
void
|
||||
ScreenDroplets::ScreenDrop::Fade(void)
|
||||
{
|
||||
int delta = CTimer::GetTimeStepInMilliseconds();
|
||||
time += delta;
|
||||
if(time < lifetime){
|
||||
color.a = 255 - time/lifetime*255;
|
||||
}else if(fades){
|
||||
ScreenDroplets::ms_numDrops--;
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Im2D with two uv coors
|
||||
*/
|
||||
|
||||
#ifdef RW_D3D9
|
||||
// stolen from RW, not in a public header
|
||||
namespace rw {
|
||||
namespace d3d {
|
||||
void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer
|
||||
void removeDynamicVB(IDirect3DVertexBuffer9 **buf);
|
||||
void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer
|
||||
void removeDynamicIB(IDirect3DIndexBuffer9 **buf);
|
||||
}
|
||||
}
|
||||
// different than im2d
|
||||
#define NUMINDICES 1024
|
||||
#define NUMVERTICES 1024
|
||||
|
||||
static int primTypeMap[] = {
|
||||
D3DPT_POINTLIST, // invalid
|
||||
D3DPT_LINELIST,
|
||||
D3DPT_LINESTRIP,
|
||||
D3DPT_TRIANGLELIST,
|
||||
D3DPT_TRIANGLESTRIP,
|
||||
D3DPT_TRIANGLEFAN,
|
||||
D3DPT_POINTLIST, // actually not supported!
|
||||
};
|
||||
// end of stolen stuff
|
||||
|
||||
|
||||
static IDirect3DVertexDeclaration9 *im2ddecl_uv2;
|
||||
static IDirect3DVertexBuffer9 *im2dvertbuf_uv2;
|
||||
static IDirect3DIndexBuffer9 *im2dindbuf_uv2;
|
||||
|
||||
void
|
||||
openim2d_uv2(void)
|
||||
{
|
||||
using namespace rw;
|
||||
using namespace d3d;
|
||||
D3DVERTEXELEMENT9 elements[5] = {
|
||||
{ 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
|
||||
{ 0, offsetof(Im2DVertexUV2, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
|
||||
{ 0, offsetof(Im2DVertexUV2, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
|
||||
{ 0, offsetof(Im2DVertexUV2, u2), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
|
||||
D3DDECL_END()
|
||||
};
|
||||
assert(im2ddecl_uv2 == nil);
|
||||
im2ddecl_uv2 = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements);
|
||||
assert(im2ddecl_uv2);
|
||||
|
||||
assert(im2dvertbuf_uv2 == nil);
|
||||
im2dvertbuf_uv2 = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertexUV2), 0, true);
|
||||
assert(im2dvertbuf_uv2);
|
||||
addDynamicVB(NUMVERTICES*sizeof(Im2DVertexUV2), 0, &im2dvertbuf_uv2);
|
||||
|
||||
assert(im2dindbuf_uv2 == nil);
|
||||
im2dindbuf_uv2 = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(rw::uint16), true);
|
||||
assert(im2dindbuf_uv2);
|
||||
addDynamicIB(NUMINDICES*sizeof(rw::uint16), &im2dindbuf_uv2);
|
||||
}
|
||||
|
||||
void
|
||||
closeim2d_uv2(void)
|
||||
{
|
||||
using namespace rw;
|
||||
using namespace d3d;
|
||||
|
||||
d3d9::destroyVertexDeclaration(im2ddecl_uv2);
|
||||
im2ddecl_uv2 = nil;
|
||||
|
||||
removeDynamicVB(&im2dvertbuf_uv2);
|
||||
destroyVertexBuffer(im2dvertbuf_uv2);
|
||||
im2dvertbuf_uv2 = nil;
|
||||
|
||||
removeDynamicIB(&im2dindbuf_uv2);
|
||||
destroyIndexBuffer(im2dindbuf_uv2);
|
||||
im2dindbuf_uv2 = nil;
|
||||
}
|
||||
|
||||
void
|
||||
RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
|
||||
{
|
||||
using namespace rw;
|
||||
using namespace d3d;
|
||||
|
||||
if(numVertices > NUMVERTICES ||
|
||||
numIndices > NUMINDICES){
|
||||
// TODO: error
|
||||
return;
|
||||
}
|
||||
rw::uint16 *lockedindices = lockIndices(im2dindbuf_uv2, 0, numIndices*sizeof(rw::uint16), D3DLOCK_DISCARD);
|
||||
memcpy(lockedindices, indices, numIndices*sizeof(rw::uint16));
|
||||
unlockIndices(im2dindbuf_uv2);
|
||||
|
||||
rw::uint8 *lockedvertices = lockVertices(im2dvertbuf_uv2, 0, numVertices*sizeof(Im2DVertexUV2), D3DLOCK_DISCARD);
|
||||
memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertexUV2));
|
||||
unlockVertices(im2dvertbuf_uv2);
|
||||
|
||||
setStreamSource(0, im2dvertbuf_uv2, 0, sizeof(Im2DVertexUV2));
|
||||
setIndices(im2dindbuf_uv2);
|
||||
setVertexDeclaration(im2ddecl_uv2);
|
||||
|
||||
if(im2dOverridePS)
|
||||
setPixelShader(im2dOverridePS);
|
||||
else if(engine->device.getRenderState(TEXTURERASTER))
|
||||
setPixelShader(im2d_tex_PS);
|
||||
else
|
||||
setPixelShader(im2d_PS);
|
||||
|
||||
d3d::flushCache();
|
||||
|
||||
rw::uint32 primCount = 0;
|
||||
switch(primType){
|
||||
case PRIMTYPELINELIST:
|
||||
primCount = numIndices/2;
|
||||
break;
|
||||
case PRIMTYPEPOLYLINE:
|
||||
primCount = numIndices-1;
|
||||
break;
|
||||
case PRIMTYPETRILIST:
|
||||
primCount = numIndices/3;
|
||||
break;
|
||||
case PRIMTYPETRISTRIP:
|
||||
primCount = numIndices-2;
|
||||
break;
|
||||
case PRIMTYPETRIFAN:
|
||||
primCount = numIndices-2;
|
||||
break;
|
||||
case PRIMTYPEPOINTLIST:
|
||||
primCount = numIndices;
|
||||
break;
|
||||
}
|
||||
d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
|
||||
0, numVertices,
|
||||
0, primCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef RW_GL3
|
||||
// different than im2d
|
||||
#define NUMINDICES 1024
|
||||
#define NUMVERTICES 1024
|
||||
|
||||
static rw::gl3::AttribDesc im2d_UV2_attribDesc[4] = {
|
||||
{ rw::gl3::ATTRIB_POS, GL_FLOAT, GL_FALSE, 4,
|
||||
sizeof(Im2DVertexUV2), 0 },
|
||||
{ rw::gl3::ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
|
||||
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, r) },
|
||||
{ rw::gl3::ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
|
||||
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u) },
|
||||
{ rw::gl3::ATTRIB_TEXCOORDS1, GL_FLOAT, GL_FALSE, 2,
|
||||
sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u2) }
|
||||
};
|
||||
|
||||
static int primTypeMap[] = {
|
||||
GL_POINTS, // invalid
|
||||
GL_LINES,
|
||||
GL_LINE_STRIP,
|
||||
GL_TRIANGLES,
|
||||
GL_TRIANGLE_STRIP,
|
||||
GL_TRIANGLE_FAN,
|
||||
GL_POINTS
|
||||
};
|
||||
|
||||
static int32 u_xform;
|
||||
|
||||
uint32 im2D_UV2_Vbo, im2D_UV2_Ibo;
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
uint32 im2D_UV2_Vao;
|
||||
#endif
|
||||
|
||||
void
|
||||
openim2d_uv2(void)
|
||||
{
|
||||
u_xform = rw::gl3::registerUniform("u_xform"); // this doesn't add a new one, so it's safe
|
||||
|
||||
glGenBuffers(1, &im2D_UV2_Ibo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
|
||||
|
||||
glGenBuffers(1, &im2D_UV2_Vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glGenVertexArrays(1, &im2D_UV2_Vao);
|
||||
glBindVertexArray(im2D_UV2_Vao);
|
||||
setAttribPointers(im2d_UV2_attribDesc, 4);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
closeim2d_uv2(void)
|
||||
{
|
||||
glDeleteBuffers(1, &im2D_UV2_Ibo);
|
||||
glDeleteBuffers(1, &im2D_UV2_Vbo);
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glDeleteVertexArrays(1, &im2D_UV2_Vao);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
|
||||
{
|
||||
using namespace rw;
|
||||
using namespace gl3;
|
||||
|
||||
GLfloat xform[4];
|
||||
Camera *cam;
|
||||
cam = (Camera*)engine->currentCamera;
|
||||
|
||||
#ifdef RW_GL_USE_VAOS
|
||||
glBindVertexArray(im2D_UV2_Vao);
|
||||
#endif
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertexUV2), vertices);
|
||||
|
||||
xform[0] = 2.0f/cam->frameBuffer->width;
|
||||
xform[1] = -2.0f/cam->frameBuffer->height;
|
||||
xform[2] = -1.0f;
|
||||
xform[3] = 1.0f;
|
||||
|
||||
if(im2dOverrideShader)
|
||||
im2dOverrideShader->use();
|
||||
else
|
||||
assert(0);//im2dShader->use();
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
setAttribPointers(im2d_UV2_attribDesc, 4);
|
||||
#endif
|
||||
|
||||
glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(primTypeMap[primType], numIndices,
|
||||
GL_UNSIGNED_SHORT, nil);
|
||||
#ifndef RW_GL_USE_VAOS
|
||||
disableAttribPointers(im2d_UV2_attribDesc, 4);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
78
src/extras/screendroplets.h
Normal file
78
src/extras/screendroplets.h
Normal file
@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef SCREEN_DROPLETS
|
||||
|
||||
class CParticleObject;
|
||||
|
||||
class ScreenDroplets
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
MAXDROPS = 2000,
|
||||
MAXDROPSMOVING = 700
|
||||
};
|
||||
|
||||
class ScreenDrop
|
||||
{
|
||||
public:
|
||||
float x, y, time; // shorts on xbox (short float?)
|
||||
float size, magnification, lifetime; // "
|
||||
CRGBA color;
|
||||
bool active;
|
||||
bool fades;
|
||||
|
||||
void Fade(void);
|
||||
};
|
||||
|
||||
struct ScreenDropMoving
|
||||
{
|
||||
ScreenDrop *drop;
|
||||
float dist;
|
||||
};
|
||||
|
||||
static int ms_initialised;
|
||||
static RwTexture *ms_maskTex;
|
||||
static RwTexture *ms_screenTex;
|
||||
|
||||
static bool ms_enabled;
|
||||
static bool ms_movingEnabled;
|
||||
|
||||
static ScreenDrop ms_drops[MAXDROPS];
|
||||
static int ms_numDrops;
|
||||
static ScreenDropMoving ms_dropsMoving[MAXDROPSMOVING];
|
||||
static int ms_numDropsMoving;
|
||||
|
||||
static CVector ms_prevCamUp;
|
||||
static CVector ms_prevCamPos;
|
||||
static CVector ms_camMoveDelta;
|
||||
static float ms_camMoveDist;
|
||||
static CVector ms_screenMoveDelta;
|
||||
static float ms_screenMoveDist;
|
||||
static float ms_camUpAngle;
|
||||
|
||||
static int ms_splashDuration;
|
||||
static CParticleObject *ms_splashObject;
|
||||
|
||||
static void Initialise(void);
|
||||
static void InitDraw(void);
|
||||
static void Shutdown(void);
|
||||
static void Process(void);
|
||||
static void Render(void);
|
||||
static void AddToRenderList(ScreenDrop *drop);
|
||||
|
||||
static void Clear(void);
|
||||
static ScreenDrop *NewDrop(float x, float y, float size, float lifetime, bool fades, int r = 255, int g = 255, int b = 255);
|
||||
static void SetMoving(ScreenDroplets::ScreenDrop *drop);
|
||||
static void FillScreen(int n);
|
||||
static void FillScreenMoving(float amount, bool isBlood = false);
|
||||
static void RegisterSplash(CParticleObject *pobj);
|
||||
|
||||
static void ProcessCameraMovement(void);
|
||||
static void SprayDrops(void);
|
||||
static void NewTrace(ScreenDroplets::ScreenDropMoving *moving);
|
||||
static void MoveDrop(ScreenDropMoving *moving);
|
||||
static void ProcessMoving(void);
|
||||
static void Fade(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -65,3 +65,13 @@ neoVehicle_fs_gl.inc: neoVehicle.frag
|
||||
(echo 'const char *neoVehicle_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' neoVehicle.frag;\
|
||||
echo ';') >neoVehicle_fs_gl.inc
|
||||
|
||||
im2d_UV2_gl.inc: im2d_UV2.vert
|
||||
(echo 'const char *im2d_UV2_vert_src =';\
|
||||
sed 's/..*/"&\\n"/' im2d_UV2.vert;\
|
||||
echo ';') >im2d_UV2_gl.inc
|
||||
|
||||
screenDroplet_fs_gl.inc: screenDroplet.frag
|
||||
(echo 'const char *screenDroplet_frag_src =';\
|
||||
sed 's/..*/"&\\n"/' screenDroplet.frag;\
|
||||
echo ';') >screenDroplet_fs_gl.inc
|
||||
|
21
src/extras/shaders/im2d_UV2.vert
Normal file
21
src/extras/shaders/im2d_UV2.vert
Normal file
@ -0,0 +1,21 @@
|
||||
uniform vec4 u_xform;
|
||||
|
||||
VSIN(ATTRIB_POS) vec4 in_pos;
|
||||
|
||||
VSOUT vec4 v_color;
|
||||
VSOUT vec2 v_tex0;
|
||||
VSOUT vec2 v_tex1;
|
||||
VSOUT float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
gl_Position = in_pos;
|
||||
gl_Position.w = 1.0;
|
||||
gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
|
||||
v_fog = DoFog(gl_Position.z);
|
||||
gl_Position.xyz *= gl_Position.w;
|
||||
v_color = in_color;
|
||||
v_tex0 = in_tex0;
|
||||
v_tex1 = in_tex1;
|
||||
}
|
18
src/extras/shaders/screenDroplet.frag
Normal file
18
src/extras/shaders/screenDroplet.frag
Normal file
@ -0,0 +1,18 @@
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
|
||||
FSIN vec4 v_color;
|
||||
FSIN vec2 v_tex0;
|
||||
FSIN vec2 v_tex1;
|
||||
FSIN float v_fog;
|
||||
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
vec4 color;
|
||||
color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
|
||||
color *= texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
|
||||
|
||||
FRAGCOLOR(color);
|
||||
}
|
||||
|
BIN
src/extras/shaders/screenDroplet_PS.cso
Normal file
BIN
src/extras/shaders/screenDroplet_PS.cso
Normal file
Binary file not shown.
17
src/extras/shaders/screenDroplet_PS.hlsl
Normal file
17
src/extras/shaders/screenDroplet_PS.hlsl
Normal file
@ -0,0 +1,17 @@
|
||||
struct VS_out {
|
||||
float4 Position : POSITION;
|
||||
float2 TexCoord0 : TEXCOORD0;
|
||||
float2 TexCoord1 : TEXCOORD1;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
sampler2D tex0 : register(s0);
|
||||
sampler2D tex1 : register(s1);
|
||||
|
||||
float4 main(VS_out input) : COLOR
|
||||
{
|
||||
float4 color = input.Color;
|
||||
color *= tex2D(tex0, input.TexCoord0.xy);
|
||||
color *= tex2D(tex1, input.TexCoord1.xy);
|
||||
return color;
|
||||
}
|
29
src/extras/shaders/screenDroplet_PS.inc
Normal file
29
src/extras/shaders/screenDroplet_PS.inc
Normal file
@ -0,0 +1,29 @@
|
||||
static unsigned char screenDroplet_PS_cso[] = {
|
||||
0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2c, 0x00, 0x43, 0x54, 0x41, 0x42,
|
||||
0x1c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
|
||||
0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x74, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0x00,
|
||||
0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x30,
|
||||
0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x31,
|
||||
0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x73, 0x5f, 0x32,
|
||||
0x5f, 0x30, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74,
|
||||
0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68,
|
||||
0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
|
||||
0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33,
|
||||
0x31, 0x31, 0x31, 0x00, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||
0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||
0x01, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
|
||||
0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
|
||||
0x00, 0x08, 0x0f, 0xa0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
|
||||
0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
|
||||
0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
|
||||
0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0,
|
||||
0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80,
|
||||
0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
|
||||
0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
|
||||
0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
|
||||
};
|
@ -8,6 +8,7 @@
|
||||
#include "Camera.h"
|
||||
#include "Game.h"
|
||||
#include "DMAudio.h"
|
||||
#include "screendroplets.h"
|
||||
|
||||
|
||||
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
|
||||
@ -18,6 +19,8 @@ CParticleObject *CParticleObject::pUnusedListHead;
|
||||
|
||||
CAudioHydrant List[MAX_AUDIOHYDRANTS];
|
||||
|
||||
CAudioHydrant *CAudioHydrant::Get(int n) { return &List[n]; }
|
||||
|
||||
bool
|
||||
CAudioHydrant::Add(CParticleObject *particleobject)
|
||||
{
|
||||
@ -246,6 +249,9 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
|
||||
pobj->m_nNumEffectCycles = 0;
|
||||
pobj->m_nSkipFrames = 1;
|
||||
pobj->m_nCreationChance = 0;
|
||||
#ifdef SCREEN_DROPLETS
|
||||
ScreenDroplets::RegisterSplash(pobj);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -107,4 +107,6 @@ public:
|
||||
|
||||
static bool Add (CParticleObject *particleobject);
|
||||
static void Remove(CParticleObject *particleobject);
|
||||
|
||||
static CAudioHydrant *Get(int n); // for neo screen droplets
|
||||
};
|
Loading…
Reference in New Issue
Block a user