From 23ea2ea034415150ccaca349b62478055c8e270e Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Tue, 20 Jun 2017 18:31:32 +0200 Subject: [PATCH] GL3: Square particles with cvar gl3_particle_square if that cvar is set to 1, particles aren't rendered as nice circles, but as squares, like in the software renderer or in Quake1. Also documented it in cvarlist.md and fixed some typos there --- src/client/refresh/gl3/gl3_main.c | 8 +++++ src/client/refresh/gl3/gl3_shaders.c | 46 ++++++++++++++++++++++++--- src/client/refresh/gl3/header/local.h | 2 ++ stuff/cvarlist.md | 14 +++++--- 4 files changed, 61 insertions(+), 9 deletions(-) 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`. + +