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);
|
void destroyVertexDeclaration(void *delaration);
|
||||||
uint32 getDeclaration(void *declaration, VertexElement *elements);
|
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
|
// 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 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 alphaTestEnable;
|
||||||
uint32 alphaFunc;
|
uint32 alphaFunc;
|
||||||
bool32 textureAlpha;
|
bool32 textureAlpha;
|
||||||
|
bool32 blendEnable;
|
||||||
uint32 srcblend, destblend;
|
uint32 srcblend, destblend;
|
||||||
uint32 zwrite;
|
uint32 zwrite;
|
||||||
uint32 ztest;
|
uint32 ztest;
|
||||||
|
@ -135,6 +136,11 @@ struct RwStateCache {
|
||||||
uint32 fogEnable;
|
uint32 fogEnable;
|
||||||
float32 fogStart;
|
float32 fogStart;
|
||||||
float32 fogEnd;
|
float32 fogEnd;
|
||||||
|
|
||||||
|
// emulation of PS2 GS
|
||||||
|
bool32 gsalpha;
|
||||||
|
uint32 gsalpharef;
|
||||||
|
|
||||||
RwRasterStateCache texstage[MAXNUMSTAGES];
|
RwRasterStateCache texstage[MAXNUMSTAGES];
|
||||||
};
|
};
|
||||||
static RwStateCache rwStateCache;
|
static RwStateCache rwStateCache;
|
||||||
|
@ -157,6 +163,21 @@ static uint32 blendMap[] = {
|
||||||
GL_SRC_ALPHA_SATURATE,
|
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
|
static void
|
||||||
setDepthTest(bool32 enable)
|
setDepthTest(bool32 enable)
|
||||||
{
|
{
|
||||||
|
@ -224,7 +245,7 @@ setVertexAlpha(bool32 enable)
|
||||||
{
|
{
|
||||||
if(rwStateCache.vertexAlpha != enable){
|
if(rwStateCache.vertexAlpha != enable){
|
||||||
if(!rwStateCache.textureAlpha){
|
if(!rwStateCache.textureAlpha){
|
||||||
(enable ? glEnable : glDisable)(GL_BLEND);
|
setAlphaBlend(enable);
|
||||||
setAlphaTest(enable);
|
setAlphaTest(enable);
|
||||||
}
|
}
|
||||||
rwStateCache.vertexAlpha = enable;
|
rwStateCache.vertexAlpha = enable;
|
||||||
|
@ -343,7 +364,7 @@ setRasterStageOnly(uint32 stage, Raster *raster)
|
||||||
if(alpha != rwStateCache.textureAlpha){
|
if(alpha != rwStateCache.textureAlpha){
|
||||||
rwStateCache.textureAlpha = alpha;
|
rwStateCache.textureAlpha = alpha;
|
||||||
if(!rwStateCache.vertexAlpha){
|
if(!rwStateCache.vertexAlpha){
|
||||||
(alpha ? glEnable : glDisable)(GL_BLEND);
|
setAlphaBlend(alpha);
|
||||||
setAlphaTest(alpha);
|
setAlphaTest(alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +413,7 @@ setRasterStage(uint32 stage, Raster *raster)
|
||||||
if(alpha != rwStateCache.textureAlpha){
|
if(alpha != rwStateCache.textureAlpha){
|
||||||
rwStateCache.textureAlpha = alpha;
|
rwStateCache.textureAlpha = alpha;
|
||||||
if(!rwStateCache.vertexAlpha){
|
if(!rwStateCache.vertexAlpha){
|
||||||
(alpha ? glEnable : glDisable)(GL_BLEND);
|
setAlphaBlend(alpha);
|
||||||
setAlphaTest(alpha);
|
setAlphaTest(alpha);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -492,6 +513,11 @@ setRenderState(int32 state, void *pvalue)
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GSALPHATEST:
|
||||||
|
rwStateCache.gsalpha = value;
|
||||||
|
break;
|
||||||
|
case GSALPHATESTREF:
|
||||||
|
rwStateCache.gsalpharef = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,6 +577,12 @@ getRenderState(int32 state)
|
||||||
case ALPHATESTREF:
|
case ALPHATESTREF:
|
||||||
val = (uint32)(uniformState.alphaRef*255.0f);
|
val = (uint32)(uniformState.alphaRef*255.0f);
|
||||||
break;
|
break;
|
||||||
|
case GSALPHATEST:
|
||||||
|
val = rwStateCache.gsalpha;
|
||||||
|
break;
|
||||||
|
case GSALPHATESTREF:
|
||||||
|
val = rwStateCache.gsalpharef;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
val = 0;
|
val = 0;
|
||||||
}
|
}
|
||||||
|
@ -568,13 +600,16 @@ resetRenderState(void)
|
||||||
uniformState.fogEnd = 0.0f;
|
uniformState.fogEnd = 0.0f;
|
||||||
uniformState.fogRange = 0.0f;
|
uniformState.fogRange = 0.0f;
|
||||||
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
uniformState.fogColor = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
|
rwStateCache.gsalpha = 0;
|
||||||
|
rwStateCache.gsalpharef = 128;
|
||||||
stateDirty = 1;
|
stateDirty = 1;
|
||||||
|
|
||||||
rwStateCache.vertexAlpha = 0;
|
rwStateCache.vertexAlpha = 0;
|
||||||
rwStateCache.textureAlpha = 0;
|
rwStateCache.textureAlpha = 0;
|
||||||
glDisable(GL_BLEND);
|
|
||||||
rwStateCache.alphaTestEnable = 0;
|
rwStateCache.alphaTestEnable = 0;
|
||||||
|
|
||||||
|
rwStateCache.blendEnable = 0;
|
||||||
|
glDisable(GL_BLEND);
|
||||||
rwStateCache.srcblend = BLENDSRCALPHA;
|
rwStateCache.srcblend = BLENDSRCALPHA;
|
||||||
rwStateCache.destblend = BLENDINVSRCALPHA;
|
rwStateCache.destblend = BLENDINVSRCALPHA;
|
||||||
glBlendFunc(blendMap[rwStateCache.srcblend], blendMap[rwStateCache.destblend]);
|
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);
|
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||||
|
|
||||||
flushCache();
|
drawInst(header, inst);
|
||||||
glDrawElements(header->primType, inst->numIndex,
|
|
||||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Frame *lastEnvFrame;
|
static Frame *lastEnvFrame;
|
||||||
|
@ -152,9 +150,7 @@ matfxEnvRender(InstanceDataHeader *header, InstanceData *inst, MatFX::Env *env)
|
||||||
rw::SetRenderState(VERTEXALPHA, 1);
|
rw::SetRenderState(VERTEXALPHA, 1);
|
||||||
rw::SetRenderState(SRCBLEND, BLENDONE);
|
rw::SetRenderState(SRCBLEND, BLENDONE);
|
||||||
|
|
||||||
flushCache();
|
drawInst(header, inst);
|
||||||
glDrawElements(header->primType, inst->numIndex,
|
|
||||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
|
||||||
|
|
||||||
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
rw::SetRenderState(SRCBLEND, BLENDSRCALPHA);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,58 @@
|
||||||
namespace rw {
|
namespace rw {
|
||||||
namespace gl3 {
|
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
|
void
|
||||||
setAttribPointers(AttribDesc *attribDescs, int32 numAttribs)
|
setAttribPointers(AttribDesc *attribDescs, int32 numAttribs)
|
||||||
|
@ -102,9 +153,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||||
|
|
||||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||||
|
|
||||||
flushCache();
|
drawInst(header, inst);
|
||||||
glDrawElements(header->primType, inst->numIndex,
|
|
||||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||||
|
|
|
@ -309,9 +309,7 @@ skinRenderCB(Atomic *atomic, InstanceDataHeader *header)
|
||||||
|
|
||||||
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
rw::SetRenderState(VERTEXALPHA, inst->vertexAlpha || m->color.alpha != 0xFF);
|
||||||
|
|
||||||
flushCache();
|
drawInst(header, inst);
|
||||||
glDrawElements(header->primType, inst->numIndex,
|
|
||||||
GL_UNSIGNED_SHORT, (void*)(uintptr)inst->offset);
|
|
||||||
inst++;
|
inst++;
|
||||||
}
|
}
|
||||||
disableAttribPointers(header->attribDesc, header->numAttribs);
|
disableAttribPointers(header->attribDesc, header->numAttribs);
|
||||||
|
|
|
@ -171,10 +171,11 @@ int32 setLights(WorldLights *lightData);
|
||||||
// per Mesh
|
// per Mesh
|
||||||
void setTexture(int32 n, Texture *tex);
|
void setTexture(int32 n, Texture *tex);
|
||||||
|
|
||||||
|
void setAlphaBlend(bool32 enable);
|
||||||
|
bool32 getAlphaBlend(void);
|
||||||
|
|
||||||
uint32 bindTexture(uint32 texid);
|
uint32 bindTexture(uint32 texid);
|
||||||
|
|
||||||
|
|
||||||
void flushCache(void);
|
void flushCache(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -194,6 +195,13 @@ void defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header);
|
||||||
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
void defaultRenderCB(Atomic *atomic, InstanceDataHeader *header);
|
||||||
int32 lightingCB(Atomic *atomic);
|
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);
|
void *destroyNativeData(void *object, int32, int32);
|
||||||
|
|
||||||
ObjPipeline *makeDefaultPipeline(void);
|
ObjPipeline *makeDefaultPipeline(void);
|
||||||
|
|
Loading…
Reference in New Issue