X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=e8a8156037aef0780dfd95d1b6858124ce24cd53;hb=7a33e14ce92c006199d3f6dc76c1afdcfcae30b4;hp=25b889239efaaaa370077db007b46baa674b334a;hpb=f841fb65de00253a0157b9d1763b34b7338cc5c8;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 25b88923..e8a81560 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -204,6 +204,7 @@ cvar_t r_water_hideplayer = {CVAR_CLIENT | CVAR_SAVE, "r_water_hideplayer", "0", cvar_t r_lerpsprites = {CVAR_CLIENT | CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"}; cvar_t r_lerpmodels = {CVAR_CLIENT | CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"}; +cvar_t r_nolerp_list = {CVAR_CLIENT | CVAR_SAVE, "r_nolerp_list", "progs/v_nail.mdl,progs/v_nail2.mdl,progs/flame.mdl,progs/flame2.mdl,progs/braztall.mdl,progs/brazshrt.mdl,progs/longtrch.mdl,progs/flame_pyre.mdl,progs/v_saw.mdl,progs/v_xfist.mdl,progs/h2stuff/newfire.mdl", "comma separated list of models that will not have their animations smoothed"}; cvar_t r_lerplightstyles = {CVAR_CLIENT | CVAR_SAVE, "r_lerplightstyles", "0", "enable animation smoothing on flickering lights"}; cvar_t r_waterscroll = {CVAR_CLIENT | CVAR_SAVE, "r_waterscroll", "1", "makes water scroll around, value controls how much"}; @@ -709,7 +710,7 @@ typedef struct r_glsl_permutation_s /// hash lookup data struct r_glsl_permutation_s *hashnext; unsigned int mode; - dpuint64 permutation; + uint64_t permutation; /// indicates if we have tried compiling this permutation already qboolean compiled; @@ -925,7 +926,7 @@ qboolean R_CompileShader_CheckStaticParms(void) shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \ else \ shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n" -static void R_CompileShader_AddStaticParms(unsigned int mode, dpuint64 permutation) +static void R_CompileShader_AddStaticParms(unsigned int mode, uint64_t permutation) { shaderstaticparms_count = 0; @@ -953,7 +954,7 @@ r_glsl_permutation_t *r_glsl_permutation; /// storage for permutations linked in the hash table memexpandablearray_t r_glsl_permutationarray; -static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, dpuint64 permutation) +static r_glsl_permutation_t *R_GLSL_FindPermutation(unsigned int mode, uint64_t permutation) { //unsigned int hashdepth = 0; unsigned int hashindex = (permutation * 0x1021) & (SHADERPERMUTATION_HASHSIZE - 1); @@ -1037,7 +1038,7 @@ static char *ShaderModeInfo_GetShaderText(shadermodeinfo_t *modeinfo, qboolean p return Mem_strdup(r_main_mempool, modeinfo->builtinstring); } -static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, dpuint64 permutation) +static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode, uint64_t permutation) { int i; int ubibind; @@ -1359,7 +1360,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode Mem_Free(sourcestring); } -static void R_SetupShader_SetPermutationGLSL(unsigned int mode, dpuint64 permutation) +static void R_SetupShader_SetPermutationGLSL(unsigned int mode, uint64_t permutation) { r_glsl_permutation_t *perm = R_GLSL_FindPermutation(mode, permutation); if (r_glsl_permutation != perm) @@ -1369,7 +1370,7 @@ static void R_SetupShader_SetPermutationGLSL(unsigned int mode, dpuint64 permuta { if (!r_glsl_permutation->compiled) { - Con_DPrintf("Compiling shader mode %u permutation %llx\n", mode, permutation); + Con_DPrintf("Compiling shader mode %u permutation %" PRIx64 "\n", mode, permutation); R_GLSL_CompilePermutation(perm, mode, permutation); } if (!r_glsl_permutation->program) @@ -1379,7 +1380,7 @@ static void R_SetupShader_SetPermutationGLSL(unsigned int mode, dpuint64 permuta for (i = 0;i < SHADERPERMUTATION_COUNT;i++) { // reduce i more quickly whenever it would not remove any bits - dpuint64 j = 1ll<<(SHADERPERMUTATION_COUNT-1-i); + uint64_t j = 1ll<<(SHADERPERMUTATION_COUNT-1-i); if (!(permutation & j)) continue; permutation -= j; @@ -1468,14 +1469,14 @@ static void R_GLSL_DumpShader_f(cmd_state_t *cmd) Con_Printf("%s written\n", modeinfo[mode].filename); } else - Con_Errorf("failed to write to %s\n", modeinfo[mode].filename); + Con_Printf(CON_ERROR "failed to write to %s\n", modeinfo[mode].filename); } } } void R_SetupShader_Generic(rtexture_t *t, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha) { - dpuint64 permutation = 0; + uint64_t permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; permutation |= SHADERPERMUTATION_VIEWTINT; @@ -1507,7 +1508,7 @@ void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy) void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb, qboolean skeletal) { - dpuint64 permutation = 0; + uint64_t permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; if (depthrgb) @@ -1581,7 +1582,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif // combination of texture, entity, light source, and fogging, only use the // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used - dpuint64 permutation = 0; + uint64_t permutation = 0; unsigned int mode = 0; int blendfuncflags; texture_t *t = rsurface.texture; @@ -1842,7 +1843,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif // lightmapped wall if ((t->glowtexture || t->backgroundglowtexture) && r_hdr_glowintensity.value > 0 && !gl_lightmaps.integer) permutation |= SHADERPERMUTATION_GLOW; - if (r_refdef.fogenabled) + if (r_refdef.fogenabled && !notrippy) permutation |= r_texture_fogheighttexture ? SHADERPERMUTATION_FOGHEIGHTTEXTURE : (r_refdef.fogplaneviewabove ? SHADERPERMUTATION_FOGOUTSIDE : SHADERPERMUTATION_FOGINSIDE); if (t->colormapping) permutation |= SHADERPERMUTATION_COLORMAPPING; @@ -1914,7 +1915,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif } if(!(blendfuncflags & BLENDFUNC_ALLOWS_ANYFOG)) permutation &= ~(SHADERPERMUTATION_FOGHEIGHTTEXTURE | SHADERPERMUTATION_FOGOUTSIDE | SHADERPERMUTATION_FOGINSIDE); - if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA) + if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACKALPHA && !notrippy) permutation |= SHADERPERMUTATION_FOGALPHAHACK; switch(vid.renderpath) { @@ -1965,7 +1966,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Diffuse, t->render_rtlight_diffuse[0], t->render_rtlight_diffuse[1], t->render_rtlight_diffuse[2]); if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3f(r_glsl_permutation->loc_LightColor, 1, 1, 1); // DEPRECATED - if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, t->render_modellight_lightdir[0], t->render_modellight_lightdir[1], t->render_modellight_lightdir[2]); + if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3f(r_glsl_permutation->loc_LightDir, t->render_modellight_lightdir_local[0], t->render_modellight_lightdir_local[1], t->render_modellight_lightdir_local[2]); } else { @@ -1976,7 +1977,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3f(r_glsl_permutation->loc_DeferredMod_Specular, t->render_rtlight_specular[0], t->render_rtlight_specular[1], t->render_rtlight_specular[2]); } // additive passes are only darkened by fog, not tinted - if (r_glsl_permutation->loc_FogColor >= 0) + if (r_glsl_permutation->loc_FogColor >= 0 && !notrippy) { if(blendfuncflags & BLENDFUNC_ALLOWS_FOG_HACK0) qglUniform3f(r_glsl_permutation->loc_FogColor, 0, 0, 0); @@ -2037,7 +2038,7 @@ void R_SetupShader_Surface(const float rtlightambient[3], const float rtlightdif if (r_glsl_permutation->loc_OffsetMapping_LodDistance >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_LodDistance, r_glsl_offsetmapping_lod_distance.integer * r_refdef.view.quality); if (r_glsl_permutation->loc_OffsetMapping_Bias >= 0) qglUniform1f(r_glsl_permutation->loc_OffsetMapping_Bias, t->offsetbias); if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f(r_glsl_permutation->loc_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); - if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); + if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/r_fb.screentexturewidth, 1.0f/r_fb.screentextureheight); if (r_glsl_permutation->loc_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegrid_state.matrix, &rsurface.matrix);Matrix4x4_ToArrayFloatGL(&tempmatrix, m16f);qglUniformMatrix4fv(r_glsl_permutation->loc_BounceGridMatrix, 1, false, m16f);} if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegrid_state.intensity*r_refdef.view.colorscale); if (r_glsl_permutation->loc_LightGridMatrix >= 0 && r_refdef.scene.worldmodel) @@ -2109,7 +2110,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) // combination of texture, entity, light source, and fogging, only use the // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used - dpuint64 permutation = 0; + uint64_t permutation = 0; unsigned int mode = 0; const float *lightcolorbase = rtlight->currentcolor; float ambientscale = rtlight->ambientscale; @@ -2158,7 +2159,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) if (r_glsl_permutation->loc_ShadowMap_Parameters >= 0) qglUniform4f( r_glsl_permutation->loc_ShadowMap_Parameters , r_shadow_lightshadowmap_parameters[0], r_shadow_lightshadowmap_parameters[1], r_shadow_lightshadowmap_parameters[2], r_shadow_lightshadowmap_parameters[3]); if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1f( r_glsl_permutation->loc_SpecularPower , (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); if (r_glsl_permutation->loc_ScreenToDepth >= 0) qglUniform2f( r_glsl_permutation->loc_ScreenToDepth , r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); - if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height); + if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/r_fb.screentexturewidth, 1.0f/r_fb.screentextureheight); if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture ); if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture ); @@ -2950,10 +2951,18 @@ static int componentorder[4] = {0, 1, 2, 3}; static rtexture_t *R_LoadCubemap(const char *basename) { - int i, j, cubemapsize; + int i, j, cubemapsize, forcefilter; unsigned char *cubemappixels, *image_buffer; rtexture_t *cubemaptexture; char name[256]; + + // HACK: if the cubemap name starts with a !, the cubemap is nearest-filtered + forcefilter = TEXF_FORCELINEAR; + if (basename && basename[0] == '!') + { + basename++; + forcefilter = TEXF_FORCENEAREST; + } // must start 0 so the first loadimagepixels has no requested width/height cubemapsize = 0; cubemappixels = NULL; @@ -2996,7 +3005,7 @@ static rtexture_t *R_LoadCubemap(const char *basename) if (developer_loading.integer) Con_Printf("loading cubemap \"%s\"\n", basename); - cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer && gl_texturecompression.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, vid.sRGB3D ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer && gl_texturecompression.integer ? TEXF_COMPRESS : 0) | forcefilter | TEXF_CLAMP, -1, NULL); Mem_Free(cubemappixels); } else @@ -3268,8 +3277,8 @@ void GL_Main_Init(void) r_main_mempool = Mem_AllocPool("Renderer", 0, NULL); R_InitShaderModeInfo(); - Cmd_AddCommand(&cmd_client, "r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed"); - Cmd_AddCommand(&cmd_client, "r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl"); + Cmd_AddCommand(CMD_CLIENT, "r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed"); + Cmd_AddCommand(CMD_CLIENT, "r_glsl_dumpshader", R_GLSL_DumpShader_f, "dumps the engine internal default.glsl shader into glsl/default.glsl"); // FIXME: the client should set up r_refdef.fog stuff including the fogmasktable if (gamemode == GAME_NEHAHRA) { @@ -3412,6 +3421,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_lerpsprites); Cvar_RegisterVariable(&r_lerpmodels); + Cvar_RegisterVariable(&r_nolerp_list); Cvar_RegisterVariable(&r_lerplightstyles); Cvar_RegisterVariable(&r_waterscroll); Cvar_RegisterVariable(&r_bloom); @@ -4138,8 +4148,8 @@ static void R_View_UpdateEntityVisible (void) { samples = ent->last_trace_visibility == 0 ? r_cullentities_trace_tempentitysamples.integer : r_cullentities_trace_samples.integer; if (R_CanSeeBox(samples, r_cullentities_trace_eyejitter.value, r_cullentities_trace_enlarge.value, r_cullentities_trace_expand.value, r_cullentities_trace_pad.value, r_refdef.view.origin, ent->mins, ent->maxs)) - ent->last_trace_visibility = realtime; - if (ent->last_trace_visibility < realtime - r_cullentities_trace_delay.value) + ent->last_trace_visibility = host.realtime; + if (ent->last_trace_visibility < host.realtime - r_cullentities_trace_delay.value) r_refdef.viewcache.entityvisible[i] = 0; } } @@ -4631,7 +4641,7 @@ void R_RenderTarget_FreeUnused(qboolean force) // free resources for rendertargets that have not been used for a while // (note: this check is run after the frame render, so any targets used // this frame will not be affected even at low framerates) - if (r && (realtime - r->lastusetime > 0.2 || force)) + if (r && (host.realtime - r->lastusetime > 0.2 || force)) { if (r->fbo) R_Mesh_DestroyFramebufferObject(r->fbo); @@ -4672,7 +4682,7 @@ r_rendertarget_t *R_RenderTarget_Get(int texturewidth, int textureheight, textyp for (i = 0; i < end; i++) { r = (r_rendertarget_t *)Mem_ExpandableArray_RecordAtIndex(&r_fb.rendertargets, i); - if (r && r->lastusetime != realtime && r->texturewidth == texturewidth && r->textureheight == textureheight && r->depthtextype == depthtextype && r->colortextype[0] == colortextype0 && r->colortextype[1] == colortextype1 && r->colortextype[2] == colortextype2 && r->colortextype[3] == colortextype3) + if (r && r->lastusetime != host.realtime && r->texturewidth == texturewidth && r->textureheight == textureheight && r->depthtextype == depthtextype && r->colortextype[0] == colortextype0 && r->colortextype[1] == colortextype1 && r->colortextype[2] == colortextype2 && r->colortextype[3] == colortextype3) break; } if (i == end) @@ -4695,13 +4705,13 @@ r_rendertarget_t *R_RenderTarget_Get(int texturewidth, int textureheight, textyp if (r->depthisrenderbuffer) r->depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, va(vabuf, sizeof(vabuf), "renderbuffer%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, r->depthtextype); else - r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, j, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + r->depthtexture = R_LoadTexture2D(r_main_texturepool, va(vabuf, sizeof(vabuf), "rendertarget%i_depth_type%i", i, (int)r->depthtextype), r->texturewidth, r->textureheight, NULL, r->depthtextype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); } r->fbo = R_Mesh_CreateFramebufferObject(r->depthtexture, r->colortexture[0], r->colortexture[1], r->colortexture[2], r->colortexture[3]); } r_refdef.stats[r_stat_rendertargets_used]++; r_refdef.stats[r_stat_rendertargets_pixels] += r->texturewidth * r->textureheight; - r->lastusetime = realtime; + r->lastusetime = host.realtime; R_CalcTexCoordsForView(0, 0, r->texturewidth, r->textureheight, r->texturewidth, r->textureheight, r->texcoord2f); return r; } @@ -4710,7 +4720,7 @@ static void R_Water_StartFrame(int viewwidth, int viewheight) { int waterwidth, waterheight; - if (vid.width > (int)vid.maxtexturesize_2d || vid.height > (int)vid.maxtexturesize_2d) + if (viewwidth > (int)vid.maxtexturesize_2d || viewheight > (int)vid.maxtexturesize_2d) return; // set waterwidth and waterheight to the water resolution that will be @@ -5178,9 +5188,9 @@ static void R_Bloom_StartFrame(void) // set bloomwidth and bloomheight to the bloom resolution that will be // used (often less than the screen resolution for faster rendering) - r_fb.bloomheight = bound(1, r_bloom_resolution.value * 0.75f, vid.height * 4); - r_fb.bloomwidth = r_fb.bloomheight * vid.width / vid.height; - r_fb.bloomwidth = bound(1, r_fb.bloomwidth, vid.width * 4); + r_fb.bloomheight = bound(1, r_bloom_resolution.value * 0.75f, screentextureheight); + r_fb.bloomwidth = r_fb.bloomheight * screentexturewidth / screentextureheight; + r_fb.bloomwidth = bound(1, r_fb.bloomwidth, screentexturewidth); r_fb.bloomwidth = bound(1, r_fb.bloomwidth, (int)vid.maxtexturesize_2d); r_fb.bloomheight = bound(1, r_fb.bloomheight, (int)vid.maxtexturesize_2d); @@ -5330,7 +5340,7 @@ static void R_Bloom_MakeTexture(void) static void R_BlendView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight) { - dpuint64 permutation; + uint64_t permutation; float uservecs[4][4]; rtexture_t *viewtexture; rtexture_t *bloomtexture; @@ -5457,7 +5467,7 @@ static void R_BlendView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *v if (r_glsl_permutation->loc_UserVec3 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec3 , uservecs[2][0], uservecs[2][1], uservecs[2][2], uservecs[2][3]); if (r_glsl_permutation->loc_UserVec4 >= 0) qglUniform4f(r_glsl_permutation->loc_UserVec4 , uservecs[3][0], uservecs[3][1], uservecs[3][2], uservecs[3][3]); if (r_glsl_permutation->loc_Saturation >= 0) qglUniform1f(r_glsl_permutation->loc_Saturation , r_glsl_saturation.value); - if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); + if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f(r_glsl_permutation->loc_PixelToScreenTexCoord, 1.0f/r_fb.screentexturewidth, 1.0f/r_fb.screentextureheight); if (r_glsl_permutation->loc_BloomColorSubtract >= 0) qglUniform4f(r_glsl_permutation->loc_BloomColorSubtract , r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 0.0f); if (r_glsl_permutation->loc_ColorFringe >= 0) qglUniform1f(r_glsl_permutation->loc_ColorFringe, r_colorfringe.value ); break; @@ -6721,7 +6731,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (q = 0; q < 3; q++) { t->render_glowmod[q] = rsurface.entity->glowmod[q]; - t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_lightdir_world[q] = q == 2; + t->render_modellight_lightdir_local[q] = q == 2; t->render_modellight_ambient[q] = 1; t->render_modellight_diffuse[q] = 0; t->render_modellight_specular[q] = 0; @@ -6740,7 +6751,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) { t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; t->render_modellight_ambient[q] = rsurface.entity->render_fullbright[q] * r_refdef.view.colorscale; - t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_lightdir_world[q] = q == 2; + t->render_modellight_lightdir_local[q] = q == 2; t->render_modellight_diffuse[q] = 0; t->render_modellight_specular[q] = 0; t->render_lightmap_ambient[q] = 0; @@ -6756,7 +6768,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (q = 0; q < 3; q++) { t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; - t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_lightdir_world[q] = q == 2; + t->render_modellight_lightdir_local[q] = q == 2; t->render_modellight_ambient[q] = 0; t->render_modellight_diffuse[q] = 0; t->render_modellight_specular[q] = 0; @@ -6774,7 +6787,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (q = 0; q < 3; q++) { t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; - t->render_modellight_lightdir[q] = rsurface.entity->render_modellight_lightdir[q]; + t->render_modellight_lightdir_world[q] = rsurface.entity->render_modellight_lightdir_world[q]; + t->render_modellight_lightdir_local[q] = rsurface.entity->render_modellight_lightdir_local[q]; t->render_modellight_ambient[q] = rsurface.entity->render_modellight_ambient[q] * r_refdef.view.colorscale; t->render_modellight_diffuse[q] = rsurface.entity->render_modellight_diffuse[q] * r_refdef.view.colorscale; t->render_modellight_specular[q] = rsurface.entity->render_modellight_specular[q] * r_refdef.view.colorscale; @@ -6791,7 +6805,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (q = 0; q < 3; q++) { t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; - t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_lightdir_world[q] = q == 2; + t->render_modellight_lightdir_local[q] = q == 2; t->render_modellight_ambient[q] = 0; t->render_modellight_diffuse[q] = 0; t->render_modellight_specular[q] = 0; @@ -6815,7 +6830,8 @@ texture_t *R_GetCurrentTexture(texture_t *t) for (q = 0; q < 3; q++) { t->render_glowmod[q] = rsurface.entity->render_glowmod[q] * r_refdef.view.colorscale; - t->render_modellight_lightdir[q] = q == 2; + t->render_modellight_lightdir_world[q] = q == 2; + t->render_modellight_lightdir_local[q] = q == 2; t->render_modellight_ambient[q] = 0; t->render_modellight_diffuse[q] = 0; t->render_modellight_specular[q] = 0; @@ -6942,7 +6958,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) // lightmaps mode looks bad with dlights using actual texturing, so turn // off the colormap and glossmap, but leave the normalmap on as it still // accurately represents the shading involved - if (gl_lightmaps.integer) + if (gl_lightmaps.integer && ent != &cl_meshentities[MESH_UI].render) { t->basetexture = r_texture_grey128; t->pantstexture = r_texture_black; @@ -8663,7 +8679,10 @@ void RSurf_SetupDepthAndCulling(void) static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_t **texturesurfacelist) { - int i, j; + int j; + const float *v; + float p[3], mins[3], maxs[3]; + int scissor[4]; // transparent sky would be ridiculous if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) return; @@ -8675,54 +8694,46 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_ // add the vertices of the surfaces to a world bounding box so we can scissor the sky render later if (r_sky_scissor.integer) { - RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ALLOWMULTIDRAW, texturenumsurfaces, texturesurfacelist); - for (i = 0; i < texturenumsurfaces; i++) + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + for (j = 0, v = rsurface.batchvertex3f + 3 * rsurface.batchfirstvertex; j < rsurface.batchnumvertices; j++, v += 3) { - const msurface_t *surf = texturesurfacelist[i]; - const float *v; - float p[3]; - float mins[3], maxs[3]; - int scissor[4]; - for (j = 0, v = rsurface.batchvertex3f + 3 * surf->num_firstvertex; j < surf->num_vertices; j++, v += 3) + Matrix4x4_Transform(&rsurface.matrix, v, p); + if (j > 0) { - Matrix4x4_Transform(&rsurface.matrix, v, p); - if (j > 0) - { - if (mins[0] > p[0]) mins[0] = p[0]; - if (mins[1] > p[1]) mins[1] = p[1]; - if (mins[2] > p[2]) mins[2] = p[2]; - if (maxs[0] < p[0]) maxs[0] = p[0]; - if (maxs[1] < p[1]) maxs[1] = p[1]; - if (maxs[2] < p[2]) maxs[2] = p[2]; - } - else - { - VectorCopy(p, mins); - VectorCopy(p, maxs); - } + if (mins[0] > p[0]) mins[0] = p[0]; + if (mins[1] > p[1]) mins[1] = p[1]; + if (mins[2] > p[2]) mins[2] = p[2]; + if (maxs[0] < p[0]) maxs[0] = p[0]; + if (maxs[1] < p[1]) maxs[1] = p[1]; + if (maxs[2] < p[2]) maxs[2] = p[2]; + } + else + { + VectorCopy(p, mins); + VectorCopy(p, maxs); } - if (!R_ScissorForBBox(mins, maxs, scissor)) + } + if (!R_ScissorForBBox(mins, maxs, scissor)) + { + if (skyscissor[2]) { - if (skyscissor[2]) + if (skyscissor[0] > scissor[0]) { - if (skyscissor[0] > scissor[0]) - { - skyscissor[2] += skyscissor[0] - scissor[0]; - skyscissor[0] = scissor[0]; - } - if (skyscissor[1] > scissor[1]) - { - skyscissor[3] += skyscissor[1] - scissor[1]; - skyscissor[1] = scissor[1]; - } - if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2]) - skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0]; - if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3]) - skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1]; + skyscissor[2] += skyscissor[0] - scissor[0]; + skyscissor[0] = scissor[0]; } - else - Vector4Copy(scissor, skyscissor); + if (skyscissor[1] > scissor[1]) + { + skyscissor[3] += skyscissor[1] - scissor[1]; + skyscissor[1] = scissor[1]; + } + if (skyscissor[0] + skyscissor[2] < scissor[0] + scissor[2]) + skyscissor[2] = scissor[0] + scissor[2] - skyscissor[0]; + if (skyscissor[1] + skyscissor[3] < scissor[1] + scissor[3]) + skyscissor[3] = scissor[1] + scissor[3] - skyscissor[1]; } + else + Vector4Copy(scissor, skyscissor); } } @@ -9470,6 +9481,8 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor surfaceindex = bih_surfaces[triangleindex]; surface = surfaces + surfaceindex; texture = surface->texture; + if (!texture) + continue; if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) continue; if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS) @@ -9488,6 +9501,8 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor continue; // skip transparent surfaces texture = surface->texture; + if (!texture) + continue; if (texture->currentmaterialflags & (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST | MATERIALFLAG_SKY | MATERIALFLAG_SHORTDEPTHRANGE | MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION)) continue; if (texture->surfaceflags & Q3SURFACEFLAG_NOMARKS)