diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index d27776c8c8b..174f97533d8 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -3752,9 +3752,9 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, D3DRENDE GLint action = StencilOp(Value); - glGetIntegerv(GL_STENCIL_FAIL, &stencilFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &depthFail); - glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &stencilPass); + glGetIntegerv(GL_STENCIL_BACK_FAIL, &stencilFail); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &depthFail); + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS, &stencilPass); if(WINED3DRS_CCW_STENCILFAIL == State) { stencilFail = action; @@ -3770,8 +3770,22 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetRenderState(IWineD3DDevice *iface, D3DRENDE if(GL_EXTCALL(glStencilOpSeparate)) { GL_EXTCALL(glStencilOpSeparate(GL_BACK, stencilFail, depthFail, stencilPass)); checkGLcall("glStencilOpSeparate(GL_BACK,...)"); + } + else if(GL_EXTCALL(glActiveStencilFaceEXT)) { + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); + checkGLcall("glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT)"); + GL_EXTCALL(glActiveStencilFaceEXT(GL_BACK)); + checkGLcall("glActiveStencilFaceEXT(GL_BACK)"); + glStencilOp(stencilFail, depthFail, stencilPass); + checkGLcall("glStencilOp(...)"); + } + else if(GL_EXTCALL(glStencilOpSeparateATI)) { + GL_EXTCALL(glStencilOpSeparateATI(GL_BACK, stencilFail, depthFail, stencilPass)); + checkGLcall("glStencilOpSeparateATI(GL_BACK,...)"); } else { - WARN("Unsupported in local OpenGL implementation: glStencilOpSeparate\n"); + TRACE("Separate stencil operation not supported on this version of opengl"); + glStencilOp(stencilFail, depthFail, stencilPass); + checkGLcall("glStencilOp(...)"); } } else { glStencilOp(stencilFail, depthFail, stencilPass); diff --git a/include/wine/wined3d_gl.h b/include/wine/wined3d_gl.h index fa391ba3e5a..c4cd565f048 100644 --- a/include/wine/wined3d_gl.h +++ b/include/wine/wined3d_gl.h @@ -803,6 +803,23 @@ typedef void (APIENTRY * PGLFNBEGINOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRY * PGLFNENDOCCLUSIONQUERYNVPROC) (void); typedef void (APIENTRY * PGLFNGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRY * PGLFNGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); +/* GL_EXT_stencil_two_side */ +#ifndef GL_EXT_stencil_two_side +#define GL_EXT_stencil_two_side 1 +#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 +#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 +#endif +typedef void (APIENTRY * PGLFNACTIVESTENCILFACEEXTPROC) (GLenum face); +/* GL_ATI_separate_stencil */ +#ifndef GL_ATI_separate_stencil +#define GL_ATI_separate_stencil 1 +#define GL_STENCIL_BACK_FUNC_ATI 0x8800 +#define GL_STENCIL_BACK_FAIL_ATI 0x8801 +#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 +#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 +#endif +typedef void (APIENTRY * PGLFNSTENCILOPSEPARATEATIPROC) (GLenum, GLenum, GLenum, GLenum); +typedef void (APIENTRY * PGLFNSTENCILFUNCSEPARATEATIPROC) (GLenum, GLenum, GLint, GLuint); /* OpenGL 2.0 */ typedef void (APIENTRY * PGLFNSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRY * PGLFNSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); @@ -1034,6 +1051,10 @@ typedef enum _GL_SupportedExt { USE_GL_FUNC(PGLFNVERTEXATTRIBPOINTERARBPROC, glVertexAttribPointerARB); \ USE_GL_FUNC(PGLFNENABLEVERTEXATTRIBARRAYARBPROC, glEnableVertexAttribArrayARB); \ USE_GL_FUNC(PGLFNDISABLEVERTEXATTRIBARRAYARBPROC, glDisableVertexAttribArrayARB); \ + /* GL_EXT_stencil_two_side */ \ + USE_GL_FUNC(PGLFNACTIVESTENCILFACEEXTPROC, glActiveStencilFaceEXT); \ + USE_GL_FUNC(PGLFNSTENCILOPSEPARATEATIPROC, glStencilOpSeparateATI); \ + USE_GL_FUNC(PGLFNSTENCILFUNCSEPARATEATIPROC, glStencilFuncSeparateATI); \ /* OpenGL 2.0 */ \ USE_GL_FUNC(PGLFNSTENCILOPSEPARATEPROC, glStencilOpSeparate); \ USE_GL_FUNC(PGLFNSTENCILFUNCSEPARATEPROC, glStencilFuncSeparate); \