forgot the actual file...
This commit is contained in:
parent
dd3f1f88ac
commit
f2d1ceb043
212
src/RwMatFX.cpp
Normal file
212
src/RwMatFX.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
#define WITHD3D
|
||||
#include "common.h"
|
||||
#include "patcher.h"
|
||||
|
||||
struct MatFXNothing { int pad[5]; int effect; };
|
||||
|
||||
struct MatFXBump
|
||||
{
|
||||
RwFrame *bumpFrame;
|
||||
RwTexture *bumpedTex;
|
||||
RwTexture *bumpTex;
|
||||
float negBumpCoefficient;
|
||||
int pad;
|
||||
int effect;
|
||||
};
|
||||
|
||||
struct MatFXEnv
|
||||
{
|
||||
RwFrame *envFrame;
|
||||
RwTexture *envTex;
|
||||
float envCoeff;
|
||||
int envFBalpha;
|
||||
int pad;
|
||||
int effect;
|
||||
};
|
||||
|
||||
struct MatFXDual
|
||||
{
|
||||
RwTexture *dualTex;
|
||||
RwInt32 srcBlend;
|
||||
RwInt32 dstBlend;
|
||||
};
|
||||
|
||||
|
||||
struct MatFX
|
||||
{
|
||||
union {
|
||||
MatFXNothing n;
|
||||
MatFXBump b;
|
||||
MatFXEnv e;
|
||||
MatFXDual d;
|
||||
} fx[2];
|
||||
int effects;
|
||||
};
|
||||
|
||||
int &MatFXMaterialDataOffset = *(int*)0x66188C;
|
||||
int &MatFXAtomicDataOffset = *(int*)0x66189C;
|
||||
|
||||
#ifdef PS2_MATFX
|
||||
|
||||
void
|
||||
_rpMatFXD3D8AtomicMatFXDefaultRender(RxD3D8InstanceData *inst, int flags, RwTexture *texture)
|
||||
{
|
||||
if(flags & (rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2) && texture)
|
||||
RwD3D8SetTexture(texture, 0);
|
||||
else
|
||||
RwD3D8SetTexture(NULL, 0);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(inst->vertexAlpha || inst->material->color.alpha != 0xFF));
|
||||
RwD3D8SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, inst->vertexAlpha != 0);
|
||||
RwD3D8SetPixelShader(0);
|
||||
RwD3D8SetVertexShader(inst->vertexShader);
|
||||
RwD3D8SetStreamSource(0, inst->vertexBuffer, inst->stride);
|
||||
|
||||
if(inst->indexBuffer){
|
||||
RwD3D8SetIndices(inst->indexBuffer, inst->baseIndex);
|
||||
RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices);
|
||||
}else
|
||||
RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices);
|
||||
}
|
||||
|
||||
// map [-1; -1] -> [0; 1], flip V
|
||||
static RwMatrix scalenormal = {
|
||||
{ 0.5f, 0.0f, 0.0f }, 0,
|
||||
{ 0.0f, -0.5f, 0.0f }, 0,
|
||||
{ 0.0f, 0.0f, 1.0f }, 0,
|
||||
{ 0.5f, 0.5f, 0.0f }, 0,
|
||||
|
||||
};
|
||||
|
||||
// flipped U for PS2
|
||||
static RwMatrix scalenormal_flipU = {
|
||||
{ -0.5f, 0.0f, 0.0f }, 0,
|
||||
{ 0.0f, -0.5f, 0.0f }, 0,
|
||||
{ 0.0f, 0.0f, 1.0f }, 0,
|
||||
{ 0.5f, 0.5f, 0.0f }, 0,
|
||||
|
||||
};
|
||||
|
||||
void
|
||||
ApplyEnvMapTextureMatrix(RwTexture *tex, int n, RwFrame *frame)
|
||||
{
|
||||
RwD3D8SetTexture(tex, n);
|
||||
RwD3D8SetTextureStageState(n, D3DRS_ALPHAREF, 2);
|
||||
RwD3D8SetTextureStageState(n, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACENORMAL);
|
||||
if(frame){
|
||||
RwMatrix *envframemat = RwMatrixCreate();
|
||||
RwMatrix *tmpmat = RwMatrixCreate();
|
||||
RwMatrix *envmat = RwMatrixCreate();
|
||||
|
||||
RwMatrixInvert(envframemat, RwFrameGetLTM(frame));
|
||||
// PS2
|
||||
// can this be simplified?
|
||||
*tmpmat = *RwFrameGetLTM(RwCameraGetFrame((RwCamera*)RWSRCGLOBAL(curCamera)));
|
||||
RwV3dNegate(&tmpmat->right, &tmpmat->right);
|
||||
tmpmat->flags = 0;
|
||||
tmpmat->pos.x = 0.0f;
|
||||
tmpmat->pos.y = 0.0f;
|
||||
tmpmat->pos.z = 0.0f;
|
||||
RwMatrixMultiply(envmat, tmpmat, envframemat);
|
||||
*tmpmat = *envmat;
|
||||
// important because envframemat can have a translation that we don't like
|
||||
tmpmat->pos.x = 0.0f;
|
||||
tmpmat->pos.y = 0.0f;
|
||||
tmpmat->pos.z = 0.0f;
|
||||
// for some reason we flip in U as well
|
||||
RwMatrixMultiply(envmat, tmpmat, &scalenormal_flipU);
|
||||
|
||||
RwD3D8SetTransform(D3DTS_TEXTURE0+n, envmat);
|
||||
|
||||
RwMatrixDestroy(envmat);
|
||||
RwMatrixDestroy(tmpmat);
|
||||
RwMatrixDestroy(envframemat);
|
||||
}else
|
||||
RwD3D8SetTransform(D3DTS_TEXTURE0+n, &scalenormal);
|
||||
}
|
||||
|
||||
void
|
||||
_rpMatFXD3D8AtomicMatFXEnvRender_ps2(RxD3D8InstanceData *inst, int flags, int sel, RwTexture *texture, RwTexture *envMap)
|
||||
{
|
||||
MatFX *matfx = *RWPLUGINOFFSET(MatFX*, inst->material, MatFXMaterialDataOffset);
|
||||
MatFXEnv *env = &matfx->fx[sel].e;
|
||||
|
||||
uint8 intens = (uint8)(env->envCoeff*255.0f);
|
||||
|
||||
if(intens == 0 || envMap == nil){
|
||||
if(sel == 0)
|
||||
_rpMatFXD3D8AtomicMatFXDefaultRender(inst, flags, texture);
|
||||
return;
|
||||
}
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)(inst->vertexAlpha || inst->material->color.alpha != 0xFF));
|
||||
if(flags & (rpGEOMETRYTEXTURED|rpGEOMETRYTEXTURED2) && texture)
|
||||
RwD3D8SetTexture(texture, 0);
|
||||
else
|
||||
RwD3D8SetTexture(nil, 0);
|
||||
RwD3D8SetVertexShader(inst->vertexShader);
|
||||
RwD3D8SetStreamSource(0, inst->vertexBuffer, inst->stride);
|
||||
RwD3D8SetIndices(inst->indexBuffer, inst->baseIndex);
|
||||
if(inst->indexBuffer)
|
||||
RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices);
|
||||
else
|
||||
RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices);
|
||||
|
||||
// Effect pass
|
||||
|
||||
ApplyEnvMapTextureMatrix(envMap, 0, env->envFrame);
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
|
||||
RwUInt32 src, dst, lighting, zwrite, fog, fogcol;
|
||||
RwRenderStateGet(rwRENDERSTATESRCBLEND, &src);
|
||||
RwRenderStateGet(rwRENDERSTATEDESTBLEND, &dst);
|
||||
|
||||
// This is of course not using framebuffer alpha,
|
||||
// but if the diffuse texture had no alpha, the result should actually be rather the same
|
||||
if(env->envFBalpha)
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
|
||||
else
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
|
||||
RwD3D8GetRenderState(D3DRS_LIGHTING, &lighting);
|
||||
RwD3D8GetRenderState(D3DRS_ZWRITEENABLE, &zwrite);
|
||||
RwD3D8GetRenderState(D3DRS_FOGENABLE, &fog);
|
||||
RwD3D8SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
|
||||
if(fog){
|
||||
RwD3D8GetRenderState(D3DRS_FOGCOLOR, &fogcol);
|
||||
RwD3D8SetRenderState(D3DRS_FOGCOLOR, 0);
|
||||
}
|
||||
|
||||
D3DCOLOR texfactor = D3DCOLOR_RGBA(intens, intens, intens, intens);
|
||||
RwD3D8SetRenderState(D3DRS_TEXTUREFACTOR, texfactor);
|
||||
RwD3D8SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
|
||||
RwD3D8SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
|
||||
RwD3D8SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TFACTOR);
|
||||
// alpha unused
|
||||
//RwD3D8SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
|
||||
//RwD3D8SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
|
||||
//RwD3D8SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TFACTOR);
|
||||
|
||||
if(inst->indexBuffer)
|
||||
RwD3D8DrawIndexedPrimitive(inst->primType, 0, inst->numVertices, 0, inst->numIndices);
|
||||
else
|
||||
RwD3D8DrawPrimitive(inst->primType, inst->baseIndex, inst->numVertices);
|
||||
|
||||
// Reset states
|
||||
|
||||
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
|
||||
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)src);
|
||||
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)dst);
|
||||
RwD3D8SetRenderState(D3DRS_LIGHTING, lighting);
|
||||
RwD3D8SetRenderState(D3DRS_ZWRITEENABLE, zwrite);
|
||||
if(fog)
|
||||
RwD3D8SetRenderState(D3DRS_FOGCOLOR, fogcol);
|
||||
RwD3D8SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
||||
RwD3D8SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
||||
RwD3D8SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, 0);
|
||||
RwD3D8SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
|
||||
}
|
||||
|
||||
STARTPATCHES
|
||||
InjectHook(0x5CF6C0, _rpMatFXD3D8AtomicMatFXEnvRender_ps2, PATCH_JUMP);
|
||||
ENDPATCHES
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user