diff options
Diffstat (limited to '')
-rw-r--r-- | src/render/MBlur.cpp | 149 |
1 files changed, 116 insertions, 33 deletions
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp index ec811e56..568a0bc1 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" // Originally taken from RW example 'mblur' @@ -17,8 +18,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 @@ -193,6 +196,43 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect) RwIm2DVertexSetV(&Vertex[3], 0.0f, 1.0f/RwCameraGetNearClipPlane(cam)); RwIm2DVertexSetIntRGBA(&Vertex[3], 255, 255, 255, 255); + + RwIm2DVertexSetScreenX(&Vertex2[0], zero); + RwIm2DVertexSetScreenY(&Vertex2[0], zero); + 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], zero); + RwIm2DVertexSetScreenY(&Vertex2[1], ymax); + 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); + RwIm2DVertexSetScreenY(&Vertex2[2], ymax); + 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); + RwIm2DVertexSetScreenY(&Vertex2[3], zero); + 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 @@ -203,18 +243,14 @@ 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 } @@ -266,41 +302,75 @@ 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); - - a = bluralpha/2; - if(a < 30) - a = 30; - - 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); - 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); + + 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); + } } + // TODO(MIAMI): drunkness + + // TODO(MIAMI): OverlayRenderFx + RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE); RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE); RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE); @@ -309,3 +379,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 |