X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=gl_rmain.c;h=c61abfcf04e2d341de170be6118998a242101eb1;hb=0732f3fb08b62b1d907235222d5ea9daf00641ca;hp=cd72658e7d9b429b3c237eda5aece3b2d8ca4d0b;hpb=2a755441321c22a7a4210bb3c3f6ae0de80eca6b;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index cd72658e..c61abfcf 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -28,21 +28,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. mempool_t *r_main_mempool; rtexturepool_t *r_main_texturepool; -static int r_frame = 0; // used only by R_GetCurrentTexture +static int r_frame = 0; ///< used only by R_GetCurrentTexture // // screen size info // r_refdef_t r_refdef; -cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "motionblur frame-by-frame alpha control {0 to 1} - 0.7 recommended"}; -cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "motionblur based on damage; requires r_motionblur to have a value"}; -cvar_t r_motionblur_vmin = {CVAR_SAVE, "r_motionblur_vmin", "300", "velocity at which there is minimum blur"}; -cvar_t r_motionblur_vmax = {CVAR_SAVE, "r_motionblur_vmax", "600", "velocity at which there is full blur"}; +cvar_t r_motionblur = {CVAR_SAVE, "r_motionblur", "0", "motionblur value scale - 0.7 recommended"}; +cvar_t r_damageblur = {CVAR_SAVE, "r_damageblur", "0", "motionblur based on damage"}; +cvar_t r_motionblur_vmin = {CVAR_SAVE, "r_motionblur_vmin", "300", "minimum influence from velocity"}; +cvar_t r_motionblur_vmax = {CVAR_SAVE, "r_motionblur_vmax", "600", "maximum influence from velocity"}; cvar_t r_motionblur_bmin = {CVAR_SAVE, "r_motionblur_bmin", "0.5", "velocity at which there is no blur yet (may be negative to always have some blur)"}; -cvar_t r_motionblur_vtime = {CVAR_SAVE, "r_motionblur_vcoeff", "0.05", "sliding average reaction time for velocity"}; -cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.88", "cap for the alpha level of the motion blur variable"}; -cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.01", "randomizing coefficient to fix ghosting"}; +cvar_t r_motionblur_vcoeff = {CVAR_SAVE, "r_motionblur_vcoeff", "0.05", "sliding average reaction time for velocity"}; +cvar_t r_motionblur_maxblur = {CVAR_SAVE, "r_motionblur_maxblur", "0.88", "cap for motionblur alpha value"}; +cvar_t r_motionblur_randomize = {CVAR_SAVE, "r_motionblur_randomize", "0.1", "randomizing coefficient to workaround ghosting"}; cvar_t r_motionblur_debug = {0, "r_motionblur_debug", "0", "outputs current motionblur alpha value"}; cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "0", "renders a depth-only version of the scene before normal rendering begins to eliminate overdraw, values: 0 = off, 1 = world depth, 2 = world and model depth"}; @@ -152,7 +152,7 @@ static struct r_bloomstate_s int bloomwidth, bloomheight; int screentexturewidth, screentextureheight; - rtexture_t *texture_screen; // also used for motion blur if enabled! + rtexture_t *texture_screen; /// \note also used for motion blur if enabled! int bloomtexturewidth, bloomtextureheight; rtexture_t *texture_bloom; @@ -166,7 +166,7 @@ r_bloomstate; r_waterstate_t r_waterstate; -// shadow volume bsp struct with automatically growing nodes buffer +/// shadow volume bsp struct with automatically growing nodes buffer svbsp_t r_svbsp; rtexture_t *r_texture_blanknormalmap; @@ -188,7 +188,7 @@ unsigned int r_maxqueries; char r_qwskincache[MAX_SCOREBOARD][MAX_QPATH]; skinframe_t *r_qwskincache_skinframe[MAX_SCOREBOARD]; -// vertex coordinates for a quad that covers the screen exactly +/// vertex coordinates for a quad that covers the screen exactly const static float r_screenvertex3f[12] = { 0, 0, 0, @@ -590,6 +590,9 @@ static const char *builtinshaderstring = "#else // !MODE_GENERIC\n" "\n" "varying vec2 TexCoord;\n" +"#ifdef USEVERTEXTEXTUREBLEND\n" +"varying vec2 TexCoord2;\n" +"#endif\n" "varying vec2 TexCoordLightmap;\n" "\n" "#ifdef MODE_LIGHTSOURCE\n" @@ -640,6 +643,9 @@ static const char *builtinshaderstring = " gl_FrontColor = gl_Color;\n" " // copy the surface texcoord\n" " TexCoord = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);\n" +"#ifdef USEVERTEXTEXTUREBLEND\n" +" TexCoord2 = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord0);\n" +"#endif\n" "#ifndef MODE_LIGHTSOURCE\n" "# ifndef MODE_LIGHTDIRECTION\n" " TexCoordLightmap = vec2(gl_MultiTexCoord4);\n" @@ -881,7 +887,7 @@ static const char *builtinshaderstring = " myhalf terrainblend = clamp(myhalf(gl_Color.a) * color.a * 2.0 - 0.5, myhalf(0.0), myhalf(1.0));\n" " //myhalf terrainblend = min(myhalf(gl_Color.a) * color.a * 2.0, myhalf(1.0));\n" " //myhalf terrainblend = myhalf(gl_Color.a) * color.a > 0.5;\n" -" color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord)), color.rgb, terrainblend);\n" +" color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord2)), color.rgb, terrainblend);\n" " color.a = 1.0;\n" " //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n" "#endif\n" @@ -889,9 +895,9 @@ static const char *builtinshaderstring = "#ifdef USEDIFFUSE\n" " // get the surface normal and the gloss color\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n" +" myhalf3 surfacenormal = normalize(mix(myhalf3(texture2D(Texture_SecondaryNormal, TexCoord2)), myhalf3(texture2D(Texture_Normal, TexCoord)), terrainblend) - myhalf3(0.5, 0.5, 0.5));\n" "# ifdef USESPECULAR\n" -" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" +" myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord2)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" "# endif\n" "# else\n" " myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n" @@ -1061,8 +1067,12 @@ static const char *builtinshaderstring = " color *= TintColor;\n" "\n" "#ifdef USEGLOW\n" +"#ifdef USEVERTEXTEXTUREBLEND\n" +" color.rgb += mix(myhalf3(texture2D(Texture_SecondaryGlow, TexCoord2)), myhalf3(texture2D(Texture_Glow, TexCoord)), terrainblend);\n" +"#else\n" " color.rgb += myhalf3(texture2D(Texture_Glow, TexCoord)) * GlowScale;\n" "#endif\n" +"#endif\n" "\n" "#ifdef USECONTRASTBOOST\n" " color.rgb = color.rgb / (ContrastBoostCoeff * color.rgb + myhalf3(1, 1, 1));\n" @@ -1114,23 +1124,23 @@ shadermodeinfo_t; typedef enum shaderpermutation_e { - SHADERPERMUTATION_DIFFUSE = 1<<0, // (lightsource) whether to use directional shading - SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, // indicates this is a two-layer material blend based on vertex alpha (q3bsp) - SHADERPERMUTATION_COLORMAPPING = 1<<2, // indicates this is a colormapped skin - SHADERPERMUTATION_CONTRASTBOOST = 1<<3, // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma) - SHADERPERMUTATION_FOG = 1<<4, // tint the color by fog color or black if using additive blend mode - SHADERPERMUTATION_CUBEFILTER = 1<<5, // (lightsource) use cubemap light filter - SHADERPERMUTATION_GLOW = 1<<6, // (lightmap) blend in an additive glow texture - SHADERPERMUTATION_SPECULAR = 1<<7, // (lightsource or deluxemapping) render specular effects - SHADERPERMUTATION_EXACTSPECULARMATH = 1<<8, // (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation - SHADERPERMUTATION_REFLECTION = 1<<9, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface - SHADERPERMUTATION_OFFSETMAPPING = 1<<10, // adjust texcoords to roughly simulate a displacement mapped surface - SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<11, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!) - SHADERPERMUTATION_GAMMARAMPS = 1<<12, // gamma (postprocessing only) - SHADERPERMUTATION_POSTPROCESSING = 1<<13, // user defined postprocessing - SHADERPERMUTATION_SATURATION = 1<<14, // user defined postprocessing - SHADERPERMUTATION_LIMIT = 1<<15, // size of permutations array - SHADERPERMUTATION_COUNT = 15 // size of shaderpermutationinfo array + SHADERPERMUTATION_DIFFUSE = 1<<0, ///< (lightsource) whether to use directional shading + SHADERPERMUTATION_VERTEXTEXTUREBLEND = 1<<1, ///< indicates this is a two-layer material blend based on vertex alpha (q3bsp) + SHADERPERMUTATION_COLORMAPPING = 1<<2, ///< indicates this is a colormapped skin + SHADERPERMUTATION_CONTRASTBOOST = 1<<3, ///< r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma) + SHADERPERMUTATION_FOG = 1<<4, ///< tint the color by fog color or black if using additive blend mode + SHADERPERMUTATION_CUBEFILTER = 1<<5, ///< (lightsource) use cubemap light filter + SHADERPERMUTATION_GLOW = 1<<6, ///< (lightmap) blend in an additive glow texture + SHADERPERMUTATION_SPECULAR = 1<<7, ///< (lightsource or deluxemapping) render specular effects + SHADERPERMUTATION_EXACTSPECULARMATH = 1<<8, ///< (lightsource or deluxemapping) use exact reflection map for specular effects, as opposed to the usual OpenGL approximation + SHADERPERMUTATION_REFLECTION = 1<<9, ///< normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface + SHADERPERMUTATION_OFFSETMAPPING = 1<<10, ///< adjust texcoords to roughly simulate a displacement mapped surface + SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<11, ///< adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!) + SHADERPERMUTATION_GAMMARAMPS = 1<<12, ///< gamma (postprocessing only) + SHADERPERMUTATION_POSTPROCESSING = 1<<13, ///< user defined postprocessing + SHADERPERMUTATION_SATURATION = 1<<14, ///< user defined postprocessing + SHADERPERMUTATION_LIMIT = 1<<15, ///< size of permutations array + SHADERPERMUTATION_COUNT = 15 ///< size of shaderpermutationinfo array } shaderpermutation_t; @@ -1154,21 +1164,21 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USESATURATION\n", " saturation"}, }; -// this enum is multiplied by SHADERPERMUTATION_MODEBASE +/// this enum is multiplied by SHADERPERMUTATION_MODEBASE typedef enum shadermode_e { - SHADERMODE_GENERIC, // (particles/HUD/etc) vertex color, optionally multiplied by one texture - SHADERMODE_POSTPROCESS, // postprocessing shader (r_glsl_postprocess) - SHADERMODE_DEPTH_OR_SHADOW, // (depthfirst/shadows) vertex shader only - SHADERMODE_FLATCOLOR, // (lightmap) modulate texture by uniform color (q1bsp, q3bsp) - SHADERMODE_VERTEXCOLOR, // (lightmap) modulate texture by vertex colors (q3bsp) - SHADERMODE_LIGHTMAP, // (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp) - SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, // (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap) - SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, // (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap) - SHADERMODE_LIGHTDIRECTION, // (lightmap) use directional pixel shading from fixed light direction (q3bsp) - SHADERMODE_LIGHTSOURCE, // (lightsource) use directional pixel shading from light source (rtlight) - SHADERMODE_REFRACTION, // refract background (the material is rendered normally after this pass) - SHADERMODE_WATER, // refract background and reflection (the material is rendered normally after this pass) + SHADERMODE_GENERIC, ///< (particles/HUD/etc) vertex color, optionally multiplied by one texture + SHADERMODE_POSTPROCESS, ///< postprocessing shader (r_glsl_postprocess) + SHADERMODE_DEPTH_OR_SHADOW, ///< (depthfirst/shadows) vertex shader only + SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp) + SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp) + SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp) + SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap) + SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap) + SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp) + SHADERMODE_LIGHTSOURCE, ///< (lightsource) use directional pixel shading from light source (rtlight) + SHADERMODE_REFRACTION, ///< refract background (the material is rendered normally after this pass) + SHADERMODE_WATER, ///< refract background and reflection (the material is rendered normally after this pass) SHADERMODE_COUNT } shadermode_t; @@ -1192,11 +1202,11 @@ shadermodeinfo_t shadermodeinfo[SHADERMODE_COUNT] = typedef struct r_glsl_permutation_s { - // indicates if we have tried compiling this permutation already + /// indicates if we have tried compiling this permutation already qboolean compiled; - // 0 if compilation failed + /// 0 if compilation failed int program; - // locations of detected uniforms in program object, or -1 if not found + /// locations of detected uniforms in program object, or -1 if not found int loc_Texture_First; int loc_Texture_Second; int loc_Texture_GammaRamps; @@ -1235,8 +1245,8 @@ typedef struct r_glsl_permutation_s int loc_DiffuseColor; int loc_SpecularColor; int loc_LightDir; - int loc_ContrastBoostCoeff; // 1 - 1/ContrastBoost - int loc_GammaCoeff; // 1 / gamma + int loc_ContrastBoostCoeff; ///< 1 - 1/ContrastBoost + int loc_GammaCoeff; ///< 1 / gamma int loc_DistortScaleRefractReflect; int loc_ScreenScaleRefractReflect; int loc_ScreenCenterRefractReflect; @@ -1254,9 +1264,9 @@ typedef struct r_glsl_permutation_s } r_glsl_permutation_t; -// information about each possible shader permutation +/// information about each possible shader permutation r_glsl_permutation_t r_glsl_permutations[SHADERMODE_COUNT][SHADERPERMUTATION_LIMIT]; -// currently selected permutation +/// currently selected permutation r_glsl_permutation_t *r_glsl_permutation; static char *R_GLSL_GetText(const char *filename, qboolean printfromdisknotice) @@ -1411,6 +1421,7 @@ static void R_GLSL_CompilePermutation(unsigned int mode, unsigned int permutatio p->loc_UserVec4 = qglGetUniformLocationARB(p->program, "UserVec4"); p->loc_ClientTime = qglGetUniformLocationARB(p->program, "ClientTime"); p->loc_PixelSize = qglGetUniformLocationARB(p->program, "PixelSize"); + p->loc_Saturation = qglGetUniformLocationARB(p->program, "Saturation"); // initialize the samplers to refer to the texture units we use if (p->loc_Texture_First >= 0) qglUniform1iARB(p->loc_Texture_First , GL20TU_FIRST); if (p->loc_Texture_Second >= 0) qglUniform1iARB(p->loc_Texture_Second , GL20TU_SECOND); @@ -2391,7 +2402,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_motionblur_bmin); Cvar_RegisterVariable(&r_motionblur_vmin); Cvar_RegisterVariable(&r_motionblur_vmax); - Cvar_RegisterVariable(&r_motionblur_vtime); + Cvar_RegisterVariable(&r_motionblur_vcoeff); Cvar_RegisterVariable(&r_motionblur_randomize); Cvar_RegisterVariable(&r_damageblur); Cvar_RegisterVariable(&r_motionblur_debug); @@ -2731,7 +2742,7 @@ static void R_View_UpdateEntityVisible (void) } } -// only used if skyrendermasked, and normally returns false +/// only used if skyrendermasked, and normally returns false int R_DrawBrushModelsSky (void) { int i, sky; @@ -3337,14 +3348,15 @@ void R_Bloom_StartFrame(void) for (bloomtextureheight = 1;bloomtextureheight < r_bloomstate.bloomheight;bloomtextureheight *= 2); } - if ((r_hdr.integer || r_bloom.integer || r_motionblur.value) && ((r_bloom_resolution.integer < 4 || r_bloom_blur.value < 1 || r_bloom_blur.value >= 512) || r_refdef.view.width > gl_max_texture_size || r_refdef.view.height > gl_max_texture_size)) + if ((r_hdr.integer || r_bloom.integer || 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 > gl_max_texture_size || r_refdef.view.height > gl_max_texture_size)) { Cvar_SetValueQuick(&r_hdr, 0); Cvar_SetValueQuick(&r_bloom, 0); - //Cvar_SetValueQuick(&r_motionblur, 0); + Cvar_SetValueQuick(&r_motionblur, 0); + Cvar_SetValueQuick(&r_damageblur, 0); } - if (!(r_glsl.integer && (r_glsl_postprocess.integer || (v_glslgamma.integer && !vid_gammatables_trivial))) && !r_bloom.integer && !r_hdr.integer && !r_motionblur.value) + if (!(r_glsl.integer && (r_glsl_postprocess.integer || r_glsl_saturation.value != 1 || (v_glslgamma.integer && !vid_gammatables_trivial))) && !r_bloom.integer && !r_hdr.integer && r_motionblur.value <= 0 && r_damageblur.value <= 0) screentexturewidth = screentextureheight = 0; if (!r_hdr.integer && !r_bloom.integer) bloomtexturewidth = bloomtextureheight = 0; @@ -3618,7 +3630,7 @@ static void R_BlendView(void) speed = VectorLength(cl.movement_velocity); - a = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_vtime.value), 1); + a = bound(0, (cl.time - cl.oldtime) / max(0.001, r_motionblur_vcoeff.value), 1); avgspeed = avgspeed * (1 - a) + speed * a; speed = (avgspeed - r_motionblur_vmin.value) / max(1, r_motionblur_vmax.value - r_motionblur_vmin.value); @@ -4706,14 +4718,70 @@ static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms) return (float)(parms[0] + parms[1] * f); } -texture_t *R_GetCurrentTexture(texture_t *t) +void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcmod_t *tcmod, int currentmaterialflags) { int w, h, idx; + float f; + float tcmat[12]; + matrix4x4_t matrix, temp; + switch(tcmod->tcmod) + { + case Q3TCMOD_COUNT: + case Q3TCMOD_NONE: + if (currentmaterialflags & MATERIALFLAG_WATERSCROLL) + matrix = r_waterscrollmatrix; + else + matrix = identitymatrix; + break; + case Q3TCMOD_ENTITYTRANSLATE: + // this is used in Q3 to allow the gamecode to control texcoord + // scrolling on the entity, which is not supported in darkplaces yet. + Matrix4x4_CreateTranslate(&matrix, 0, 0, 0); + break; + case Q3TCMOD_ROTATE: + Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0); + Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.scene.time, 0, 0, 1); + Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0); + break; + case Q3TCMOD_SCALE: + Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1); + break; + case Q3TCMOD_SCROLL: + 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 = (int) tcmod->parms[0]; + h = (int) tcmod->parms[1]; + f = r_refdef.scene.time / (tcmod->parms[2] * w * h); + f = f - floor(f); + idx = (int) floor(f * w * h); + Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0); + break; + case Q3TCMOD_STRETCH: + f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms); + Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f); + break; + case Q3TCMOD_TRANSFORM: + VectorSet(tcmat + 0, tcmod->parms[0], tcmod->parms[1], 0); + VectorSet(tcmat + 3, tcmod->parms[2], tcmod->parms[3], 0); + VectorSet(tcmat + 6, 0 , 0 , 1); + VectorSet(tcmat + 9, tcmod->parms[4], tcmod->parms[5], 0); + Matrix4x4_FromArray12FloatGL(&matrix, tcmat); + break; + case Q3TCMOD_TURBULENT: + // this is handled in the RSurf_PrepareVertices function + matrix = identitymatrix; + break; + } + temp = *texmatrix; + Matrix4x4_Concat(texmatrix, &matrix, &temp); +} + +texture_t *R_GetCurrentTexture(texture_t *t) +{ int i; const entity_render_t *ent = rsurface.entity; dp_model_t *model = ent->model; - float f; - float tcmat[12]; q3shaderinfo_layer_tcmod_t *tcmod; if (t->update_lastrenderframe == r_frame && t->update_lastrenderentity == (void *)ent) @@ -4807,70 +4875,21 @@ texture_t *R_GetCurrentTexture(texture_t *t) // there is no tcmod if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL) + { t->currenttexmatrix = r_waterscrollmatrix; - - for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) + t->currentbackgroundtexmatrix = r_waterscrollmatrix; + } + else { - matrix4x4_t matrix; - switch(tcmod->tcmod) - { - case Q3TCMOD_COUNT: - case Q3TCMOD_NONE: - if (t->currentmaterialflags & MATERIALFLAG_WATERSCROLL) - matrix = r_waterscrollmatrix; - else - matrix = identitymatrix; - break; - case Q3TCMOD_ENTITYTRANSLATE: - // this is used in Q3 to allow the gamecode to control texcoord - // scrolling on the entity, which is not supported in darkplaces yet. - Matrix4x4_CreateTranslate(&matrix, 0, 0, 0); - break; - case Q3TCMOD_ROTATE: - Matrix4x4_CreateTranslate(&matrix, 0.5, 0.5, 0); - Matrix4x4_ConcatRotate(&matrix, tcmod->parms[0] * r_refdef.scene.time, 0, 0, 1); - Matrix4x4_ConcatTranslate(&matrix, -0.5, -0.5, 0); - break; - case Q3TCMOD_SCALE: - Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1); - break; - case Q3TCMOD_SCROLL: - 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 = (int) tcmod->parms[0]; - h = (int) tcmod->parms[1]; - f = r_refdef.scene.time / (tcmod->parms[2] * w * h); - f = f - floor(f); - idx = (int) floor(f * w * h); - Matrix4x4_CreateTranslate(&matrix, (idx % w) / tcmod->parms[0], (idx / w) / tcmod->parms[1], 0); - break; - case Q3TCMOD_STRETCH: - f = 1.0f / R_EvaluateQ3WaveFunc(tcmod->wavefunc, tcmod->waveparms); - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5f * (1 - f), 0.5 * (1 - f), 0, 0, 0, 0, f); - break; - case Q3TCMOD_TRANSFORM: - VectorSet(tcmat + 0, tcmod->parms[0], tcmod->parms[1], 0); - VectorSet(tcmat + 3, tcmod->parms[2], tcmod->parms[3], 0); - VectorSet(tcmat + 6, 0 , 0 , 1); - VectorSet(tcmat + 9, tcmod->parms[4], tcmod->parms[5], 0); - Matrix4x4_FromArray12FloatGL(&matrix, tcmat); - break; - case Q3TCMOD_TURBULENT: - // this is handled in the RSurf_PrepareVertices function - matrix = identitymatrix; - break; - } - // either replace or concatenate the transformation - if (i < 1) - t->currenttexmatrix = matrix; - else - { - matrix4x4_t temp = t->currenttexmatrix; - Matrix4x4_Concat(&t->currenttexmatrix, &matrix, &temp); - } + Matrix4x4_CreateIdentity(&t->currenttexmatrix); + Matrix4x4_CreateIdentity(&t->currentbackgroundtexmatrix); } + for (i = 0, tcmod = t->tcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) + R_tcMod_ApplyToMatrix(&t->currenttexmatrix, tcmod, t->currentmaterialflags); + for (i = 0, tcmod = t->backgroundtcmods;i < Q3MAXTCMODS && tcmod->tcmod;i++, tcmod++) + R_tcMod_ApplyToMatrix(&t->currentbackgroundtexmatrix, tcmod, t->currentmaterialflags); + t->colormapping = VectorLength2(ent->colormap_pantscolor) + VectorLength2(ent->colormap_shirtcolor) >= (1.0f / 1048576.0f); t->basetexture = (!t->colormapping && t->currentskinframe->merged) ? t->currentskinframe->merged : t->currentskinframe->base; t->glosstexture = r_texture_black; @@ -5406,8 +5425,8 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta VectorSubtract(end, start, up); VectorNormalize(up); // calculate a forward vector to use instead of the original plane normal (this is how we get a new right vector) - //VectorSubtract(rsurface.modelorg, center, forward); - Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, forward); + VectorSubtract(rsurface.modelorg, center, forward); + //Matrix4x4_Transform3x3(&rsurface.inversematrix, r_refdef.view.forward, forward); VectorNegate(forward, forward); VectorReflect(forward, 0, up, forward); VectorNormalize(forward); @@ -6270,6 +6289,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t return; R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix); + R_Mesh_TexMatrix(1, &rsurface.texture->currentbackgroundtexmatrix); R_Mesh_TexBind(GL20TU_NORMAL, R_GetTexture(rsurface.texture->currentskinframe->nmap)); R_Mesh_TexBind(GL20TU_COLOR, R_GetTexture(rsurface.texture->basetexture)); R_Mesh_TexBind(GL20TU_GLOSS, R_GetTexture(rsurface.texture->glosstexture)); @@ -6627,7 +6647,10 @@ static void R_DrawTextureSurfaceList_ShowSurfaces3(int texturenumsurfaces, msurf R_SetupGenericShader(false); if(rsurface.texture && rsurface.texture->currentskinframe) + { memcpy(c, rsurface.texture->currentskinframe->avgcolor, sizeof(c)); + c[3] *= rsurface.texture->currentalpha; + } else { c[0] = 1;