X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=07228b6e863a9301b6a27425fe271ed21be73338;hb=5329f72efb4a855e1d3caac8434e816fe8d3da5e;hp=80c87db9cda5cda8a3a5f8aeb9d0b4b83769e262;hpb=05bd75d2c2fd89278adea7b53fae425351f9446b;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 80c87db9..07228b6e 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -70,6 +70,7 @@ cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables cvar_t r_farclip_base = {0, "r_farclip_base", "65536", "farclip (furthest visible distance) for rendering when r_useinfinitefarclip is 0"}; cvar_t r_farclip_world = {0, "r_farclip_world", "2", "adds map size to farclip multiplied by this value"}; cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" }; +cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"}; cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"}; cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"}; cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"}; @@ -115,6 +116,7 @@ cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", cvar_t r_polygonoffset_decals_factor = {0, "r_polygonoffset_decals_factor", "0", "biases depth values of decals to prevent z-fighting artifacts"}; cvar_t r_polygonoffset_decals_offset = {0, "r_polygonoffset_decals_offset", "-14", "biases depth values of decals to prevent z-fighting artifacts"}; cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rather than realistic GL_EXP fog"}; +cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"}; cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"}; cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"}; @@ -130,21 +132,33 @@ cvar_t gl_skyclip = {0, "gl_skyclip", "4608", "nehahra farclip distance - the re cvar_t r_texture_dds_load = {CVAR_SAVE, "r_texture_dds_load", "0", "load compressed dds/filename.dds texture instead of filename.tga, if the file exists (requires driver support)"}; cvar_t r_texture_dds_save = {CVAR_SAVE, "r_texture_dds_save", "0", "save compressed dds/filename.dds texture when filename.tga is loaded, so that it can be loaded instead next time"}; -cvar_t r_texture_convertsRGB_2d = {0, "r_texture_convertsRGB_2d", "0", "load textures as sRGB and convert to linear for proper shading"}; -cvar_t r_texture_convertsRGB_skin = {0, "r_texture_convertsRGB_skin", "0", "load textures as sRGB and convert to linear for proper shading"}; -cvar_t r_texture_convertsRGB_cubemap = {0, "r_texture_convertsRGB_cubemap", "0", "load textures as sRGB and convert to linear for proper shading"}; -cvar_t r_texture_convertsRGB_skybox = {0, "r_texture_convertsRGB_skybox", "0", "load textures as sRGB and convert to linear for proper shading"}; -cvar_t r_texture_convertsRGB_particles = {0, "r_texture_convertsRGB_particles", "0", "load textures as sRGB and convert to linear for proper shading"}; +cvar_t r_texture_sRGB_2d = {0, "r_texture_sRGB_2d", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_skin_diffuse = {0, "r_texture_sRGB_skin_diffuse", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_skin_gloss = {0, "r_texture_sRGB_skin_gloss", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_skin_glow = {0, "r_texture_sRGB_skin_glow", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_skin_reflect = {0, "r_texture_sRGB_skin_reflect", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_cubemap = {0, "r_texture_sRGB_cubemap", "0", "load textures as sRGB"}; +cvar_t r_texture_sRGB_skybox = {0, "r_texture_sRGB_skybox", "0", "load textures as sRGB"}; cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to use in GL 1.1 and GL 1.3 rendering paths"}; static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"}; static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"}; +cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"}; +cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"}; +cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"}; +cvar_t r_viewscale_fpsscaling_min = {CVAR_SAVE, "r_viewscale_fpsscaling_min", "0.0625", "worst acceptable quality"}; +cvar_t r_viewscale_fpsscaling_multiply = {CVAR_SAVE, "r_viewscale_fpsscaling_multiply", "5", "adjust quality up or down by the frametime difference from 1.0/target, multiplied by this factor"}; +cvar_t r_viewscale_fpsscaling_stepsize = {CVAR_SAVE, "r_viewscale_fpsscaling_stepsize", "0.01", "smallest adjustment to hit the target framerate (this value prevents minute oscillations)"}; +cvar_t r_viewscale_fpsscaling_stepmax = {CVAR_SAVE, "r_viewscale_fpsscaling_stepmax", "1.00", "largest adjustment to hit the target framerate (this value prevents wild overshooting of the estimate)"}; +cvar_t r_viewscale_fpsscaling_target = {CVAR_SAVE, "r_viewscale_fpsscaling_target", "70", "desired framerate"}; + cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"}; cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"}; cvar_t r_glsl_offsetmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_steps", "2", "offset mapping steps (note: too high values may be not supported by your GPU)"}; cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"}; cvar_t r_glsl_offsetmapping_reliefmapping_steps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_steps", "10", "relief mapping steps (note: too high values may be not supported by your GPU)"}; +cvar_t r_glsl_offsetmapping_reliefmapping_refinesteps = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping_refinesteps", "5", "relief mapping refine steps (these are a binary search executed as the last step as given by r_glsl_offsetmapping_reliefmapping_steps)"}; cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"}; cvar_t r_glsl_postprocess = {CVAR_SAVE, "r_glsl_postprocess", "0", "use a GLSL postprocessing shader"}; cvar_t r_glsl_postprocess_uservec1 = {CVAR_SAVE, "r_glsl_postprocess_uservec1", "0 0 0 0", "a 4-component vector to pass as uservec1 to the postprocessing shader (only useful if default.glsl has been customized)"}; @@ -221,6 +235,13 @@ static struct r_bloomstate_s int bloomwidth, bloomheight; + textype_t texturetype; + int viewfbo; // used to check if r_viewfbo cvar has changed + + int fbo_framebuffer; // non-zero if r_viewfbo is enabled and working + rtexture_t *texture_framebuffercolor; // non-NULL if fbo_screen is non-zero + rtexture_t *texture_framebufferdepth; // non-NULL if fbo_screen is non-zero + int screentexturewidth, screentextureheight; rtexture_t *texture_screen; /// \note also used for motion blur if enabled! @@ -1771,7 +1792,7 @@ void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutatio void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation) { - DPSOFTRAST_SetShader(mode, permutation); + DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer); DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f); DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time); @@ -1832,8 +1853,9 @@ void R_GLSL_Restart_f(void) memset(r_glsl_permutationhash, 0, sizeof(r_glsl_permutationhash)); } break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: break; case RENDERPATH_SOFT: break; @@ -1906,6 +1928,7 @@ void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemod R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second, second); break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: R_Mesh_TexBind(0, first ); R_Mesh_TexCombine(0, GL_MODULATE, GL_MODULATE, 1, 1); R_Mesh_TexBind(1, second); @@ -1943,6 +1966,7 @@ void R_SetupShader_DepthOrShadow(void) R_SetupShader_SetPermutationGLSL(SHADERMODE_DEPTH_OR_SHADOW, 0); break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: R_Mesh_TexBind(0, 0); R_Mesh_TexBind(1, 0); break; @@ -1975,6 +1999,7 @@ void R_SetupShader_ShowDepth(void) R_SetupShader_SetPermutationGLSL(SHADERMODE_SHOWDEPTH, 0); break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: break; case RENDERPATH_GL11: break; @@ -2071,14 +2096,14 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane; if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) permutation |= SHADERPERMUTATION_ALPHAKILL; + if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1]) + permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; // todo: make generic if (rsurfacepass == RSURFPASS_BACKGROUND) { // distorted background if (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERSHADER) { mode = SHADERMODE_WATER; - if (rsurface.texture->r_water_waterscroll[0] && rsurface.texture->r_water_waterscroll[1]) - permutation |= SHADERPERMUTATION_NORMALMAPSCROLLBLEND; if((r_wateralpha.value < 1) && (rsurface.texture->currentmaterialflags & MATERIALFLAG_WATERALPHA)) { // this is the right thing to do for wateralpha @@ -2110,23 +2135,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // normalmap (deferred prepass), may use alpha test on diffuse mode = SHADERMODE_DEFERREDGEOMETRY; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; GL_BlendFunc(GL_ONE, GL_ZERO); blendfuncflags = R_BlendFuncFlags(GL_ONE, GL_ZERO); } @@ -2134,23 +2154,18 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; // light source mode = SHADERMODE_LIGHTSOURCE; - if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) - permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND; if (rsurface.rtlight->currentcubemap != r_texture_whitecube) permutation |= SHADERPERMUTATION_CUBEFILTER; if (diffusescale > 0) @@ -2183,15 +2198,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) @@ -2228,15 +2240,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) @@ -2283,15 +2292,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) @@ -2335,15 +2341,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_offsetmapping.integer) { - if (rsurface.texture->offsetmapping == OFFSETMAPPING_LINEAR) - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - else if (rsurface.texture->offsetmapping == OFFSETMAPPING_RELIEF) - permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; - else if (rsurface.texture->offsetmapping != OFFSETMAPPING_OFF) + switch(rsurface.texture->offsetmapping) { - permutation |= SHADERPERMUTATION_OFFSETMAPPING; - if (r_glsl_offsetmapping_reliefmapping.integer) - permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; + case OFFSETMAPPING_LINEAR: permutation |= SHADERPERMUTATION_OFFSETMAPPING;break; + case OFFSETMAPPING_RELIEF: permutation |= SHADERPERMUTATION_OFFSETMAPPING | SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_DEFAULT: permutation |= SHADERPERMUTATION_OFFSETMAPPING;if (r_glsl_offsetmapping_reliefmapping.integer) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING;break; + case OFFSETMAPPING_OFF: break; } } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND) @@ -2520,7 +2523,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, hlslPSSetParameter1f(D3DPSREGISTER_FogPlaneViewDist, rsurface.fogplaneviewdist); hlslPSSetParameter1f(D3DPSREGISTER_FogRangeRecip, rsurface.fograngerecip); hlslPSSetParameter1f(D3DPSREGISTER_FogHeightFade, rsurface.fogheightfade); - hlslPSSetParameter3f(D3DPSREGISTER_OffsetMapping_ScaleSteps, r_glsl_offsetmapping_scale.value, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer)); + hlslPSSetParameter4f(D3DPSREGISTER_OffsetMapping_ScaleSteps, + r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) + ); hlslPSSetParameter2f(D3DPSREGISTER_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height); @@ -2675,11 +2683,16 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->loc_FogPlaneViewDist >= 0) qglUniform1f(r_glsl_permutation->loc_FogPlaneViewDist, rsurface.fogplaneviewdist); if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1f(r_glsl_permutation->loc_FogRangeRecip, rsurface.fograngerecip); if (r_glsl_permutation->loc_FogHeightFade >= 0) qglUniform1f(r_glsl_permutation->loc_FogHeightFade, rsurface.fogheightfade); - if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform3f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer)); + if (r_glsl_permutation->loc_OffsetMapping_ScaleSteps >= 0) qglUniform4f(r_glsl_permutation->loc_OffsetMapping_ScaleSteps, + r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) + ); 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_BounceGridMatrix >= 0) {Matrix4x4_Concat(&tempmatrix, &r_shadow_bouncegridmatrix, &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_bouncegridintensity); + if (r_glsl_permutation->loc_BounceGridIntensity >= 0) qglUniform1f(r_glsl_permutation->loc_BounceGridIntensity, r_shadow_bouncegridintensity*r_refdef.view.colorscale); if (r_glsl_permutation->tex_Texture_First >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_First , r_texture_white ); if (r_glsl_permutation->tex_Texture_Second >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Second , r_texture_white ); @@ -2727,8 +2740,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, if (r_glsl_permutation->tex_Texture_BounceGrid >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_BounceGrid, r_shadow_bouncegridtexture); CHECKGLERROR break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: break; case RENDERPATH_SOFT: RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | (rsurface.modellightmapcolor4f ? BATCHNEED_ARRAY_VERTEXCOLOR : 0) | BATCHNEED_ARRAY_TEXCOORD | (rsurface.uselightmaptexture ? BATCHNEED_ARRAY_LIGHTMAP : 0), texturenumsurfaces, texturesurfacelist); @@ -2814,7 +2828,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogPlaneViewDist, rsurface.fogplaneviewdist); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogRangeRecip, rsurface.fograngerecip); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_FogHeightFade, rsurface.fogheightfade); - DPSOFTRAST_Uniform3f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps, r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer)); + DPSOFTRAST_Uniform4f(DPSOFTRAST_UNIFORM_OffsetMapping_ScaleSteps, + r_glsl_offsetmapping_scale.value*rsurface.texture->offsetscale, + max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + 1.0 / max(1, (permutation & SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING) ? r_glsl_offsetmapping_reliefmapping_steps.integer : r_glsl_offsetmapping_steps.integer), + max(1, r_glsl_offsetmapping_reliefmapping_refinesteps.integer) + ); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_ScreenToDepth, r_refdef.view.viewport.screentodepth[0], r_refdef.view.viewport.screentodepth[1]); DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); @@ -2887,7 +2906,7 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) permutation |= SHADERPERMUTATION_CUBEFILTER; if (diffusescale > 0) permutation |= SHADERPERMUTATION_DIFFUSE; - if (specularscale > 0) + if (specularscale > 0 && r_shadow_gloss.integer > 0) permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; if (r_shadow_usingshadowmap2d) { @@ -2957,8 +2976,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture ); if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture ); break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: break; case RENDERPATH_SOFT: R_SetupShader_SetPermutationGLSL(mode, permutation); @@ -3173,7 +3193,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole // check for DDS texture file first if (!r_loaddds || !(ddsbase = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s.dds", basename), textureflags, &ddshasalpha, ddsavgcolor, miplevel))) { - basepixels = loadimagepixelsbgra(name, complain, true, r_texture_convertsRGB_skin.integer != 0, &miplevel); + basepixels = loadimagepixelsbgra(name, complain, true, false, &miplevel); if (basepixels == NULL) return NULL; } @@ -3211,7 +3231,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { basepixels_width = image_width; basepixels_height = image_height; - skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL); + skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, r_texture_sRGB_skin_diffuse.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL); if (textureflags & TEXF_ALPHA) { for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4) @@ -3290,18 +3310,18 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole // _luma is supported only for tenebrae compatibility // _glow is the preferred name mymiplevel = savemiplevel; - if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))) + if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow", skinframe->basename), false, false, false, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, false, &mymiplevel)))) { - skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); + skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, r_texture_sRGB_skin_glow.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow) R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true, true); Mem_Free(pixels);pixels = NULL; } mymiplevel = savemiplevel; - if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))) + if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, false, &mymiplevel))) { - skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); + skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, r_texture_sRGB_skin_gloss.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss) R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true, true); Mem_Free(pixels); @@ -3309,9 +3329,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole } mymiplevel = savemiplevel; - if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))) + if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, false, &mymiplevel))) { - skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); + skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, r_texture_sRGB_skin_diffuse.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants) R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true, false); Mem_Free(pixels); @@ -3319,9 +3339,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole } mymiplevel = savemiplevel; - if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))) + if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, false, &mymiplevel))) { - skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); + skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, r_texture_sRGB_skin_diffuse.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt) R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true, false); Mem_Free(pixels); @@ -3329,9 +3349,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole } mymiplevel = savemiplevel; - if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))) + if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, false, &mymiplevel))) { - skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); + skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, r_texture_sRGB_skin_reflect.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL); if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect) R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true, true); Mem_Free(pixels); @@ -3345,7 +3365,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole } // this is only used by .spr32 sprites, HL .spr files, HL .bsp files -skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height) +skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, const unsigned char *skindata, int width, int height, qboolean sRGB) { int i; unsigned char *temp1, *temp2; @@ -3386,7 +3406,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL); Mem_Free(temp1); } - skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, textureflags, -1, NULL); + skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, sRGB ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, textureflags, -1, NULL); if (textureflags & TEXF_ALPHA) { for (i = 3;i < width * height * 4;i += 4) @@ -3673,7 +3693,7 @@ rtexture_t *R_LoadCubemap(const char *basename) // generate an image name based on the base and and suffix dpsnprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix); // load it - if ((image_buffer = loadimagepixelsbgra(name, false, false, r_texture_convertsRGB_cubemap.integer != 0, NULL))) + if ((image_buffer = loadimagepixelsbgra(name, false, false, false, NULL))) { // an image loaded, make sure width and height are equal if (image_width == image_height && (!cubemappixels || image_width == cubemapsize)) @@ -3702,7 +3722,7 @@ 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, TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + cubemaptexture = R_LoadTextureCubeMap(r_main_texturepool, basename, cubemapsize, cubemappixels, r_texture_sRGB_cubemap.integer != 0 ? TEXTYPE_SRGB_BGRA : TEXTYPE_BGRA, (gl_texturecompression_lightcubemaps.integer ? TEXF_COMPRESS : 0) | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); Mem_Free(cubemappixels); } else @@ -3823,6 +3843,7 @@ void gl_main_start(void) case RENDERPATH_D3D10: case RENDERPATH_D3D11: case RENDERPATH_SOFT: + case RENDERPATH_GLES2: Cvar_SetValueQuick(&r_textureunits, vid.texunits); Cvar_SetValueQuick(&gl_combine, 1); Cvar_SetValueQuick(&r_glsl, 1); @@ -3831,6 +3852,7 @@ void gl_main_start(void) r_loadfog = false; break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: Cvar_SetValueQuick(&r_textureunits, vid.texunits); Cvar_SetValueQuick(&gl_combine, 1); Cvar_SetValueQuick(&r_glsl, 0); @@ -3846,14 +3868,6 @@ void gl_main_start(void) r_loadgloss = false; r_loadfog = true; break; - case RENDERPATH_GLES2: - Cvar_SetValueQuick(&r_textureunits, 1); - Cvar_SetValueQuick(&gl_combine, 1); - Cvar_SetValueQuick(&r_glsl, 1); - r_loadnormalmap = true; - r_loadgloss = false; - r_loadfog = false; - break; } R_AnimCache_Free(); @@ -3915,6 +3929,7 @@ void gl_main_shutdown(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: if (r_maxqueries) qglDeleteQueriesARB(r_maxqueries, r_queries); @@ -4036,6 +4051,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_farclip_base); Cvar_RegisterVariable(&r_farclip_world); Cvar_RegisterVariable(&r_nearclip); + Cvar_RegisterVariable(&r_showoverdraw); Cvar_RegisterVariable(&r_showbboxes); Cvar_RegisterVariable(&r_showsurfaces); Cvar_RegisterVariable(&r_showtris); @@ -4078,23 +4094,35 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_polygonoffset_decals_factor); Cvar_RegisterVariable(&r_polygonoffset_decals_offset); Cvar_RegisterVariable(&r_fog_exp2); + Cvar_RegisterVariable(&r_fog_clear); Cvar_RegisterVariable(&r_drawfog); Cvar_RegisterVariable(&r_transparentdepthmasking); Cvar_RegisterVariable(&r_texture_dds_load); Cvar_RegisterVariable(&r_texture_dds_save); - Cvar_RegisterVariable(&r_texture_convertsRGB_2d); - Cvar_RegisterVariable(&r_texture_convertsRGB_skin); - Cvar_RegisterVariable(&r_texture_convertsRGB_cubemap); - Cvar_RegisterVariable(&r_texture_convertsRGB_skybox); - Cvar_RegisterVariable(&r_texture_convertsRGB_particles); + Cvar_RegisterVariable(&r_texture_sRGB_2d); + Cvar_RegisterVariable(&r_texture_sRGB_skin_diffuse); + Cvar_RegisterVariable(&r_texture_sRGB_skin_gloss); + Cvar_RegisterVariable(&r_texture_sRGB_skin_glow); + Cvar_RegisterVariable(&r_texture_sRGB_skin_reflect); + Cvar_RegisterVariable(&r_texture_sRGB_cubemap); + Cvar_RegisterVariable(&r_texture_sRGB_skybox); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&gl_combine); + Cvar_RegisterVariable(&r_viewfbo); + Cvar_RegisterVariable(&r_viewscale); + Cvar_RegisterVariable(&r_viewscale_fpsscaling); + Cvar_RegisterVariable(&r_viewscale_fpsscaling_min); + Cvar_RegisterVariable(&r_viewscale_fpsscaling_multiply); + Cvar_RegisterVariable(&r_viewscale_fpsscaling_stepsize); + Cvar_RegisterVariable(&r_viewscale_fpsscaling_stepmax); + Cvar_RegisterVariable(&r_viewscale_fpsscaling_target); Cvar_RegisterVariable(&r_glsl); Cvar_RegisterVariable(&r_glsl_deluxemapping); Cvar_RegisterVariable(&r_glsl_offsetmapping); Cvar_RegisterVariable(&r_glsl_offsetmapping_steps); Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping); Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_steps); + Cvar_RegisterVariable(&r_glsl_offsetmapping_reliefmapping_refinesteps); Cvar_RegisterVariable(&r_glsl_offsetmapping_scale); Cvar_RegisterVariable(&r_glsl_postprocess); Cvar_RegisterVariable(&r_glsl_postprocess_uservec1); @@ -4550,8 +4578,9 @@ void R_AnimCache_CacheVisibleEntities(void) case RENDERPATH_D3D11: case RENDERPATH_GLES2: break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: wanttangents = false; break; case RENDERPATH_SOFT: @@ -4601,7 +4630,7 @@ static void R_View_UpdateEntityLighting (void) VectorClear(ent->modellight_ambient); VectorClear(ent->modellight_diffuse); VectorClear(tempdiffusenormal); - if ((ent->flags & RENDER_LIGHT) && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.LightPoint) + if (ent->flags & RENDER_LIGHT) { vec3_t org; Matrix4x4_OriginFromMatrix(&ent->matrix, org); @@ -4612,7 +4641,7 @@ static void R_View_UpdateEntityLighting (void) { if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites org[2] = org[2] + r_overheadsprites_pushback.value; - R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); + R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT); } else R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP); @@ -4743,24 +4772,6 @@ static void R_View_UpdateEntityVisible (void) if ((ent->flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL)) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs)) r_refdef.viewcache.entityvisible[i] = true; } - if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane) - // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling - { - for (i = 0;i < r_refdef.scene.numentities;i++) - { - ent = r_refdef.scene.entities[i]; - if(r_refdef.viewcache.entityvisible[i] && !(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*'))) - { - samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer; - if (samples < 0) - continue; // temp entities do pvs only - if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.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) - r_refdef.viewcache.entityvisible[i] = 0; - } - } - } } else { @@ -4771,6 +4782,26 @@ static void R_View_UpdateEntityVisible (void) r_refdef.viewcache.entityvisible[i] = !(ent->flags & renderimask) && ((ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)) || !R_CullBox(ent->mins, ent->maxs)); } } + if(r_cullentities_trace.integer && r_refdef.scene.worldmodel->brush.TraceLineOfSight && !r_refdef.view.useclipplane) + // sorry, this check doesn't work for portal/reflection/refraction renders as the view origin is not useful for culling + { + for (i = 0;i < r_refdef.scene.numentities;i++) + { + if (!r_refdef.viewcache.entityvisible[i]) + continue; + ent = r_refdef.scene.entities[i]; + if(!(ent->flags & (RENDER_VIEWMODEL | RENDER_NOCULL | RENDER_NODEPTHTEST)) && !(ent->model && (ent->model->name[0] == '*'))) + { + samples = ent->entitynumber ? r_cullentities_trace_samples.integer : r_cullentities_trace_tempentitysamples.integer; + if (samples < 0) + continue; // temp entities do pvs only + if(R_CanSeeBox(samples, r_cullentities_trace_enlarge.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) + r_refdef.viewcache.entityvisible[i] = 0; + } + } + } } /// only used if skyrendermasked, and normally returns false @@ -4904,14 +4935,15 @@ static void R_View_SetFrustum(const int *scissor) case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: - case RENDERPATH_SOFT: // non-flipped y coordinates fny = -1.0 + 2.0 * (vid.height - scissor[1] - scissor[3] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height); fpy = -1.0 + 2.0 * (vid.height - scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height); break; + case RENDERPATH_SOFT: case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: // non-flipped y coordinates fny = -1.0 + 2.0 * (scissor[1] - r_refdef.view.viewport.y) / (double) (r_refdef.view.viewport.height); @@ -5106,10 +5138,29 @@ void R_View_Update(void) R_View_UpdateEntityLighting(); } +float viewscalefpsadjusted = 1.0f; + +void R_GetScaledViewSize(int width, int height, int *outwidth, int *outheight) +{ + float scale = r_viewscale.value * sqrt(viewscalefpsadjusted); + scale = bound(0.03125f, scale, 1.0f); + *outwidth = (int)ceil(width * scale); + *outheight = (int)ceil(height * scale); +} + +void R_Mesh_SetMainRenderTargets(void) +{ + if (r_bloomstate.fbo_framebuffer) + R_Mesh_SetRenderTargets(r_bloomstate.fbo_framebuffer, r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL); + else + R_Mesh_ResetRenderTargets(); +} + void R_SetupView(qboolean allowwaterclippingplane) { const float *customclipplane = NULL; float plane[4]; + int scaledwidth, scaledheight; if (r_refdef.view.useclipplane && allowwaterclippingplane) { // LordHavoc: couldn't figure out how to make this approach the @@ -5120,17 +5171,29 @@ void R_SetupView(qboolean allowwaterclippingplane) plane[0] = r_refdef.view.clipplane.normal[0]; plane[1] = r_refdef.view.clipplane.normal[1]; plane[2] = r_refdef.view.clipplane.normal[2]; - plane[3] = dist; - customclipplane = plane; + plane[3] = -dist; + if(vid.renderpath != RENDERPATH_SOFT) customclipplane = plane; } + R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &scaledwidth, &scaledheight); if (!r_refdef.view.useperspective) - R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane); + R_Viewport_InitOrtho(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, -r_refdef.view.ortho_x, -r_refdef.view.ortho_y, r_refdef.view.ortho_x, r_refdef.view.ortho_y, -r_refdef.farclip, r_refdef.farclip, customclipplane); else if (vid.stencil && r_useinfinitefarclip.integer) - R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane); + R_Viewport_InitPerspectiveInfinite(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, customclipplane); else - R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane); + R_Viewport_InitPerspective(&r_refdef.view.viewport, &r_refdef.view.matrix, r_refdef.view.x, vid.height - scaledheight - r_refdef.view.y, scaledwidth, scaledheight, r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip, customclipplane); + R_Mesh_SetMainRenderTargets(); R_SetViewport(&r_refdef.view.viewport); + if (r_refdef.view.useclipplane && allowwaterclippingplane && vid.renderpath == RENDERPATH_SOFT) + { + matrix4x4_t mvpmatrix, invmvpmatrix, invtransmvpmatrix; + float screenplane[4]; + Matrix4x4_Concat(&mvpmatrix, &r_refdef.view.viewport.projectmatrix, &r_refdef.view.viewport.viewmatrix); + Matrix4x4_Invert_Full(&invmvpmatrix, &mvpmatrix); + Matrix4x4_Transpose(&invtransmvpmatrix, &invmvpmatrix); + Matrix4x4_Transform4(&invtransmvpmatrix, plane, screenplane); + DPSOFTRAST_ClipPlane(screenplane[0], screenplane[1], screenplane[2], screenplane[3]); + } } void R_EntityMatrix(const matrix4x4_t *matrix) @@ -5158,8 +5221,9 @@ void R_EntityMatrix(const matrix4x4_t *matrix) case RENDERPATH_D3D11: Con_DPrintf("FIXME D3D11 shader %s:%i\n", __FILE__, __LINE__); break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: qglLoadMatrixf(gl_modelview16f);CHECKGLERROR break; case RENDERPATH_SOFT: @@ -5182,6 +5246,7 @@ void R_ResetViewRendering2D(void) // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, 1, 1, -10, 100, NULL); + R_Mesh_ResetRenderTargets(); R_SetViewport(&viewport); GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); GL_Color(1, 1, 1, 1); @@ -5201,6 +5266,7 @@ void R_ResetViewRendering2D(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR break; @@ -5236,6 +5302,7 @@ void R_ResetViewRendering3D(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: qglEnable(GL_POLYGON_OFFSET_FILL);CHECKGLERROR break; @@ -5285,8 +5352,9 @@ static void R_Water_StartFrame(void) case RENDERPATH_SOFT: case RENDERPATH_GLES2: break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: return; } @@ -5624,6 +5692,7 @@ static void R_Water_ProcessPlanes(void) } } + if(vid.renderpath==RENDERPATH_SOFT) DPSOFTRAST_ClipPlane(0, 0, 0, 1); r_waterstate.renderingscene = false; r_refdef.view = originalview; R_ResetViewRendering3D(); @@ -5641,6 +5710,27 @@ error: void R_Bloom_StartFrame(void) { int bloomtexturewidth, bloomtextureheight, screentexturewidth, screentextureheight; + int viewwidth, viewheight; + textype_t textype; + + if (r_viewscale_fpsscaling.integer) + { + double actualframetime; + double targetframetime; + double adjust; + actualframetime = r_refdef.lastdrawscreentime; + targetframetime = (1.0 / r_viewscale_fpsscaling_target.value); + adjust = (targetframetime - actualframetime) * r_viewscale_fpsscaling_multiply.value; + adjust = bound(-r_viewscale_fpsscaling_stepmax.value, adjust, r_viewscale_fpsscaling_stepmax.value); + if (r_viewscale_fpsscaling_stepsize.value > 0) + adjust = (int)(adjust / r_viewscale_fpsscaling_stepsize.value) * r_viewscale_fpsscaling_stepsize.value; + viewscalefpsadjusted += adjust; + viewscalefpsadjusted = bound(r_viewscale_fpsscaling_min.value, viewscalefpsadjusted, 1.0f); + } + else + viewscalefpsadjusted = 1.0f; + + R_GetScaledViewSize(r_refdef.view.width, r_refdef.view.height, &viewwidth, &viewheight); switch(vid.renderpath) { @@ -5651,8 +5741,9 @@ void R_Bloom_StartFrame(void) case RENDERPATH_SOFT: case RENDERPATH_GLES2: break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: return; } @@ -5667,8 +5758,8 @@ void R_Bloom_StartFrame(void) // calculate desired texture sizes if (vid.support.arb_texture_non_power_of_two) { - screentexturewidth = r_refdef.view.width; - screentextureheight = r_refdef.view.height; + screentexturewidth = vid.width; + screentextureheight = vid.height; bloomtexturewidth = r_bloomstate.bloomwidth; bloomtextureheight = r_bloomstate.bloomheight; } @@ -5688,31 +5779,83 @@ void R_Bloom_StartFrame(void) Cvar_SetValueQuick(&r_damageblur, 0); } - if (!(r_glsl_postprocess.integer || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial)) && !r_bloom.integer && !r_hdr.integer && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0))) + if (!(r_glsl_postprocess.integer || (!R_Stereo_ColorMasking() && r_glsl_saturation.value != 1) || (v_glslgamma.integer && !vid_gammatables_trivial)) && !r_bloom.integer && !r_hdr.integer && (R_Stereo_Active() || (r_motionblur.value <= 0 && r_damageblur.value <= 0)) && r_viewfbo.integer < 1 && r_viewscale.value == 1.0f && !r_viewscale_fpsscaling.integer) screentexturewidth = screentextureheight = 0; if (!r_hdr.integer && !r_bloom.integer) bloomtexturewidth = bloomtextureheight = 0; + textype = TEXTYPE_COLORBUFFER; + switch (vid.renderpath) + { + case RENDERPATH_GL20: + case RENDERPATH_GLES2: + if (vid.support.ext_framebuffer_object) + { + if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F; + if (r_viewfbo.integer == 3) textype = TEXTYPE_COLORBUFFER32F; + } + break; + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: + case RENDERPATH_D3D9: + case RENDERPATH_D3D10: + case RENDERPATH_D3D11: + case RENDERPATH_SOFT: + break; + } + // allocate textures as needed - if (r_bloomstate.screentexturewidth != screentexturewidth || r_bloomstate.screentextureheight != screentextureheight) + if (r_bloomstate.screentexturewidth != screentexturewidth + || r_bloomstate.screentextureheight != screentextureheight + || r_bloomstate.bloomtexturewidth != bloomtexturewidth + || r_bloomstate.bloomtextureheight != bloomtextureheight + || r_bloomstate.texturetype != textype + || r_bloomstate.viewfbo != r_viewfbo.integer) { + if (r_bloomstate.texture_bloom) + R_FreeTexture(r_bloomstate.texture_bloom); + r_bloomstate.texture_bloom = NULL; if (r_bloomstate.texture_screen) R_FreeTexture(r_bloomstate.texture_screen); r_bloomstate.texture_screen = NULL; + if (r_bloomstate.fbo_framebuffer) + R_Mesh_DestroyFramebufferObject(r_bloomstate.fbo_framebuffer); + r_bloomstate.fbo_framebuffer = 0; + if (r_bloomstate.texture_framebuffercolor) + R_FreeTexture(r_bloomstate.texture_framebuffercolor); + r_bloomstate.texture_framebuffercolor = NULL; + if (r_bloomstate.texture_framebufferdepth) + R_FreeTexture(r_bloomstate.texture_framebufferdepth); + r_bloomstate.texture_framebufferdepth = NULL; r_bloomstate.screentexturewidth = screentexturewidth; r_bloomstate.screentextureheight = screentextureheight; if (r_bloomstate.screentexturewidth && r_bloomstate.screentextureheight) - r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP, -1, NULL); - } - if (r_bloomstate.bloomtexturewidth != bloomtexturewidth || r_bloomstate.bloomtextureheight != bloomtextureheight) - { - if (r_bloomstate.texture_bloom) - R_FreeTexture(r_bloomstate.texture_bloom); - r_bloomstate.texture_bloom = NULL; + r_bloomstate.texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + if (r_viewfbo.integer >= 1 && vid.support.ext_framebuffer_object) + { + // FIXME: choose depth bits based on a cvar + r_bloomstate.texture_framebufferdepth = R_LoadTextureShadowMap2D(r_main_texturepool, "framebufferdepth", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, 24, false); + r_bloomstate.texture_framebuffercolor = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_bloomstate.screentexturewidth, r_bloomstate.screentextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + r_bloomstate.fbo_framebuffer = R_Mesh_CreateFramebufferObject(r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_bloomstate.fbo_framebuffer, r_bloomstate.texture_framebufferdepth, r_bloomstate.texture_framebuffercolor, NULL, NULL, NULL); + // render depth into one texture and normalmap into the other + if (qglDrawBuffer) + { + int status; + qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR + qglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);CHECKGLERROR + status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);CHECKGLERROR + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + Con_Printf("R_Bloom_StartFrame: glCheckFramebufferStatusEXT returned %i\n", status); + } + } r_bloomstate.bloomtexturewidth = bloomtexturewidth; r_bloomstate.bloomtextureheight = bloomtextureheight; if (r_bloomstate.bloomtexturewidth && r_bloomstate.bloomtextureheight) - r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + r_bloomstate.texture_bloom = R_LoadTexture2D(r_main_texturepool, "bloom", r_bloomstate.bloomtexturewidth, r_bloomstate.bloomtextureheight, NULL, textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); + r_bloomstate.viewfbo = r_viewfbo.integer; + r_bloomstate.texturetype = textype; } // when doing a reduced render (HDR) we want to use a smaller area @@ -5725,10 +5868,10 @@ void R_Bloom_StartFrame(void) // set up a texcoord array for the full resolution screen image // (we have to keep this around to copy back during final render) r_bloomstate.screentexcoord2f[0] = 0; - r_bloomstate.screentexcoord2f[1] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight; - r_bloomstate.screentexcoord2f[2] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth; - r_bloomstate.screentexcoord2f[3] = (float)r_refdef.view.height / (float)r_bloomstate.screentextureheight; - r_bloomstate.screentexcoord2f[4] = (float)r_refdef.view.width / (float)r_bloomstate.screentexturewidth; + r_bloomstate.screentexcoord2f[1] = (float)viewheight / (float)r_bloomstate.screentextureheight; + r_bloomstate.screentexcoord2f[2] = (float)viewwidth / (float)r_bloomstate.screentexturewidth; + r_bloomstate.screentexcoord2f[3] = (float)viewheight / (float)r_bloomstate.screentextureheight; + r_bloomstate.screentexcoord2f[4] = (float)viewwidth / (float)r_bloomstate.screentexturewidth; r_bloomstate.screentexcoord2f[5] = 0; r_bloomstate.screentexcoord2f[6] = 0; r_bloomstate.screentexcoord2f[7] = 0; @@ -5750,6 +5893,7 @@ void R_Bloom_StartFrame(void) case RENDERPATH_GL13: case RENDERPATH_GL20: case RENDERPATH_SOFT: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: break; case RENDERPATH_D3D9: @@ -5768,13 +5912,16 @@ void R_Bloom_StartFrame(void) break; } - if (r_hdr.integer || r_bloom.integer) + if ((r_hdr.integer || r_bloom.integer) && r_bloomstate.bloomwidth) { r_bloomstate.enabled = true; - r_bloomstate.hdr = r_hdr.integer != 0; + r_bloomstate.hdr = r_hdr.integer != 0 && !r_bloomstate.fbo_framebuffer; } R_Viewport_InitOrtho(&r_bloomstate.viewport, &identitymatrix, r_refdef.view.x, vid.height - r_bloomstate.bloomheight - r_refdef.view.y, r_bloomstate.bloomwidth, r_bloomstate.bloomheight, 0, 0, 1, 1, -10, 100, NULL); + + if (r_bloomstate.fbo_framebuffer) + r_refdef.view.clear = true; } void R_Bloom_CopyBloomTexture(float colorscale) @@ -5783,6 +5930,7 @@ void R_Bloom_CopyBloomTexture(float colorscale) // scale down screen texture to the bloom texture size CHECKGLERROR + R_Mesh_SetMainRenderTargets(); R_SetViewport(&r_bloomstate.viewport); GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(colorscale, colorscale, colorscale, 1); @@ -5792,8 +5940,9 @@ void R_Bloom_CopyBloomTexture(float colorscale) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: - case RENDERPATH_SOFT: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: + case RENDERPATH_SOFT: R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f); break; case RENDERPATH_D3D9: @@ -5850,7 +5999,7 @@ void R_Bloom_MakeTexture(void) range = r_bloom_blur.integer * r_bloomstate.bloomwidth / 320; brighten = r_bloom_brighten.value; - if (r_hdr.integer) + if (r_bloomstate.hdr) brighten *= r_hdr_range.value; brighten = sqrt(brighten); if(range >= 1) @@ -5985,6 +6134,7 @@ static void R_BlendView(void) if (r_bloom_blur.value < 1) { Cvar_SetValueQuick(&r_bloom_blur, 1); } R_ResetViewRendering2D(); + R_Mesh_SetMainRenderTargets(); if(!R_Stereo_Active() && (r_motionblur.value > 0 || r_damageblur.value > 0)) { @@ -6024,8 +6174,9 @@ static void R_BlendView(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GL20: - case RENDERPATH_SOFT: + case RENDERPATH_GLES1: case RENDERPATH_GLES2: + case RENDERPATH_SOFT: R_Mesh_PrepareVertices_Generic_Arrays(4, r_screenvertex3f, NULL, r_bloomstate.screentexcoord2f); break; case RENDERPATH_D3D9: @@ -6150,10 +6301,11 @@ static void R_BlendView(void) break; } R_Mesh_Draw(0, 4, 0, 2, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); - r_refdef.stats.bloom_drawpixels += r_refdef.view.viewport.width * r_refdef.view.viewport.height; + r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height; break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: if (r_refdef.viewblend[3] >= (1.0f / 256.0f)) { // apply a color tint to the whole view @@ -6335,8 +6487,9 @@ void R_UpdateVariables(void) // remove GLSL gamma texture } break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: break; } } @@ -6455,7 +6608,7 @@ void R_RenderView(void) r_refdef.view.clear = true; // this produces a bloom texture to be used in R_BlendView() later - if (r_hdr.integer && r_bloomstate.bloomwidth) + if (r_bloomstate.hdr) { R_HDR_RenderBloomTexture(); // we have to bump the texture frame again because r_refdef.view.colorscale is cached in the textures @@ -6718,7 +6871,7 @@ void R_RenderScene(void) if (r_timereport_active) R_TimeReport("drawtrans"); - if (r_refdef.view.showdebug && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDebug && (r_showtris.value > 0 || r_shownormals.value != 0 || r_showcollisionbrushes.value > 0)) + if (r_refdef.view.showdebug && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->DrawDebug && (r_showtris.value > 0 || r_shownormals.value != 0 || r_showcollisionbrushes.value > 0 || r_showoverdraw.value > 0)) { r_refdef.scene.worldmodel->DrawDebug(r_refdef.scene.worldentity); if (r_timereport_active) @@ -7359,7 +7512,7 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT; else if (FAKELIGHT_ENABLED) { - // no modellight if using fakelight for the map + // no modellight if using fakelight for the map } else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) { @@ -9204,6 +9357,12 @@ static void RSurf_DrawBatch_GL11_MakeFogColor(float r, float g, float b, float a float f; const float *v; float *c; + + // fake shading + rsurface.passcolor4f = (float *)R_FrameData_Alloc(rsurface.batchnumvertices * sizeof(float[4])); + rsurface.passcolor4f_vertexbuffer = 0; + rsurface.passcolor4f_bufferoffset = 0; + for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, c = rsurface.passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, c += 4) { f = 1 - RSurf_FogVertex(v); @@ -9753,6 +9912,7 @@ static void R_DrawWorldTextureSurfaceList(int texturenumsurfaces, const msurface R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass); break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth); break; case RENDERPATH_GL11: @@ -9782,6 +9942,7 @@ static void R_DrawModelTextureSurfaceList(int texturenumsurfaces, const msurface R_DrawTextureSurfaceList_GL20(texturenumsurfaces, texturesurfacelist, writedepth, prepass); break; case RENDERPATH_GL13: + case RENDERPATH_GLES1: R_DrawTextureSurfaceList_GL13(texturenumsurfaces, texturesurfacelist, writedepth); break; case RENDERPATH_GL11: @@ -9819,8 +9980,9 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const case RENDERPATH_GLES2: RSurf_ActiveModelEntity(ent, true, true, false); break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: RSurf_ActiveModelEntity(ent, true, false, false); break; } @@ -9973,7 +10135,7 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf else R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } - else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer) + else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3)) R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; @@ -10051,7 +10213,7 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf else R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } - else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && !r_showsurfaces.integer) + else if ((rsurface.texture->currentmaterialflags & MATERIALFLAG_SKY) && (!r_showsurfaces.integer || r_showsurfaces.integer == 3)) R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; @@ -10269,6 +10431,9 @@ static void R_DecalSystem_SpawnTriangle(decalsystem_t *decalsystem, const float decal->texcoord2f[1][1] = t1[1]; decal->texcoord2f[2][0] = t2[0]; decal->texcoord2f[2][1] = t2[1]; + TriangleNormal(v0, v1, v2, decal->plane); + VectorNormalize(decal->plane); + decal->plane[3] = DotProduct(v0, decal->plane); } extern cvar_t cl_decals_bias; @@ -10722,6 +10887,10 @@ static void R_DrawModelDecals_Entity(entity_render_t *ent) if (surfacevisible && !surfacevisible[decal->surfaceindex]) continue; + // skip backfaces + if (decal->triangleindex < 0 && DotProduct(r_refdef.view.origin, decal->plane) < decal->plane[3]) + continue; + // update color values for fading decals if (decal->lived >= cl_decals_time.value) alpha = 1 - faderate * (decal->lived - cl_decals_time.value); @@ -10844,27 +11013,38 @@ void R_DrawDebugModel(void) dp_model_t *model = ent->model; vec3_t v; - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - break; - case RENDERPATH_D3D9: - //Con_DPrintf("FIXME D3D9 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - return; - case RENDERPATH_D3D10: - Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - return; - case RENDERPATH_D3D11: - Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - return; - case RENDERPATH_SOFT: - //Con_DPrintf("FIXME SOFT %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); - return; - case RENDERPATH_GLES2: - //Con_DPrintf("FIXME GLES2 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); + if (!sv.active && !cls.demoplayback && ent != r_refdef.scene.worldentity) return; + + if (r_showoverdraw.value > 0) + { + float c = r_refdef.view.colorscale * r_showoverdraw.value * 0.125f; + flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL; + R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1); + GL_DepthTest(false); + GL_DepthMask(false); + GL_DepthRange(0, 1); + GL_BlendFunc(GL_ONE, GL_ONE); + for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) + { + if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j]) + continue; + rsurface.texture = R_GetCurrentTexture(surface->texture); + if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles) + { + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_NOGAPS, 1, &surface); + GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : r_refdef.view.cullface_back); + if (!rsurface.texture->currentlayers->depthmask) + GL_Color(c, 0, 0, 1.0f); + else if (ent == r_refdef.scene.worldentity) + GL_Color(c, c, c, 1.0f); + else + GL_Color(0, c, 0, 1.0f); + R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL); + RSurf_DrawBatch(); + } + } + rsurface.texture = NULL; } flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL; @@ -10926,7 +11106,7 @@ void R_DrawDebugModel(void) GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset); - if (r_showtris.integer || (r_shownormals.value != 0)) + if (r_showtris.integer && qglPolygonMode) { if (r_showdisabledepthtest.integer) { @@ -10938,6 +11118,7 @@ void R_DrawDebugModel(void) GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); } + qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);CHECKGLERROR for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) { if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j]) @@ -10946,23 +11127,43 @@ void R_DrawDebugModel(void) if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles) { RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface); - if (r_showtris.value > 0) - { - if (!rsurface.texture->currentlayers->depthmask) - GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value); - else if (ent == r_refdef.scene.worldentity) - GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value); - else - GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value); - R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL); - qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - RSurf_DrawBatch(); - qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - CHECKGLERROR - } + if (!rsurface.texture->currentlayers->depthmask) + GL_Color(r_refdef.view.colorscale, 0, 0, r_showtris.value); + else if (ent == r_refdef.scene.worldentity) + GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, r_showtris.value); + else + GL_Color(0, r_refdef.view.colorscale, 0, r_showtris.value); + R_Mesh_PrepareVertices_Generic_Arrays(rsurface.batchnumvertices, rsurface.batchvertex3f, NULL, NULL); + RSurf_DrawBatch(); + } + } + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);CHECKGLERROR + rsurface.texture = NULL; + } + + if (r_shownormals.value != 0 && qglBegin) + { + if (r_showdisabledepthtest.integer) + { + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GL_DepthMask(false); + } + else + { + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthMask(true); + } + for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) + { + if (ent == r_refdef.scene.worldentity && !r_refdef.viewcache.world_surfacevisible[j]) + continue; + rsurface.texture = R_GetCurrentTexture(surface->texture); + if ((rsurface.texture->currentmaterialflags & flagsmask) && surface->num_triangles) + { + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_ARRAY_VECTOR | BATCHNEED_NOGAPS, 1, &surface); + qglBegin(GL_LINES); if (r_shownormals.value < 0) { - qglBegin(GL_LINES); for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++) { VectorCopy(rsurface.batchvertex3f + l * 3, v); @@ -10972,12 +11173,9 @@ void R_DrawDebugModel(void) GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1); qglVertex3f(v[0], v[1], v[2]); } - qglEnd(); - CHECKGLERROR } if (r_shownormals.value > 0 && rsurface.batchsvector3f) { - qglBegin(GL_LINES); for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++) { VectorCopy(rsurface.batchvertex3f + l * 3, v); @@ -10987,9 +11185,6 @@ void R_DrawDebugModel(void) GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1); qglVertex3f(v[0], v[1], v[2]); } - qglEnd(); - CHECKGLERROR - qglBegin(GL_LINES); for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++) { VectorCopy(rsurface.batchvertex3f + l * 3, v); @@ -10999,9 +11194,6 @@ void R_DrawDebugModel(void) GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1); qglVertex3f(v[0], v[1], v[2]); } - qglEnd(); - CHECKGLERROR - qglBegin(GL_LINES); for (k = 0, l = rsurface.batchfirstvertex;k < rsurface.batchnumvertices;k++, l++) { VectorCopy(rsurface.batchvertex3f + l * 3, v); @@ -11011,9 +11203,9 @@ void R_DrawDebugModel(void) GL_Color(r_refdef.view.colorscale, r_refdef.view.colorscale, r_refdef.view.colorscale, 1); qglVertex3f(v[0], v[1], v[2]); } - qglEnd(); - CHECKGLERROR } + qglEnd(); + CHECKGLERROR } } rsurface.texture = NULL; @@ -11157,8 +11349,9 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr case RENDERPATH_GLES2: RSurf_ActiveModelEntity(ent, model->wantnormals, model->wanttangents, false); break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: RSurf_ActiveModelEntity(ent, model->wantnormals, false, false); break; } @@ -11175,8 +11368,9 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr case RENDERPATH_GLES2: RSurf_ActiveModelEntity(ent, true, true, false); break; - case RENDERPATH_GL13: case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: RSurf_ActiveModelEntity(ent, true, false, false); break; }