]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
use trace_plane_normal to check whether the trace succeeded
[xonotic/darkplaces.git] / gl_rmain.c
index 662a1c7314dea043d937507200cba1b1bba919ea..eada61fd7f141851647a12324f63cd15256f2e0b 100644 (file)
@@ -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)
 {
@@ -1907,7 +1919,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid
 
 #define R_SKINFRAME_LOAD_AVERAGE_COLORS(cnt, getpixel) \
        { \
-               unsigned long avgcolor[5], wsum; \
+               unsigned long long avgcolor[5], wsum; \
                int pix, comp, w; \
                avgcolor[0] = 0; \
                avgcolor[1] = 0; \
@@ -2016,6 +2028,7 @@ skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int texturefl
        }
 
        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)
@@ -2134,6 +2147,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
        }
 
        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;
 }
@@ -2142,6 +2156,7 @@ skinframe_t *R_SkinFrame_LoadInternalQuake(const char *name, int textureflags, i
 {
        int i;
        unsigned char *temp1, *temp2;
+       unsigned int *palette;
        skinframe_t *skinframe;
 
        if (cls.state == ca_dedicated)
@@ -2152,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;
@@ -2180,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)
@@ -2199,7 +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
        }
 
-       R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette_bgra_alpha)[skindata[pix]*4 + comp]);
+       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;
 }
@@ -2211,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;
@@ -2232,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));
 
@@ -2261,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));
 
@@ -2459,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();
 
@@ -3740,7 +3769,7 @@ void R_UpdateVariables(void)
                        // build GLSL gamma texture
 #define RAMPWIDTH 256
                        unsigned short ramp[RAMPWIDTH * 3];
-                       unsigned char ramprgb[RAMPWIDTH][4];
+                       unsigned char rampbgr[RAMPWIDTH][4];
                        int i;
 
                        r_texture_gammaramps_serial = vid_gammatables_serial;
@@ -3748,18 +3777,18 @@ void R_UpdateVariables(void)
                        VID_BuildGammaTables(&ramp[0], RAMPWIDTH);
                        for(i = 0; i < RAMPWIDTH; ++i)
                        {
-                               ramprgb[i][0] = ramp[i] >> 8;
-                               ramprgb[i][1] = ramp[i + RAMPWIDTH] >> 8;
-                               ramprgb[i][2] = ramp[i + 2 * RAMPWIDTH] >> 8;
-                               ramprgb[i][3] = 0;
+                               rampbgr[i][0] = (unsigned char) (ramp[i + 2 * RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
+                               rampbgr[i][1] = (unsigned char) (ramp[i + RAMPWIDTH] * 255.0 / 65535.0 + 0.5);
+                               rampbgr[i][2] = (unsigned char) (ramp[i] * 255.0 / 65535.0 + 0.5);
+                               rampbgr[i][3] = 0;
                        }
                        if (r_texture_gammaramps)
                        {
-                               R_UpdateTexture(r_texture_gammaramps, &ramprgb[0][0], 0, 0, RAMPWIDTH, 1);
+                               R_UpdateTexture(r_texture_gammaramps, &rampbgr[0][0], 0, 0, RAMPWIDTH, 1);
                        }
                        else
                        {
-                               r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &ramprgb[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
+                               r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &rampbgr[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL);
                        }
                }
        }
@@ -4544,7 +4573,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
 
        if (t->basematerialflags & MATERIALFLAG_NODRAW)
        {
-               t->currentmaterialflags = MATERIALFLAG_NODRAW;
+               t->currentmaterialflags = t->basematerialflags & (MATERIALFLAG_NODRAW | MATERIALFLAG_NOSHADOW);
                return;
        }
 
@@ -4587,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;
@@ -4665,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:
@@ -5851,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];
                }
        }
@@ -6929,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();
@@ -7019,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