diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index 79f0206..5e23ae0 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -20,6 +20,43 @@ using namespace d3d; void defaultRenderCB(Atomic*, InstanceDataHeader*) {} #else +void +drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst) +{ + d3d::flushCache(); + d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, + 0, inst->numVertices, + inst->startIndex, inst->numPrimitives); +} + +// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer +void +drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst) +{ + uint32 hasAlpha; + int alphafunc; + int zwrite; + d3d::getRenderState(D3DRS_ALPHABLENDENABLE, &hasAlpha); + if(hasAlpha){ + zwrite = rw::GetRenderState(rw::ZWRITEENABLE); + alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC); + if(zwrite){ + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL); + drawInst(header, inst); + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS); + SetRenderState(rw::ZWRITEENABLE, 0); + drawInst(header, inst); + SetRenderState(rw::ZWRITEENABLE, 1); + SetRenderState(rw::ALPHATESTFUNC, alphafunc); + }else{ + SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS); + drawInst(header, inst); + SetRenderState(rw::ALPHATESTFUNC, alphafunc); + } + }else + drawInst(header, inst); +} + void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) { @@ -29,8 +66,6 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) int lighting = !!(geo->flags & rw::Geometry::LIGHT); if(lighting) d3d::lightingCB(); -// else -// return; d3d::setRenderState(D3DRS_LIGHTING, lighting); @@ -76,10 +111,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, inst->vertexAlpha ? D3DMCS_COLOR1 : D3DMCS_MATERIAL); - d3d::flushCache(); - d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, - 0, inst->numVertices, - inst->startIndex, inst->numPrimitives); + drawInst(header, inst); inst++; } d3d::setTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index 3b6718c..d8d12e2 100755 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -418,6 +418,40 @@ setMaterial(SurfaceProperties surfProps, rw::RGBA color) setD3dMaterial(&mat9); } +// Shaders + +void +setVertexShader(void *vs) +{ + d3ddevice->SetVertexShader((IDirect3DVertexShader9*)vs); +} + +void +setPixelShader(void *ps) +{ + d3ddevice->SetPixelShader((IDirect3DPixelShader9*)ps); +} + +void* +createVertexShader(void *csosrc) +{ + void *shdr; + if(d3ddevice->CreateVertexShader((DWORD*)csosrc, (IDirect3DVertexShader9**)&shdr) == D3D_OK) + return shdr; + return nil; +} + +void* +createPixelShader(void *csosrc) +{ + void *shdr; + if(d3ddevice->CreatePixelShader((DWORD*)csosrc, (IDirect3DPixelShader9**)&shdr) == D3D_OK) + return shdr; + return nil; +} + +// Camera + static void beginUpdate(Camera *cam) { diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index dc8abb1..37050a0 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -153,5 +153,10 @@ void flushCache(void); void setTexture(uint32 stage, Texture *tex); void setMaterial(SurfaceProperties surfProps, rw::RGBA color); +void setVertexShader(void *vs); +void setPixelShader(void *ps); +void *createVertexShader(void *csosrc); +void *createPixelShader(void *csosrc); + } } diff --git a/src/d3d/rwd3d9.h b/src/d3d/rwd3d9.h index 8176d64..b06af7a 100644 --- a/src/d3d/rwd3d9.h +++ b/src/d3d/rwd3d9.h @@ -54,6 +54,10 @@ struct InstanceDataHeader : rw::InstanceDataHeader void *createVertexDeclaration(VertexElement *elements); uint32 getDeclaration(void *declaration, VertexElement *elements); +void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst); +// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer +void drawInst_GSemu(d3d9::InstanceDataHeader *header, InstanceData *inst); + void *destroyNativeData(void *object, int32, int32); Stream *readNativeData(Stream *stream, int32 len, void *object, int32, int32); Stream *writeNativeData(Stream *stream, int32 len, void *object, int32, int32);