From 581cb5edfa39a263bcbcdf3e37c608a5c7758849 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Wed, 29 Jul 2020 14:56:06 +0300 Subject: The real pickup reflection fix --- src/rw/RwHelper.cpp | 34 ++++++++++++++++++++++++++++++++++ src/rw/RwHelper.h | 10 +++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src/rw') diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 3503e27d..bf70c8dc 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -611,3 +611,37 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer) WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x598B10); } WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x598B30); } #endif + +#if defined(FIX_BUGS) && defined(GTA_PC) +RwUInt32 saved_alphafunc, saved_alpharef; + +void +SetAlphaTest(RwUInt32 alpharef) +{ +#ifdef LIBRW + saved_alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC); + saved_alpharef = rw::GetRenderState(rw::ALPHATESTREF); + + rw::SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL); + rw::SetRenderState(rw::ALPHATESTREF, 0); +#else + RwD3D8GetRenderState(D3DRS_ALPHAFUNC, &saved_alphafunc); + RwD3D8GetRenderState(D3DRS_ALPHAREF, &saved_alpharef); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + RwD3D8SetRenderState(D3DRS_ALPHAREF, alpharef); +#endif +} + +void +RestoreAlphaTest() +{ +#ifdef LIBRW + rw::SetRenderState(rw::ALPHATESTFUNC, saved_alphafunc); + rw::SetRenderState(rw::ALPHATESTREF, saved_alpharef); +#else + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, saved_alphafunc); + RwD3D8SetRenderState(D3DRS_ALPHAREF, saved_alpharef); +#endif +} +#endif diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h index a751ee39..eceaee07 100644 --- a/src/rw/RwHelper.h +++ b/src/rw/RwHelper.h @@ -52,4 +52,12 @@ RwCamera *CameraCreate(RwInt32 width, void _TexturePoolsInitialise(); -void _TexturePoolsShutdown(); \ No newline at end of file +void _TexturePoolsShutdown(); + +#if defined(FIX_BUGS) && defined (GTA_PC) +void SetAlphaTest(RwUInt32 alpharef); +void RestoreAlphaTest(); +#else +#define SetAlphaTest(a) (0) +#define RestoreAlphaTest() (0) +#endif \ No newline at end of file -- cgit v1.2.3 From 6b92e9e12b376b9edf04070ecf83179e9a0f8fda Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Wed, 29 Jul 2020 15:24:42 +0300 Subject: Dual pass rendering for RW 3.3 --- src/rw/RwHelper.cpp | 8 ++++++-- src/rw/RwMatFX.cpp | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/rw') diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index bf70c8dc..08a8fca4 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -11,7 +11,11 @@ RtCharset *debugCharset; #endif -bool gPS2alphaTest = 1; +#ifdef DUAL_PASS_RENDERING +bool gPS2alphaTest = true; +#else +bool gPS2alphaTest = false; +#endif #ifndef FINAL static bool charsetOpen; @@ -644,4 +648,4 @@ RestoreAlphaTest() RwD3D8SetRenderState(D3DRS_ALPHAREF, saved_alpharef); #endif } -#endif +#endif \ No newline at end of file diff --git a/src/rw/RwMatFX.cpp b/src/rw/RwMatFX.cpp index a128ff1a..c8384b0f 100644 --- a/src/rw/RwMatFX.cpp +++ b/src/rw/RwMatFX.cpp @@ -2,7 +2,6 @@ #define WITHD3D #include "common.h" -#include "rwcore.h" #include "rpmatfx.h" struct MatFXNothing { int pad[5]; int effect; }; @@ -305,7 +304,8 @@ ReplaceMatFxCallback() { RxD3D8AllInOneSetRenderCallBack( RxPipelineFindNodeByName(RpMatFXGetD3D8Pipeline(rpMATFXD3D8ATOMICPIPELINE), RxNodeDefinitionGetD3D8AtomicAllInOne()->name, nil, nil), - _rwD3D8AtomicMatFXRenderCallback); + _rwD3D8AtomicMatFXRenderCallback); + } #endif // PS2_MATFX -- cgit v1.2.3 From 4a4feb948d0f6e67f3ff5c71a7aa23176cabb0e2 Mon Sep 17 00:00:00 2001 From: Sergeanur Date: Wed, 29 Jul 2020 15:25:57 +0300 Subject: Add forgotten file --- src/rw/RwDualPass.cpp | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 src/rw/RwDualPass.cpp (limited to 'src/rw') diff --git a/src/rw/RwDualPass.cpp b/src/rw/RwDualPass.cpp new file mode 100644 index 00000000..c8ebb8ad --- /dev/null +++ b/src/rw/RwDualPass.cpp @@ -0,0 +1,247 @@ +#ifndef LIBRW + +#define WITHD3D +#include "common.h" +#ifdef DUAL_PASS_RENDERING +#include "rwcore.h" + +extern "C" { +RwBool _rwD3D8RenderStateIsVertexAlphaEnable(void); +RwBool _rwD3D8RenderStateVertexAlphaEnable(RwBool enable); +RwRaster *_rwD3D8RWGetRasterStage(RwUInt32 stage); +} + +extern bool gPS2alphaTest; + +void +_rxD3D8DualPassRenderCallback(RwResEntry *repEntry, void *object, RwUInt8 type, RwUInt32 flags) +{ + RxD3D8ResEntryHeader *resEntryHeader; + RxD3D8InstanceData *instancedData; + RwInt32 numMeshes; + RwBool lighting; + RwBool vertexAlphaBlend; + RwBool forceBlack; + RwUInt32 ditherEnable; + RwUInt32 shadeMode; + void *lastVertexBuffer; + + /* Get lighting state */ + RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting); + + forceBlack = FALSE; + + if (lighting) { + if (flags & rxGEOMETRY_PRELIT) { + /* Emmisive color from the vertex colors */ + RwD3D8SetRenderState(D3DRS_COLORVERTEX, TRUE); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + } else { + /* Emmisive color from material, set to black in the submit node */ + RwD3D8SetRenderState(D3DRS_COLORVERTEX, FALSE); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + } + } else { + if ((flags & rxGEOMETRY_PRELIT) == 0) { + forceBlack = TRUE; + + RwD3D8GetRenderState(D3DRS_DITHERENABLE, &ditherEnable); + RwD3D8GetRenderState(D3DRS_SHADEMODE, &shadeMode); + + RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, 0xff000000); + RwD3D8SetRenderState(D3DRS_DITHERENABLE, FALSE); + RwD3D8SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + } + + /* Enable clipping */ + if (type == rpATOMIC) { + RpAtomic *atomic; + RwCamera *cam; + + atomic = (RpAtomic *)object; + + cam = RwCameraGetCurrentCamera(); + // RWASSERT(cam); + + if (RwD3D8CameraIsSphereFullyInsideFrustum(cam, RpAtomicGetWorldBoundingSphere(atomic))) { + RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); + } else { + RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); + } + } else { + RpWorldSector *worldSector; + RwCamera *cam; + + worldSector = (RpWorldSector *)object; + + cam = RwCameraGetCurrentCamera(); + // RWASSERT(cam); + + if (RwD3D8CameraIsBBoxFullyInsideFrustum(cam, RpWorldSectorGetTightBBox(worldSector))) { + RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); + } else { + RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); + } + } + + /* Set texture to NULL if hasn't any texture flags */ + if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2)) == 0) { + RwD3D8SetTexture(NULL, 0); + + if (forceBlack) { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + + RwD3D8SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + } + + /* Get vertex alpha Blend state */ + vertexAlphaBlend = _rwD3D8RenderStateIsVertexAlphaEnable(); + + /* Set Last vertex buffer to force the call */ + lastVertexBuffer = (void *)0xffffffff; + + /* Get the instanced data */ + resEntryHeader = (RxD3D8ResEntryHeader *)(repEntry + 1); + instancedData = (RxD3D8InstanceData *)(resEntryHeader + 1); + + /* + * Data shared between meshes + */ + + /* + * Set the Default Pixel shader + */ + RwD3D8SetPixelShader(0); + + /* + * Vertex shader + */ + RwD3D8SetVertexShader(instancedData->vertexShader); + + /* Get the number of meshes */ + numMeshes = resEntryHeader->numMeshes; + while (numMeshes--) { + // RWASSERT(instancedData->material != NULL); + + if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2))) { + RwD3D8SetTexture(instancedData->material->texture, 0); + + if (forceBlack) { + /* Only change the colorop, we need to use the texture alpha channel */ + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + } + } + + if (instancedData->vertexAlpha || (0xFF != instancedData->material->color.alpha)) { + if (!vertexAlphaBlend) { + vertexAlphaBlend = TRUE; + + _rwD3D8RenderStateVertexAlphaEnable(TRUE); + } + } else { + if (vertexAlphaBlend) { + vertexAlphaBlend = FALSE; + + _rwD3D8RenderStateVertexAlphaEnable(FALSE); + } + } + + if (lighting) { + if (instancedData->vertexAlpha) { + RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); + } else { + RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); + } + + RwD3D8SetSurfaceProperties(&instancedData->material->color, &instancedData->material->surfaceProps, (flags & rxGEOMETRY_MODULATE)); + } + + /* + * Render + */ + + /* Set the stream source */ + if (lastVertexBuffer != instancedData->vertexBuffer) { + RwD3D8SetStreamSource(0, instancedData->vertexBuffer, instancedData->stride); + + lastVertexBuffer = instancedData->vertexBuffer; + } + if (!gPS2alphaTest) { + /* Set the Index buffer */ + if (instancedData->indexBuffer != NULL) { + RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); + + /* Draw the indexed primitive */ + RwD3D8DrawIndexedPrimitive((D3DPRIMITIVETYPE)instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + } else { + RwD3D8DrawPrimitive((D3DPRIMITIVETYPE)instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + } + } else { + RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); + + int hasAlpha, alphafunc, alpharef, zwrite; + RwD3D8GetRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); + RwD3D8GetRenderState(D3DRS_ZWRITEENABLE, &zwrite); + if (hasAlpha && zwrite) { + RwD3D8GetRenderState(D3DRS_ALPHAFUNC, &alphafunc); + RwD3D8GetRenderState(D3DRS_ALPHAREF, &alpharef); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + RwD3D8SetRenderState(D3DRS_ALPHAREF, 128); + + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); + + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, alphafunc); + RwD3D8SetRenderState(D3DRS_ALPHAREF, alpharef); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE); + } else { + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + } + } + + /* Move onto the next instancedData */ + instancedData++; + } + + if (forceBlack) { + RwD3D8SetRenderState(D3DRS_DITHERENABLE, ditherEnable); + RwD3D8SetRenderState(D3DRS_SHADEMODE, shadeMode); + + if (_rwD3D8RWGetRasterStage(0)) { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } else { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } + } +} + +void +ReplaceAtomicPipeCallback() +{ + RxD3D8AllInOneSetRenderCallBack(RxPipelineFindNodeByName(RXPIPELINEGLOBAL(platformAtomicPipeline), RxNodeDefinitionGetD3D8AtomicAllInOne()->name, nil, nil), + _rxD3D8DualPassRenderCallback); +} + +#endif // DUAL_PASS_RENDERING + +#endif // !LIBRW \ No newline at end of file -- cgit v1.2.3 From e13d80a4ebfdaa89de3ad2eb6dc9ec6fbc1d3132 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 29 Jul 2020 14:31:34 +0200 Subject: rename shit --- src/rw/RwDualPass.cpp | 247 ---------------------------------------------- src/rw/RwHelper.cpp | 2 +- src/rw/RwPS2AlphaTest.cpp | 247 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 248 insertions(+), 248 deletions(-) delete mode 100644 src/rw/RwDualPass.cpp create mode 100644 src/rw/RwPS2AlphaTest.cpp (limited to 'src/rw') diff --git a/src/rw/RwDualPass.cpp b/src/rw/RwDualPass.cpp deleted file mode 100644 index c8ebb8ad..00000000 --- a/src/rw/RwDualPass.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#ifndef LIBRW - -#define WITHD3D -#include "common.h" -#ifdef DUAL_PASS_RENDERING -#include "rwcore.h" - -extern "C" { -RwBool _rwD3D8RenderStateIsVertexAlphaEnable(void); -RwBool _rwD3D8RenderStateVertexAlphaEnable(RwBool enable); -RwRaster *_rwD3D8RWGetRasterStage(RwUInt32 stage); -} - -extern bool gPS2alphaTest; - -void -_rxD3D8DualPassRenderCallback(RwResEntry *repEntry, void *object, RwUInt8 type, RwUInt32 flags) -{ - RxD3D8ResEntryHeader *resEntryHeader; - RxD3D8InstanceData *instancedData; - RwInt32 numMeshes; - RwBool lighting; - RwBool vertexAlphaBlend; - RwBool forceBlack; - RwUInt32 ditherEnable; - RwUInt32 shadeMode; - void *lastVertexBuffer; - - /* Get lighting state */ - RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting); - - forceBlack = FALSE; - - if (lighting) { - if (flags & rxGEOMETRY_PRELIT) { - /* Emmisive color from the vertex colors */ - RwD3D8SetRenderState(D3DRS_COLORVERTEX, TRUE); - RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); - } else { - /* Emmisive color from material, set to black in the submit node */ - RwD3D8SetRenderState(D3DRS_COLORVERTEX, FALSE); - RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); - } - } else { - if ((flags & rxGEOMETRY_PRELIT) == 0) { - forceBlack = TRUE; - - RwD3D8GetRenderState(D3DRS_DITHERENABLE, &ditherEnable); - RwD3D8GetRenderState(D3DRS_SHADEMODE, &shadeMode); - - RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, 0xff000000); - RwD3D8SetRenderState(D3DRS_DITHERENABLE, FALSE); - RwD3D8SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); - } - } - - /* Enable clipping */ - if (type == rpATOMIC) { - RpAtomic *atomic; - RwCamera *cam; - - atomic = (RpAtomic *)object; - - cam = RwCameraGetCurrentCamera(); - // RWASSERT(cam); - - if (RwD3D8CameraIsSphereFullyInsideFrustum(cam, RpAtomicGetWorldBoundingSphere(atomic))) { - RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); - } else { - RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); - } - } else { - RpWorldSector *worldSector; - RwCamera *cam; - - worldSector = (RpWorldSector *)object; - - cam = RwCameraGetCurrentCamera(); - // RWASSERT(cam); - - if (RwD3D8CameraIsBBoxFullyInsideFrustum(cam, RpWorldSectorGetTightBBox(worldSector))) { - RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); - } else { - RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); - } - } - - /* Set texture to NULL if hasn't any texture flags */ - if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2)) == 0) { - RwD3D8SetTexture(NULL, 0); - - if (forceBlack) { - RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - - RwD3D8SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - } - - /* Get vertex alpha Blend state */ - vertexAlphaBlend = _rwD3D8RenderStateIsVertexAlphaEnable(); - - /* Set Last vertex buffer to force the call */ - lastVertexBuffer = (void *)0xffffffff; - - /* Get the instanced data */ - resEntryHeader = (RxD3D8ResEntryHeader *)(repEntry + 1); - instancedData = (RxD3D8InstanceData *)(resEntryHeader + 1); - - /* - * Data shared between meshes - */ - - /* - * Set the Default Pixel shader - */ - RwD3D8SetPixelShader(0); - - /* - * Vertex shader - */ - RwD3D8SetVertexShader(instancedData->vertexShader); - - /* Get the number of meshes */ - numMeshes = resEntryHeader->numMeshes; - while (numMeshes--) { - // RWASSERT(instancedData->material != NULL); - - if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2))) { - RwD3D8SetTexture(instancedData->material->texture, 0); - - if (forceBlack) { - /* Only change the colorop, we need to use the texture alpha channel */ - RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); - } - } - - if (instancedData->vertexAlpha || (0xFF != instancedData->material->color.alpha)) { - if (!vertexAlphaBlend) { - vertexAlphaBlend = TRUE; - - _rwD3D8RenderStateVertexAlphaEnable(TRUE); - } - } else { - if (vertexAlphaBlend) { - vertexAlphaBlend = FALSE; - - _rwD3D8RenderStateVertexAlphaEnable(FALSE); - } - } - - if (lighting) { - if (instancedData->vertexAlpha) { - RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); - } else { - RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); - } - - RwD3D8SetSurfaceProperties(&instancedData->material->color, &instancedData->material->surfaceProps, (flags & rxGEOMETRY_MODULATE)); - } - - /* - * Render - */ - - /* Set the stream source */ - if (lastVertexBuffer != instancedData->vertexBuffer) { - RwD3D8SetStreamSource(0, instancedData->vertexBuffer, instancedData->stride); - - lastVertexBuffer = instancedData->vertexBuffer; - } - if (!gPS2alphaTest) { - /* Set the Index buffer */ - if (instancedData->indexBuffer != NULL) { - RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); - - /* Draw the indexed primitive */ - RwD3D8DrawIndexedPrimitive((D3DPRIMITIVETYPE)instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); - } else { - RwD3D8DrawPrimitive((D3DPRIMITIVETYPE)instancedData->primType, instancedData->baseIndex, instancedData->numVertices); - } - } else { - RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); - - int hasAlpha, alphafunc, alpharef, zwrite; - RwD3D8GetRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); - RwD3D8GetRenderState(D3DRS_ZWRITEENABLE, &zwrite); - if (hasAlpha && zwrite) { - RwD3D8GetRenderState(D3DRS_ALPHAFUNC, &alphafunc); - RwD3D8GetRenderState(D3DRS_ALPHAREF, &alpharef); - - RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - RwD3D8SetRenderState(D3DRS_ALPHAREF, 128); - - if (instancedData->indexBuffer) - RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); - else - RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); - - RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); - - if (instancedData->indexBuffer) - RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); - else - RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); - - RwD3D8SetRenderState(D3DRS_ALPHAFUNC, alphafunc); - RwD3D8SetRenderState(D3DRS_ALPHAREF, alpharef); - RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE); - } else { - if (instancedData->indexBuffer) - RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); - else - RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); - } - } - - /* Move onto the next instancedData */ - instancedData++; - } - - if (forceBlack) { - RwD3D8SetRenderState(D3DRS_DITHERENABLE, ditherEnable); - RwD3D8SetRenderState(D3DRS_SHADEMODE, shadeMode); - - if (_rwD3D8RWGetRasterStage(0)) { - RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - } else { - RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - } - } -} - -void -ReplaceAtomicPipeCallback() -{ - RxD3D8AllInOneSetRenderCallBack(RxPipelineFindNodeByName(RXPIPELINEGLOBAL(platformAtomicPipeline), RxNodeDefinitionGetD3D8AtomicAllInOne()->name, nil, nil), - _rxD3D8DualPassRenderCallback); -} - -#endif // DUAL_PASS_RENDERING - -#endif // !LIBRW \ No newline at end of file diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp index 08a8fca4..f568532a 100644 --- a/src/rw/RwHelper.cpp +++ b/src/rw/RwHelper.cpp @@ -11,7 +11,7 @@ RtCharset *debugCharset; #endif -#ifdef DUAL_PASS_RENDERING +#ifdef PS2_ALPHA_TEST bool gPS2alphaTest = true; #else bool gPS2alphaTest = false; diff --git a/src/rw/RwPS2AlphaTest.cpp b/src/rw/RwPS2AlphaTest.cpp new file mode 100644 index 00000000..c0d68355 --- /dev/null +++ b/src/rw/RwPS2AlphaTest.cpp @@ -0,0 +1,247 @@ +#ifndef LIBRW + +#define WITHD3D +#include "common.h" +#ifdef PS2_ALPHA_TEST +#include "rwcore.h" + +extern "C" { +RwBool _rwD3D8RenderStateIsVertexAlphaEnable(void); +RwBool _rwD3D8RenderStateVertexAlphaEnable(RwBool enable); +RwRaster *_rwD3D8RWGetRasterStage(RwUInt32 stage); +} + +extern bool gPS2alphaTest; + +void +_rxD3D8DualPassRenderCallback(RwResEntry *repEntry, void *object, RwUInt8 type, RwUInt32 flags) +{ + RxD3D8ResEntryHeader *resEntryHeader; + RxD3D8InstanceData *instancedData; + RwInt32 numMeshes; + RwBool lighting; + RwBool vertexAlphaBlend; + RwBool forceBlack; + RwUInt32 ditherEnable; + RwUInt32 shadeMode; + void *lastVertexBuffer; + + /* Get lighting state */ + RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting); + + forceBlack = FALSE; + + if (lighting) { + if (flags & rxGEOMETRY_PRELIT) { + /* Emmisive color from the vertex colors */ + RwD3D8SetRenderState(D3DRS_COLORVERTEX, TRUE); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); + } else { + /* Emmisive color from material, set to black in the submit node */ + RwD3D8SetRenderState(D3DRS_COLORVERTEX, FALSE); + RwD3D8SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); + } + } else { + if ((flags & rxGEOMETRY_PRELIT) == 0) { + forceBlack = TRUE; + + RwD3D8GetRenderState(D3DRS_DITHERENABLE, &ditherEnable); + RwD3D8GetRenderState(D3DRS_SHADEMODE, &shadeMode); + + RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, 0xff000000); + RwD3D8SetRenderState(D3DRS_DITHERENABLE, FALSE); + RwD3D8SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); + } + } + + /* Enable clipping */ + if (type == rpATOMIC) { + RpAtomic *atomic; + RwCamera *cam; + + atomic = (RpAtomic *)object; + + cam = RwCameraGetCurrentCamera(); + // RWASSERT(cam); + + if (RwD3D8CameraIsSphereFullyInsideFrustum(cam, RpAtomicGetWorldBoundingSphere(atomic))) { + RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); + } else { + RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); + } + } else { + RpWorldSector *worldSector; + RwCamera *cam; + + worldSector = (RpWorldSector *)object; + + cam = RwCameraGetCurrentCamera(); + // RWASSERT(cam); + + if (RwD3D8CameraIsBBoxFullyInsideFrustum(cam, RpWorldSectorGetTightBBox(worldSector))) { + RwD3D8SetRenderState(D3DRS_CLIPPING, FALSE); + } else { + RwD3D8SetRenderState(D3DRS_CLIPPING, TRUE); + } + } + + /* Set texture to NULL if hasn't any texture flags */ + if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2)) == 0) { + RwD3D8SetTexture(NULL, 0); + + if (forceBlack) { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + + RwD3D8SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); + } + } + + /* Get vertex alpha Blend state */ + vertexAlphaBlend = _rwD3D8RenderStateIsVertexAlphaEnable(); + + /* Set Last vertex buffer to force the call */ + lastVertexBuffer = (void *)0xffffffff; + + /* Get the instanced data */ + resEntryHeader = (RxD3D8ResEntryHeader *)(repEntry + 1); + instancedData = (RxD3D8InstanceData *)(resEntryHeader + 1); + + /* + * Data shared between meshes + */ + + /* + * Set the Default Pixel shader + */ + RwD3D8SetPixelShader(0); + + /* + * Vertex shader + */ + RwD3D8SetVertexShader(instancedData->vertexShader); + + /* Get the number of meshes */ + numMeshes = resEntryHeader->numMeshes; + while (numMeshes--) { + // RWASSERT(instancedData->material != NULL); + + if ((flags & (rxGEOMETRY_TEXTURED | rpGEOMETRYTEXTURED2))) { + RwD3D8SetTexture(instancedData->material->texture, 0); + + if (forceBlack) { + /* Only change the colorop, we need to use the texture alpha channel */ + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); + } + } + + if (instancedData->vertexAlpha || (0xFF != instancedData->material->color.alpha)) { + if (!vertexAlphaBlend) { + vertexAlphaBlend = TRUE; + + _rwD3D8RenderStateVertexAlphaEnable(TRUE); + } + } else { + if (vertexAlphaBlend) { + vertexAlphaBlend = FALSE; + + _rwD3D8RenderStateVertexAlphaEnable(FALSE); + } + } + + if (lighting) { + if (instancedData->vertexAlpha) { + RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); + } else { + RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); + } + + RwD3D8SetSurfaceProperties(&instancedData->material->color, &instancedData->material->surfaceProps, (flags & rxGEOMETRY_MODULATE)); + } + + /* + * Render + */ + + /* Set the stream source */ + if (lastVertexBuffer != instancedData->vertexBuffer) { + RwD3D8SetStreamSource(0, instancedData->vertexBuffer, instancedData->stride); + + lastVertexBuffer = instancedData->vertexBuffer; + } + if (!gPS2alphaTest) { + /* Set the Index buffer */ + if (instancedData->indexBuffer != NULL) { + RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); + + /* Draw the indexed primitive */ + RwD3D8DrawIndexedPrimitive((D3DPRIMITIVETYPE)instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + } else { + RwD3D8DrawPrimitive((D3DPRIMITIVETYPE)instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + } + } else { + RwD3D8SetIndices(instancedData->indexBuffer, instancedData->baseIndex); + + int hasAlpha, alphafunc, alpharef, zwrite; + RwD3D8GetRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); + RwD3D8GetRenderState(D3DRS_ZWRITEENABLE, &zwrite); + if (hasAlpha && zwrite) { + RwD3D8GetRenderState(D3DRS_ALPHAFUNC, &alphafunc); + RwD3D8GetRenderState(D3DRS_ALPHAREF, &alpharef); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); + RwD3D8SetRenderState(D3DRS_ALPHAREF, 128); + + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE); + + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + + RwD3D8SetRenderState(D3DRS_ALPHAFUNC, alphafunc); + RwD3D8SetRenderState(D3DRS_ALPHAREF, alpharef); + RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE); + } else { + if (instancedData->indexBuffer) + RwD3D8DrawIndexedPrimitive(instancedData->primType, 0, instancedData->numVertices, 0, instancedData->numIndices); + else + RwD3D8DrawPrimitive(instancedData->primType, instancedData->baseIndex, instancedData->numVertices); + } + } + + /* Move onto the next instancedData */ + instancedData++; + } + + if (forceBlack) { + RwD3D8SetRenderState(D3DRS_DITHERENABLE, ditherEnable); + RwD3D8SetRenderState(D3DRS_SHADEMODE, shadeMode); + + if (_rwD3D8RWGetRasterStage(0)) { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } else { + RwD3D8SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + RwD3D8SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + } + } +} + +void +ReplaceAtomicPipeCallback() +{ + RxD3D8AllInOneSetRenderCallBack(RxPipelineFindNodeByName(RXPIPELINEGLOBAL(platformAtomicPipeline), RxNodeDefinitionGetD3D8AtomicAllInOne()->name, nil, nil), + _rxD3D8DualPassRenderCallback); +} + +#endif // PS2_ALPHA_TEST + +#endif // !LIBRW \ No newline at end of file -- cgit v1.2.3