mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Add basic stencil test functionality, shadows work in Wipeout. update native.
This is not the whole story though, the PSP is being tricky by sharing the dest alpha and stencil.
This commit is contained in:
parent
508e2512f3
commit
590d94da9f
@ -60,16 +60,25 @@ const GLuint ztests[] =
|
||||
GL_LESS, GL_LEQUAL, GL_GREATER, GL_GEQUAL,
|
||||
};
|
||||
|
||||
void ApplyDrawState()
|
||||
{
|
||||
const GLuint stencilOps[] = {
|
||||
GL_KEEP,
|
||||
GL_ZERO,
|
||||
GL_REPLACE,
|
||||
GL_INVERT,
|
||||
GL_INCR_WRAP,
|
||||
GL_DECR_WRAP, // don't know if these should be wrap or not
|
||||
GL_KEEP, // reserved
|
||||
GL_KEEP, // reserved
|
||||
};
|
||||
|
||||
void ApplyDrawState(int prim) {
|
||||
// TODO: All this setup is soon so expensive that we'll need dirty flags, or simply do it in the command writes where we detect dirty by xoring. Silly to do all this work on every drawcall.
|
||||
|
||||
// TODO: The top bit of the alpha channel should be written to the stencil bit somehow. This appears to require very expensive multipass rendering :( Alternatively, one could do a
|
||||
// single fullscreen pass that converts alpha to stencil (or 2 passes, to set both the 0 and 1 values) very easily.
|
||||
|
||||
// Set cull
|
||||
bool wantCull = !gstate.isModeClear() && !gstate.isModeThrough() && gstate.isCullEnabled();
|
||||
bool wantCull = !gstate.isModeClear() && !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
|
||||
glstate.cullFace.set(wantCull);
|
||||
|
||||
if (wantCull) {
|
||||
@ -165,6 +174,19 @@ void ApplyDrawState()
|
||||
glstate.colorMask.set(rmask, gmask, bmask, amask);
|
||||
}
|
||||
|
||||
// Stencil test
|
||||
if (!gstate.isModeClear() && gstate.isStencilTestEnabled()) {
|
||||
glstate.stencilTest.enable();
|
||||
glstate.stencilFunc.set(ztests[gstate.stenciltest & 0x7], // func
|
||||
(gstate.stenciltest >> 8) & 0xFF, // ref
|
||||
(gstate.stenciltest >> 16) & 0xFF); // mask
|
||||
glstate.stencilOp.set(stencilOps[gstate.stencilop & 0x7], // stencil fail
|
||||
stencilOps[(gstate.stencilop >> 8) & 0x7], // depth fail
|
||||
stencilOps[(gstate.stencilop >> 16) & 0x7]);
|
||||
} else {
|
||||
glstate.stencilTest.disable();
|
||||
}
|
||||
|
||||
bool wantDepthWrite = gstate.isModeClear() || gstate.isDepthWriteEnabled();
|
||||
glstate.depthWrite.set(wantDepthWrite ? GL_TRUE : GL_FALSE);
|
||||
|
||||
|
@ -7,6 +7,6 @@ extern const GLint cullingMode[];
|
||||
extern const GLuint ztests[];
|
||||
|
||||
|
||||
void ApplyDrawState();
|
||||
void ApplyDrawState(int prim);
|
||||
void UpdateViewportAndProjection();
|
||||
|
||||
|
@ -742,7 +742,7 @@ void TransformDrawEngine::Flush() {
|
||||
|
||||
int prim = indexGen.Prim();
|
||||
|
||||
ApplyDrawState();
|
||||
ApplyDrawState(prim);
|
||||
UpdateViewportAndProjection();
|
||||
|
||||
LinkedShader *program = shaderManager_->ApplyShader(prim);
|
||||
|
@ -208,6 +208,7 @@ struct GPUgstate
|
||||
bool isDepthWriteEnabled() const { return !(zmsk & 1); }
|
||||
int getDepthTestFunc() const { return ztestfunc & 0x7; }
|
||||
bool isFogEnabled() const { return fogEnable & 1; }
|
||||
bool isStencilTestEnabled() const { return stencilTestEnable & 1; }
|
||||
|
||||
// UV gen
|
||||
int getUVGenMode() const { return texmapmode & 3;} // 2 bits
|
||||
|
@ -88,10 +88,12 @@ void UIShader_Prepare()
|
||||
glstate.cullFace.disable();
|
||||
glstate.depthTest.disable();
|
||||
glstate.scissorTest.disable();
|
||||
glstate.stencilTest.disable();
|
||||
|
||||
glstate.blend.enable();
|
||||
glstate.blendFunc.set(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glstate.colorMask.set(true, true, true, true);
|
||||
glstate.Restore();
|
||||
|
||||
uiTexture->Bind(0);
|
||||
|
2
native
2
native
@ -1 +1 @@
|
||||
Subproject commit c60bda83b6871f151921ca818a4ba292714bd7ec
|
||||
Subproject commit de36ea9f34187172b8da2bbb25d5b0e03027eb2c
|
Loading…
Reference in New Issue
Block a user