diff options
Diffstat (limited to 'src/render/MBlur.cpp')
-rw-r--r-- | src/render/MBlur.cpp | 177 |
1 files changed, 147 insertions, 30 deletions
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index de15358e..08298a1f 100644 --- a/src/render/MBlur.cpp +++ b/src/render/MBlur.cpp @@ -10,6 +10,7 @@ #include "RwHelper.h" #include "Camera.h" #include "MBlur.h" +#include "Timer.h" #include "postfx.h" // Originally taken from RW example 'mblur' @@ -18,8 +19,10 @@ RwRaster *CMBlur::pFrontBuffer; bool CMBlur::ms_bJustInitialised; bool CMBlur::ms_bScaledBlur; bool CMBlur::BlurOn; +float CMBlur::Drunkness; static RwIm2DVertex Vertex[4]; +static RwIm2DVertex Vertex2[4]; static RwImVertexIndex Index[6] = { 0, 1, 2, 0, 2, 3 }; #ifndef LIBRW @@ -201,6 +204,43 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect) RwIm2DVertexSetU(&Vertex[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam)); RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255); + + + RwIm2DVertexSetScreenX(&Vertex2[0], zero + 2.0f); + RwIm2DVertexSetScreenY(&Vertex2[0], zero + 2.0f); + RwIm2DVertexSetScreenZ(&Vertex2[0], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Vertex2[0], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&Vertex2[0], 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetU(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetV(&Vertex2[0], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetIntRGBA(&Vertex2[0], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Vertex2[1], 2.0f); + RwIm2DVertexSetScreenY(&Vertex2[1], ymax + 2.0f); + RwIm2DVertexSetScreenZ(&Vertex2[1], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Vertex2[1], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&Vertex2[1], 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetU(&Vertex2[1], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetV(&Vertex2[1], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetIntRGBA(&Vertex2[1], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Vertex2[2], xmax + 2.0f); + RwIm2DVertexSetScreenY(&Vertex2[2], ymax + 2.0f); + RwIm2DVertexSetScreenZ(&Vertex2[2], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Vertex2[2], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&Vertex2[2], 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetU(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetV(&Vertex2[2], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetIntRGBA(&Vertex2[2], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Vertex2[3], xmax + 2.0f); + RwIm2DVertexSetScreenY(&Vertex2[3], zero + 2.0f); + RwIm2DVertexSetScreenZ(&Vertex2[3], RwIm2DGetNearScreenZ()); + RwIm2DVertexSetCameraZ(&Vertex2[3], RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetRecipCameraZ(&Vertex2[3], 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetU(&Vertex2[3], 1.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetV(&Vertex2[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); + RwIm2DVertexSetIntRGBA(&Vertex2[3], 255, 255, 255, 255); } void @@ -214,23 +254,24 @@ CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, u if( pFrontBuffer ) OverlayRender(cam, pFrontBuffer, color, type, bluralpha); #else + if(ms_bJustInitialised) + ms_bJustInitialised = false; + else + OverlayRender(cam, pFrontBuffer, color, type, bluralpha); if(BlurOn){ - if(pFrontBuffer){ - if(ms_bJustInitialised) - ms_bJustInitialised = false; - else - OverlayRender(cam, pFrontBuffer, color, type, bluralpha); - } RwRasterPushContext(pFrontBuffer); RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0); RwRasterPopContext(); - }else{ - OverlayRender(cam, nil, color, type, bluralpha); } #endif #endif } +static uint8 DrunkBlurRed = 128; +static uint8 DrunkBlurGreen = 128; +static uint8 DrunkBlurBlue = 128; +static int32 DrunkBlurIncrement = 1; + void CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, int32 bluralpha) { @@ -278,41 +319,104 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, } if(!BlurOn){ - r = Min(r*0.6f, 255.0f); - g = Min(g*0.6f, 255.0f); - b = Min(b*0.6f, 255.0f); - if(type != MOTION_BLUR_SNIPER) - a = Min(a*0.6f, 255.0f); - // game clamps to 255 here, but why? + // gta clamps these to 255 (probably a macro or inlined function) + int ovR = r * 0.6f; + int ovG = g * 0.6f; + int ovB = b * 0.6f; + int ovA = type == MOTION_BLUR_SNIPER ? a : a*0.6f; + RwIm2DVertexSetIntRGBA(&Vertex[0], ovR, ovG, ovB, ovA); + RwIm2DVertexSetIntRGBA(&Vertex[1], ovR, ovG, ovB, ovA); + RwIm2DVertexSetIntRGBA(&Vertex[2], ovR, ovG, ovB, ovA); + RwIm2DVertexSetIntRGBA(&Vertex[3], ovR, ovG, ovB, ovA); + }else{ + RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a); } - RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a); - RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a); - RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a); - RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a); RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST); RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE); - RwRenderStateSet(rwRENDERSTATETEXTURERASTER, BlurOn ? raster : nil); + RwRenderStateSet(rwRENDERSTATETEXTURERASTER, raster); RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE); - RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); - RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); - RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + + if(BlurOn){ + if(type == MOTION_BLUR_SNIPER){ + RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, 80); + RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, 80); + RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, 80); + RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, 80); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + // TODO(MIAMI): pBufVertCount = 0; + }else{ + RwIm2DVertexSetIntRGBA(&Vertex2[0], r*2, g*2, b*2, 30); + RwIm2DVertexSetIntRGBA(&Vertex2[1], r*2, g*2, b*2, 30); + RwIm2DVertexSetIntRGBA(&Vertex2[2], r*2, g*2, b*2, 30); + RwIm2DVertexSetIntRGBA(&Vertex2[3], r*2, g*2, b*2, 30); + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6); - a = bluralpha/2; - if(a < 30) - a = 30; + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE); + + RwIm2DVertexSetIntRGBA(&Vertex2[0], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[0], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[1], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[1], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[2], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[2], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex2[3], r, g, b, a); + RwIm2DVertexSetIntRGBA(&Vertex[3], r, g, b, a); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); + RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex2, 4, Index, 6); + } + } - if(BlurOn && a != 0){ // the second condition should always be true - RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, a); - RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, a); - RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, a); - RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, a); + int DrunkBlurAlpha = 175.0f * Drunkness; + if(DrunkBlurAlpha != 0){ + RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); + RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); + if(BlurOn){ + RwIm2DVertexSetIntRGBA(&Vertex[0], 255, 255, 255, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[1], 255, 255, 255, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[2], 255, 255, 255, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, DrunkBlurAlpha); + }else{ + RwIm2DVertexSetIntRGBA(&Vertex[0], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[1], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[2], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha); + RwIm2DVertexSetIntRGBA(&Vertex[3], DrunkBlurRed, DrunkBlurGreen, DrunkBlurBlue, DrunkBlurAlpha); + if(DrunkBlurIncrement){ + if(DrunkBlurRed < 255) DrunkBlurRed++; + if(DrunkBlurGreen < 255) DrunkBlurGreen++; + if(DrunkBlurBlue < 255) DrunkBlurBlue++; + if(DrunkBlurRed == 255) + DrunkBlurIncrement = 0; + }else{ + if(DrunkBlurRed > 128) DrunkBlurRed--; + if(DrunkBlurGreen > 128) DrunkBlurGreen--; + if(DrunkBlurBlue > 128) DrunkBlurBlue--; + if(DrunkBlurRed == 128) + DrunkBlurIncrement = 1; + } + } RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6); } + // TODO(MIAMI): OverlayRenderFx + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); @@ -321,3 +425,16 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type, RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA); RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA); } + +void +CMBlur::SetDrunkBlur(float drunkness) +{ + Drunkness = clamp(drunkness, 0.0f, 1.0f); +} + +void +CMBlur::ClearDrunkBlur() +{ + Drunkness = 0.0f; + CTimer::SetTimeScale(1.0f); +}
\ No newline at end of file |