mirror of https://github.com/aap/librw.git
implemented GS alpha test emu for gl3
This commit is contained in:
parent
438397f411
commit
a312007893
|
@ -55,9 +55,11 @@ void *createVertexDeclaration(VertexElement *elements);
|
|||
void destroyVertexDeclaration(void *delaration);
|
||||
uint32 getDeclaration(void *declaration, VertexElement *elements);
|
||||
|
||||
void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst);
|
||||
void drawInst_simple(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);
|
||||
// This one switches between the above two depending on render state;
|
||||
void drawInst(d3d9::InstanceDataHeader *header, d3d9::InstanceData *inst);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -128,6 +128,7 @@ struct RwStateCache {
|
|||
uint32 alphaTestEnable;
|
||||
uint32 alphaFunc;
|
||||
bool32 textureAlpha;
|
||||
bool32 blendEnable;
|
||||
uint32 srcblend, destblend;
|
||||
uint32 zwrite;
|
||||
uint32 ztest;
|
||||
|
@ -135,6 +136,11 @@ struct RwStateCache {
|
|||
uint32 fogEnable;
|
||||
float32 fogStart;
|
||||
float32 fogEnd;
|
||||
|
||||
// emulation of PS2 GS
|
||||
bool32 gsalpha;
|
||||
uint32 gsalpharef;
|
||||
|
||||
RwRasterStateCache texstage[MAXNUMSTAGES];
|
||||
};
|
||||
static RwStateCache rwStateCache;
|
||||
|
@ -157,6 +163,21 @@ static uint32 blendMap[] = {
|
|||
GL_SRC_ALPHA_SATURATE,
|
||||
};
|
||||
|
||||
void
|
||||
setAlphaBlend(bool32 enable)
|
||||
{
|
||||
if(rwStateCache.blendEnable != enable){
|
||||
rwStateCache.blendEnable = enable;
|
||||
(enable ? glEnable : glDisable)(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
bool32
|
||||
getAlphaBlend(void)
|
||||
{
|
||||
return rwStateCache.blendEnable;
|
||||
}
|
||||
|
||||
static void
|
||||
setDepthTest(bool32 enable)
|
||||
{
|
||||
|
@ -224,7 +245,7 @@ setVertexAlpha(bool32 enable)
|
|||
{
|
||||
if(rwStateCache.vertexAlpha != enable){
|
||||
if(!rwStateCache.textureAlpha){
|
||||
(enable ? glEnable : glDisable)(GL_BLEND);
|
||||
setAlphaBlend(enable);
|
||||
setAlphaTest(enable);
|
||||
}
|
||||
rwStateCache.vertexAlpha = enable;
|
||||
|
@ -343,7 +364,7 @@ setRasterStageOnly(uint32 stage, Raster *raster)
|
|||
if(alpha != rwStateCache.textureAlpha){
|
||||
rwStateCache.textureAlpha = alpha;
|
||||
if(!rwStateCache.vertexAlpha){
|
||||
(alpha ? glEnable : glDisable)(GL_BLEND);
|
||||
setAlphaBlend(alpha);
|
||||
setAlphaTest(alpha);
|
||||
}
|
||||
}
|
||||
|
@ -392,7 +413,7 @@ setRasterStage(uint32 stage, Raster *raster)
|
|||
if(alpha != rwStateCache.textureAlpha){
|
||||
rwStateCache.textureAlpha = alpha;
|
||||
if(!rwStateCache.vertexAlpha){
|
||||
(alpha ? glEnable : glDisable)(GL_BLEND);
|
||||
setAlphaBlend(alpha);
|
||||
setAlphaTest(alpha);
|
||||
}
|
||||
}
|
||||
|
@ -492,6 +513,11 @@ setRenderState(int32 state, void *pvalue)
|
|||
stateDirty = 1;
|
||||
}
|
||||
break;
|
||||
case GSALPHATEST:
|
||||
rwStateCache.gsalpha = value;
|
||||
break;
|
||||
case GSALPHATESTREF:
|
||||
rwStateCache.gsalpharef = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -551,6 +577,12 @@ getRenderState(int32 state)
|
|||
case ALPHATESTREF:
|
||||
val = (uint32)(uniformState.alphaRef*255.0f);
|
||||
break;
|
||||
case GSALPHATEST:
|
||||
val = rwStateCache.gsalpha;
|
||||
break;
|
||||
case GSALPHATESTREF:
|
||||
val = rwStateCache.gsalpharef;
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
}
|
||||
|
@ -568,13 +600,16 @@ resetRenderState(void)
|
|||
uniformState.fogEnd = 0.0f;
|
||||
uniformState.fogRange = 0.0f;
|
||||
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
rwStateCache.gsalpha = 0;
|
||||
rwStateCache.gsalpharef = 128;
|
||||
stateDirty = 1;
|
||||
|
||||
rwStateCache.vertexAlpha = 0;
|
||||
rwStateCache.textureAlpha = 0;
|
||||
glDisable(GL_BLEND);
|
||||
rwStateCache.alphaTestEnable = 0;
|
||||
|
||||
rwStateCache.blendEnable = 0;
|
||||
glDisable(GL_BLEND);
|
||||
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
||||
|
|
|
@ -85,9 +85,7 @@ matfxDefaultRender(InstanceDataHeader *header, InstanceData *inst)
|
|||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
drawInst(header, inst);
|
||||
}
|
||||
|
||||
static Frame *lastEnvFrame;
|
||||
|
@ -152,9 +150,7 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, MatFX::Env *env)
|
|||
rw::SetRenderState(VERTEXALPHA, 1);
|
||||
rw::SetRenderState(SRCBLEND, BLENDONE);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
drawInst(header, inst);
|
||||
|
||||
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,58 @@
|
|||
namespace rw {
|
||||
namespace gl3 {
|
||||
|
||||
#define MAX_LIGHTS 8
|
||||
#define MAX_LIGHTS
|
||||
|
||||
void
|
||||
drawInst_simple(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
}
|
||||
|
||||
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
|
||||
void
|
||||
drawInst_GSemu(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
uint32 hasAlpha;
|
||||
int alphafunc, alpharef, gsalpharef;
|
||||
int zwrite;
|
||||
hasAlpha = getAlphaBlend();
|
||||
if(hasAlpha){
|
||||
zwrite = rw::GetRenderState(rw::ZWRITEENABLE);
|
||||
alphafunc = rw::GetRenderState(rw::ALPHATESTFUNC);
|
||||
if(zwrite){
|
||||
alpharef = rw::GetRenderState(rw::ALPHATESTREF);
|
||||
gsalpharef = rw::GetRenderState(rw::GSALPHATESTREF);
|
||||
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAGREATEREQUAL);
|
||||
SetRenderState(rw::ALPHATESTREF, gsalpharef);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHALESS);
|
||||
SetRenderState(rw::ZWRITEENABLE, 0);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ZWRITEENABLE, 1);
|
||||
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
|
||||
SetRenderState(rw::ALPHATESTREF, alpharef);
|
||||
}else{
|
||||
SetRenderState(rw::ALPHATESTFUNC, rw::ALPHAALWAYS);
|
||||
drawInst_simple(header, inst);
|
||||
SetRenderState(rw::ALPHATESTFUNC, alphafunc);
|
||||
}
|
||||
}else
|
||||
drawInst_simple(header, inst);
|
||||
}
|
||||
|
||||
void
|
||||
drawInst(InstanceDataHeader *header, InstanceData *inst)
|
||||
{
|
||||
if(rw::GetRenderState(rw::GSALPHATEST))
|
||||
drawInst_GSemu(header, inst);
|
||||
else
|
||||
drawInst_simple(header, inst);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setAttribPointers(AttribDesc *attribDescs, int32 numAttribs)
|
||||
|
@ -102,9 +153,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
drawInst(header, inst);
|
||||
inst++;
|
||||
}
|
||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||
|
|
|
@ -309,9 +309,7 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
|||
|
||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||
|
||||
flushCache();
|
||||
glDrawElements(header->primType, inst->numIndex,
|
||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
||||
drawInst(header, inst);
|
||||
inst++;
|
||||
}
|
||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||
|
|
|
@ -171,10 +171,11 @@ int32 setLights(WorldLights *lightData);
|
|||
// per Mesh
|
||||
void setTexture(int32 n, Texture *tex);
|
||||
|
||||
void setAlphaBlend(bool32 enable);
|
||||
bool32 getAlphaBlend(void);
|
||||
|
||||
uint32 bindTexture(uint32 texid);
|
||||
|
||||
|
||||
void flushCache(void);
|
||||
|
||||
#endif
|
||||
|
@ -194,6 +195,13 @@ void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
|||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||
int32 lightingCB(Atomic *atomic);
|
||||
|
||||
void drawInst_simple(InstanceDataHeader *header, InstanceData *inst);
|
||||
// Emulate PS2 GS alpha test FB_ONLY case: failed alpha writes to frame- but not to depth buffer
|
||||
void drawInst_GSemu(InstanceDataHeader *header, InstanceData *inst);
|
||||
// This one switches between the above two depending on render state;
|
||||
void drawInst(InstanceDataHeader *header, InstanceData *inst);
|
||||
|
||||
|
||||
void *destroyNativeData(void *object, int32, int32);
|
||||
|
||||
ObjPipeline *makeDefaultPipeline(void);
|
||||
|
|
Loading…
Reference in New Issue