From a29be70dcd1a862bf56d64523f1d0fa6b9ad9d26 Mon Sep 17 00:00:00 2001 From: Jamie Wilkinson Date: Fri, 3 May 2002 08:50:13 +0000 Subject: [PATCH] - Added a new cvar, "gl_stencilshadow". Off by default, set it to 1 to enable stencilbuffer shadows. (Turn gl_shadows on first!) Based on MrG's tutorial on quakesrc.org, but hacked a bit to work for GLX instead of Win32, and is a bit more robust (won't die if it can't get a stencil buffer). - Updated TODO list to reflect this change. --- TODO | 5 ++--- baseq2/config.cfg | 1 + src/gl_glx.c | 54 ++++++++++++++++++++++++++++++++++++++++++-- src/gl_local.h | 1 + src/gl_mesh.c | 57 ++++++++++++++++++++++++++++++----------------- src/gl_rmain.c | 49 +++++++++++++++++++++++----------------- 6 files changed, 121 insertions(+), 46 deletions(-) diff --git a/TODO b/TODO index 1a0813b..5cf3d94 100644 --- a/TODO +++ b/TODO @@ -20,6 +20,7 @@ http://gozer.quakeforge.net/list-archives/quakeforge-cvs/2002-April/000151.html - investigate the possibility of savegames not being tied to a particular build - fix software assembler when building without --disable-asm on i386 - split out assembler per arch/os (we currently have gas i386 and win i386) +- make sure that we give back the mouse and keyboard if the game crashes from http://www.quakesrc.org/?Page=tutorials&Dir=Quake2 : (replace - with X when done) @@ -32,7 +33,7 @@ from http://www.quakesrc.org/?Page=tutorials&Dir=Quake2 : - Transparent console - How to add .m32 texture support to the Quake2 engine and compile tools. - TGA textures -- Stencil buffered shadows +X Stencil buffered shadows - Adding true color TGA loading for MD2 Models - Better dynamic light falloff - Controlable water waves @@ -41,5 +42,3 @@ from http://www.quakesrc.org/?Page=tutorials&Dir=Quake2 : - Adding a skybox size variable - Adding new video resolutions - Drawing alias model bounding boxes - - diff --git a/baseq2/config.cfg b/baseq2/config.cfg index 3e718de..a571c0e 100644 --- a/baseq2/config.cfg +++ b/baseq2/config.cfg @@ -88,6 +88,7 @@ set gl_texturemode "GL_LINEAR_MIPMAP_NEAREST" set gl_driver "opengl32" set gl_finish "0" set gl_shadows "0" +set gl_stencilshadow "0" set gl_mode "3" set gl_modulate "1" set gl_particle_att_c "0.01" diff --git a/src/gl_glx.c b/src/gl_glx.c index 544ea08..bad173b 100644 --- a/src/gl_glx.c +++ b/src/gl_glx.c @@ -111,6 +111,8 @@ static XF86VidModeModeInfo **vidmodes; //static int default_dotclock_vidmode; static int num_vidmodes; static qboolean vidmode_active = false; + +/* hardware gamma */ static XF86VidModeGamma oldgamma; static qboolean mlooking; @@ -119,6 +121,9 @@ static qboolean mouse_active = false; static qboolean dgamouse = false; static qboolean vidmode_ext = false; +/* stencilbuffer shadows */ +qboolean have_stencil = false; + // state struct passed in Init static in_state_t *in_state; @@ -684,10 +689,20 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole unsigned int width, height; int attrib[] = { GLX_RGBA, + GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, + GLX_DEPTH_SIZE, 1, + GLX_STENCIL_SIZE, 1, + None + }; + int attrib_nostencil[] = { + GLX_RGBA, GLX_DOUBLEBUFFER, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, None }; @@ -749,12 +764,47 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole visinfo = qglXChooseVisual(dpy, scrnum, attrib); if (!visinfo) { - fprintf(stderr, "Error couldn't get an RGB, Double-buffered, Depth visual\n"); - return rserr_invalid_mode; + fprintf(stderr, "W: couldn't get an RGBA, DOUBLEBUFFER, DEPTH, STENCIL visual\n"); + visinfo = qglXChooseVisual(dpy, scrnum, attrib_nostencil); + if (!visinfo) { + fprintf(stderr, "E: couldn't get an RGBA, DOUBLEBUFFER, DEPTH visual\n"); + return rserr_invalid_mode; + } } gl_state.hwgamma = false; +#if 0 + /* do some pantsness */ + { + int red_bits, blue_bits, green_bits, depth_bits, alpha_bits; + + glXGetConfig(dpy, visinfo, GLX_RED_SIZE, &red_bits); + glXGetConfig(dpy, visinfo, GLX_BLUE_SIZE, &blue_bits); + glXGetConfig(dpy, visinfo, GLX_GREEN_SIZE, &green_bits); + glXGetConfig(dpy, visinfo, GLX_DEPTH_SIZE, &depth_bits); + glXGetConfig(dpy, visinfo, GLX_ALPHA_SIZE, &alpha_bits); + + ri.Con_Printf(PRINT_ALL, "I: got %d bits of red\n", red_bits); + ri.Con_Printf(PRINT_ALL, "I: got %d bits of blue\n", blue_bits); + ri.Con_Printf(PRINT_ALL, "I: got %d bits of green\n", green_bits); + ri.Con_Printf(PRINT_ALL, "I: got %d bits of depth\n", depth_bits); + ri.Con_Printf(PRINT_ALL, "I: got %d bits of alpha\n", alpha_bits); + } +#endif + + /* stencilbuffer shadows */ + { + int stencil_bits; + + if (!glXGetConfig(dpy, visinfo, GLX_STENCIL_SIZE, &stencil_bits)) { + ri.Con_Printf(PRINT_ALL, "I: got %d bits of stencil\n", stencil_bits); + if (stencil_bits >= 1) { + have_stencil = true; + } + } + } + if (vidmode_ext) { int best_fit, best_dist, dist, x, y; diff --git a/src/gl_local.h b/src/gl_local.h index 9a66558..685aacf 100644 --- a/src/gl_local.h +++ b/src/gl_local.h @@ -214,6 +214,7 @@ extern cvar_t *gl_mode; extern cvar_t *gl_log; extern cvar_t *gl_lightmap; extern cvar_t *gl_shadows; +extern cvar_t * gl_stencilshadow; extern cvar_t *gl_dynamic; extern cvar_t *gl_monolightmap; extern cvar_t *gl_nobind; diff --git a/src/gl_mesh.c b/src/gl_mesh.c index 0157a67..32588da 100644 --- a/src/gl_mesh.c +++ b/src/gl_mesh.c @@ -1,23 +1,25 @@ -/* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// gl_mesh.c: triangle model functions +/* $Id$ + * + * triangle model functions + * + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (c) 2002 The Quakeforge Project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "gl_local.h" @@ -302,6 +304,8 @@ GL_DrawAliasShadow ============= */ extern vec3_t lightspot; +/* stencilbuffer shadows */ +extern qboolean have_stencil; void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum) { @@ -324,6 +328,13 @@ void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum) height = -lheight + 1.0; + /* stencilbuffer shadows */ + if (have_stencil && gl_stencilshadow->value) { + qglEnable(GL_STENCIL_TEST); + qglStencilFunc(GL_EQUAL, 1, 2); + qglStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + } + while (1) { // get the vertex count and primitive type @@ -362,7 +373,11 @@ void GL_DrawAliasShadow (dmdl_t *paliashdr, int posenum) } while (--count); qglEnd (); - } + } + + /* stencilbuffer shadows */ + if (have_stencil && gl_stencilshadow->value) + qglDisable(GL_STENCIL_TEST); } #endif diff --git a/src/gl_rmain.c b/src/gl_rmain.c index 1f8524e..b4640ad 100644 --- a/src/gl_rmain.c +++ b/src/gl_rmain.c @@ -1,23 +1,23 @@ -/* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// r_main.c +/* $Id$ + * + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (c) 2002 The Quakeforge Project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include @@ -111,6 +111,7 @@ cvar_t *gl_drawbuffer; cvar_t *gl_driver; cvar_t *gl_lightmap; cvar_t *gl_shadows; +cvar_t * gl_stencilshadow; cvar_t *gl_mode; cvar_t *gl_dynamic; cvar_t *gl_monolightmap; @@ -770,6 +771,8 @@ void R_SetupGL (void) R_Clear ============= */ +extern qboolean have_stencil; + void R_Clear (void) { if (gl_ztrick->value) @@ -806,6 +809,11 @@ void R_Clear (void) qglDepthRange (gldepthmin, gldepthmax); + /* stencilbuffer shadows */ + if (gl_shadows->value && have_stencil && gl_stencilshadow->value) { + qglClearStencil(1); + qglClear(GL_STENCIL_BUFFER_BIT); + } } void R_Flash( void ) @@ -1010,6 +1018,7 @@ void R_Register( void ) gl_mode = ri.Cvar_Get( "gl_mode", "3", CVAR_ARCHIVE ); gl_lightmap = ri.Cvar_Get ("gl_lightmap", "0", 0); gl_shadows = ri.Cvar_Get ("gl_shadows", "0", CVAR_ARCHIVE ); + gl_stencilshadow = ri.Cvar_Get("gl_stencilshadow", "0", CVAR_ARCHIVE); gl_dynamic = ri.Cvar_Get ("gl_dynamic", "1", 0); gl_nobind = ri.Cvar_Get ("gl_nobind", "0", 0); gl_round_down = ri.Cvar_Get ("gl_round_down", "1", 0);