From 101b9b14bbbb5ae985afdc257b99f502f4cd2e1a Mon Sep 17 00:00:00 2001 From: Daniel Gibson Date: Sun, 19 Feb 2017 02:18:53 +0100 Subject: [PATCH] GL3: Flowing (non-warping) textures --- src/client/refresh/constants/warpsin.h | 14 +++++++ src/client/refresh/gl3/gl3_main.c | 7 ---- src/client/refresh/gl3/gl3_shaders.c | 54 ++++++++------------------ src/client/refresh/gl3/gl3_surf.c | 52 +++++++++++-------------- src/client/refresh/gl3/gl3_warp.c | 9 ++--- src/client/refresh/gl3/header/local.h | 4 +- 6 files changed, 60 insertions(+), 80 deletions(-) diff --git a/src/client/refresh/constants/warpsin.h b/src/client/refresh/constants/warpsin.h index f6a86218..01f478b3 100644 --- a/src/client/refresh/constants/warpsin.h +++ b/src/client/refresh/constants/warpsin.h @@ -24,6 +24,20 @@ * ======================================================================= */ +#if 0 +// In case you wonder how these were generated/what they mean: +for (int i = 0; i < 256; i++) { + r_turbsin[i] = 8.0 * sin( (float)i / TURBSCALE ); // TURBSCALE = 256.0 / (2.0 * M_PI) +} +// so r_turbsin[i] is 8 * sin( i/TURBSCALE ); +// however, the values are multiplied with 0.5 in RI_Init() +// so what's actually used is 4 * sin(i/TURBSCALE) +// in R_EmitWaterPolys() something like +s = os + r_turbsin [ (int) ( ( ot * 0.125 + r_newrefdef.time ) * TURBSCALE ) & 255 ]; +// is used; which should (except for rounding errors from lookup table) be equivalent to +s = os + 4.0*sin( ot*0.125 + r_newrefdef.time ); +#endif // 0 + 0, 0.19633, 0.392541, 0.588517, 0.784137, 0.979285, 1.17384, 1.3677, 1.56072, 1.75281, 1.94384, 2.1337, 2.32228, 2.50945, 2.69512, 2.87916, 3.06147, 3.24193, 3.42044, 3.59689, 3.77117, 3.94319, 4.11282, 4.27998, diff --git a/src/client/refresh/gl3/gl3_main.c b/src/client/refresh/gl3/gl3_main.c index 0d11ed94..7280b709 100644 --- a/src/client/refresh/gl3/gl3_main.c +++ b/src/client/refresh/gl3/gl3_main.c @@ -431,13 +431,6 @@ GL3_SetMode(void) static qboolean GL3_Init(void) { - int j; - extern float gl3_turbsin[256]; - for (j = 0; j < 256; j++) - { - gl3_turbsin[j] *= 0.5; - } - Swap_Init(); // FIXME: for fucks sake, this doesn't have to be done at runtime! /* Options */ diff --git a/src/client/refresh/gl3/gl3_shaders.c b/src/client/refresh/gl3/gl3_shaders.c index 9b556181..d31c4448 100644 --- a/src/client/refresh/gl3/gl3_shaders.c +++ b/src/client/refresh/gl3/gl3_shaders.c @@ -267,7 +267,8 @@ static const char* vertexCommon3D = MULTILINE_STRING(#version 150\n mat4 transProj; mat4 transModelView; // TODO: or maybe transViewProj and transModel ?? float scroll; // for SURF_FLOWING - float time; // or sth like this? + float time; + float alpha; }; ); @@ -292,7 +293,8 @@ static const char* fragmentCommon3D = MULTILINE_STRING(#version 150\n mat4 transProj; mat4 transModelView; // TODO: or maybe transViewProj and transModel ?? float scroll; // for SURF_FLOWING - float time; // or sth like this? + float time; + float alpha; }; ); @@ -302,8 +304,8 @@ static const char* vertexSrc3D = MULTILINE_STRING( void main() { - gl_Position = transProj * transModelView * vec4(position, 1.0); passTexCoord = texCoord; + gl_Position = transProj * transModelView * vec4(position, 1.0); } ); @@ -322,24 +324,10 @@ static const char* fragmentSrc3D = MULTILINE_STRING( // apply gamma correction and intensity texel.rgb *= intensity; outColor.rgb = pow(texel.rgb, vec3(gamma)); - outColor.a = texel.a; // I think alpha shouldn't be modified by gamma and intensity + outColor.a = texel.a*alpha; // I think alpha shouldn't be modified by gamma and intensity } ); -/* - os = v [ 3 ]; - ot = v [ 4 ]; - - float TURBSCALE = (256.0 / (2 * M_PI)); - - s = os + gl3_turbsin [ (int) ( ( ot * 0.125 + rdt ) * TURBSCALE ) & 255 ]; - s += scroll; - tex[index_tex++] = s * ( 1.0 / 64 ); - - t = ot + gl3_turbsin [ (int) ( ( os * 0.125 + rdt ) * TURBSCALE ) & 255 ]; - tex[index_tex++] = t * ( 1.0 / 64 ); - */ - static const char* vertexSrc3Dwater = MULTILINE_STRING( // it gets attributes and uniforms from vertexCommon3D @@ -356,31 +344,17 @@ static const char* vertexSrc3Dwater = MULTILINE_STRING( } ); -static const char* fragmentSrc3Dwater = MULTILINE_STRING( - - // it gets attributes and uniforms from fragmentCommon3D - - uniform sampler2D tex; - - const float PI = 3.141592653589793238462643383; // TODO: put in common - const float TURBSCALE = (256.0 / (2 * PI)); +static const char* vertexSrc3Dflow = MULTILINE_STRING( + // it gets attributes and uniforms from vertexCommon3D void main() { - vec4 texel = texture(tex, passTexCoord); - - // TODO: something about GL_BLEND vs GL_ALPHATEST etc - - // apply gamma correction and intensity - texel.rgb *= intensity; - outColor.rgb = pow(texel.rgb, vec3(gamma)); - //outColor.a = texel.a; // I think alpha shouldn't be modified by gamma and intensity - outColor.a = 0.666; // FIXME: set alpha via uniform + passTexCoord = texCoord + vec2(0, scroll); + gl_Position = transProj * transModelView * vec4(position, 1.0); } ); - #undef MULTILINE_STRING enum { @@ -618,6 +592,7 @@ static void initUBOs(void) // the matrices will be set to something more useful later, before being used gl3state.uni3DData.scroll = 0.0f; gl3state.uni3DData.time = 0.0f; + gl3state.uni3DData.alpha = 1.0f; glGenBuffers(1, &gl3state.uni3DUBO); glBindBuffer(GL_UNIFORM_BUFFER, gl3state.uni3DUBO); @@ -644,11 +619,16 @@ qboolean GL3_InitShaders(void) R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for textured 3D rendering!\n"); return false; } - if(!initShader3D(&gl3state.si3Dturb, vertexSrc3Dwater, fragmentSrc3Dwater)) + if(!initShader3D(&gl3state.si3Dturb, vertexSrc3Dwater, fragmentSrc3D)) { R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for water rendering!\n"); return false; } + if(!initShader3D(&gl3state.si3Dflow, vertexSrc3Dflow, fragmentSrc3D)) + { + R_Printf(PRINT_ALL, "WARNING: Failed to create shader program for scrolling textures 3D rendering!\n"); + return false; + } gl3state.currentShaderProgram = 0; return true; diff --git a/src/client/refresh/gl3/gl3_surf.c b/src/client/refresh/gl3/gl3_surf.c index b04af6f1..7c0ff425 100644 --- a/src/client/refresh/gl3/gl3_surf.c +++ b/src/client/refresh/gl3/gl3_surf.c @@ -142,37 +142,26 @@ GL3_DrawGLFlowingPoly(msurface_t *fa) p = fa->polys; - scroll = -64 * ((gl3_newrefdef.time / 40.0) - (int)(gl3_newrefdef.time / 40.0)); + scroll = -64.0f * ((gl3_newrefdef.time / 40.0f) - (int)(gl3_newrefdef.time / 40.0f)); - if (scroll == 0.0) + if (scroll == 0.0f) { - scroll = -64.0; + scroll = -64.0f; } - GLfloat tex[2*p->numverts]; - unsigned int index_tex = 0; - - v = p->verts [ 0 ]; - - for ( i = 0; i < p->numverts; i++, v += VERTEXSIZE ) + if(gl3state.uni3DData.scroll != scroll) { - tex[index_tex++] = v [ 3 ] + scroll; - tex[index_tex++] = v [ 4 ]; + gl3state.uni3DData.scroll = scroll; + GL3_UpdateUBO3D(); } - v = p->verts [ 0 ]; - STUB_ONCE("TODO: Implement OpenGL stuff!"); -#if 0 - glEnableClientState( GL_VERTEX_ARRAY ); - glEnableClientState( GL_TEXTURE_COORD_ARRAY ); + GL3_UseProgram(gl3state.si3Dflow.shaderProgram); - glVertexPointer( 3, GL_FLOAT, VERTEXSIZE*sizeof(GLfloat), v ); - glTexCoordPointer( 2, GL_FLOAT, 0, tex ); - glDrawArrays( GL_TRIANGLE_FAN, 0, p->numverts ); + GL3_BindVAO(gl3state.vao3D); + glBindBuffer(GL_ARRAY_BUFFER, gl3state.vbo3D); - glDisableClientState( GL_VERTEX_ARRAY ); - glDisableClientState( GL_TEXTURE_COORD_ARRAY ); -#endif // 0 + glBufferData(GL_ARRAY_BUFFER, VERTEXSIZE*sizeof(GLfloat)*p->numverts, p->verts[0], GL_STREAM_DRAW); + glDrawArrays(GL_TRIANGLE_FAN, 0, p->numverts); } static void @@ -504,7 +493,7 @@ RenderBrushPoly(msurface_t *fa) { GL3_Bind(image->texnum); - STUB("TODO: do something about R_TexEnv()!"); + STUB_ONCE("TODO: do something about inverse intensity on water surfaces b/c they have no lightmap!"); #if 0 // TODO /* This is a hack ontop of a hack. Warping surfaces like those generated by R_EmitWaterPolys() don't have a lightmap. Original Quake II therefore @@ -645,26 +634,26 @@ GL3_DrawAlphaSurfaces(void) /* the textures are prescaled up for a better lighting range, so scale it back down */ //intens = gl_state.inverse_intensity; - STUB_ONCE("Something about inverse intensity"); + STUB_ONCE("Something about inverse intensity??"); for (s = gl3_alpha_surfaces; s != NULL; s = s->texturechain) { GL3_Bind(s->texinfo->image->texnum); c_brush_polys++; -#if 0 + float alpha = 1.0f; if (s->texinfo->flags & SURF_TRANS33) { - glColor4f(intens, intens, intens, 0.33); + alpha = 0.333f; } else if (s->texinfo->flags & SURF_TRANS66) { - glColor4f(intens, intens, intens, 0.66); + alpha = 0.666f; } - else + if(alpha != gl3state.uni3DData.alpha) { - glColor4f(intens, intens, intens, 1); + gl3state.uni3DData.alpha = alpha; + GL3_UpdateUBO3D(); } -#endif // 0 if (s->flags & SURF_DRAWTURB) { @@ -680,6 +669,9 @@ GL3_DrawAlphaSurfaces(void) } } + gl3state.uni3DData.alpha = 1.0f; + GL3_UpdateUBO3D(); + //R_TexEnv(GL_REPLACE); //glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); diff --git a/src/client/refresh/gl3/gl3_warp.c b/src/client/refresh/gl3/gl3_warp.c index 5527a52e..e5a1d7c3 100644 --- a/src/client/refresh/gl3/gl3_warp.c +++ b/src/client/refresh/gl3/gl3_warp.c @@ -27,11 +27,6 @@ #include "header/local.h" -// TODO: can we get rid of this? -float gl3_turbsin[] = { -#include "../constants/warpsin.h" -}; - static void R_BoundPoly(int numverts, float *verts, vec3_t mins, vec3_t maxs) { @@ -234,6 +229,10 @@ GL3_EmitWaterPolys(msurface_t *fa) if (fa->texinfo->flags & SURF_FLOWING) { scroll = -64.0f * ((gl3_newrefdef.time * 0.5) - (int)(gl3_newrefdef.time * 0.5)); + if (scroll == 0.0f) // this is done in GL3_DrawGLFlowingPoly() TODO: keep? + { + scroll = -64.0f; + } } if(gl3state.uni3DData.scroll != scroll) diff --git a/src/client/refresh/gl3/header/local.h b/src/client/refresh/gl3/header/local.h index 1f8032c4..5b1fb637 100644 --- a/src/client/refresh/gl3/header/local.h +++ b/src/client/refresh/gl3/header/local.h @@ -136,8 +136,9 @@ typedef struct GLfloat scroll; // for SURF_FLOWING GLfloat time; // for warping surfaces like water & possibly other things + GLfloat alpha; // for translucent surfaces (water, glass, ..) - GLfloat _padding[2]; // again, some padding to ensure this has right size + GLfloat _padding; // again, some padding to ensure this has right size } gl3Uni3D_t; typedef struct @@ -168,6 +169,7 @@ typedef struct gl3ShaderInfo_t si2Dcolor; // shader for rendering 2D with flat colors gl3ShaderInfo_t si3D; gl3ShaderInfo_t si3Dturb; // for water etc + gl3ShaderInfo_t si3Dflow; // for flowing/scrolling things (conveyor, ..?) GLuint vao3D, vbo3D; // for brushes etc, using 7 floats as vertex input (x,y,z, s,t, lms,lmt)