]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
Fix r_celoutlines description to not mention OpenGL 2.x as that's no longer relevant.
[xonotic/darkplaces.git] / gl_rmain.c
index 5c71f4565a07ff4140a0fcdfbd3b85969b32d123..7f70f9d83f5ec730d116b8f82e9777b311982550 100644 (file)
@@ -142,7 +142,7 @@ cvar_t r_transparent_sortmindist = {CVAR_CLIENT | CVAR_SAVE, "r_transparent_sort
 cvar_t r_transparent_sortmaxdist = {CVAR_CLIENT | CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
 cvar_t r_transparent_sortarraysize = {CVAR_CLIENT | CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
 cvar_t r_celshading = {CVAR_CLIENT | CVAR_SAVE, "r_celshading", "0", "cartoon-style light shading (OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
-cvar_t r_celoutlines = {CVAR_CLIENT | CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred; OpenGL 2.x only)"}; // FIXME remove OpenGL 2.x only once implemented for DX9
+cvar_t r_celoutlines = {CVAR_CLIENT | CVAR_SAVE, "r_celoutlines", "0", "cartoon-style outlines (requires r_shadow_deferred)"};
 
 cvar_t gl_fogenable = {CVAR_CLIENT, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"};
 cvar_t gl_fogdensity = {CVAR_CLIENT, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"};
@@ -190,6 +190,7 @@ cvar_t r_glsl_postprocess_uservec1_enable = {CVAR_CLIENT | CVAR_SAVE, "r_glsl_po
 cvar_t r_glsl_postprocess_uservec2_enable = {CVAR_CLIENT | CVAR_SAVE, "r_glsl_postprocess_uservec2_enable", "1", "enables postprocessing uservec2 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
 cvar_t r_glsl_postprocess_uservec3_enable = {CVAR_CLIENT | CVAR_SAVE, "r_glsl_postprocess_uservec3_enable", "1", "enables postprocessing uservec3 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
 cvar_t r_glsl_postprocess_uservec4_enable = {CVAR_CLIENT | CVAR_SAVE, "r_glsl_postprocess_uservec4_enable", "1", "enables postprocessing uservec4 usage, creates USERVEC1 define (only useful if default.glsl has been customized)"};
+cvar_t r_colorfringe = {CVAR_CLIENT | CVAR_SAVE, "r_colorfringe", "0", "Chromatic aberration. Values higher than 0.025 will noticeably distort the image"};
 
 cvar_t r_water = {CVAR_CLIENT | CVAR_SAVE, "r_water", "0", "whether to use reflections and refraction on water surfaces (note: r_wateralpha must be set below 1)"};
 cvar_t r_water_cameraentitiesonly = {CVAR_CLIENT | CVAR_SAVE, "r_water_cameraentitiesonly", "0", "whether to only show QC-defined reflections/refractions (typically used for camera- or portal-like effects)"};
@@ -198,7 +199,7 @@ cvar_t r_water_resolutionmultiplier = {CVAR_CLIENT | CVAR_SAVE, "r_water_resolut
 cvar_t r_water_refractdistort = {CVAR_CLIENT | CVAR_SAVE, "r_water_refractdistort", "0.01", "how much water refractions shimmer"};
 cvar_t r_water_reflectdistort = {CVAR_CLIENT | CVAR_SAVE, "r_water_reflectdistort", "0.01", "how much water reflections shimmer"};
 cvar_t r_water_scissormode = {CVAR_CLIENT, "r_water_scissormode", "3", "scissor (1) or cull (2) or both (3) water renders"};
-cvar_t r_water_lowquality = {CVAR_CLIENT, "r_water_lowquality", "0", "special option to accelerate water rendering, 1 disables shadows and particles, 2 disables all dynamic lights"};
+cvar_t r_water_lowquality = {CVAR_CLIENT, "r_water_lowquality", "0", "special option to accelerate water rendering: 1 disables all dynamic lights, 2 disables particles too"};
 cvar_t r_water_hideplayer = {CVAR_CLIENT | CVAR_SAVE, "r_water_hideplayer", "0", "if set to 1 then player will be hidden in refraction views, if set to 2 then player will also be hidden in reflection views, player is always visible in camera views"};
 
 cvar_t r_lerpsprites = {CVAR_CLIENT | CVAR_SAVE, "r_lerpsprites", "0", "enables animation smoothing on sprites"};
@@ -817,6 +818,7 @@ typedef struct r_glsl_permutation_s
        int loc_UserVec2;
        int loc_UserVec3;
        int loc_UserVec4;
+       int loc_ColorFringe;
        int loc_ViewTintColor;
        int loc_ViewToLight;
        int loc_ModelToLight;
@@ -1247,6 +1249,7 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                p->loc_UserVec2                   = qglGetUniformLocation(p->program, "UserVec2");
                p->loc_UserVec3                   = qglGetUniformLocation(p->program, "UserVec3");
                p->loc_UserVec4                   = qglGetUniformLocation(p->program, "UserVec4");
+               p->loc_ColorFringe                = qglGetUniformLocation(p->program, "ColorFringe");
                p->loc_ViewTintColor              = qglGetUniformLocation(p->program, "ViewTintColor");
                p->loc_ViewToLight                = qglGetUniformLocation(p->program, "ViewToLight");
                p->loc_ModelToLight               = qglGetUniformLocation(p->program, "ModelToLight");
@@ -3082,6 +3085,8 @@ static void gl_main_start(void)
 #endif
 }
 
+extern unsigned int r_shadow_occlusion_buf;
+
 static void gl_main_shutdown(void)
 {
        R_RenderTarget_FreeUnused(true);
@@ -3102,7 +3107,7 @@ static void gl_main_shutdown(void)
 #endif
                break;
        }
-
+       r_shadow_occlusion_buf = 0;
        r_numqueries = 0;
        r_maxqueries = 0;
        memset(r_queries, 0, sizeof(r_queries));
@@ -3317,6 +3322,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_lerplightstyles);
        Cvar_RegisterVariable(&r_waterscroll);
        Cvar_RegisterVariable(&r_bloom);
+       Cvar_RegisterVariable(&r_colorfringe);
        Cvar_RegisterVariable(&r_bloom_colorscale);
        Cvar_RegisterVariable(&r_bloom_brighten);
        Cvar_RegisterVariable(&r_bloom_blur);
@@ -5033,7 +5039,7 @@ finish:
 
 static void R_Bloom_StartFrame(void)
 {
-       int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight;
+       int screentexturewidth, screentextureheight;
        int viewwidth, viewheight;
        textype_t textype = TEXTYPE_COLORBUFFER;
 
@@ -5083,8 +5089,6 @@ static void R_Bloom_StartFrame(void)
        // calculate desired texture sizes
        screentexturewidth = viewwidth;
        screentextureheight = viewheight;
-       bloomtexturewidth = r_fb.bloomwidth;
-       bloomtextureheight = r_fb.bloomheight;
 
        if ((r_bloom.integer || (!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0))) && ((r_bloom_resolution.integer < 4 || r_bloom_blur.value < 1 || r_bloom_blur.value >= 512) || r_refdef.view.width > (int)vid.maxtexturesize_2d || r_refdef.view.height > (int)vid.maxtexturesize_2d))
        {
@@ -5369,6 +5373,7 @@ static void R_BlendView(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *v
                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_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;
        }
        R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0);
@@ -5793,7 +5798,6 @@ extern cvar_t cl_locs_show;
 static void R_DrawLocs(void);
 static void R_DrawEntityBBoxes(prvm_prog_t *prog);
 static void R_DrawModelDecals(void);
-extern cvar_t cl_decals_newsystem;
 extern qboolean r_shadow_usingdeferredprepass;
 extern int r_shadow_shadowmapatlas_modelshadows_size;
 void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewcolortexture, int viewx, int viewy, int viewwidth, int viewheight)
@@ -5920,18 +5924,9 @@ void R_RenderScene(int viewfbo, rtexture_t *viewdepthtexture, rtexture_t *viewco
 
        if (cl.csqc_vidvars.drawworld)
        {
-               if (cl_decals_newsystem.integer)
-               {
-                       R_DrawModelDecals();
-                       if (r_timereport_active)
-                               R_TimeReport("modeldecals");
-               }
-               else
-               {
-                       R_DrawDecals();
-                       if (r_timereport_active)
-                               R_TimeReport("decals");
-               }
+               R_DrawModelDecals();
+               if (r_timereport_active)
+                       R_TimeReport("modeldecals");
 
                R_DrawParticles();
                if (r_timereport_active)
@@ -6134,9 +6129,9 @@ static void R_DrawEntityBBoxes(prvm_prog_t *prog)
                if (edict->priv.server->free)
                        continue;
                // exclude the following for now, as they don't live in world coordinate space and can't be solid:
-               if (PRVM_serveredictedict(edict, tag_entity) != 0)
+               if (PRVM_gameedictedict(edict, tag_entity) != 0)
                        continue;
-               if (PRVM_serveredictedict(edict, viewmodelforclient) != 0)
+               if (prog == SVVM_prog && PRVM_serveredictedict(edict, viewmodelforclient) != 0)
                        continue;
                VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center);
                R_MeshQueue_AddTransparent(TRANSPARENTSORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)prog);
@@ -7123,6 +7118,24 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q
 void RSurf_ActiveCustomEntity(const matrix4x4_t *matrix, const matrix4x4_t *inversematrix, int entflags, double shadertime, float r, float g, float b, float a, int numvertices, const float *vertex3f, const float *texcoord2f, const float *normal3f, const float *svector3f, const float *tvector3f, const float *color4f, int numtriangles, const int *element3i, const unsigned short *element3s, qboolean wantnormals, qboolean wanttangents)
 {
        rsurface.entity = r_refdef.scene.worldentity;
+       if (r != 1.0f || g != 1.0f || b != 1.0f || a != 1.0f) {
+               // HACK to provide a valid entity with modded colors to R_GetCurrentTexture.
+               // A better approach could be making this copy only once per frame.
+               static entity_render_t custom_entity;
+               int q;
+               custom_entity = *rsurface.entity;
+               for (q = 0; q < 3; ++q) {
+                       float colormod = q == 0 ? r : q == 1 ? g : b;
+                       custom_entity.render_fullbright[q] *= colormod;
+                       custom_entity.render_modellight_ambient[q] *= colormod;
+                       custom_entity.render_modellight_diffuse[q] *= colormod;
+                       custom_entity.render_lightmap_ambient[q] *= colormod;
+                       custom_entity.render_lightmap_diffuse[q] *= colormod;
+                       custom_entity.render_rtlight_diffuse[q] *= colormod;
+               }
+               custom_entity.alpha *= a;
+               rsurface.entity = &custom_entity;
+       }
        rsurface.skeleton = NULL;
        rsurface.ent_skinnum = 0;
        rsurface.ent_qwskin = -1;
@@ -9389,9 +9402,6 @@ static void R_DecalSystem_ApplySplatEntities(const vec3_t worldorigin, const vec
        float worldmaxs[3];
        entity_render_t *ent;
 
-       if (!cl_decals_newsystem.integer)
-               return;
-
        worldmins[0] = worldorigin[0] - worldsize;
        worldmins[1] = worldorigin[1] - worldsize;
        worldmins[2] = worldorigin[2] - worldsize;
@@ -9429,7 +9439,7 @@ void R_DecalSystem_SplatEntities(const vec3_t worldorigin, const vec3_t worldnor
 {
        r_decalsystem_splatqueue_t *queue;
 
-       if (!cl_decals_newsystem.integer || r_decalsystem_numqueued == MAX_DECALSYSTEM_QUEUE)
+       if (r_decalsystem_numqueued == MAX_DECALSYSTEM_QUEUE)
                return;
 
        queue = &r_decalsystem_queue[r_decalsystem_numqueued++];
@@ -9673,7 +9683,7 @@ static void R_DrawModelDecals(void)
 
        r_refdef.stats[r_stat_totaldecals] += numdecals;
 
-       if (r_showsurfaces.integer)
+       if (r_showsurfaces.integer || !r_drawdecals.integer)
                return;
 
        R_DrawModelDecals_Entity(r_refdef.scene.worldentity);
@@ -10072,10 +10082,7 @@ void R_DebugLine(vec3_t start, vec3_t end)
 
 void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass, qboolean ui)
 {
-       int q;
        static texture_t texture;
-       static msurface_t surface;
-       const msurface_t *surfacelist = &surface;
 
        // fake enough texture and surface state to render this geometry
 
@@ -10089,36 +10096,8 @@ void R_DrawCustomSurface(skinframe_t *skinframe, const matrix4x4_t *texmatrix, i
        texture.specularscalemod = 1;
        texture.specularpowermod = 1;
        texture.transparentsort = TRANSPARENTSORT_DISTANCE;
-       // WHEN ADDING DEFAULTS HERE, REMEMBER TO PUT DEFAULTS IN ALL LOADERS
-       // JUST GREP FOR "specularscalemod = 1".
 
-       for (q = 0; q < 3; q++)
-       {
-               texture.render_glowmod[q] = r_refdef.view.colorscale * r_hdr_glowintensity.value;
-               texture.render_modellight_lightdir[q] = q == 2;
-               texture.render_modellight_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
-               texture.render_modellight_diffuse[q] = r_refdef.view.colorscale;
-               texture.render_modellight_specular[q] = r_refdef.view.colorscale;
-               texture.render_lightmap_ambient[q] = r_refdef.view.colorscale * r_refdef.scene.ambientintensity;
-               texture.render_lightmap_diffuse[q] = r_refdef.view.colorscale * r_refdef.scene.lightmapintensity;
-               texture.render_lightmap_specular[q] = r_refdef.view.colorscale;
-               texture.render_rtlight_diffuse[q] = r_refdef.view.colorscale;
-               texture.render_rtlight_specular[q] = r_refdef.view.colorscale;
-       }
-       texture.currentalpha = 1.0f;
-
-       surface.texture = &texture;
-       surface.num_triangles = numtriangles;
-       surface.num_firsttriangle = firsttriangle;
-       surface.num_vertices = numvertices;
-       surface.num_firstvertex = firstvertex;
-
-       // now render it
-       rsurface.texture = R_GetCurrentTexture(surface.texture);
-       rsurface.lightmaptexture = NULL;
-       rsurface.deluxemaptexture = NULL;
-       rsurface.uselightmaptexture = false;
-       R_DrawModelTextureSurfaceList(1, &surfacelist, writedepth, prepass, ui);
+       R_DrawCustomSurface_Texture(&texture, texmatrix, materialflags, firstvertex, numvertices, firsttriangle, numtriangles, writedepth, prepass, ui);
 }
 
 void R_DrawCustomSurface_Texture(texture_t *texture, const matrix4x4_t *texmatrix, int materialflags, int firstvertex, int numvertices, int firsttriangle, int numtriangles, qboolean writedepth, qboolean prepass, qboolean ui)