From 5d25e9991f16bcb738c0cfb511dfd8273938ba6a Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 22 Nov 2010 02:03:28 +0000 Subject: [PATCH] Misc fixes+cleanups. r_loadlit 2 will now use a few more cpu cores to get the job done, if it can. Fixes the menu background shader that I broke. Shader parser accepts cvars in more places. d3d+gl now share common conwidth calcs code, fixing d3d issues. d3d supports more backend features (no more gun in walls). show_fps calcs the framerate itself, so is more accurate in regard to frame times, regardless of how much I break other stuff. Now attempts to sleep a little between frames, to reduce cpu load and electricity (important on laptops maybe). cl_netfps will now default to 100.Enabling independant physics by default. The framerate defaults to a max 500, to avoid too many issues with too small time deltas. You can still set it higher if you wish. Enable voice chat by default (sorry moodles!). git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3668 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_input.c | 4 +- engine/client/cl_main.c | 25 +++-- engine/client/cl_screen.c | 35 ++++--- engine/client/quakedef.h | 2 +- engine/client/r_2d.c | 113 +++++++++++++++++++++ engine/client/r_surf.c | 45 +++++---- engine/client/sys_win.c | 21 +--- engine/common/bothdefs.h | 2 +- engine/d3d/d3d_backend.c | 69 +++++++++++-- engine/d3d/vid_d3d.c | 31 +----- engine/gl/gl_backend.c | 12 ++- engine/gl/gl_model.c | 63 +++++++++--- engine/gl/gl_rmain.c | 7 +- engine/gl/gl_rmisc.c | 3 - engine/gl/gl_screen.c | 105 ------------------- engine/gl/gl_shader.c | 207 +++++++++++++++++++++++--------------- engine/gl/gl_vidcommon.c | 10 +- engine/gl/glquake.h | 1 + 18 files changed, 447 insertions(+), 308 deletions(-) diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 54b756dfc..9094340f6 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -33,7 +33,7 @@ cvar_t cl_nodelta = CVAR("cl_nodelta","0"); cvar_t cl_c2spps = CVAR("cl_c2spps", "0"); cvar_t cl_c2sImpulseBackup = SCVAR("cl_c2sImpulseBackup","3"); -cvar_t cl_netfps = CVAR("cl_netfps", "0"); +cvar_t cl_netfps = CVAR("cl_netfps", "100"); cvar_t cl_sparemsec = CVARC("cl_sparemsec", "10", CL_SpareMsec_Callback); cvar_t cl_queueimpulses = CVAR("cl_queueimpulses", "0"); cvar_t cl_smartjump = CVAR("cl_smartjump", "1"); @@ -899,7 +899,7 @@ float CL_FilterTime (double time, float wantfps) //now returns the extra time no } if (time < 1000 / fps) - return false; + return 0; return time - (1000 / fps); } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 2d9d014b9..3fc0be762 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -47,7 +47,7 @@ cvar_t cl_shownet = SCVAR("cl_shownet","0"); // can be 0, 1, or 2 cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback); cvar_t cl_hudswap = CVARF("cl_hudswap", "0", CVAR_ARCHIVE); -cvar_t cl_maxfps = CVARF("cl_maxfps", "1000", CVAR_ARCHIVE); +cvar_t cl_maxfps = CVARF("cl_maxfps", "500", CVAR_ARCHIVE); cvar_t cl_nopext = CVARF("cl_nopext", "0", CVAR_ARCHIVE); cvar_t cl_pext_mask = CVAR("cl_pext_mask", "0xffffffff"); cvar_t cl_nolerp = CVAR("cl_nolerp", "2"); @@ -3311,7 +3311,7 @@ extern cvar_t cl_sparemsec; int nopacketcount; void SNDDMA_SetUnderWater(qboolean underwater); float CL_FilterTime (double time, float wantfps); -void Host_Frame (double time) +float Host_Frame (double time) { static double time1 = 0; static double time2 = 0; @@ -3324,7 +3324,7 @@ void Host_Frame (double time) RSpeedLocals(); if (setjmp (host_abort) ) - return; // something bad happened, or the server disconnected + return 0; // something bad happened, or the server disconnected realframetime = time = Media_TweekCaptureFrameTime(time); @@ -3375,15 +3375,22 @@ void Host_Frame (double time) if ((cl_netfps.value>0 || cls.demoplayback || cl_indepphysics.ival)) { //limit the fps freely, and expect the netfps to cope. if (cl_maxfps.ival > 0) - if ((realtime - oldrealtime) < 1/cl_maxfps.value) - return; + { +// realtime += spare/1000; //don't use it all! + spare = CL_FilterTime((realtime - oldrealtime)*1000, cl_maxfps.value); + if (!spare) + return 1; + +// realtime -= spare/1000; //don't use it all! + } } else { + float maxfps = (cl_maxfps.ival>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value; realtime += spare/1000; //don't use it all! - spare = CL_FilterTime((realtime - oldrealtime)*1000, (cl_maxfps.ival>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value); + spare = CL_FilterTime((realtime - oldrealtime)*1000, maxfps); if (!spare) - return; + return 1; if (spare < 0 || cls.state < ca_onserver) spare = 0; //uncapped. if (spare > cl_sparemsec.ival) @@ -3422,7 +3429,7 @@ void Host_Frame (double time) #ifndef CLIENTONLY if (isDedicated) //someone changed it. - return; + return true; #endif cls.framecount++; @@ -3522,6 +3529,8 @@ void Host_Frame (double time) CL_QTVPoll(); TP_UpdateAutoStatus(); + + return 0; } static void simple_crypt(char *buf, int len) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 875d5780f..6e9bf68ec 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1199,7 +1199,8 @@ void SCR_StringXY(char *str, float x, float y) void SCR_DrawFPS (void) { extern cvar_t show_fps; - static double lastframetime; + static double lastupdatetime; + static double lastsystemtime; double t; extern int fps_count; static float lastfps; @@ -1209,16 +1210,20 @@ void SCR_DrawFPS (void) int sfps, frame; qboolean usemsecs = false; + float frametime; + if (!show_fps.ival) return; t = Sys_DoubleTime(); - if ((t - lastframetime) >= 1.0) + if ((t - lastupdatetime) >= 1.0) { - lastfps = fps_count/(t - lastframetime); + lastfps = fps_count/(t - lastupdatetime); fps_count = 0; - lastframetime = t; + lastupdatetime = t; } + frametime = t - lastsystemtime; + lastsystemtime = t; sfps = show_fps.ival; if (sfps < 0) @@ -1230,39 +1235,39 @@ void SCR_DrawFPS (void) switch (sfps) { case 2: // lowest FPS, highest MS encountered - if (lastfps > 1/host_frametime) + if (lastfps > 1/frametime) { - lastfps = 1/host_frametime; + lastfps = 1/frametime; fps_count = 0; - lastframetime = t; + lastupdatetime = t; } break; case 3: // highest FPS, lowest MS encountered - if (lastfps < 1/host_frametime) + if (lastfps < 1/frametime) { - lastfps = 1/host_frametime; + lastfps = 1/frametime; fps_count = 0; - lastframetime = t; + lastupdatetime = t; } break; case 4: // immediate FPS/MS - lastfps = 1/host_frametime; - lastframetime = t; + lastfps = 1/frametime; + lastupdatetime = t; break; #ifdef GLQUAKE case 5: if (qrenderer == QR_OPENGL) - GLR_FrameTimeGraph((int)(1000.0*2*host_frametime)); + GLR_FrameTimeGraph((int)(1000.0*2*frametime)); break; case 7: if (qrenderer == QR_OPENGL) - GLR_FrameTimeGraph((int)(1000.0*1*host_frametime)); + GLR_FrameTimeGraph((int)(1000.0*1*frametime)); break; #endif case 6: { float mean, deviation; - deviationtimes[deviationframe++&63] = host_frametime*1000; + deviationtimes[deviationframe++&63] = frametime*1000; mean = 0; for (frame = 0; frame < 64; frame++) { diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index ff5febb64..17cb9ec34 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -250,7 +250,7 @@ void Host_Shutdown(void); NORETURN void VARGS Host_Error (char *error, ...) LIKEPRINTF(1); NORETURN void VARGS Host_EndGame (char *message, ...) LIKEPRINTF(1); qboolean Host_SimulationTime(float time); -void Host_Frame (double time); +float Host_Frame (double time); void Host_Quit_f (void); void VARGS Host_ClientCommands (char *fmt, ...) LIKEPRINTF(1); void Host_ShutdownServer (qboolean crash); diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index a1b7a62ba..8294dbda8 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -23,7 +23,12 @@ extern cvar_t gl_conback; extern cvar_t gl_font; extern cvar_t gl_contrast; extern cvar_t vid_conautoscale; +extern cvar_t vid_conheight; +extern cvar_t vid_conwidth; void R2D_Font_Callback(struct cvar_s *var, char *oldvalue); +void R2D_Conautoscale_Callback(struct cvar_s *var, char *oldvalue); +void R2D_Conheight_Callback(struct cvar_s *var, char *oldvalue); +void R2D_Conwidth_Callback(struct cvar_s *var, char *oldvalue); //We need this for minor things though, so we'll just use the slow accurate method. //this is unlikly to be called too often. @@ -122,6 +127,9 @@ void R2D_Init(void) ); Cvar_Hook(&gl_font, R2D_Font_Callback); + Cvar_Hook(&vid_conautoscale, R2D_Conautoscale_Callback); + Cvar_Hook(&vid_conheight, R2D_Conheight_Callback); + Cvar_Hook(&vid_conwidth, R2D_Conwidth_Callback); Cvar_ForceCallback(&gl_conback); Cvar_ForceCallback(&vid_conautoscale); @@ -380,6 +388,111 @@ void R2D_Font_Callback(struct cvar_s *var, char *oldvalue) font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, ""); } +// console size manipulation callbacks +void R2D_Console_Resize(void) +{ + extern cvar_t gl_font; + extern cvar_t vid_conwidth, vid_conheight; + int cwidth, cheight; + float xratio; + float yratio=0; + cwidth = vid_conwidth.value; + cheight = vid_conheight.value; + + xratio = vid_conautoscale.value; + if (xratio > 0) + { + char *s = strchr(vid_conautoscale.string, ' '); + if (s) + yratio = atof(s + 1); + + if (yratio <= 0) + yratio = xratio; + + xratio = 1 / xratio; + yratio = 1 / yratio; + + //autoscale overrides conwidth/height (without actually changing them) + cwidth = vid.pixelwidth; + cheight = vid.pixelheight; + } + else + { + xratio = 1; + yratio = 1; + } + + + if (!cwidth) + cwidth = vid.pixelwidth; + if (!cheight) + cheight = vid.pixelheight; + + cwidth*=xratio; + cheight*=yratio; + + if (cwidth < 320) + cwidth = 320; + if (cheight < 200) + cheight = 200; + + vid.width = cwidth; + vid.height = cheight; + + vid.recalc_refdef = true; + + if (font_tiny) + Font_Free(font_tiny); + font_tiny = NULL; + if (font_conchar) + Font_Free(font_conchar); + font_conchar = NULL; + + Cvar_ForceCallback(&gl_font); + +#ifdef PLUGINS + Plug_ResChanged(); +#endif +} + +void R2D_Conheight_Callback(struct cvar_s *var, char *oldvalue) +{ + if (var->value > 1536) //anything higher is unreadable. + { + Cvar_ForceSet(var, "1536"); + return; + } + if (var->value < 200 && var->value) //lower would be wrong + { + Cvar_ForceSet(var, "200"); + return; + } + + R2D_Console_Resize(); +} + +void R2D_Conwidth_Callback(struct cvar_s *var, char *oldvalue) +{ + //let let the user be too crazy + if (var->value > 2048) //anything higher is unreadable. + { + Cvar_ForceSet(var, "2048"); + return; + } + if (var->value < 320 && var->value) //lower would be wrong + { + Cvar_ForceSet(var, "320"); + return; + } + + R2D_Console_Resize(); +} + +void R2D_Conautoscale_Callback(struct cvar_s *var, char *oldvalue) +{ + R2D_Console_Resize(); +} + /* ============ diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 225f0ecd2..e0ec0f9a3 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2536,31 +2536,36 @@ void Surf_BuildLightmaps (void) if (cl.worldmodel->fromgame == fg_doom) return; //no lightmaps. - lightmap_bgra = (qrenderer == QR_DIRECT3D); + lightmap_bgra = true; - if (qrenderer == QR_DIRECT3D) + switch(qrenderer) { +#ifdef D3DQUAKE + case QR_DIRECT3D: + /*always bgra, hope your card supports it*/ lightmap_bytes = 4; lightmap_bgra = true; - } - else if (cl.worldmodel->fromgame == fg_quake3 || (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value) - { + break; +#endif +#ifdef GLQUAKE + case QR_OPENGL: + /*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/ lightmap_bgra = false; - lightmap_bytes = 3; - } - else - lightmap_bytes = 1; - - if (cl.worldmodel->fromgame == fg_quake3 && lightmap_bytes != 3 && lightmap_bytes != 4) - lightmap_bytes = 3; - - lightmap_bgra = true; - lightmap_bytes = 4; - - if (atof(qglGetString(GL_VERSION)) < 1.2) - { - lightmap_bgra = false; - lightmap_bytes = 3; + if (gl_config.glversion >= 1.2) + { + /*the more common case*/ + lightmap_bytes = 4; + lightmap_bgra = true; + } + else if (cl.worldmodel->fromgame == fg_quake3 || (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value) + { + lightmap_bgra = false; + lightmap_bytes = 3; + } + else + lightmap_bytes = 1; + break; +#endif } for (j=1 ; j 0) + Sleep(sleeptime); #else Sys_Error("wut?"); #endif diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index e83b33ae5..c47c365cd 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -199,7 +199,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PSET_CLASSIC //#define PSET_DARKPLACES - //#define VOICECHAT //not added yet. + #define VOICECHAT //not added yet. //these things were moved to plugins. #endif diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index c30a24645..d55ddf1c7 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -334,6 +334,27 @@ static void BE_ApplyTMUState(unsigned int tu, unsigned int flags) static void D3DBE_ApplyShaderBits(unsigned int bits) { unsigned int delta; + + if (shaderstate.flags & ~BEF_PUSHDEPTH) + { + if (shaderstate.flags & BEF_FORCEADDITIVE) + bits = (bits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) + | (SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE); + else if ((shaderstate.flags & BEF_FORCETRANSPARENT) && !(bits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/ + bits = (bits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) + | (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + + if (shaderstate.flags & BEF_FORCENODEPTH) /*EF_NODEPTHTEST dp extension*/ + bits |= SBITS_MISC_NODEPTHTEST; + else + { + if (shaderstate.flags & BEF_FORCEDEPTHTEST) + bits &= ~SBITS_MISC_NODEPTHTEST; + if (shaderstate.flags & BEF_FORCEDEPTHWRITE) + bits |= SBITS_MISC_DEPTHWRITE; + } + } + delta = bits ^ shaderstate.shaderbits; if (!delta) return; @@ -573,9 +594,18 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass) IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); -// IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + if (shaderstate.flags & (BEF_FORCETRANSPARENT | BEF_FORCEADDITIVE)) + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + } + else + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + // IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + } break; case GL_ADD: IDirect3DDevice9_SetTextureStageState(pD3DDev9, tu, D3DTSS_COLORARG1, D3DTA_TEXTURE); @@ -765,8 +795,23 @@ static void alphagenbyte(const shaderpass_t *pass, int cnt, const byte_vec4_t *s { default: case ALPHA_GEN_IDENTITY: - while(cnt--) - dst[cnt][3] = 255; + if (shaderstate.flags & BEF_FORCETRANSPARENT) + { + f = shaderstate.curentity->shaderRGBAf[3]; + if (f < 0) + t = 0; + else if (f >= 1) + t = 255; + else + t = f*255; + while(cnt--) + dst[cnt][3] = t; + } + else + { + while(cnt--) + dst[cnt][3] = 255; + } break; case ALPHA_GEN_CONST: @@ -1865,15 +1910,19 @@ static void BE_RotateForEntity (const entity_t *e, const model_t *mod) Matrix4_Multiply(mv, Matrix4_NewRotation(-90, 1, 0, 0), iv); Matrix4_Multiply(iv, Matrix4_NewRotation(90, 0, 0, 1), mv); - m[2] *= 0.1; - m[6] *= 0.1; - m[10] *= 0.1; IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)mv); } else { IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m); } + + { + D3DVIEWPORT9 vport; + IDirect3DDevice9_GetViewport(pD3DDev9, &vport); + vport.MaxZ = (e->flags & Q2RF_DEPTHHACK)?0.333:1; + IDirect3DDevice9_SetViewport(pD3DDev9, &vport); + } } void BE_SubmitBatch(batch_t *batch) @@ -1881,9 +1930,6 @@ void BE_SubmitBatch(batch_t *batch) shaderstate.nummeshes = batch->meshes - batch->firstmesh; if (!shaderstate.nummeshes) return; - //FIXME: Why does this seem to work in GL? - if (batch->shader->flags & SHADER_FLARE) - return; if (shaderstate.curentity != batch->ent) { BE_RotateForEntity(batch->ent, batch->ent->model); @@ -1892,6 +1938,7 @@ void BE_SubmitBatch(batch_t *batch) shaderstate.meshlist = batch->mesh + batch->firstmesh; shaderstate.curshader = batch->shader; shaderstate.curtexnums = batch->skin; + shaderstate.flags = batch->flags; if (batch->lightmap < 0) shaderstate.curlightmap = r_nulltex; else diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index d8b9bd28e..34b6389f6 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -344,11 +344,10 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA case WM_SIZE: if (!vid_initializing) { + extern cvar_t vid_conautoscale, vid_conwidth; // force width/height to be updated //vid.pixelwidth = window_rect.right - window_rect.left; //vid.pixelheight = window_rect.bottom - window_rect.top; -// Cvar_ForceCallback(&vid_conautoscale); -// Cvar_ForceCallback(&vid_conwidth); D3DVID_UpdateWindowStatus(hWnd); BE_D3D_Reset(true); @@ -356,6 +355,9 @@ static LRESULT WINAPI D3D9_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA vid.pixelheight = d3dpp.BackBufferHeight = window_rect.bottom - window_rect.top; resetD3D9(); BE_D3D_Reset(false); + + Cvar_ForceCallback(&vid_conautoscale); + Cvar_ForceCallback(&vid_conwidth); } break; @@ -876,30 +878,7 @@ static void (D3D9_SCR_UpdateScreen) (void) return; // not initialized yet } -#pragma message("Fixme: remove the code from here...") - { - unsigned int ow = vid.width, oh = vid.height; - extern cvar_t vid_conwidth, vid_conheight, vid_conautoscale; - if (vid_conautoscale.value) - { - vid.width = vid.pixelwidth*vid_conautoscale.value; - vid.height = vid.pixelheight*vid_conautoscale.value; - } - else - { - vid.width = vid_conwidth.value; - vid.height = vid_conheight.value; - } - - if (!vid.width) - vid.width = vid.pixelwidth; - if (!vid.height) - vid.height = vid.pixelheight; - - if (vid.width != ow || vid.height != oh) - vid.recalc_refdef = true; - } - + Shader_DoReload(); #ifdef VM_UI uimenu = UI_MenuState(); diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 435a4a7d1..a57ec4eaf 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -2227,7 +2227,17 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas qglUniform1fARB(s->progparm[i].handle[perm], ((cvar_t*)s->progparm[i].pval)->value); break; case SP_CVAR3F: -// qglUniform3fvARB(uniformloc, 1, specialvec); + { + cvar_t *var = (cvar_t*)s->progparm[i].pval; + char *vs = var->string; + vs = COM_Parse(vs); + param3[0] = atof(com_token); + vs = COM_Parse(vs); + param3[1] = atof(com_token); + vs = COM_Parse(vs); + param3[2] = atof(com_token); + qglUniform3fvARB(s->progparm[i].handle[perm], 1, param3); + } break; default: diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 666c9f4f5..7e9ebba2b 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -181,17 +181,24 @@ void RMod_BlockTextureColour_f (void) #if defined(RUNTIMELIGHTING) && defined(MULTITHREAD) -void *relightthread; +void *relightthread[8]; +unsigned int relightthreads; volatile qboolean wantrelight; int RelightThread(void *arg) { - while (wantrelight && relitsurface < lightmodel->numsurfaces) + int surf; + while (wantrelight) { - LightFace(relitsurface); - lightmodel->surfaces[relitsurface].cached_dlight = -1; - - relitsurface++; +#ifdef _WIN32 + surf = InterlockedIncrement(&relitsurface); +#else + surf = relightthreads++; +#endif + if (surf >= lightmodel->numsurfaces) + break; + LightFace(surf); + lightmodel->surfaces[surf].cached_dlight = -1; } return 0; } @@ -207,10 +214,33 @@ void RMod_Think (void) return; } #ifdef MULTITHREAD - if (!relightthread) + if (!relightthreads) { + int i; +#ifdef _WIN32 + HANDLE me = GetCurrentProcess(); + DWORD_PTR proc, sys; + int t; + /*count cpus*/ + GetProcessAffinityMask(me, &proc, &sys); + relightthreads = 0; + for (i = 0; i < sizeof(proc)*8; i++) + if (proc & (1u< sizeof(relightthread)/sizeof(relightthread[0])) + relightthreads = sizeof(relightthread)/sizeof(relightthread[0]); wantrelight = true; - relightthread = Sys_CreateThread(RelightThread, lightmodel, 0); + for (i = 0; i < relightthreads; i++) + relightthread[i] = Sys_CreateThread(RelightThread, lightmodel, 0); } #else LightFace(relitsurface); @@ -226,9 +256,14 @@ void RMod_Think (void) #ifdef MULTITHREAD if (relightthread) { + int i; wantrelight = false; - Sys_WaitOnThread(relightthread); - relightthread = NULL; + for (i = 0; i < relightthreads; i++) + { + Sys_WaitOnThread(relightthread[i]); + relightthread[i] = NULL; + } + relightthreads = 0; } #endif @@ -267,8 +302,12 @@ void RMod_ClearAll (void) if (relightthread) { wantrelight = false; - Sys_WaitOnThread(relightthread); - relightthread = NULL; + for (i = 0; i < relightthreads; i++) + { + Sys_WaitOnThread(relightthread[i]); + relightthread[i] = NULL; + } + relightthreads = 0; } #endif lightmodel = NULL; diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 4951b972a..091c95ea7 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -271,9 +271,10 @@ void GL_InitFisheyeFov(void) void GL_InitSceneProcessingShaders_MenuTint(void) { extern cvar_t gl_menutint_shader; + if (gl_config.arb_shader_objects && gl_menutint_shader.ival) { - scenepp_mt_shader = R_RegisterShader("menutint", + scenepp_mt_shader = R_RegisterShader("menutint", "{\n" "glslprogram\n" "{\n" @@ -303,7 +304,7 @@ void GL_InitSceneProcessingShaders_MenuTint(void) float luminance = dot(lumfactors, texcolor);\ texcolor = vec3(luminance, luminance, luminance);\ texcolor *= colorparam;\ - texcolor = invert > 0 ? (invertvec - texcolor) : texcolor;\ + texcolor = (invert > 0) ? (invertvec - texcolor) : texcolor;\ gl_FragColor = vec4(texcolor, 1.0);\ }\n" "#endif\n" @@ -318,7 +319,7 @@ void GL_InitSceneProcessingShaders_MenuTint(void) "param rendertexturescale rendertexturescale\n" "}"); } - if (!scenepp_mt_shader) + else { scenepp_mt_shader = R_RegisterShader("menutint", "{\n" diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index 9f9c832a7..4397d9518 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -509,9 +509,6 @@ void GLR_Init (void) Cvar_Hook(&crosshairimage, GLCrosshairimage_Callback); Cvar_Hook(&crosshaircolor, GLCrosshaircolor_Callback); Cvar_Hook(&r_menutint, GLR_Menutint_Callback); - Cvar_Hook(&vid_conautoscale, GLVID_Conautoscale_Callback); - Cvar_Hook(&vid_conheight, GLVID_Conheight_Callback); - Cvar_Hook(&vid_conwidth, GLVID_Conwidth_Callback); // Cvar_Hook(&r_floorcolour, GLR_Floorcolour_Callback); // Cvar_Hook(&r_fastskycolour, GLR_Fastskycolour_Callback); // Cvar_Hook(&r_wallcolour, GLR_Wallcolour_Callback); diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index 64a408a6f..6334c9cbf 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -45,111 +45,6 @@ extern cvar_t scr_chatmodecvar; extern cvar_t vid_conautoscale; extern qboolean scr_con_forcedraw; -// console size manipulation callbacks -void GLVID_Console_Resize(void) -{ - extern cvar_t gl_font; - extern cvar_t vid_conwidth, vid_conheight; - int cwidth, cheight; - float xratio; - float yratio=0; - cwidth = vid_conwidth.value; - cheight = vid_conheight.value; - - xratio = vid_conautoscale.value; - if (xratio > 0) - { - char *s = strchr(vid_conautoscale.string, ' '); - if (s) - yratio = atof(s + 1); - - if (yratio <= 0) - yratio = xratio; - - xratio = 1 / xratio; - yratio = 1 / yratio; - - //autoscale overrides conwidth/height (without actually changing them) - cwidth = vid.pixelwidth; - cheight = vid.pixelheight; - } - else - { - xratio = 1; - yratio = 1; - } - - - if (!cwidth) - cwidth = vid.pixelwidth; - if (!cheight) - cheight = vid.pixelheight; - - cwidth*=xratio; - cheight*=yratio; - - if (cwidth < 320) - cwidth = 320; - if (cheight < 200) - cheight = 200; - - vid.width = cwidth; - vid.height = cheight; - - vid.recalc_refdef = true; - - if (font_tiny) - Font_Free(font_tiny); - font_tiny = NULL; - if (font_conchar) - Font_Free(font_conchar); - font_conchar = NULL; - - Cvar_ForceCallback(&gl_font); - -#ifdef PLUGINS - Plug_ResChanged(); -#endif -} - -void GLVID_Conheight_Callback(struct cvar_s *var, char *oldvalue) -{ - if (var->value > 1536) //anything higher is unreadable. - { - Cvar_ForceSet(var, "1536"); - return; - } - if (var->value < 200 && var->value) //lower would be wrong - { - Cvar_ForceSet(var, "200"); - return; - } - - GLVID_Console_Resize(); -} - -void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue) -{ - //let let the user be too crazy - if (var->value > 2048) //anything higher is unreadable. - { - Cvar_ForceSet(var, "2048"); - return; - } - if (var->value < 320 && var->value) //lower would be wrong - { - Cvar_ForceSet(var, "320"); - return; - } - - GLVID_Console_Resize(); -} - -void GLVID_Conautoscale_Callback(struct cvar_s *var, char *oldvalue) -{ - GLVID_Console_Resize(); -} - /* ================== SCR_UpdateScreen diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 8eb5e8bb8..a824e4514 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -319,16 +319,27 @@ static char *Shader_ParseSensString ( char **ptr ) return token; } -static float Shader_ParseFloat ( char **ptr ) +static float Shader_ParseFloat(char **ptr) { - if ( !ptr || !(*ptr) ) { + char *token; + if (!ptr || !(*ptr)) + { return 0; } - if ( !**ptr || **ptr == '}' ) { + if (!**ptr || **ptr == '}') + { return 0; } - return atof ( COM_ParseExt ( ptr, false ) ); + token = COM_ParseExt(ptr, false); + if (*token == '$') + { + cvar_t *var; + var = Cvar_FindVar(token+1); + if (var) + return var->value; + } + return atof(token); } static void Shader_ParseVector ( char **ptr, vec3_t v ) @@ -992,6 +1003,68 @@ static shaderkey_t shaderkeys[] = // =============================================================== +static qboolean ShaderPass_MapGen (shader_t *shader, shaderpass_t *pass, char *tname) +{ + if (!Q_stricmp (tname, "$lightmap")) + { + pass->tcgen = TC_GEN_LIGHTMAP; + pass->flags |= SHADER_PASS_LIGHTMAP | SHADER_PASS_NOMIPMAP; + pass->texgen = T_GEN_LIGHTMAP; + shader->flags |= SHADER_HASLIGHTMAP; + } + else if (!Q_stricmp (tname, "$deluxmap")) + { + pass->tcgen = TC_GEN_LIGHTMAP; + pass->flags |= SHADER_PASS_DELUXMAP | SHADER_PASS_NOMIPMAP; + pass->texgen = T_GEN_DELUXMAP; + } + else if (!Q_stricmp (tname, "$diffuse")) + { + pass->texgen = T_GEN_DIFFUSE; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$normalmap")) + { + pass->texgen = T_GEN_NORMALMAP; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$specular")) + { + pass->texgen = T_GEN_SPECULAR; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$fullbright")) + { + pass->texgen = T_GEN_FULLBRIGHT; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$upperoverlay")) + { + shader->flags |= SHADER_HASTOPBOTTOM; + pass->texgen = T_GEN_UPPEROVERLAY; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$loweroverlay")) + { + shader->flags |= SHADER_HASTOPBOTTOM; + pass->texgen = T_GEN_LOWEROVERLAY; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (tname, "$shadowmap")) + { + pass->texgen = T_GEN_SHADOWMAP; + pass->tcgen = TC_GEN_BASE; //FIXME: moo! + } + else if (!Q_stricmp (tname, "$currentrender")) + { + pass->texgen = T_GEN_CURRENTRENDER; + pass->tcgen = TC_GEN_BASE; //FIXME: moo! + } + else + return false; + return true; +} + static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr) { int flags; @@ -1000,75 +1073,13 @@ static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr) pass->anim_frames[0] = r_nulltex; token = Shader_ParseString (ptr); - if (!Q_stricmp (token, "$lightmap")) - { - pass->tcgen = TC_GEN_LIGHTMAP; - pass->flags |= SHADER_PASS_LIGHTMAP | SHADER_PASS_NOMIPMAP; - pass->texgen = T_GEN_LIGHTMAP; - shader->flags |= SHADER_HASLIGHTMAP; - } - else if (!Q_stricmp (token, "$deluxmap")) - { - pass->tcgen = TC_GEN_LIGHTMAP; - pass->flags |= SHADER_PASS_DELUXMAP | SHADER_PASS_NOMIPMAP; - pass->texgen = T_GEN_DELUXMAP; - } - else if (!Q_stricmp (token, "$diffuse")) - { - pass->texgen = T_GEN_DIFFUSE; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$normalmap")) - { - pass->texgen = T_GEN_NORMALMAP; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$specular")) - { - pass->texgen = T_GEN_SPECULAR; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$fullbright")) - { - pass->texgen = T_GEN_FULLBRIGHT; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$upperoverlay")) - { - shader->flags |= SHADER_HASTOPBOTTOM; - pass->texgen = T_GEN_UPPEROVERLAY; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$loweroverlay")) - { - shader->flags |= SHADER_HASTOPBOTTOM; - pass->texgen = T_GEN_LOWEROVERLAY; - pass->tcgen = TC_GEN_BASE; - } - else if (!Q_stricmp (token, "$shadowmap")) - { - pass->texgen = T_GEN_SHADOWMAP; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! - } - else if (!Q_stricmp (token, "$currentrender")) - { - pass->texgen = T_GEN_CURRENTRENDER; - pass->tcgen = TC_GEN_BASE; //FIXME: moo! - } - else + if (!ShaderPass_MapGen(shader, pass, token)) { + pass->texgen = T_GEN_SINGLEMAP; flags = Shader_SetImageFlags (shader); pass->tcgen = TC_GEN_BASE; pass->anim_frames[0] = Shader_FindImage (token, flags); - - /* - if (!pass->anim_frames[0]) - { - pass->anim_frames[0] = missing_texture; - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token ); - } - */ } } @@ -1117,18 +1128,22 @@ static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **pt char *token; token = Shader_ParseString (ptr); - flags = Shader_SetImageFlags (shader); - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP); - pass->texgen = T_GEN_SINGLEMAP; - pass->flags |= SHADER_PASS_CLAMP; - - if (!TEXVALID(pass->anim_frames[0])) + if (!ShaderPass_MapGen(shader, pass, token)) { - pass->anim_frames[0] = missing_texture; - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token); - } + flags = Shader_SetImageFlags (shader); + + pass->tcgen = TC_GEN_BASE; + pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP); + pass->texgen = T_GEN_SINGLEMAP; + + if (!TEXVALID(pass->anim_frames[0])) + { + pass->anim_frames[0] = missing_texture; + Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token); + } + } + pass->flags |= SHADER_PASS_CLAMP; } static void Shaderpass_VideoMap (shader_t *shader, shaderpass_t *pass, char **ptr) @@ -2191,6 +2206,7 @@ void Shader_Finish (shader_t *s) if (!Q_stricmp (s->name, "flareShader")) { s->flags |= SHADER_FLARE; + s->flags |= SHADER_NODRAW; } if (!s->numpasses && !s->sort) @@ -2724,7 +2740,17 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args) if (!builtin && (*shortname == '*')) { //q1 water - if (r_fastturb.ival) + if (r_wateralpha.value == 0) + { + builtin = ( + "{\n" + "sort seethrough\n" + "surfaceparm nodraw\n" + "surfaceparm nodlight\n" + "}\n" + ); + } + else if (r_fastturb.ival) { builtin = ( "{\n" @@ -2796,14 +2822,29 @@ void Shader_DefaultBSPQ1(char *shortname, shader_t *s, const void *args) ); } #endif + else if (r_wateralpha.value < 1) + { + builtin = ( + "{\n" + "{\n" + "map $diffuse\n" + "tcmod turb 0 0 3 0.1\n" + "alphagen const $r_wateralpha\n" + "blendfunc blend\n" + "}\n" + "surfaceparm nodlight\n" + "}\n" + ); + } else { builtin = ( "{\n" "{\n" "map $diffuse\n" - "tcmod turb 0 0.01 0.5 0\n" + "tcmod turb 0 0 3 0.1\n" "}\n" + "surfaceparm nodlight\n" "}\n" ); } @@ -3016,6 +3057,8 @@ void Shader_DefaultBSPFlare(char *shortname, shader_t *s, const void *args) s->features = MF_STCOORDS|MF_COLORS; s->sort = SHADER_SORT_ADDITIVE; s->uses = 1; + + s->flags |= SHADER_NODRAW; } void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args) { @@ -3078,7 +3121,7 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs) "{\n" "nomipmaps\n" "{\n" - "map $diffuse\n" + "clampmap $diffuse\n" "rgbgen vertex\n" "alphagen vertex\n" "blendfunc gl_src_alpha gl_one_minus_src_alpha\n" @@ -3087,7 +3130,7 @@ void Shader_Default2D(char *shortname, shader_t *s, const void *genargs) "}\n" ); - s->defaulttextures.base = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP); + s->defaulttextures.base = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP|IF_CLAMP); if (!TEXVALID(s->defaulttextures.base)) { unsigned char data[4*4] = {0}; diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index c8a005b04..5ffe8f7b7 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -278,8 +278,6 @@ const char *gl_renderer; const char *gl_version; static const char *gl_extensions; -unsigned int gl_major_version; -unsigned int gl_minor_version; static unsigned int gl_num_extensions; @@ -763,6 +761,9 @@ GLint GLSlang_GetUniformLocation (int prog, char *name) //the vid routines have initialised a window, and now they are giving us a reference to some of of GetProcAddress to get pointers to the funcs. void GL_Init(void *(*getglfunction) (char *name)) { + unsigned int gl_major_version; + unsigned int gl_minor_version; + qglAlphaFunc = (void *)getglcore("glAlphaFunc"); qglBegin = (void *)getglcore("glBegin"); qglBlendFunc = (void *)getglcore("glBlendFunc"); @@ -895,9 +896,14 @@ void GL_Init(void *(*getglfunction) (char *name)) qglGetIntegerv(GL_MINOR_VERSION, &gl_minor_version); if (qglGetError()) { + gl_config.glversion = atof(gl_version); gl_major_version = 1; gl_minor_version = 1; } + else + { + gl_config.glversion = gl_major_version + (gl_minor_version/10.f); + } qglGetIntegerv(GL_NUM_EXTENSIONS, &gl_num_extensions); if (!qglGetError() && gl_num_extensions) { diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index cc5b38f9a..f82fa98d0 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -112,6 +112,7 @@ extern FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI; qboolean GL_CheckExtension(char *extname); typedef struct { + float glversion; qboolean tex_env_combine; qboolean nv_tex_env_combine4; qboolean env_add;