diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 323d2973..a96103d9 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -96,6 +96,7 @@ cvar_t *gl_drawbuffer; cvar_t *gl_clear; cvar_t *gl3_particle_size; cvar_t *gl3_particle_fade_factor; +cvar_t *gl3_particle_square; cvar_t *gl_lefthand; cvar_t *gl_farsee; @@ -208,6 +209,7 @@ GL3_Register(void) gl_customheight = ri.Cvar_Get("gl_customheight", "768", CVAR_ARCHIVE); gl3_particle_size = ri.Cvar_Get("gl3_particle_size", "40", CVAR_ARCHIVE); gl3_particle_fade_factor = ri.Cvar_Get("gl3_particle_fade_factor", "1.2", CVAR_ARCHIVE); + gl3_particle_square = ri.Cvar_Get("gl3_particle_square", "0", CVAR_ARCHIVE); gl_norefresh = ri.Cvar_Get("gl_norefresh", "0", 0); gl_drawentities = ri.Cvar_Get("gl_drawentities", "1", 0); @@ -1655,6 +1657,12 @@ GL3_BeginFrame(float camera_separation) GL3_UpdateUBO3D(); } + if(gl3_particle_square->modified) + { + gl3_particle_square->modified = false; + GL3_RecreateShaders(); + } + /* go into 2D mode */ diff --git a/src/client/refresh/gl3/gl3_shaders.c b/src/client/refresh/gl3/gl3_shaders.c index 43466194..9e034426 100644 --- a/src/client/refresh/gl3/gl3_shaders.c +++ b/src/client/refresh/gl3/gl3_shaders.c @@ -689,6 +689,18 @@ static const char* fragmentSrcParticles = MULTILINE_STRING( } ); +static const char* fragmentSrcParticlesSquare = MULTILINE_STRING( + + // it gets attributes and uniforms from fragmentCommon3D + + in vec4 passColor; + + void main() + { + outColor = passColor; + } +); + #undef MULTILINE_STRING @@ -977,10 +989,8 @@ static void initUBOs(void) gl3state.currentUBO = gl3state.uniLightsUBO; } -qboolean GL3_InitShaders(void) +static qboolean createShaders(void) { - initUBOs(); - if(!initShader2D(&gl3state.si2D, vertexSrc2D, fragmentSrc2D)) { R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 2D rendering!\n"); @@ -1053,7 +1063,14 @@ qboolean GL3_InitShaders(void) R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for rendering flat-colored models!\n"); return false; } - if(!initShader3D(&gl3state.siParticle, vertexSrcParticles, fragmentSrcParticles)) + + const char* particleFrag = fragmentSrcParticles; + if(gl3_particle_square->value != 0.0f) + { + particleFrag = fragmentSrcParticlesSquare; + } + + if(!initShader3D(&gl3state.siParticle, vertexSrcParticles, particleFrag)) { R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for rendering particles!\n"); return false; @@ -1064,7 +1081,14 @@ qboolean GL3_InitShaders(void) return true; } -void GL3_ShutdownShaders(void) +qboolean GL3_InitShaders(void) +{ + initUBOs(); + + return createShaders(); +} + +static void deleteShaders(void) { const gl3ShaderInfo_t siZero = {0}; for(gl3ShaderInfo_t* si = &gl3state.si2D; si <= &gl3state.siParticle; ++si) @@ -1072,6 +1096,11 @@ void GL3_ShutdownShaders(void) if(si->shaderProgram != 0) glDeleteProgram(si->shaderProgram); *si = siZero; } +} + +void GL3_ShutdownShaders(void) +{ + deleteShaders(); // let's (ab)use the fact that all 4 UBO handles are consecutive fields // of the gl3state struct @@ -1079,6 +1108,13 @@ void GL3_ShutdownShaders(void) gl3state.uniCommonUBO = gl3state.uni2DUBO = gl3state.uni3DUBO = gl3state.uniLightsUBO = 0; } +qboolean GL3_RecreateShaders(void) +{ + // delete and recreate the existing shaders (but not the UBOs) + deleteShaders(); + return createShaders(); +} + static inline void updateUBO(GLuint ubo, GLsizeiptr size, void* data) { diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index 2e900b55..5b49be1d 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -468,6 +468,7 @@ extern void GL3_ShutdownMeshes(void); // gl3_shaders.c +extern qboolean GL3_RecreateShaders(void); extern qboolean GL3_InitShaders(void); extern void GL3_ShutdownShaders(void); extern void GL3_UpdateUBOCommon(void); @@ -507,6 +508,7 @@ extern cvar_t *gl_anisotropic; extern cvar_t *gl_lightlevel; extern cvar_t *gl3_overbrightbits; extern cvar_t *gl3_particle_fade_factor; +extern cvar_t *gl3_particle_square; extern cvar_t *gl_modulate; extern cvar_t *gl_lightmap; diff --git a/stuff/cvarlist.md b/stuff/cvarlist.md index ef21d57b..06c4abde 100644 --- a/stuff/cvarlist.md +++ b/stuff/cvarlist.md @@ -13,7 +13,8 @@ General: * **basedir**: Directory from which the game data is loaded. Can be used in startup scripts, to test binaries, etc. If not set, the directory - containing the binaries is used. + containing the binaries is used. + To use this cvar, set it at startup, like `./quake2 +set basedir /path/to/quake2` * **cl_async**: If set to `1` (the default) the client is asynchronous. The client framerate is fixed, the renderer framerate is variable. @@ -76,7 +77,7 @@ Graphics (all renderers): with an aspect ratio of 4:3, regardless what the actual windows size or resolution is. -* **cl_gun**: Decides weather the gun is drawn. If set to `0` the gun +* **cl_gun**: Decides whether the gun is drawn. If set to `0` the gun is omitted. If set to `1` the gun is only drawn if the FOV is equal or smaller than 90. This was the default with Vanilla Quake II. If set to `2` the gun is drawn regardless of the FOV. This is the default @@ -126,8 +127,8 @@ Graphics (all renderers): * **gl_msaa_samples**: Full scene anti aliasing samples. The number of samples depends on the GPU driver, most drivers support at least - `2`, `4` and `8` samples. If an invalid value is set the value is - reverted the highest number of samples supported. Especially on OpenGL + `2`, `4` and `8` samples. If an invalid value is set, the value is + reverted to the highest number of samples supported. Especially on OpenGL 3.2 anti aliasing is expensive and can lead to a huge performance hit, so try setting it to a lower value if your framerate is too low. @@ -192,3 +193,8 @@ Graphics (GL3 only): * **gl3_particle_fade_factor**: "softness" of particles: higher values look less soft. Defaults to `1.2`. A value of `10` looks similar to the GL1 particles. + +* **gl3_particle_square**: If set to `1`, particles are rendered as squares, + like in the old software renderer or Quake1. Default is `0`. + +