From 4446f60fe83238f2908f4fc293de02e55e7b5bca Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 10 May 2012 01:00:41 +0000 Subject: [PATCH] Added code for glsl-less rtlights. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4035 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/gl/gl_backend.c | 143 ++++++++++++++++++++++++++++++++++++--- engine/gl/gl_rmisc.c | 11 +-- engine/gl/gl_shadow.c | 4 +- engine/gl/gl_vidcommon.c | 6 ++ engine/gl/shader.h | 3 +- 5 files changed, 151 insertions(+), 16 deletions(-) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index a5ad36e40..35826a73c 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -94,9 +94,9 @@ struct { //internal state struct { int lastpasstmus; - int vbo_colour; - int vbo_texcoords[SHADER_PASS_MAX]; - int vbo_deforms; //holds verticies... in case you didn't realise. +// int vbo_colour; +// int vbo_texcoords[SHADER_PASS_MAX]; +// int vbo_deforms; //holds verticies... in case you didn't realise. qboolean inited_shader_rtlight; const shader_t *shader_rtlight; @@ -167,6 +167,7 @@ struct { texid_t temptexture; //$current texid_t fogtexture; + texid_t normalisationcubemap; float fogfar; }; @@ -279,6 +280,13 @@ static void BE_SetPassBlendMode(int tmu, int pbm) qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB); qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); break; + case PBM_MODULATE_PREV_COLOUR: + GL_TexEnv(GL_COMBINE_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + qglTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1); + break; case PBM_REPLACELIGHT: if (shaderstate.identitylighting != 1) goto forcemod; @@ -675,8 +683,8 @@ void GLBE_SetupVAO(vbo_t *vbo, unsigned vaodynamic) else { /*always select the coord vbo and indicies ebo, for easy bufferdata*/ - GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo); - GL_SelectVBO(shaderstate.sourcevbo->coord.gl.vbo); + GL_SelectEBO(vbo->indicies.gl.vbo); + GL_SelectVBO(vbo->coord.gl.vbo); } } @@ -2911,12 +2919,12 @@ void GLBE_SelectMode(backendmode_t mode) break; case BEM_LIGHT: - if (!shaderstate.inited_shader_rtlight) + if (!shaderstate.inited_shader_rtlight && gl_config.arb_shader_objects) { shaderstate.inited_shader_rtlight = true; shaderstate.shader_rtlight = R_RegisterCustom("rtlight", Shader_LightPass_Std, NULL); } - if (!shaderstate.inited_shader_cube) + if (!shaderstate.inited_shader_cube && gl_config.arb_shader_objects) { shaderstate.inited_shader_cube = true; shaderstate.shader_cube = R_RegisterCustom("rtlight_sube", Shader_LightPass_Cube, NULL); @@ -3085,6 +3093,120 @@ void BE_PushOffsetShadow(qboolean pushdepth) } } +#ifdef RTLIGHTS +texid_t GenerateNormalisationCubeMap(void); +static void BE_LegacyLighting(void) +{ + //bigfoot wants rtlight support without glsl, so here goes madness... + //register combiners for bumpmapping using 4 tmus... + float *col; + float *ldir; + vec3_t lightdir, rellight; + float scale; + int i, m; + mesh_t *mesh; + unsigned int attr = (1u<vbofirstvert*4; + ldir = texcoordarray[0] + mesh->vbofirstvert*3; + for (i = 0; i < mesh->numvertexes; i++, col+=4, ldir+=3) + { + VectorSubtract(rellight, mesh->xyz_array[i], lightdir); + scale = VectorNormalize(lightdir); + scale = 1 - (scale/shaderstate.lightradius); + VectorScale(shaderstate.lightcolours, scale, col); + col[3] = 1; + ldir[0] = -DotProduct(lightdir, mesh->snormals_array[i]); + ldir[1] = DotProduct(lightdir, mesh->tnormals_array[i]); + ldir[2] = DotProduct(lightdir, mesh->normals_array[i]); + } + } + + if (shaderstate.curtexnums->bump.num) + { + attr |= (1u<<(VATTR_LEG_TMU0)) | (1u<<(VATTR_LEG_TMU0+1)) | (1u<<(VATTR_LEG_TMU0+2)); + + //tmu0: normalmap+replace+regular tex coords + GL_LazyBind(0, GL_TEXTURE_2D, shaderstate.curtexnums->bump); + BE_SetPassBlendMode(0, PBM_REPLACE); + qglClientActiveTextureARB(mtexid0 + 0); + GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo); + qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr); + + //tmu1: normalizationcubemap+dot3+lightdir + GL_LazyBind(1, GL_TEXTURE_CUBE_MAP_ARB, shaderstate.normalisationcubemap); + BE_SetPassBlendMode(1, PBM_DOTPRODUCT); + qglClientActiveTextureARB(mtexid0 + 1); + GL_SelectVBO(0); + qglTexCoordPointer(3, GL_FLOAT, 0, texcoordarray[0]); + + //tmu2: $diffuse+multiply+regular tex coords + GL_LazyBind(2, GL_TEXTURE_2D, shaderstate.curtexnums->base); //texture not used, its just to make sure the code leaves it enabled. + BE_SetPassBlendMode(2, PBM_MODULATE); + qglClientActiveTextureARB(mtexid0 + 2); + GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo); + qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr); + + //tmu3: $any+multiply-by-colour+notc + GL_LazyBind(3, GL_TEXTURE_2D, shaderstate.curtexnums->bump); //texture not used, its just to make sure the code leaves it enabled. + BE_SetPassBlendMode(3, PBM_MODULATE_PREV_COLOUR); + + //note we need 4 combiners in the first because we can't use the colour argument in the first without breaking the normals. + + for (i = 4; i < shaderstate.lastpasstmus; i++) + { + GL_LazyBind(i, GL_TEXTURE_2D, r_nulltex); + } + shaderstate.lastpasstmus = 4; + } + else + { + attr |= (1u<<(VATTR_LEG_TMU0)); + + //tmu0: $diffuse+multiply+regular tex coords + //multiplies by vertex colours + GL_LazyBind(0, GL_TEXTURE_2D, shaderstate.curtexnums->base); //texture not used, its just to make sure the code leaves it enabled. + BE_SetPassBlendMode(0, PBM_MODULATE); + qglClientActiveTextureARB(mtexid0 + 0); + GL_SelectVBO(shaderstate.sourcevbo->texcoord.gl.vbo); + qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord.gl.addr); + + for (i = 1; i < shaderstate.lastpasstmus; i++) + { + GL_LazyBind(i, GL_TEXTURE_2D, r_nulltex); + } + shaderstate.lastpasstmus = 1; + } + + shaderstate.colourarraytype = GL_FLOAT; + shaderstate.pendingcolourvbo = 0; + shaderstate.pendingcolourpointer = coloursarray; + + GL_SelectEBO(shaderstate.sourcevbo->indicies.gl.vbo); + GL_DeSelectProgram(); + BE_EnableShaderAttributes(attr); + + BE_SubmitMeshChain(); + + GL_LazyBind(1, GL_TEXTURE_2D, r_nulltex); + GL_LazyBind(2, GL_TEXTURE_2D, r_nulltex); + GL_LazyBind(3, GL_TEXTURE_2D, r_nulltex); +} +#endif + static void DrawMeshes(void) { const shaderpass_t *p; @@ -3149,6 +3271,11 @@ static void DrawMeshes(void) BE_RenderMeshProgram(shaderstate.shader_smap, shaderstate.shader_smap->passes); break; case BEM_LIGHT: + if (!shaderstate.inited_shader_rtlight) + { + BE_LegacyLighting(); + break; + } if (TEXVALID(shaderstate.lightcubemap)) BE_RenderMeshProgram(shaderstate.shader_cube, shaderstate.shader_cube->passes); else @@ -3830,7 +3957,7 @@ void GLBE_DrawWorld (qbyte *vis) } #ifdef RTLIGHTS - if (r_shadow_realtime_world.ival && gl_config.arb_shader_objects) + if (r_shadow_realtime_world.ival) shaderstate.identitylighting = r_shadow_realtime_world_lightmaps.value; else #endif diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 5e6c600da..8d3f7cfd9 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -66,9 +66,10 @@ void GLR_InitTextures (void) -#if 0 -qboolean GenerateNormalisationCubeMap() +#if 1 +texid_t GenerateNormalisationCubeMap(void) { + texid_t normalisationCubeMap; unsigned char data[32*32*3]; //some useful variables @@ -80,8 +81,8 @@ qboolean GenerateNormalisationCubeMap() int i, j; - normalisationCubeMap = GL_AllocNewTexture(); - GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); + normalisationCubeMap = R_AllocNewTexture("normalisationcubemap", 32, 32); + GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); //positive x bytePtr=data; @@ -228,7 +229,7 @@ qboolean GenerateNormalisationCubeMap() qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - return true; + return normalisationCubeMap; } diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index 894e7e628..c1c0eccad 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -2911,13 +2911,13 @@ void Sh_DrawLights(qbyte *vis, batch_t **mbatches) #ifdef GLQUAKE case QR_OPENGL: /*no stencil?*/ - if (!gl_config.arb_shader_objects) + /*if (!gl_config.arb_shader_objects) { Con_Printf("Missing GL extensions: switching off realtime lighting.\n"); r_shadow_realtime_world.ival = 0; r_shadow_realtime_dlight.ival = 0; return; - } + }*/ break; #endif #ifdef D3DQUAKE diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index ace20c281..94ec61ac8 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -753,6 +753,12 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) Con_DPrintf("GLSL available\n"); } + //we only use vao with shaders anyway. + if (!gl_config.arb_shader_objects) + { + qglGenVertexArrays = NULL; + qglBindVertexArray = NULL; + } if (GL_CheckExtension("GL_EXT_framebuffer_object")) { diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 013055790..25eb8389b 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -151,7 +151,8 @@ typedef struct shaderpass_s { PBM_ADD, PBM_DOTPRODUCT, PBM_REPLACE, - PBM_REPLACELIGHT + PBM_REPLACELIGHT, + PBM_MODULATE_PREV_COLOUR } blendmode; enum {