diff --git a/source/src/protos.h b/source/src/protos.h index 3032eb08..b7c4f39a 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -2,7 +2,8 @@ #ifndef STANDALONE -extern bool hasTE, hasMT, hasMDA, hasDRE, hasstencil, hasST2, hasSTW; +extern bool hasTE, hasMT, hasMDA, hasDRE, hasstencil, hasST2, hasSTW, hasSTS; + // GL_ARB_multitexture extern PFNGLACTIVETEXTUREARBPROC glActiveTexture_; extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture_; @@ -19,6 +20,10 @@ extern PFNGLDRAWRANGEELEMENTSEXTPROC glDrawRangeElements_; // GL_EXT_stencil_two_side extern PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFace_; +// GL_ATI_separate_stencil +extern PFNGLSTENCILOPSEPARATEATIPROC glStencilOpSeparate_; +extern PFNGLSTENCILFUNCSEPARATEATIPROC glStencilFuncSeparate_; + struct color { float r, g, b, alpha; diff --git a/source/src/rendergl.cpp b/source/src/rendergl.cpp index c2f0682a..9f74aa53 100644 --- a/source/src/rendergl.cpp +++ b/source/src/rendergl.cpp @@ -4,7 +4,7 @@ #include "cube.h" #include "bot/bot.h" -bool hasTE = false, hasMT = false, hasMDA = false, hasDRE = false, hasstencil = false, hasST2 = false, hasSTW = false; +bool hasTE = false, hasMT = false, hasMDA = false, hasDRE = false, hasstencil = false, hasST2 = false, hasSTW = false, hasSTS = false; // GL_ARB_multitexture PFNGLACTIVETEXTUREARBPROC glActiveTexture_ = NULL; @@ -22,6 +22,10 @@ PFNGLDRAWRANGEELEMENTSEXTPROC glDrawRangeElements_ = NULL; // GL_EXT_stencil_two_side PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFace_ = NULL; +// GL_ATI_separate_stencil +PFNGLSTENCILOPSEPARATEATIPROC glStencilOpSeparate_ = NULL; +PFNGLSTENCILFUNCSEPARATEATIPROC glStencilFuncSeparate_ = NULL; + void *getprocaddress(const char *name) { return SDL_GL_GetProcAddress(name); @@ -74,9 +78,16 @@ void gl_checkextensions() hasST2 = true; } + if(strstr(exts, "GL_ATI_separate_stencil")) + { + glStencilOpSeparate_ = (PFNGLSTENCILOPSEPARATEATIPROC) getprocaddress("glStencilOpSeparateATI"); + glStencilFuncSeparate_ = (PFNGLSTENCILFUNCSEPARATEATIPROC)getprocaddress("glStencilFuncSeparateATI"); + hasSTS = true; + } + if(strstr(exts, "GL_EXT_stencil_wrap")) hasSTW = true; - if(!hasST2 || !hasSTW) + if((!hasST2 && !hasSTS) || !hasSTW) { // only enable stencil shadows by default if card is efficient at rendering them stencilshadow = 0; @@ -833,18 +844,28 @@ void drawstencilshadows() stenciling = 1; - if(hasST2 && hasSTW) + if((hasST2 || hasSTS) && hasSTW) { - glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); glDisable(GL_CULL_FACE); - glActiveStencilFace_(GL_BACK); - glStencilFunc(GL_ALWAYS, 0, ~0U); - glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT); + if(hasST2) + { + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); - glActiveStencilFace_(GL_FRONT); - glStencilFunc(GL_ALWAYS, 0, ~0U); - glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT); + glActiveStencilFace_(GL_BACK); + glStencilFunc(GL_ALWAYS, 0, ~0U); + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT); + + glActiveStencilFace_(GL_FRONT); + glStencilFunc(GL_ALWAYS, 0, ~0U); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT); + } + else + { + glStencilFuncSeparate_(GL_ALWAYS, GL_ALWAYS, 0, ~0U); + glStencilOpSeparate_(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP_EXT); + glStencilOpSeparate_(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP_EXT); + } startmodelbatches(); renderentities(); @@ -852,8 +873,8 @@ void drawstencilshadows() renderbounceents(); endmodelbatches(); + if(hasST2) glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); glEnable(GL_CULL_FACE); - glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); } else {