X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_rmain.c;h=a568885d484fec70d1dd694e587c8da2d51b4cb0;hp=ec66a384d65d46135b6e520ce7bab68ed50b99ad;hb=1d8da66c6d6e2f48017b9020125538d3bfa74814;hpb=8d376b57de94bafd3bae224088b469649c853028 diff --git a/gl_rmain.c b/gl_rmain.c index ec66a384..a568885d 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -33,7 +33,8 @@ rtexturepool_t *r_main_texturepool; // r_refdef_t r_refdef; -cvar_t r_depthfirst = {CVAR_SAVE, "r_depthfirst", "1", "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"}; +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"}; +cvar_t r_useinfinitefarclip = {CVAR_SAVE, "r_useinfinitefarclip", "1", "enables use of a special kind of projection matrix that has an extremely large farclip"}; cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" }; 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)"}; @@ -63,6 +64,7 @@ cvar_t r_q1bsp_skymasking = {0, "r_q1bsp_skymasking", "1", "allows sky polygons cvar_t r_polygonoffset_submodel_factor = {0, "r_polygonoffset_submodel_factor", "0", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; cvar_t r_polygonoffset_submodel_offset = {0, "r_polygonoffset_submodel_offset", "2", "biases depth values of world submodels such as doors, to prevent z-fighting artifacts in Quake maps"}; 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_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"}; cvar_t gl_fogenable = {0, "gl_fogenable", "0", "nehahra fog enable (for Nehahra compatibility only)"}; cvar_t gl_fogdensity = {0, "gl_fogdensity", "0.25", "nehahra fog density (recommend values below 0.1) (for Nehahra compatibility only)"}; @@ -240,7 +242,7 @@ float FogPoint_World(const vec3_t p) float FogPoint_Model(const vec3_t p) { - return FogForDistance(VectorDistance((p), rsurface.modelorg)); + return FogForDistance(VectorDistance((p), rsurface.modelorg) * Matrix4x4_ScaleFromMatrix(&rsurface.matrix)); } static void R_BuildBlankTextures(void) @@ -546,7 +548,7 @@ static const char *builtinshaderstring = " gl_FragColor += tex2;\n" "# endif\n" "# ifdef USEVERTEXTEXTUREBLEND\n" -" gl_FragColor = mix(tex2, gl_FragColor, tex2.a);\n" +" gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n" "# endif\n" "}\n" "# endif\n" @@ -845,7 +847,8 @@ 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 = mix(myhalf4(texture2D(Texture_SecondaryColor, TexCoord)), color, terrainblend);\n" +" color.rgb = mix(myhalf3(texture2D(Texture_SecondaryColor, TexCoord)), color.rgb, terrainblend);\n" +" color.a = 1.0;\n" " //color = mix(myhalf4(1, 0, 0, 1), color, terrainblend);\n" "#endif\n" "\n" @@ -857,7 +860,7 @@ static const char *builtinshaderstring = " myhalf3 glosscolor = mix(myhalf3(texture2D(Texture_SecondaryGloss, TexCoord)), myhalf3(texture2D(Texture_Gloss, TexCoord)), terrainblend);\n" "# endif\n" "# else\n" -" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5));\n" +" myhalf3 surfacenormal = normalize(myhalf3(texture2D(Texture_Normal, TexCoord)) - myhalf3(0.5, 0.5, 0.5));\n" "# ifdef USESPECULAR\n" " myhalf3 glosscolor = myhalf3(texture2D(Texture_Gloss, TexCoord));\n" "# endif\n" @@ -878,10 +881,8 @@ static const char *builtinshaderstring = " myhalf3 diffusenormal = myhalf3(normalize(LightVector));\n" "# endif\n" "# ifdef USESPECULAR\n" -" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n" -"\n" " // calculate directional shading\n" -" color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * glosscolor);\n" +" color.rgb = myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower)) * glosscolor);\n" "# else\n" "# ifdef USEDIFFUSE\n" " // calculate directional shading\n" @@ -911,8 +912,7 @@ static const char *builtinshaderstring = "# ifdef USESPECULAR\n" " // calculate directional shading\n" " color.rgb *= AmbientColor + DiffuseColor * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n" -" myhalf3 specularnormal = normalize(diffusenormal + myhalf3(normalize(EyeVector)));\n" -" color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" color.rgb += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularColor * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" "# else\n" "# ifdef USEDIFFUSE\n" "\n" @@ -931,13 +931,15 @@ static const char *builtinshaderstring = " // deluxemap lightmapping using light vectors in modelspace (evil q3map2)\n" "\n" " // get the light normal\n" -" myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5);\n" -" myhalf3 diffusenormal = normalize(myhalf3(dot(diffusenormal_modelspace, myhalf3(VectorS)), dot(diffusenormal_modelspace, myhalf3(VectorT)), dot(diffusenormal_modelspace, myhalf3(VectorR))));\n" +" myhalf3 diffusenormal_modelspace = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n" +" myhalf3 diffusenormal;\n" +" diffusenormal.x = dot(diffusenormal_modelspace, myhalf3(VectorS));\n" +" diffusenormal.y = dot(diffusenormal_modelspace, myhalf3(VectorT));\n" +" diffusenormal.z = dot(diffusenormal_modelspace, myhalf3(VectorR));\n" " // calculate directional shading\n" " myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n" "# ifdef USESPECULAR\n" -" myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n" -" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" "# endif\n" "\n" " // apply lightmap color\n" @@ -951,12 +953,11 @@ static const char *builtinshaderstring = " // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n" "\n" " // get the light normal\n" -" myhalf3 diffusenormal = normalize(myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) - myhalf3(0.5));\n" +" myhalf3 diffusenormal = myhalf3(texture2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + myhalf3(-1.0, -1.0, -1.0);\n" " // calculate directional shading\n" " myhalf3 tempcolor = color.rgb * (DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n" "# ifdef USESPECULAR\n" -" myhalf3 specularnormal = myhalf3(normalize(diffusenormal + myhalf3(normalize(EyeVector))));\n" -" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" tempcolor += myhalf3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(reflect(diffusenormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n" "# endif\n" "\n" " // apply lightmap color\n" @@ -1391,7 +1392,7 @@ void R_GLSL_DumpShader_f(void) { int i; - qfile_t *file = FS_Open("glsl/default.glsl", "w", false, false); + qfile_t *file = FS_OpenRealFile("glsl/default.glsl", "w", false); if(!file) { Con_Printf("failed to write to glsl/default.glsl\n"); @@ -1684,7 +1685,7 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f } else { - if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_ambient.value * 1.0f / 128.0f); + if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_refdef.scene.ambient * 1.0f / 128.0f); if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_refdef.lightmapintensity); if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, r_refdef.lightmapintensity * specularscale); } @@ -1734,7 +1735,7 @@ void R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, f else qglUniform3fARB(r_glsl_permutation->loc_Color_Shirt, 0, 0, 0); } - if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip); + if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip * Matrix4x4_ScaleFromMatrix(&rsurface.matrix)); if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower); if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value); CHECKGLERROR @@ -1860,7 +1861,7 @@ skinframe_t *R_SkinFrame_Find(const char *name, int textureflags, int comparewid return item; } -skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain) +skinframe_t *R_SkinFrame_LoadExternal_CheckAlpha(const char *name, int textureflags, qboolean complain, qboolean *has_alpha) { // FIXME: it should be possible to disable loading various layers using // cvars, to prevent wasted loading time and memory usage if the user does @@ -1877,6 +1878,8 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole int basepixels_height; skinframe_t *skinframe; + *has_alpha = false; + if (cls.state == ca_dedicated) return NULL; @@ -1919,6 +1922,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole if (j < basepixels_width * basepixels_height * 4) { // has transparent pixels + *has_alpha = true; pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); for (j = 0;j < image_width * image_height * 4;j += 4) { @@ -1937,7 +1941,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false)) != NULL) { - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); pixels = NULL; } @@ -1945,7 +1949,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4); Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value); - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); Mem_Free(bumppixels); } @@ -1953,7 +1957,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole { pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4); Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value); - skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); + skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), NULL); Mem_Free(pixels); } } @@ -1971,6 +1975,12 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole return skinframe; } +skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboolean complain) +{ + qboolean has_alpha; + return R_SkinFrame_LoadExternal_CheckAlpha(name, textureflags, complain, &has_alpha); +} + static rtexture_t *R_SkinFrame_TextureForSkinLayer(const unsigned char *in, int width, int height, const char *name, const unsigned int *palette, int textureflags, qboolean force) { int i; @@ -2230,6 +2240,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable (&gl_skyclip); } Cvar_RegisterVariable(&r_depthfirst); + Cvar_RegisterVariable(&r_useinfinitefarclip); Cvar_RegisterVariable(&r_nearclip); Cvar_RegisterVariable(&r_showbboxes); Cvar_RegisterVariable(&r_showsurfaces); @@ -2259,6 +2270,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_polygonoffset_submodel_factor); Cvar_RegisterVariable(&r_polygonoffset_submodel_offset); Cvar_RegisterVariable(&r_fog_exp2); + Cvar_RegisterVariable(&r_drawfog); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&r_glsl); Cvar_RegisterVariable(&r_glsl_contrastboost); @@ -2344,6 +2356,22 @@ GL_Init extern char *ENGINE_EXTENSIONS; void GL_Init (void) { + gl_renderer = (const char *)qglGetString(GL_RENDERER); + gl_vendor = (const char *)qglGetString(GL_VENDOR); + gl_version = (const char *)qglGetString(GL_VERSION); + gl_extensions = (const char *)qglGetString(GL_EXTENSIONS); + + if (!gl_extensions) + gl_extensions = ""; + if (!gl_platformextensions) + gl_platformextensions = ""; + + Con_Printf("GL_VENDOR: %s\n", gl_vendor); + Con_Printf("GL_RENDERER: %s\n", gl_renderer); + Con_Printf("GL_VERSION: %s\n", gl_version); + Con_Printf("GL_EXTENSIONS: %s\n", gl_extensions); + Con_Printf("%s_EXTENSIONS: %s\n", gl_platform, gl_platformextensions); + VID_CheckExtensions(); // LordHavoc: report supported extensions @@ -2466,11 +2494,14 @@ static void R_View_UpdateEntityVisible (void) if (r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs) { // worldmodel can check visibility + memset(r_refdef.viewcache.entityvisible, 0, r_refdef.scene.numentities); for (i = 0;i < r_refdef.scene.numentities;i++) { ent = r_refdef.scene.entities[i]; - 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)) && ((ent->effects & EF_NODEPTHTEST) || (ent->flags & RENDER_VIEWMODEL) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs)); - + if (!(ent->flags & renderimask)) + if (!R_CullBox(ent->mins, ent->maxs) || (ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE))) + if ((ent->effects & EF_NODEPTHTEST) || (ent->flags & 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) { @@ -2763,7 +2794,7 @@ void R_SetupView(qboolean allowwaterclippingplane) { if (!r_refdef.view.useperspective) GL_SetupView_Mode_Ortho(-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); - else if (r_refdef.rtworldshadows || r_refdef.rtdlightshadows) + else if (gl_stencil && r_useinfinitefarclip.integer) GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip); else GL_SetupView_Mode_Perspective(r_refdef.view.frustum_x, r_refdef.view.frustum_y, r_refdef.nearclip, r_refdef.farclip); @@ -3175,7 +3206,7 @@ void R_Bloom_CopyBloomTexture(float colorscale) R_SetupGenericShader(true); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen)); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; // we now have a bloom image in the framebuffer @@ -3220,7 +3251,7 @@ void R_Bloom_MakeTexture(void) GL_Color(r, r, r, 1); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; // copy the vertically blurred bloom view to a texture @@ -3264,7 +3295,7 @@ void R_Bloom_MakeTexture(void) //r = (dir ? 1.0f : brighten)/(range*2+1); r = (dir ? 1.0f : brighten)/(range*2+1)*(1 - x*x/(float)(range*range)); GL_Color(r, r, r, 1); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; GL_BlendFunc(GL_ONE, GL_ONE); } @@ -3284,7 +3315,7 @@ void R_Bloom_MakeTexture(void) R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); GL_Color(1, 1, 1, 1); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; GL_BlendFunc(GL_ONE, GL_ONE); @@ -3292,7 +3323,7 @@ void R_Bloom_MakeTexture(void) R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); GL_Color(r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 1); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; qglBlendEquationEXT(GL_FUNC_ADD_EXT); @@ -3400,6 +3431,9 @@ static void R_BlendView(void) if (r_glsl_permutation->loc_UserVec1 >= 0) { float a=0, b=0, c=0, d=0; +#if _MSC_VER >= 1400 +#define sscanf sscanf_s +#endif sscanf(r_glsl_postprocess_uservec1.string, "%f %f %f %f", &a, &b, &c, &d); qglUniform4fARB(r_glsl_permutation->loc_UserVec1, a, b, c, d); } @@ -3421,7 +3455,7 @@ static void R_BlendView(void) sscanf(r_glsl_postprocess_uservec4.string, "%f %f %f %f", &a, &b, &c, &d); qglUniform4fARB(r_glsl_permutation->loc_UserVec4, a, b, c, d); } - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height; return; } @@ -3441,7 +3475,7 @@ static void R_BlendView(void) GL_BlendFunc(GL_ONE, GL_ONE); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height; } else if (r_bloomstate.texture_bloom) @@ -3470,14 +3504,14 @@ static void R_BlendView(void) else { R_SetupGenericShader(true); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height; // now blend on the bloom texture GL_BlendFunc(GL_ONE, GL_ONE); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen)); R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0); } - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_refdef.view.width * r_refdef.view.height; } if (r_refdef.viewblend[3] >= (1.0f / 256.0f)) @@ -3489,7 +3523,7 @@ static void R_BlendView(void) R_SetupGenericShader(false); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); } } @@ -3528,9 +3562,11 @@ void R_UpdateVariables(void) { R_Textures_Frame(); + r_refdef.scene.ambient = r_ambient.value; + r_refdef.farclip = 4096; if (r_refdef.scene.worldmodel) - r_refdef.farclip += VectorDistance(r_refdef.scene.worldmodel->normalmins, r_refdef.scene.worldmodel->normalmaxs); + r_refdef.farclip += r_refdef.scene.worldmodel->radius * 2; r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f); if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1) @@ -3540,17 +3576,17 @@ void R_UpdateVariables(void) r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1); r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1); - r_refdef.rtworld = r_shadow_realtime_world.integer; - r_refdef.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil; - r_refdef.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer; - r_refdef.rtdlightshadows = r_refdef.rtdlight && r_shadow_realtime_dlight_shadows.integer && gl_stencil; - r_refdef.lightmapintensity = r_refdef.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + r_refdef.scene.rtworld = r_shadow_realtime_world.integer; + r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && gl_stencil; + r_refdef.scene.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer; + r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && gl_stencil; + r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; if (r_showsurfaces.integer) { - r_refdef.rtworld = false; - r_refdef.rtworldshadows = false; - r_refdef.rtdlight = false; - r_refdef.rtdlightshadows = false; + r_refdef.scene.rtworld = false; + r_refdef.scene.rtworldshadows = false; + r_refdef.scene.rtdlight = false; + r_refdef.scene.rtdlightshadows = false; r_refdef.lightmapintensity = 0; } @@ -3586,7 +3622,7 @@ void R_UpdateVariables(void) // R_UpdateFogColor(); // why? R_RenderScene does it anyway - if (r_refdef.fog_density) + if (r_refdef.fog_density && r_drawfog.integer) { r_refdef.fogenabled = true; // this is the point where the fog reaches 0.9986 alpha, which we @@ -3682,7 +3718,24 @@ R_RenderView */ void R_RenderView(void) { - if (!r_refdef.scene.entities/* || !r_refdef.scene.worldmodel*/) + if (r_refdef.view.isoverlay) + { + // TODO: FIXME: move this into its own backend function maybe? [2/5/2008 Andreas] + GL_Clear( GL_DEPTH_BUFFER_BIT ); + R_TimeReport("depthclear"); + + r_refdef.view.showdebug = false; + + r_waterstate.enabled = false; + r_waterstate.numwaterplanes = 0; + + R_RenderScene(false); + + CHECKGLERROR + return; + } + + if (!r_refdef.scene.entities || r_refdef.view.width * r_refdef.view.height == 0/* || !r_refdef.scene.worldmodel*/) return; //Host_Error ("R_RenderView: NULL worldmodel"); r_refdef.view.colorscale = r_hdr_scenebrightness.value; @@ -3935,7 +3988,7 @@ void R_RenderScene(qboolean addwaterplanes) R_ResetViewRendering2D(); } -static const int bboxelements[36] = +static const unsigned short bboxelements[36] = { 5, 1, 3, 5, 3, 7, 6, 2, 0, 6, 0, 4, @@ -3980,7 +4033,7 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa R_Mesh_ColorPointer(color4f, 0, 0); R_Mesh_ResetTextureState(); R_SetupGenericShader(false); - R_Mesh_Draw(0, 8, 12, bboxelements, 0, 0); + R_Mesh_Draw(0, 8, 0, 12, NULL, bboxelements, 0, 0); } static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) @@ -3988,10 +4041,16 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh int i; float color[4]; prvm_edict_t *edict; + prvm_prog_t *prog_save = prog; + // this function draws bounding boxes of server entities if (!sv.active) return; + + GL_CullFace(GL_NONE); R_SetupGenericShader(false); + + prog = 0; SV_VM_Begin(); for (i = 0;i < numsurfaces;i++) { @@ -4012,6 +4071,7 @@ static void R_DrawEntityBBoxes_Callback(const entity_render_t *ent, const rtligh R_DrawBBoxMesh(edict->priv.server->areamins, edict->priv.server->areamaxs, color[0], color[1], color[2], color[3]); } SV_VM_End(); + prog = prog_save; } static void R_DrawEntityBBoxes(void) @@ -4019,22 +4079,32 @@ static void R_DrawEntityBBoxes(void) int i; prvm_edict_t *edict; vec3_t center; + prvm_prog_t *prog_save = prog; + // this function draws bounding boxes of server entities if (!sv.active) return; + + prog = 0; SV_VM_Begin(); for (i = 0;i < prog->num_edicts;i++) { edict = PRVM_EDICT_NUM(i); if (edict->priv.server->free) continue; + // exclude the following for now, as they don't live in world coordinate space and can't be solid: + if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.tag_entity)->edict != 0) + continue; + if(PRVM_EDICTFIELDVALUE(edict, prog->fieldoffsets.viewmodelforclient)->edict != 0) + continue; VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center); R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); } SV_VM_End(); + prog = prog_save; } -int nomodelelements[24] = +unsigned short nomodelelements[24] = { 5, 2, 0, 5, 1, 2, @@ -4122,7 +4192,7 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight else R_Mesh_ColorPointer(nomodelcolor4f, 0, 0); R_Mesh_ResetTextureState(); - R_Mesh_Draw(0, 6, 8, nomodelelements, 0, 0); + R_Mesh_Draw(0, 6, 0, 8, NULL, nomodelelements, 0, 0); } void R_DrawNoModel(entity_render_t *ent) @@ -4214,7 +4284,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_ R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f, 0, 0); // FIXME: fixed function path can't properly handle r_refdef.view.colorscale > 1 GL_Color(cr * fog * r_refdef.view.colorscale, cg * fog * r_refdef.view.colorscale, cb * fog * r_refdef.view.colorscale, ca); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA) { @@ -4222,7 +4292,7 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_ GL_BlendFunc(blendfunc1, GL_ONE); fog = 1 - fog; GL_Color(r_refdef.fogcolor[0] * fog, r_refdef.fogcolor[1] * fog, r_refdef.fogcolor[2] * fog, ca); - R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); + R_Mesh_Draw(0, 4, 0, 2, NULL, polygonelements, 0, 0); } } @@ -4376,7 +4446,7 @@ static float R_EvaluateQ3WaveFunc(q3wavefunc_t func, const float *parms) void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) { int i; - model_t *model = ent->model; + dp_model_t *model = ent->model; float f; float tcmat[12]; q3shaderinfo_layer_tcmod_t *tcmod; @@ -4415,7 +4485,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) } // update currentskinframe to be a qw skin or animation frame - if ((i = ent->entitynumber - 1) >= 0 && i < cl.maxclients) + if ((i = ent->entitynumber - 1) >= 0 && i < cl.maxclients && cls.protocol == PROTOCOL_QUAKEWORLD && cl.scores[i].qw_skin[0] && !strcmp(ent->model->name, "progs/player.mdl")) { if (strcmp(r_qwskincache[i], cl.scores[i].qw_skin)) { @@ -4436,18 +4506,10 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->currentmaterialflags = t->basematerialflags; t->currentalpha = ent->alpha; if (t->basematerialflags & MATERIALFLAG_WATERALPHA && (model->brush.supportwateralpha || r_novis.integer)) - { t->currentalpha *= r_wateralpha.value; - /* - * FIXME what is this supposed to do? - // if rendering refraction/reflection, disable transparency - if (r_waterstate.enabled && (t->currentalpha < 1 || (t->currentmaterialflags & MATERIALFLAG_ALPHA))) - t->currentmaterialflags |= MATERIALFLAG_WATERSHADER; - */ - } - if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled) + if(t->basematerialflags & MATERIALFLAG_WATERSHADER && r_waterstate.enabled && !r_refdef.view.isoverlay) t->currentalpha *= t->r_water_wateralpha; - if(!r_waterstate.enabled) + if(!r_waterstate.enabled || r_refdef.view.isoverlay) t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION); if (!(ent->flags & RENDER_LIGHT)) t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT; @@ -4628,7 +4690,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) if (ent->model->type == mod_brushq3) colorscale *= r_refdef.scene.rtlightstylevalue[0]; colorscale *= r_refdef.lightmapintensity; - VectorScale(t->lightmapcolor, r_ambient.value * (1.0f / 64.0f), ambientcolor); + VectorScale(t->lightmapcolor, r_refdef.scene.ambient * (1.0f / 64.0f), ambientcolor); VectorScale(t->lightmapcolor, colorscale, t->lightmapcolor); // basic lit geometry R_Texture_AddLayer(t, depthmask, blendfunc1, blendfunc2, TEXTURELAYERTYPE_LITTEXTURE, t->basetexture, &t->currenttexmatrix, t->lightmapcolor[0], t->lightmapcolor[1], t->lightmapcolor[2], t->lightmapcolor[3]); @@ -4701,7 +4763,7 @@ void R_Mesh_ResizeArrays(int newvertices) void RSurf_ActiveWorldEntity(void) { - model_t *model = r_refdef.scene.worldmodel; + dp_model_t *model = r_refdef.scene.worldmodel; if (rsurface.array_size < model->surfmesh.num_vertices) R_Mesh_ResizeArrays(model->surfmesh.num_vertices); rsurface.matrix = identitymatrix; @@ -4745,7 +4807,9 @@ void RSurf_ActiveWorldEntity(void) rsurface.modeltexcoordlightmap2f_bufferobject = model->surfmesh.vbo; rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f; rsurface.modelelement3i = model->surfmesh.data_element3i; - rsurface.modelelement3i_bufferobject = model->surfmesh.ebo; + rsurface.modelelement3s = model->surfmesh.data_element3s; + rsurface.modelelement3i_bufferobject = model->surfmesh.ebo3i; + rsurface.modelelement3s_bufferobject = model->surfmesh.ebo3s; rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets; rsurface.modelnum_vertices = model->surfmesh.num_vertices; rsurface.modelnum_triangles = model->surfmesh.num_triangles; @@ -4768,7 +4832,7 @@ void RSurf_ActiveWorldEntity(void) void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents) { - model_t *model = ent->model; + dp_model_t *model = ent->model; if (rsurface.array_size < model->surfmesh.num_vertices) R_Mesh_ResizeArrays(model->surfmesh.num_vertices); rsurface.matrix = ent->matrix; @@ -4796,7 +4860,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.basepolygonfactor += r_polygonoffset_submodel_factor.value; rsurface.basepolygonoffset += r_polygonoffset_submodel_offset.value; } - if (model->surfmesh.isanimated && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].frame != 0)) + if (model->surfmesh.isanimated && model->AnimateVertices && (rsurface.frameblend[0].lerp != 1 || rsurface.frameblend[0].frame != 0)) { if (wanttangents) { @@ -4804,7 +4868,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.modelsvector3f = rsurface.array_modelsvector3f; rsurface.modeltvector3f = rsurface.array_modeltvector3f; rsurface.modelnormal3f = rsurface.array_modelnormal3f; - Mod_Alias_GetMesh_Vertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, rsurface.array_modelsvector3f, rsurface.array_modeltvector3f); + model->AnimateVertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, rsurface.array_modelsvector3f, rsurface.array_modeltvector3f); } else if (wantnormals) { @@ -4812,7 +4876,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.modelsvector3f = NULL; rsurface.modeltvector3f = NULL; rsurface.modelnormal3f = rsurface.array_modelnormal3f; - Mod_Alias_GetMesh_Vertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, NULL, NULL); + model->AnimateVertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, rsurface.array_modelnormal3f, NULL, NULL); } else { @@ -4820,7 +4884,7 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.modelsvector3f = NULL; rsurface.modeltvector3f = NULL; rsurface.modelnormal3f = NULL; - Mod_Alias_GetMesh_Vertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, NULL, NULL, NULL); + model->AnimateVertices(model, rsurface.frameblend, rsurface.array_modelvertex3f, NULL, NULL, NULL); } rsurface.modelvertex3f_bufferobject = 0; rsurface.modelvertex3f_bufferoffset = 0; @@ -4858,7 +4922,9 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface.modeltexcoordlightmap2f_bufferobject = model->surfmesh.vbo; rsurface.modeltexcoordlightmap2f_bufferoffset = model->surfmesh.vbooffset_texcoordlightmap2f; rsurface.modelelement3i = model->surfmesh.data_element3i; - rsurface.modelelement3i_bufferobject = model->surfmesh.ebo; + rsurface.modelelement3s = model->surfmesh.data_element3s; + rsurface.modelelement3i_bufferobject = model->surfmesh.ebo3i; + rsurface.modelelement3s_bufferobject = model->surfmesh.ebo3s; rsurface.modellightmapoffsets = model->surfmesh.data_lightmapoffsets; rsurface.modelnum_vertices = model->surfmesh.num_vertices; rsurface.modelnum_triangles = model->surfmesh.num_triangles; @@ -5312,7 +5378,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel if (texturenumsurfaces == 1) { GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } else if (r_batchmode.integer == 2) { @@ -5325,7 +5391,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel j = i + 1; if (surface->num_triangles > MAXBATCHTRIANGLES) { - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); continue; } memcpy(batchelements, rsurface.modelelement3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3])); @@ -5344,7 +5410,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel } surface2 = texturesurfacelist[j-1]; numvertices = endvertex - firstvertex; - R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0); + R_Mesh_Draw(firstvertex, numvertices, 0, batchtriangles, batchelements, NULL, 0, 0); } } else if (r_batchmode.integer == 1) @@ -5359,7 +5425,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex; numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle; GL_LockArrays(surface->num_firstvertex, numvertices); - R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, numvertices, surface->num_firsttriangle, numtriangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } else @@ -5368,7 +5434,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel { surface = texturesurfacelist[i]; GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } } @@ -5422,7 +5488,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching_WithWaterTextureSwitching(int R_Mesh_TexBind(reflectiontexunit, R_GetTexture(r_texture_black)); } GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } @@ -5443,7 +5509,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa if (deluxemaptexunit >= 0) R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } else if (r_batchmode.integer == 2) { @@ -5459,7 +5525,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa j = i + 1; if (surface->num_triangles > MAXBATCHTRIANGLES) { - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); continue; } memcpy(batchelements, rsurface.modelelement3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3])); @@ -5478,7 +5544,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa } surface2 = texturesurfacelist[j-1]; numvertices = endvertex - firstvertex; - R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0); + R_Mesh_Draw(firstvertex, numvertices, 0, batchtriangles, batchelements, NULL, 0, 0); } } else if (r_batchmode.integer == 1) @@ -5512,7 +5578,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex; numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle; GL_LockArrays(surface->num_firstvertex, numvertices); - R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, numvertices, surface->num_firsttriangle, numtriangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } #if 0 Con_Printf("\n"); @@ -5527,7 +5593,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa if (deluxemaptexunit >= 0) R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } } @@ -5545,7 +5611,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te { float f = ((j + surface->num_firsttriangle) & 31) * (1.0f / 31.0f) * r_refdef.view.colorscale; GL_Color(f, f, f, 1); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface.modelelement3i + 3 * (j + surface->num_firsttriangle)), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * (j + surface->num_firsttriangle))); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle + j, 1, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } } @@ -5557,7 +5623,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te int k = (int)(((size_t)surface) / sizeof(msurface_t)); GL_Color((k & 15) * (1.0f / 16.0f) * r_refdef.view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_refdef.view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_refdef.view.colorscale, 1); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface.modelelement3i + 3 * surface->num_firsttriangle), rsurface.modelelement3i_bufferobject, (sizeof(int[3]) * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_firsttriangle, surface->num_triangles, rsurface.modelelement3i, rsurface.modelelement3s, rsurface.modelelement3i_bufferobject, rsurface.modelelement3s_bufferobject); } } } @@ -5660,7 +5726,7 @@ static void RSurf_DrawBatch_GL11_VertexColor(int texturenumsurfaces, msurface_t int i; float *c; // TODO: optimize - if (texturesurfacelist[0]->lightmapinfo && texturesurfacelist[0]->lightmapinfo->stainsamples) + if (texturesurfacelist[0]->lightmapinfo) { // generate color arrays for the surfaces in this list for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) @@ -5860,8 +5926,11 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t R_Mesh_TexBind(GL20TU_SECONDARY_GLOSS, R_GetTexture(rsurface.texture->backgroundglosstexture)); R_Mesh_TexBind(GL20TU_SECONDARY_GLOW, R_GetTexture(rsurface.texture->backgroundcurrentskinframe->glow)); } - R_Mesh_TexBind(GL20TU_PANTS, R_GetTexture(rsurface.texture->currentskinframe->pants)); - R_Mesh_TexBind(GL20TU_SHIRT, R_GetTexture(rsurface.texture->currentskinframe->shirt)); + if(rsurface.texture->colormapping) + { + R_Mesh_TexBind(GL20TU_PANTS, R_GetTexture(rsurface.texture->currentskinframe->pants)); + R_Mesh_TexBind(GL20TU_SHIRT, R_GetTexture(rsurface.texture->currentskinframe->shirt)); + } R_Mesh_TexBind(GL20TU_FOGMASK, R_GetTexture(r_texture_fogattenuation)); if ((rsurface.uselightmaptexture || (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) && !(rsurface.texture->currentmaterialflags & MATERIALFLAG_VERTEXTEXTUREBLEND)) R_Mesh_ColorPointer(NULL, 0, 0); @@ -6357,7 +6426,7 @@ float locboxvertex3f[6*4*3] = 1,0,0, 0,0,0, 0,1,0, 1,1,0 }; -int locboxelement3i[6*2*3] = +unsigned short locboxelements[6*2*3] = { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, @@ -6408,7 +6477,7 @@ void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, in for (j = 0;j < 3;j++, i++) vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i]; - R_Mesh_Draw(0, 6*4, 6*2, locboxelement3i, 0, 0); + R_Mesh_Draw(0, 6*4, 0, 6*2, NULL, locboxelements, 0, 0); } void R_DrawLocs(void) @@ -6430,7 +6499,7 @@ void R_DrawDebugModel(entity_render_t *ent) const int *elements; q3mbrush_t *brush; msurface_t *surface; - model_t *model = ent->model; + dp_model_t *model = ent->model; vec3_t v; flagsmask = MATERIALFLAG_SKY | MATERIALFLAG_WALL; @@ -6452,7 +6521,7 @@ void R_DrawDebugModel(entity_render_t *ent) { R_Mesh_VertexPointer(brush->colbrushf->points->v, 0, 0); GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value); - R_Mesh_Draw(0, brush->colbrushf->numpoints, brush->colbrushf->numtriangles, brush->colbrushf->elements, 0, 0); + R_Mesh_Draw(0, brush->colbrushf->numpoints, 0, brush->colbrushf->numtriangles, brush->colbrushf->elements, NULL, 0, 0); } } for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++) @@ -6461,7 +6530,7 @@ void R_DrawDebugModel(entity_render_t *ent) { R_Mesh_VertexPointer(surface->data_collisionvertex3f, 0, 0); GL_Color((i & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_refdef.view.colorscale, r_showcollisionbrushes.value); - R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i, 0, 0); + R_Mesh_Draw(0, surface->num_collisionvertices, 0, surface->num_collisiontriangles, surface->data_collisionelement3i, NULL, 0, 0); } } } @@ -6555,20 +6624,32 @@ void R_DrawDebugModel(entity_render_t *ent) } extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface); +int r_maxsurfacelist = 0; +msurface_t **r_surfacelist = NULL; void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean addwaterplanes, qboolean debug) { int i, j, endj, f, flagsmask; - msurface_t *surface; texture_t *t; - model_t *model = r_refdef.scene.worldmodel; - const int maxsurfacelist = 1024; + dp_model_t *model = r_refdef.scene.worldmodel; + msurface_t *surfaces; + unsigned char *update; int numsurfacelist = 0; - msurface_t *surfacelist[1024]; if (model == NULL) return; + if (r_maxsurfacelist < model->num_surfaces) + { + r_maxsurfacelist = model->num_surfaces; + if (r_surfacelist) + Mem_Free(r_surfacelist); + r_surfacelist = Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); + } + RSurf_ActiveWorldEntity(); + surfaces = model->data_surfaces; + update = model->brushq1.lightmapupdateflags; + // update light styles on this submodel if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) { @@ -6577,11 +6658,10 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep { if (style->value != r_refdef.scene.lightstylevalue[style->style]) { - msurface_t *surfaces = model->data_surfaces; int *list = style->surfacelist; style->value = r_refdef.scene.lightstylevalue[style->style]; for (j = 0;j < style->numsurfaces;j++) - surfaces[list[j]].cached_dlight = true; + update[list[j]] = true; } } } @@ -6601,54 +6681,60 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep rsurface.texture = NULL; rsurface.rtlight = NULL; numsurfacelist = 0; + // add visible surfaces to draw list j = model->firstmodelsurface; endj = j + model->nummodelsurfaces; - while (j < endj) + if (update) { - // quickly skip over non-visible surfaces - for (;j < endj && !r_refdef.viewcache.world_surfacevisible[j];j++) - ; - // quickly iterate over visible surfaces - for (;j < endj && r_refdef.viewcache.world_surfacevisible[j];j++) + for (;j < endj;j++) { - // process this surface - surface = model->data_surfaces + j; - // if this surface fits the criteria, add it to the list - if (surface->num_triangles) + if (r_refdef.viewcache.world_surfacevisible[j]) { - // if lightmap parameters changed, rebuild lightmap texture - if (surface->cached_dlight) - R_BuildLightMap(r_refdef.scene.worldentity, surface); - // add face to draw list - surfacelist[numsurfacelist++] = surface; - r_refdef.stats.world_triangles += surface->num_triangles; - if (numsurfacelist >= maxsurfacelist) - { - r_refdef.stats.world_surfaces += numsurfacelist; - R_QueueSurfaceList(r_refdef.scene.worldentity, numsurfacelist, surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); - numsurfacelist = 0; - } + r_surfacelist[numsurfacelist++] = surfaces + j; + // update lightmap if needed + if (update[j]) + R_BuildLightMap(r_refdef.scene.worldentity, surfaces + j); } } } - r_refdef.stats.world_surfaces += numsurfacelist; - if (numsurfacelist) - R_QueueSurfaceList(r_refdef.scene.worldentity, numsurfacelist, surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); + else + for (;j < endj;j++) + if (r_refdef.viewcache.world_surfacevisible[j]) + r_surfacelist[numsurfacelist++] = surfaces + j; + // don't do anything if there were no surfaces + if (!numsurfacelist) + return; + R_QueueSurfaceList(r_refdef.scene.worldentity, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); GL_AlphaTest(false); + + // add to stats if desired + if (r_speeds.integer && !skysurfaces && !depthonly && !addwaterplanes) + { + r_refdef.stats.world_surfaces += numsurfacelist; + for (j = 0;j < numsurfacelist;j++) + r_refdef.stats.world_triangles += r_surfacelist[j]->num_triangles; + } } void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean writedepth, qboolean depthonly, qboolean addwaterplanes, qboolean debug) { - int i, j, f, flagsmask; - msurface_t *surface, *endsurface; + int i, j, endj, f, flagsmask; texture_t *t; - model_t *model = ent->model; - const int maxsurfacelist = 1024; + dp_model_t *model = ent->model; + msurface_t *surfaces; + unsigned char *update; int numsurfacelist = 0; - msurface_t *surfacelist[1024]; if (model == NULL) return; + if (r_maxsurfacelist < model->num_surfaces) + { + r_maxsurfacelist = model->num_surfaces; + if (r_surfacelist) + Mem_Free(r_surfacelist); + r_surfacelist = Mem_Alloc(r_main_mempool, r_maxsurfacelist * sizeof(*r_surfacelist)); + } + // if the model is static it doesn't matter what value we give for // wantnormals and wanttangents, so this logic uses only rules applicable // to a model, knowing that they are meaningless otherwise @@ -6659,6 +6745,9 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr else RSurf_ActiveModelEntity(ent, true, r_glsl.integer && gl_support_fragment_shader && !depthonly); + surfaces = model->data_surfaces; + update = model->brushq1.lightmapupdateflags; + // update light styles if (!skysurfaces && !depthonly && !addwaterplanes && model->brushq1.num_lightstyles && r_refdef.lightmapintensity > 0) { @@ -6667,11 +6756,10 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr { if (style->value != r_refdef.scene.lightstylevalue[style->style]) { - msurface_t *surfaces = model->data_surfaces; int *list = style->surfacelist; style->value = r_refdef.scene.lightstylevalue[style->style]; for (j = 0;j < style->numsurfaces;j++) - surfaces[list[j]].cached_dlight = true; + update[list[j]] = true; } } } @@ -6691,29 +6779,28 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr rsurface.texture = NULL; rsurface.rtlight = NULL; numsurfacelist = 0; - surface = model->data_surfaces + model->firstmodelsurface; - endsurface = surface + model->nummodelsurfaces; - for (;surface < endsurface;surface++) + // add visible surfaces to draw list + j = model->firstmodelsurface; + endj = j + model->nummodelsurfaces; + for (;j < endj;j++) + r_surfacelist[numsurfacelist++] = surfaces + j; + // don't do anything if there were no surfaces + if (!numsurfacelist) + return; + // update lightmaps if needed + if (update) + for (j = model->firstmodelsurface;j < endj;j++) + if (update[j]) + R_BuildLightMap(ent, surfaces + j); + R_QueueSurfaceList(ent, numsurfacelist, r_surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); + GL_AlphaTest(false); + + // add to stats if desired + if (r_speeds.integer && !skysurfaces && !depthonly && !addwaterplanes) { - // if this surface fits the criteria, add it to the list - if (surface->num_triangles) - { - // if lightmap parameters changed, rebuild lightmap texture - if (surface->cached_dlight) - R_BuildLightMap(ent, surface); - // add face to draw list - surfacelist[numsurfacelist++] = surface; - r_refdef.stats.entities_triangles += surface->num_triangles; - if (numsurfacelist >= maxsurfacelist) - { - r_refdef.stats.entities_surfaces += numsurfacelist; - R_QueueSurfaceList(ent, numsurfacelist, surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); - numsurfacelist = 0; - } - } + r_refdef.stats.entities++; + r_refdef.stats.entities_surfaces += numsurfacelist; + for (j = 0;j < numsurfacelist;j++) + r_refdef.stats.entities_triangles += r_surfacelist[j]->num_triangles; } - r_refdef.stats.entities_surfaces += numsurfacelist; - if (numsurfacelist) - R_QueueSurfaceList(ent, numsurfacelist, surfacelist, flagsmask, writedepth, depthonly, addwaterplanes); - GL_AlphaTest(false); }