X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=31e10531fa24e0b9a2444b338fb7d66f410cd21e;hb=e7222a7d7b424087ddd359ded4554735f8da19fb;hp=4bdefc831534a406c4ec586b6c51977190e8216f;hpb=2af2aac721ea21992f0f3662aa00abfac790dc00;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 4bdefc83..31e10531 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -168,6 +168,10 @@ rtexture_t *r_texture_gammaramps; unsigned int r_texture_gammaramps_serial; //rtexture_t *r_texture_fogintensity; +unsigned int r_queries[R_MAX_OCCLUSION_QUERIES]; +unsigned int r_numqueries; +unsigned int r_maxqueries; + char r_qwskincache[MAX_SCOREBOARD][MAX_QPATH]; skinframe_t *r_qwskincache_skinframe[MAX_SCOREBOARD]; @@ -478,12 +482,12 @@ static const char *builtinshaderstring = "uniform vec3 Gamma;\n" "#endif\n" "//uncomment these if you want to use them:\n" -"// uniform vec4 UserVec1;\n" +"uniform vec4 UserVec1;\n" "// uniform vec4 UserVec2;\n" "// uniform vec4 UserVec3;\n" "// uniform vec4 UserVec4;\n" "// uniform float ClientTime;\n" -"// uniform vec2 PixelSize;\n" +"uniform vec2 PixelSize;\n" "void main(void)\n" "{\n" " gl_FragColor = texture2D(Texture_First, gl_TexCoord[0].xy);\n" @@ -495,7 +499,14 @@ static const char *builtinshaderstring = "#endif\n" "\n" "#ifdef USEPOSTPROCESSING\n" -"// add your own postprocessing here or make your own ifdef for it\n" +"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n" +"// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n" +" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.987688, -0.156434)) * UserVec1.y;\n" +" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.156434, -0.891007)) * UserVec1.y;\n" +" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.891007, -0.453990)) * UserVec1.y;\n" +" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2( 0.707107, 0.707107)) * UserVec1.y;\n" +" gl_FragColor += texture2D(Texture_First, gl_TexCoord[0].xy + PixelSize*UserVec1.x*vec2(-0.453990, 0.891007)) * UserVec1.y;\n" +" gl_FragColor /= (1 + 5 * UserVec1.y);\n" "#endif\n" "\n" "#ifdef USEGAMMARAMPS\n" @@ -1236,13 +1247,13 @@ static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice) } else if (!strcmp(filename, "glsl/default.glsl")) { - shaderstring = Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1); + shaderstring = (char *) Mem_Alloc(r_main_mempool, strlen(builtinshaderstring) + 1); memcpy(shaderstring, builtinshaderstring, strlen(builtinshaderstring) + 1); } return shaderstring; } -static void R_GLSL_CompilePermutation(shadermode_t mode, shaderpermutation_t permutation) +static void R_GLSL_CompilePermutation(unsigned int mode, unsigned int permutation) { int i; shadermodeinfo_t *modeinfo = shadermodeinfo + mode; @@ -1413,8 +1424,8 @@ static void R_GLSL_CompilePermutation(shadermode_t mode, shaderpermutation_t per void R_GLSL_Restart_f(void) { - shadermode_t mode; - shaderpermutation_t permutation; + unsigned int mode; + unsigned int permutation; for (mode = 0;mode < SHADERMODE_COUNT;mode++) for (permutation = 0;permutation < SHADERPERMUTATION_LIMIT;permutation++) if (r_glsl_permutations[mode][permutation].program) @@ -1446,7 +1457,7 @@ void R_GLSL_DumpShader_f(void) Con_Printf("glsl/default.glsl written\n"); } -void R_SetupShader_SetPermutation(shadermode_t mode, unsigned int permutation) +void R_SetupShader_SetPermutation(unsigned int mode, unsigned int permutation) { r_glsl_permutation_t *perm = &r_glsl_permutations[mode][permutation]; if (r_glsl_permutation != perm) @@ -1545,7 +1556,7 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used unsigned int permutation = 0; - shadermode_t mode = 0; + unsigned int mode = 0; // TODO: implement geometry-shader based shadow volumes someday if (r_glsl_offsetmapping.integer) { @@ -1727,7 +1738,7 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale); } if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2], rsurface.texture->lightmapcolor[3]); - if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value); + if (r_glsl_permutation->loc_GlowScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_GlowScale, r_hdr_glowintensity.value); // additive passes are only darkened by fog, not tinted if (r_glsl_permutation->loc_FogColor >= 0) { @@ -1787,13 +1798,14 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f #define SKINFRAME_HASH 1024 -struct +typedef struct { int loadsequence; // incremented each level change memexpandablearray_t array; skinframe_t *hash[SKINFRAME_HASH]; } -r_skinframe; +r_skinframe_t; +r_skinframe_t r_skinframe; void R_SkinFrame_PrepareForPurge(void) { @@ -1905,6 +1917,41 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid return item; } +#define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \ + { \ + unsigned long long avgcolor[5], wsum; \ + int pix, comp, w; \ + avgcolor[0] = 0; \ + avgcolor[1] = 0; \ + avgcolor[2] = 0; \ + avgcolor[3] = 0; \ + avgcolor[4] = 0; \ + wsum = 0; \ + for(pix = 0; pix < cnt; ++pix) \ + { \ + w = 0; \ + for(comp = 0; comp < 3; ++comp) \ + w += getpixel; \ + if(w) /* ignore perfectly black pixels because that is better for model skins */ \ + { \ + ++wsum; \ + /* comp = 3; -- not needed, comp is always 3 when we get here */ \ + w = getpixel; \ + for(comp = 0; comp < 3; ++comp) \ + avgcolor[comp] += getpixel * w; \ + avgcolor[3] += w; \ + } \ + /* comp = 3; -- not needed, comp is always 3 when we get here */ \ + avgcolor[4] += getpixel; \ + } \ + if(avgcolor[3] == 0) /* no pixels seen? even worse */ \ + avgcolor[3] = 1; \ + skinframe->avgcolor[0] = avgcolor[2] / (255.0 * avgcolor[3]); \ + skinframe->avgcolor[1] = avgcolor[1] / (255.0 * avgcolor[3]); \ + skinframe->avgcolor[2] = avgcolor[0] / (255.0 * avgcolor[3]); \ + skinframe->avgcolor[3] = avgcolor[4] / (255.0 * cnt); \ + } + skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int textureflags, qboolean complain, qboolean *has_alpha) { // FIXME: it should be possible to disable loading various layers using @@ -1921,7 +1968,6 @@ skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int texturefl int basepixels_width; int basepixels_height; skinframe_t *skinframe; - double avgcolor[5], w, wsum; *has_alpha = false; @@ -1981,34 +2027,8 @@ skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int texturefl } } - avgcolor[0] = 0; - avgcolor[1] = 0; - avgcolor[2] = 0; - avgcolor[3] = 0; - avgcolor[4] = 0; - wsum = 0; - for(j = 0; j < basepixels_width * basepixels_height * 4; j += 4) - { - w = (int)basepixels[j + 0] + (int)basepixels[j + 1] + (int)basepixels[j + 2]; // use this weight, so black pixels don't contribute (needed for model skins) - avgcolor[2] += basepixels[j + 0] * w; - avgcolor[1] += basepixels[j + 1] * w; - avgcolor[0] += basepixels[j + 2] * w; - avgcolor[3] += basepixels[j + 3] * w; - avgcolor[4] += basepixels[j + 3]; - wsum += w; - } - if(avgcolor[3] == 0) // just fully transparent pixels seen? bad luck... - avgcolor[3] = 255.0 * wsum; - if(avgcolor[3] == 0) // no pixels seen? even worse - avgcolor[3] = 1; - avgcolor[0] /= avgcolor[3]; - avgcolor[1] /= avgcolor[3]; - avgcolor[2] /= avgcolor[3]; - avgcolor[3] /= 255.0 * wsum; // to 0..1 range - skinframe->avgcolor[0] = avgcolor[0]; - skinframe->avgcolor[1] = avgcolor[1]; - skinframe->avgcolor[2] = avgcolor[2]; - skinframe->avgcolor[3] = avgcolor[4] / (basepixels_width * 255.0 * basepixels_height); + R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]); + //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); // _norm is the name used by tenebrae and has been adopted as standard if (loadnormalmap) @@ -2075,8 +2095,6 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co int i; unsigned char *temp1, *temp2; skinframe_t *skinframe; - double avgcolor[5], w, wsum; - int j; if (cls.state == ca_dedicated) return NULL; @@ -2128,34 +2146,8 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co } } - avgcolor[0] = 0; - avgcolor[1] = 0; - avgcolor[2] = 0; - avgcolor[3] = 0; - avgcolor[4] = 0; - wsum = 0; - for(j = 0; j < width * height * 4; j += 4) - { - w = (int)skindata[j + 0] + (int)skindata[j + 1] + (int)skindata[j + 2]; - avgcolor[2] += skindata[j + 0] * w; - avgcolor[1] += skindata[j + 1] * w; - avgcolor[0] += skindata[j + 2] * w; - avgcolor[3] += skindata[j + 3] * w; - avgcolor[4] += skindata[j + 3]; - wsum += w; - } - if(avgcolor[3] == 0) // just fully transparent pixels seen? bad luck... - avgcolor[3] = 255.0 * wsum; - if(avgcolor[3] == 0) // no pixels seen? even worse - avgcolor[3] = 1; - avgcolor[0] /= avgcolor[3]; - avgcolor[1] /= avgcolor[3]; - avgcolor[2] /= avgcolor[3]; - avgcolor[3] /= 255.0 * wsum; // to 0..1 range - skinframe->avgcolor[0] = avgcolor[0]; - skinframe->avgcolor[1] = avgcolor[1]; - skinframe->avgcolor[2] = avgcolor[2]; - skinframe->avgcolor[3] = avgcolor[4] / (width * 255.0 * height); + R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, skindata[4 * pix + comp]); + //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); return skinframe; } @@ -2164,9 +2156,8 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i { int i; unsigned char *temp1, *temp2; + unsigned int *palette; skinframe_t *skinframe; - double avgcolor[5], w, wsum; - int j; if (cls.state == ca_dedicated) return NULL; @@ -2176,6 +2167,8 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i if (skinframe && skinframe->base) return skinframe; + palette = (loadglowtexture ? palette_bgra_nofullbrights : ((skinframe->textureflags & TEXF_ALPHA) ? palette_bgra_transparent : palette_bgra_complete)); + skinframe->stain = NULL; skinframe->merged = NULL; skinframe->base = r_texture_notexture; @@ -2204,7 +2197,7 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i Mem_Free(temp1); } // use either a custom palette, or the quake palette - skinframe->base = skinframe->merged = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_merged", skinframe->basename), (loadglowtexture ? palette_bgra_nofullbrights : ((skinframe->textureflags & TEXF_ALPHA) ? palette_bgra_transparent : palette_bgra_complete)), skinframe->textureflags, true); // all + skinframe->base = skinframe->merged = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_merged", skinframe->basename), palette, skinframe->textureflags, true); // all if (loadglowtexture) skinframe->glow = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_glow", skinframe->basename), palette_bgra_onlyfullbrights, skinframe->textureflags, false); // glow if (loadpantsandshirt) @@ -2223,35 +2216,8 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i skinframe->fog = R_SkinFrame_TextureForSkinLayer(skindata, width, height, va("%s_fog", skinframe->basename), palette_bgra_alpha, skinframe->textureflags, true); // fog mask } - avgcolor[0] = 0; - avgcolor[1] = 0; - avgcolor[2] = 0; - avgcolor[3] = 0; - avgcolor[4] = 0; - wsum = 0; - for(j = 0; j < width * height; ++j) - { - temp1 = ((unsigned char *)palette_bgra_alpha) + (skindata[j]*4); - w = (int)temp1[0] + (int)temp1[1] + (int)temp1[2]; - avgcolor[2] += temp1[0] * w; - avgcolor[1] += temp1[1] * w; - avgcolor[0] += temp1[2] * w; - avgcolor[3] += temp1[3] * w; - avgcolor[4] += temp1[3]; - wsum += w; - } - if(avgcolor[3] == 0) // just fully transparent pixels seen? bad luck... - avgcolor[3] = 255.0 * wsum; - if(avgcolor[3] == 0) // no pixels seen? even worse - avgcolor[3] = 1; - avgcolor[0] /= avgcolor[3]; - avgcolor[1] /= avgcolor[3]; - avgcolor[2] /= avgcolor[3]; - avgcolor[3] /= 255.0 * wsum; // to 0..1 range - skinframe->avgcolor[0] = avgcolor[0]; - skinframe->avgcolor[1] = avgcolor[1]; - skinframe->avgcolor[2] = avgcolor[2]; - skinframe->avgcolor[3] = avgcolor[4] / (width * 255.0 * height); + R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]); + //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]); return skinframe; } @@ -2263,7 +2229,7 @@ skinframe_t *R_SkinFrame_LoadMissing(void) if (cls.state == ca_dedicated) return NULL; - skinframe = R_SkinFrame_Find("missing", TEXF_PRECACHE, 0, 0, 0, true); + skinframe = R_SkinFrame_Find("missing", TEXF_PRECACHE | TEXF_FORCENEAREST, 0, 0, 0, true); skinframe->stain = NULL; skinframe->merged = NULL; skinframe->base = r_texture_notexture; @@ -2284,6 +2250,10 @@ skinframe_t *R_SkinFrame_LoadMissing(void) void gl_main_start(void) { + r_numqueries = 0; + r_maxqueries = 0; + memset(r_queries, 0, sizeof(r_queries)); + memset(r_qwskincache, 0, sizeof(r_qwskincache)); memset(r_qwskincache_skinframe, 0, sizeof(r_qwskincache_skinframe)); @@ -2313,6 +2283,13 @@ void gl_main_start(void) void gl_main_shutdown(void) { + if (r_maxqueries) + qglDeleteQueriesARB(r_maxqueries, r_queries); + + r_numqueries = 0; + r_maxqueries = 0; + memset(r_queries, 0, sizeof(r_queries)); + memset(r_qwskincache, 0, sizeof(r_qwskincache)); memset(r_qwskincache_skinframe, 0, sizeof(r_qwskincache_skinframe)); @@ -2511,8 +2488,8 @@ void GL_Init (void) Con_Printf("GL_VENDOR: %s\n", gl_vendor); Con_Printf("GL_RENDERER: %s\n", gl_renderer); Con_Printf("GL_VERSION: %s\n", gl_version); - Con_Printf("GL_EXTENSIONS: %s\n", gl_extensions); - Con_Printf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); + Con_DPrintf("GL_EXTENSIONS: %s\n", gl_extensions); + Con_DPrintf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); VID_CheckExtensions(); @@ -3027,7 +3004,7 @@ static void R_Water_StartFrame(void) // calculate desired texture sizes // can't use water if the card does not support the texture size - if (!r_water.integer || !r_glsl.integer || !gl_support_fragment_shader || waterwidth > gl_max_texture_size || waterheight > gl_max_texture_size) + if (!r_water.integer || !r_glsl.integer || !gl_support_fragment_shader || waterwidth > gl_max_texture_size || waterheight > gl_max_texture_size || r_showsurfaces.integer) texturewidth = textureheight = waterwidth = waterheight = 0; else if (gl_support_arb_texture_non_power_of_two) { @@ -4639,12 +4616,12 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) } t->currentskinframe = r_qwskincache_skinframe[i]; if (t->currentskinframe == NULL) - t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - ent->frame2time)) % t->numskinframes]; + t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - ent->shadertime)) % t->numskinframes]; } else if (t->numskinframes >= 2) - t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - ent->frame2time)) % t->numskinframes]; + t->currentskinframe = t->skinframes[(int)(t->skinframerate * (cl.time - ent->shadertime)) % t->numskinframes]; if (t->backgroundnumskinframes >= 2) - t->backgroundcurrentskinframe = t->backgroundskinframes[(int)(t->backgroundskinframerate * (cl.time - ent->frame2time)) % t->backgroundnumskinframes]; + t->backgroundcurrentskinframe = t->backgroundskinframes[(int)(t->backgroundskinframerate * (cl.time - ent->shadertime)) % t->backgroundnumskinframes]; t->currentmaterialflags = t->basematerialflags; t->currentalpha = ent->alpha; @@ -4717,11 +4694,11 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * r_refdef.scene.time, tcmod->parms[1] * r_refdef.scene.time, 0); break; case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures) - w = tcmod->parms[0]; - h = tcmod->parms[1]; + w = (int) tcmod->parms[0]; + h = (int) tcmod->parms[1]; f = r_refdef.scene.time / (tcmod->parms[2] * w * h); f = f - floor(f); - idx = floor(f * w * h); + idx = (int) floor(f * w * h); Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0); break; case Q3TCMOD_STRETCH: @@ -5779,6 +5756,27 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te } } +static void RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(int texturenumsurfaces, msurface_t **texturesurfacelist) +{ + int texturesurfaceindex; + int i; + float *v, *c2; + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + for (i = 0, v = (rsurface.vertex3f + 3 * surface->num_firstvertex), c2 = (rsurface.array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4) + { + c2[0] = 0.5; + c2[1] = 0.5; + c2[2] = 0.5; + c2[3] = 1; + } + } + rsurface.lightmapcolor4f = rsurface.array_color4f; + rsurface.lightmapcolor4f_bufferobject = 0; + rsurface.lightmapcolor4f_bufferoffset = 0; +} + static void RSurf_DrawBatch_GL11_ApplyFog(int texturenumsurfaces, msurface_t **texturesurfacelist) { int texturesurfaceindex; @@ -5821,6 +5819,32 @@ static void RSurf_DrawBatch_GL11_ApplyFog(int texturenumsurfaces, msurface_t **t rsurface.lightmapcolor4f_bufferoffset = 0; } +static void RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(int texturenumsurfaces, msurface_t **texturesurfacelist) +{ + int texturesurfaceindex; + int i; + float f; + float *v, *c, *c2; + if (!rsurface.lightmapcolor4f) + return; + // generate color arrays for the surfaces in this list + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + for (i = 0, v = (rsurface.vertex3f + 3 * surface->num_firstvertex), c = (rsurface.lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (rsurface.array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4) + { + f = FogPoint_Model(v); + c2[0] = c[0] * f + r_refdef.fogcolor[0] * (1 - f); + c2[1] = c[1] * f + r_refdef.fogcolor[1] * (1 - f); + c2[2] = c[2] * f + r_refdef.fogcolor[2] * (1 - f); + c2[3] = c[3]; + } + } + rsurface.lightmapcolor4f = rsurface.array_color4f; + rsurface.lightmapcolor4f_bufferobject = 0; + rsurface.lightmapcolor4f_bufferoffset = 0; +} + static void RSurf_DrawBatch_GL11_ApplyColor(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a) { int texturesurfaceindex; @@ -5856,9 +5880,9 @@ static void RSurf_DrawBatch_GL11_ApplyAmbient(int texturenumsurfaces, msurface_t const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; for (i = 0, c = (rsurface.lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (rsurface.array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4, c2 += 4) { - c2[0] = c[0] + r_refdef.scene.ambient / 64.0; - c2[1] = c[1] + r_refdef.scene.ambient / 64.0; - c2[2] = c[2] + r_refdef.scene.ambient / 64.0; + c2[0] = c[0] + r_refdef.scene.ambient / 128.0; + c2[1] = c[1] + r_refdef.scene.ambient / 128.0; + c2[2] = c[2] + r_refdef.scene.ambient / 128.0; c2[3] = c[3]; } } @@ -5955,12 +5979,12 @@ static void RSurf_DrawBatch_GL11_VertexColor(int texturenumsurfaces, msurface_t RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } -static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) +static void RSurf_DrawBatch_GL11_ApplyVertexShade(int texturenumsurfaces, msurface_t **texturesurfacelist, float *r, float *g, float *b, float *a, qboolean *applycolor) { int texturesurfaceindex; int i; float f; - float *v, *c, *c2; + float *v, *c, *c2, alpha; vec3_t ambientcolor; vec3_t diffusecolor; vec3_t lightdir; @@ -5968,13 +5992,14 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t // model lighting VectorCopy(rsurface.modellight_lightdir, lightdir); f = 0.5f * r_refdef.lightmapintensity; - ambientcolor[0] = rsurface.modellight_ambient[0] * r * f; - ambientcolor[1] = rsurface.modellight_ambient[1] * g * f; - ambientcolor[2] = rsurface.modellight_ambient[2] * b * f; - diffusecolor[0] = rsurface.modellight_diffuse[0] * r * f; - diffusecolor[1] = rsurface.modellight_diffuse[1] * g * f; - diffusecolor[2] = rsurface.modellight_diffuse[2] * b * f; - if (VectorLength2(diffusecolor) > 0) + ambientcolor[0] = rsurface.modellight_ambient[0] * *r * f; + ambientcolor[1] = rsurface.modellight_ambient[1] * *g * f; + ambientcolor[2] = rsurface.modellight_ambient[2] * *b * f; + diffusecolor[0] = rsurface.modellight_diffuse[0] * *r * f; + diffusecolor[1] = rsurface.modellight_diffuse[1] * *g * f; + diffusecolor[2] = rsurface.modellight_diffuse[2] * *b * f; + alpha = *a; + if (VectorLength2(diffusecolor) > 0 && rsurface.normal3f) { // generate color arrays for the surfaces in this list for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) @@ -5991,27 +6016,32 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t VectorMA(ambientcolor, f, diffusecolor, c); else VectorCopy(ambientcolor, c); - c[3] = a; + c[3] = alpha; } } - r = 1; - g = 1; - b = 1; - a = 1; - applycolor = false; + *r = 1; + *g = 1; + *b = 1; + *a = 1; rsurface.lightmapcolor4f = rsurface.array_color4f; rsurface.lightmapcolor4f_bufferobject = 0; rsurface.lightmapcolor4f_bufferoffset = 0; + *applycolor = false; } else { - r = ambientcolor[0]; - g = ambientcolor[1]; - b = ambientcolor[2]; + *r = ambientcolor[0]; + *g = ambientcolor[1]; + *b = ambientcolor[2]; rsurface.lightmapcolor4f = NULL; rsurface.lightmapcolor4f_bufferobject = 0; rsurface.lightmapcolor4f_bufferoffset = 0; } +} + +static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) +{ + RSurf_DrawBatch_GL11_ApplyVertexShade(texturenumsurfaces, texturesurfacelist, &r, &g, &b, &a, &applycolor); if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); R_Mesh_ColorPointer(rsurface.lightmapcolor4f, rsurface.lightmapcolor4f_bufferobject, rsurface.lightmapcolor4f_bufferoffset); @@ -6436,11 +6466,115 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t } } +static void R_DrawTextureSurfaceList_ShowSurfaces3(int texturenumsurfaces, msurface_t **texturesurfacelist, qboolean writedepth) +{ + float c[4]; + + GL_AlphaTest(false); + R_Mesh_ColorPointer(NULL, 0, 0); + R_Mesh_ResetTextureState(); + R_SetupGenericShader(false); + + if(rsurface.texture && rsurface.texture->currentskinframe) + memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c)); + else + { + c[0] = 1; + c[1] = 0; + c[2] = 1; + c[3] = 1; + } + + if (rsurface.texture->currentskinframe->pants || rsurface.texture->currentskinframe->shirt) + { + c[0] = 0.5 * (rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7); + c[1] = 0.5 * (rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7); + c[2] = 0.5 * (rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7); + } + + // brighten it up (as texture value 127 means "unlit") + c[0] *= 2 * r_refdef.view.colorscale; + c[1] *= 2 * r_refdef.view.colorscale; + c[2] *= 2 * r_refdef.view.colorscale; + + if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA) + c[3] *= r_wateralpha.value; + + if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) + { + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GL_DepthMask(false); + } + else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD) + { + GL_BlendFunc(GL_ONE, GL_ONE); + GL_DepthMask(false); + } + else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + { + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead + GL_DepthMask(false); + } + else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) + { + GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]); + GL_DepthMask(false); + } + else + { + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthMask(writedepth); + } + + rsurface.lightmapcolor4f = NULL; + + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) + { + RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); + + rsurface.lightmapcolor4f = NULL; + rsurface.lightmapcolor4f_bufferobject = 0; + rsurface.lightmapcolor4f_bufferoffset = 0; + } + else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) + { + qboolean applycolor = true; + float one = 1.0; + + RSurf_PrepareVerticesForBatch(true, false, texturenumsurfaces, texturesurfacelist); + + r_refdef.lightmapintensity = 1; + RSurf_DrawBatch_GL11_ApplyVertexShade(texturenumsurfaces, texturesurfacelist, &one, &one, &one, &one, &applycolor); + r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + } + else + { + RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); + + rsurface.lightmapcolor4f = rsurface.modellightmapcolor4f; + rsurface.lightmapcolor4f_bufferobject = rsurface.modellightmapcolor4f_bufferobject; + rsurface.lightmapcolor4f_bufferoffset = rsurface.modellightmapcolor4f_bufferoffset; + } + + if(!rsurface.lightmapcolor4f) + RSurf_DrawBatch_GL11_MakeFullbrightLightmapColorArray(texturenumsurfaces, texturesurfacelist); + + RSurf_DrawBatch_GL11_ApplyAmbient(texturenumsurfaces, texturesurfacelist); + RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, c[0], c[1], c[2], c[3]); + if(r_refdef.fogenabled) + RSurf_DrawBatch_GL11_ApplyFogToFinishedVertexColors(texturenumsurfaces, texturesurfacelist); + + R_Mesh_ColorPointer(rsurface.lightmapcolor4f, rsurface.lightmapcolor4f_bufferobject, rsurface.lightmapcolor4f_bufferoffset); + RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); +} + static void R_DrawTextureSurfaceList(int texturenumsurfaces, msurface_t **texturesurfacelist, qboolean writedepth) { CHECKGLERROR RSurf_SetupDepthAndCulling(); - if (r_glsl.integer && gl_support_fragment_shader) + if (r_showsurfaces.integer == 3) + R_DrawTextureSurfaceList_ShowSurfaces3(texturenumsurfaces, texturesurfacelist, writedepth); + else if (r_glsl.integer && gl_support_fragment_shader) R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth); else if (gl_combine.integer && r_textureunits.integer >= 2) R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth); @@ -6505,7 +6639,7 @@ static void R_ProcessTextureSurfaceList(int texturenumsurfaces, msurface_t **tex RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } - else if (r_showsurfaces.integer && !(r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY))) + else if (r_showsurfaces.integer && !r_refdef.view.showdebug) { RSurf_SetupDepthAndCulling(); GL_AlphaTest(false); @@ -6513,100 +6647,30 @@ static void R_ProcessTextureSurfaceList(int texturenumsurfaces, msurface_t **tex R_Mesh_ResetTextureState(); R_SetupGenericShader(false); RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); - if (!r_refdef.view.showdebug) - { - GL_Color(0, 0, 0, 1); - GL_BlendFunc(GL_ONE, GL_ZERO); - GL_DepthTest(writedepth); - GL_DepthMask(true); - RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); - } - else if (r_showsurfaces.integer == 3) - { - float c[4]; - if(rsurface.texture && rsurface.texture->currentskinframe) - memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c)); - else - { - c[0] = 1; - c[1] = 0; - c[2] = 1; - c[3] = 1; - } - - // brighten it up (as texture value 127 means "unlit") - c[0] *= 2; - c[1] *= 2; - c[2] *= 2; - - if (rsurface.texture->currentskinframe->pants || rsurface.texture->currentskinframe->shirt) - { - c[0] = rsurface.colormap_pantscolor[0] * 0.3 + rsurface.colormap_shirtcolor[0] * 0.7; - c[1] = rsurface.colormap_pantscolor[1] * 0.3 + rsurface.colormap_shirtcolor[1] * 0.7; - c[2] = rsurface.colormap_pantscolor[2] * 0.3 + rsurface.colormap_shirtcolor[2] * 0.7; - } - - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA) - c[3] *= r_wateralpha.value; - - if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHA && c[3] != 1) - { - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GL_DepthMask(false); - } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ADD) - { - GL_BlendFunc(GL_ONE, GL_ONE); - GL_DepthMask(false); - } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) - { - GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // can't do alpha test without texture, so let's blend instead - GL_DepthMask(false); - } - else if(rsurface.texture->currentmaterialflags & MATERIALFLAG_CUSTOMBLEND) - { - GL_BlendFunc(rsurface.texture->customblendfunc[0], rsurface.texture->customblendfunc[1]); - GL_DepthMask(false); - } - else - { - GL_BlendFunc(GL_ONE, GL_ZERO); - GL_DepthMask(writedepth); - } - - rsurface.lightmapcolor4f = rsurface.modellightmapcolor4f; - rsurface.lightmapcolor4f_bufferobject = rsurface.modellightmapcolor4f_bufferobject; - rsurface.lightmapcolor4f_bufferoffset = rsurface.modellightmapcolor4f_bufferoffset; - GL_Color(c[0], c[1], c[2], c[3]); - RSurf_DrawBatch_GL11_ApplyAmbient(texturenumsurfaces, texturesurfacelist); - RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, c[0], c[1], c[2], c[3]); - - if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) && rsurface.normal3f) - { - r_refdef.lightmapintensity = 1; - RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, c[0], c[1], c[2], c[3], false, false); - r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all - } - else - { - R_Mesh_ColorPointer(rsurface.lightmapcolor4f, rsurface.lightmapcolor4f_bufferobject, rsurface.lightmapcolor4f_bufferoffset); - RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); - } - } - else - { - GL_DepthTest(true); - GL_DepthMask(true); - GL_BlendFunc(GL_ONE, GL_ZERO); - RSurf_DrawBatch_ShowSurfaces(texturenumsurfaces, texturesurfacelist); - } + GL_DepthMask(true); + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_Color(0, 0, 0, 1); + GL_DepthTest(writedepth); + RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); + } + else if (r_showsurfaces.integer && r_showsurfaces.integer != 3) + { + RSurf_SetupDepthAndCulling(); + GL_AlphaTest(false); + R_Mesh_ColorPointer(NULL, 0, 0); + R_Mesh_ResetTextureState(); + R_SetupGenericShader(false); + RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); + GL_DepthMask(true); + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthTest(true); + RSurf_DrawBatch_ShowSurfaces(texturenumsurfaces, texturesurfacelist); } else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; - else if ((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) && queueentity) + else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity) { // transparent surfaces get pushed off into the transparent queue int surfacelistindex; @@ -6894,7 +6958,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep r_maxsurfacelist = model->num_surfaces; if (r_surfacelist) Mem_Free(r_surfacelist); - r_surfacelist = Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); + r_surfacelist = (msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); } RSurf_ActiveWorldEntity(); @@ -6984,7 +7048,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr r_maxsurfacelist = model->num_surfaces; if (r_surfacelist) Mem_Free(r_surfacelist); - r_surfacelist = Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); + r_surfacelist = (msurface_t **) Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); } // if the model is static it doesn't matter what value we give for