X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=4b68e50e6cca6ad9c64c3f297f4170dfab56fe1c;hb=986e2df5ca730f3984b37805aa48c6359d09f042;hp=c9f1f0aa75ee96fb3cf9dfbaaa1029191dbe1cc1;hpb=97c801886c678d9442a1e02dead8f977de974551;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index c9f1f0aa..4b68e50e 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -132,7 +132,7 @@ rtexture_t *r_texture_notexture; rtexture_t *r_texture_whitecube; rtexture_t *r_texture_normalizationcube; rtexture_t *r_texture_fogattenuation; -rtexture_t *r_texture_fogintensity; +//rtexture_t *r_texture_fogintensity; // information about each possible shader permutation r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT]; @@ -370,9 +370,9 @@ static void R_BuildNormalizationCube(void) break; } intensity = 127.0f / sqrt(DotProduct(v, v)); - data[side][y][x][0] = 128.0f + intensity * v[0]; - data[side][y][x][1] = 128.0f + intensity * v[1]; - data[side][y][x][2] = 128.0f + intensity * v[2]; + data[side][y][x][0] = (unsigned char)(128.0f + intensity * v[0]); + data[side][y][x][1] = (unsigned char)(128.0f + intensity * v[1]); + data[side][y][x][2] = (unsigned char)(128.0f + intensity * v[2]); data[side][y][x][3] = 255; } } @@ -386,7 +386,7 @@ static void R_BuildFogTexture(void) double r, alpha; #define FOGWIDTH 64 unsigned char data1[FOGWIDTH][4]; - unsigned char data2[FOGWIDTH][4]; + //unsigned char data2[FOGWIDTH][4]; r = (-1.0/256.0) * (FOGWIDTH * FOGWIDTH); for (x = 0;x < FOGWIDTH;x++) { @@ -399,13 +399,13 @@ static void R_BuildFogTexture(void) data1[x][1] = 255 - b; data1[x][2] = 255 - b; data1[x][3] = 255; - data2[x][0] = b; - data2[x][1] = b; - data2[x][2] = b; - data2[x][3] = 255; + //data2[x][0] = b; + //data2[x][1] = b; + //data2[x][2] = b; + //data2[x][3] = 255; } r_texture_fogattenuation = R_LoadTexture2D(r_main_texturepool, "fogattenuation", FOGWIDTH, 1, &data1[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); - r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); + //r_texture_fogintensity = R_LoadTexture2D(r_main_texturepool, "fogintensity", FOGWIDTH, 1, &data2[0][0], TEXTYPE_RGBA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP, NULL); } static const char *builtinshaderstring = @@ -420,6 +420,9 @@ static const char *builtinshaderstring = "varying vec3 CubeVector;\n" "varying vec3 LightVector;\n" "varying vec3 EyeVector;\n" +"#ifdef USEFOG\n" +"varying vec3 EyeVectorModelSpace;\n" +"#endif\n" "\n" "varying vec3 VectorS; // direction of S texcoord (sometimes crudely called tangent)\n" "varying vec3 VectorT; // direction of T texcoord (sometimes crudely called binormal)\n" @@ -467,10 +470,13 @@ static const char *builtinshaderstring = "#endif\n" "\n" " // transform unnormalized eye direction into tangent space\n" -" vec3 eyeminusvertex = EyePosition - gl_Vertex.xyz;\n" -" EyeVector.x = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);\n" -" EyeVector.y = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n" -" EyeVector.z = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n" +"#ifndef USEFOG\n" +" vec3 EyeVectorModelSpace;\n" +"#endif\n" +" EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n" +" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n" +" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n" +" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n" "\n" "#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n" " VectorS = gl_MultiTexCoord1.xyz;\n" @@ -667,17 +673,19 @@ static const char *builtinshaderstring = " color.rgb *= vec3(texture2D(Texture_Lightmap, TexCoordLightmap)) * DiffuseScale + vec3(AmbientScale);\n" "#endif // MODE\n" "\n" +" color *= gl_Color;\n" +"\n" "#ifdef USEGLOW\n" " color.rgb += vec3(texture2D(Texture_Glow, TexCoord));\n" "#endif\n" "\n" "#ifdef USEFOG\n" " // apply fog\n" -" float fog = texture2D(Texture_FogMask, vec2(length(EyeVector)*FogRangeRecip, 0.0)).x;\n" +" float fog = texture2D(Texture_FogMask, vec2(length(EyeVectorModelSpace)*FogRangeRecip, 0.0)).x;\n" " color.rgb = color.rgb * fog + FogColor * (1.0 - fog);\n" "#endif\n" "\n" -" gl_FragColor = color * gl_Color;\n" +" gl_FragColor = color;\n" "}\n" "\n" "#endif // FRAGMENT_SHADER\n" @@ -837,7 +845,7 @@ void R_GLSL_Restart_f(void) memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations)); } -void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting) +void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, rtexture_t *lightmaptexture, const vec3_t modelorg, const vec3_t lightcolorbase, qboolean modellighting) { // select a permutation of the lighting shader appropriate to this // combination of texture, entity, light source, and fogging, only use the @@ -855,17 +863,20 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, } else { - if (modellighting) - permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION; - else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping) + if (!(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) { - if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace) - permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE; - else + if (modellighting) + permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION; + else if (r_glsl_deluxemapping.integer >= 1 && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping && lightmaptexture) + { + if (r_refdef.worldmodel->brushq3.deluxemapping_modelspace) + permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE; + else + permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE; + } + else if (r_glsl_deluxemapping.integer >= 2) // fake mode permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE; } - else if (r_glsl_deluxemapping.integer >= 2) // fake mode - permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE; if (texture->skin.glow) permutation |= SHADERPERMUTATION_GLOW; } @@ -952,9 +963,12 @@ void R_SetupSurfaceShader(const entity_render_t *ent, const texture_t *texture, if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(texture->skin.nmap)); if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(texture->basetexture)); if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(texture->glosstexture)); + //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap)); if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation)); if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(texture->skin.pants)); if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(texture->skin.shirt)); + if (r_glsl_permutation->loc_Texture_Lightmap >= 0) R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); + if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); if (r_glsl_permutation->loc_Texture_Glow >= 0) R_Mesh_TexBind(9, R_GetTexture(texture->skin.glow)); if (r_glsl_permutation->loc_FogColor >= 0) { @@ -1464,7 +1478,6 @@ static void R_BlendView(void) int screenwidth, screenheight; qboolean dobloom; qboolean doblend; - rmeshstate_t m; float vertex3f[12]; float texcoord2f[3][8]; @@ -1489,9 +1502,12 @@ static void R_BlendView(void) vertex3f[3] = 1;vertex3f[4] = 0;vertex3f[5] = 0; vertex3f[6] = 1;vertex3f[7] = 1;vertex3f[8] = 0; vertex3f[9] = 0;vertex3f[10] = 1;vertex3f[11] = 0; + R_Mesh_VertexPointer(vertex3f); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); if (dobloom) { - int bloomwidth, bloomheight, x, dobloomblend, range; + int bloomwidth, bloomheight, x, range; float xoffset, yoffset, r; renderstats.bloom++; // allocate textures as needed @@ -1523,11 +1539,8 @@ static void R_BlendView(void) texcoord2f[1][5] = 0; texcoord2f[1][6] = 0; texcoord2f[1][7] = 0; - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - m.pointer_texcoord[0] = texcoord2f[0]; - m.tex[0] = R_GetTexture(r_bloom_texture_screen); - R_Mesh_State(&m); + R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]); + R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen)); // copy view into the full resolution screen image texture GL_ActiveTexture(0); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); @@ -1550,11 +1563,8 @@ static void R_BlendView(void) } // we now have a darkened bloom image in the framebuffer, copy it into // the bloom image texture for more processing - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - m.tex[0] = R_GetTexture(r_bloom_texture_bloom); - m.pointer_texcoord[0] = texcoord2f[2]; - R_Mesh_State(&m); + R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom)); + R_Mesh_TexCoordPointer(0, 2, texcoord2f[2]); GL_ActiveTexture(0); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight); renderstats.bloom_copypixels += bloomwidth * bloomheight; @@ -1627,49 +1637,33 @@ static void R_BlendView(void) qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); // put the original screen image back in place and blend the bloom // texture on it - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - m.tex[0] = R_GetTexture(r_bloom_texture_screen); - m.pointer_texcoord[0] = texcoord2f[0]; -#if 0 - dobloomblend = false; -#else + GL_Color(1,1,1,1); + GL_BlendFunc(GL_ONE, GL_ZERO); // do both in one pass if possible + R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_screen)); + R_Mesh_TexCoordPointer(0, 2, texcoord2f[0]); if (r_textureunits.integer >= 2 && gl_combine.integer) { - dobloomblend = false; - m.texcombinergb[1] = GL_ADD; - m.tex[1] = R_GetTexture(r_bloom_texture_bloom); - m.pointer_texcoord[1] = texcoord2f[1]; + R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1); + R_Mesh_TexBind(1, R_GetTexture(r_bloom_texture_bloom)); + R_Mesh_TexCoordPointer(1, 2, texcoord2f[1]); } else - dobloomblend = true; -#endif - R_Mesh_State(&m); - GL_BlendFunc(GL_ONE, GL_ZERO); - GL_Color(1,1,1,1); - R_Mesh_Draw(0, 4, 2, polygonelements); - renderstats.bloom_drawpixels += r_view_width * r_view_height; - // now blend on the bloom texture if multipass - if (dobloomblend) { - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - m.tex[0] = R_GetTexture(r_bloom_texture_bloom); - m.pointer_texcoord[0] = texcoord2f[1]; - R_Mesh_State(&m); - GL_BlendFunc(GL_ONE, GL_ONE); - GL_Color(1,1,1,1); R_Mesh_Draw(0, 4, 2, polygonelements); renderstats.bloom_drawpixels += r_view_width * r_view_height; + // now blend on the bloom texture + GL_BlendFunc(GL_ONE, GL_ONE); + R_Mesh_TexBind(0, R_GetTexture(r_bloom_texture_bloom)); + R_Mesh_TexCoordPointer(0, 2, texcoord2f[1]); } + R_Mesh_Draw(0, 4, 2, polygonelements); + renderstats.bloom_drawpixels += r_view_width * r_view_height; } if (doblend) { // apply a color tint to the whole view - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - R_Mesh_State(&m); + R_Mesh_ResetTextureState(); 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); @@ -1946,7 +1940,6 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa { int i; float *v, *c, f1, f2, diff[3], vertex3f[8*3], color4f[8*4]; - rmeshstate_t m; GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_DepthMask(false); GL_DepthTest(true); @@ -1972,10 +1965,9 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa c[2] = c[2] * f1 + fogcolor[2] * f2; } } - memset(&m, 0, sizeof(m)); - m.pointer_vertex = vertex3f; - m.pointer_color = color; - R_Mesh_State(&m); + R_Mesh_VertexPointer(vertex3f); + R_Mesh_ColorPointer(color); + R_Mesh_ResetTextureState(); R_Mesh_Draw(8, 12); } */ @@ -2017,12 +2009,8 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenu int i; float f1, f2, *c; float color4f[6*4]; - rmeshstate_t m; R_Mesh_Matrix(&ent->matrix); - memset(&m, 0, sizeof(m)); - m.pointer_vertex = nomodelvertex3f; - if (ent->flags & EF_ADDITIVE) { GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -2039,10 +2027,11 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenu GL_DepthMask(true); } GL_DepthTest(!(ent->effects & EF_NODEPTHTEST)); + R_Mesh_VertexPointer(nomodelvertex3f); if (fogenabled) { memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); - m.pointer_color = color4f; + R_Mesh_ColorPointer(color4f); f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_vieworigin)); f1 = 1 - f2; for (i = 0, c = color4f;i < 6;i++, c += 4) @@ -2056,13 +2045,13 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, int surfacenu else if (ent->alpha != 1) { memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); - m.pointer_color = color4f; + R_Mesh_ColorPointer(color4f); for (i = 0, c = color4f;i < 6;i++, c += 4) c[3] *= ent->alpha; } else - m.pointer_color = nomodelcolor4f; - R_Mesh_State(&m); + R_Mesh_ColorPointer(nomodelcolor4f); + R_Mesh_ResetTextureState(); R_Mesh_Draw(0, 6, 8, nomodelelements); } @@ -2109,7 +2098,6 @@ float spritetexcoord2f[4*2] = {0, 1, 0, 0, 1, 0, 1, 1}; void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_t *fogtexture, int depthdisable, const vec3_t origin, const vec3_t left, const vec3_t up, float scalex1, float scalex2, float scaley1, float scaley2, float cr, float cg, float cb, float ca) { float fog = 0.0f, ifog; - rmeshstate_t m; float vertex3f[12]; if (fogenabled) @@ -2134,11 +2122,11 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_ vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1; vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1; - memset(&m, 0, sizeof(m)); - m.tex[0] = R_GetTexture(texture); - m.pointer_texcoord[0] = spritetexcoord2f; - m.pointer_vertex = vertex3f; - R_Mesh_State(&m); + R_Mesh_VertexPointer(vertex3f); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); + R_Mesh_TexBind(0, R_GetTexture(texture)); + R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f); GL_Color(cr * ifog, cg * ifog, cb * ifog, ca); R_Mesh_Draw(0, 4, 2, polygonelements); @@ -2218,13 +2206,10 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane } } -static void R_DrawCollisionBrush(colbrushf_t *brush) +static void R_DrawCollisionBrush(const colbrushf_t *brush) { int i; - rmeshstate_t m; - memset(&m, 0, sizeof(m)); - m.pointer_vertex = brush->points->v; - R_Mesh_State(&m); + R_Mesh_VertexPointer(brush->points->v); i = (int)(((size_t)brush) / sizeof(colbrushf_t)); GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f); GL_LockArrays(0, brush->numpoints); @@ -2232,15 +2217,12 @@ static void R_DrawCollisionBrush(colbrushf_t *brush) GL_LockArrays(0, 0); } -static void R_DrawCollisionSurface(entity_render_t *ent, msurface_t *surface) +static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t *surface) { int i; - rmeshstate_t m; if (!surface->num_collisiontriangles) return; - memset(&m, 0, sizeof(m)); - m.pointer_vertex = surface->data_collisionvertex3f; - R_Mesh_State(&m); + R_Mesh_VertexPointer(surface->data_collisionvertex3f); i = (int)(((size_t)surface) / sizeof(msurface_t)); GL_Color((i & 31) * (1.0f / 32.0f), ((i >> 5) & 31) * (1.0f / 32.0f), ((i >> 10) & 31) * (1.0f / 32.0f), 0.2f); GL_LockArrays(0, surface->num_collisionvertices); @@ -2443,7 +2425,7 @@ void R_Mesh_ResizeArrays(int newvertices) if (rsurface_array_vertex3f) Mem_Free(rsurface_array_vertex3f); rsurface_array_size = (newvertices + 1023) & ~1023; - rsurface_array_vertex3f = Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[19])); + rsurface_array_vertex3f = (float *)Mem_Alloc(r_main_mempool, rsurface_array_size * sizeof(float[19])); rsurface_array_svector3f = rsurface_array_vertex3f + rsurface_array_size * 3; rsurface_array_tvector3f = rsurface_array_vertex3f + rsurface_array_size * 6; rsurface_array_normal3f = rsurface_array_vertex3f + rsurface_array_size * 9; @@ -2456,59 +2438,44 @@ float *rsurface_svector3f; float *rsurface_tvector3f; float *rsurface_normal3f; float *rsurface_lightmapcolor4f; -qboolean rsurface_generatevertex; -qboolean rsurface_generatetangents; -qboolean rsurface_generatenormals; -qboolean rsurface_deformvertex; -qboolean rsurface_dynamicvertex; vec3_t rsurface_modelorg; const entity_render_t *rsurface_entity; const model_t *rsurface_model; const texture_t *rsurface_texture; -void RSurf_PrepareForBatch(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg) +void RSurf_PrepareVerticesForBatch(const entity_render_t *ent, const texture_t *texture, const vec3_t modelorg, qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist) { VectorCopy(modelorg, rsurface_modelorg); rsurface_entity = ent; rsurface_model = ent->model; rsurface_texture = texture; -} - -void RSurf_SetPointersForPass(qboolean generatenormals, qboolean generatetangents) -{ if (rsurface_array_size < rsurface_model->surfmesh.num_vertices) R_Mesh_ResizeArrays(rsurface_model->surfmesh.num_vertices); if ((rsurface_entity->frameblend[0].lerp != 1 || rsurface_entity->frameblend[0].frame != 0) && (rsurface_model->surfmesh.data_morphvertex3f || rsurface_model->surfmesh.data_vertexboneweights)) { - rsurface_generatevertex = true; - rsurface_generatetangents = false; - rsurface_generatenormals = false; rsurface_vertex3f = rsurface_array_vertex3f; - if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))) + rsurface_svector3f = NULL; + rsurface_tvector3f = NULL; + rsurface_normal3f = NULL; + Mod_Alias_GetMesh_Vertex3f(rsurface_model, rsurface_entity->frameblend, rsurface_array_vertex3f); + if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + generatetangents = true; + if (generatetangents) + generatenormals = true; + if (generatenormals && !rsurface_normal3f) { - rsurface_generatetangents = true; - rsurface_svector3f = rsurface_array_svector3f; - rsurface_tvector3f = rsurface_array_tvector3f; rsurface_normal3f = rsurface_array_normal3f; + Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); } - else + if (generatetangents && !rsurface_svector3f) { - rsurface_svector3f = NULL; - rsurface_tvector3f = NULL; - if (generatenormals) - { - rsurface_generatenormals = true; - rsurface_normal3f = rsurface_array_normal3f; - } - else - rsurface_normal3f = NULL; + Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_normal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer); + rsurface_svector3f = rsurface_array_svector3f; + rsurface_tvector3f = rsurface_array_tvector3f; } } else { - rsurface_generatevertex = false; - rsurface_generatetangents = false; - rsurface_generatenormals = false; rsurface_vertex3f = rsurface_model->surfmesh.data_vertex3f; rsurface_svector3f = rsurface_model->surfmesh.data_svector3f; rsurface_tvector3f = rsurface_model->surfmesh.data_tvector3f; @@ -2516,89 +2483,58 @@ void RSurf_SetPointersForPass(qboolean generatenormals, qboolean generatetangent } if (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) { - rsurface_deformvertex = true; - rsurface_vertex3f = rsurface_array_vertex3f; - rsurface_svector3f = rsurface_array_svector3f; - rsurface_tvector3f = rsurface_array_tvector3f; - rsurface_normal3f = rsurface_array_normal3f; - } - else - rsurface_deformvertex = false; - R_Mesh_VertexPointer(rsurface_vertex3f); - rsurface_dynamicvertex = rsurface_generatevertex || rsurface_deformvertex; -} - -void RSurf_PrepareDynamicSurfaceVertices(const msurface_t *surface) -{ - float *vertex3f, *svector3f, *tvector3f, *normal3f; - model_t *model = rsurface_entity->model; - if (!rsurface_dynamicvertex) - return; - if (rsurface_generatevertex) - { - Mod_Alias_GetMesh_Vertex3f(model, rsurface_entity->frameblend, rsurface_array_vertex3f); - if (rsurface_generatetangents) - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, model->surfmesh.data_texcoordtexture2f, model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); - else if (rsurface_generatenormals) - Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); - } - if (rsurface_deformvertex) - { - int i, j; + int texturesurfaceindex; float center[3], forward[3], right[3], up[3], v[4][3]; matrix4x4_t matrix1, imatrix1; - if (rsurface_generatevertex) - { - vertex3f = rsurface_array_vertex3f; - svector3f = rsurface_array_svector3f; - tvector3f = rsurface_array_tvector3f; - normal3f = rsurface_array_normal3f; - } - else - { - vertex3f = rsurface_vertex3f; - svector3f = rsurface_svector3f; - tvector3f = rsurface_tvector3f; - normal3f = rsurface_normal3f; - } Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewforward, forward); Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewright, right); Matrix4x4_Transform(&rsurface_entity->inversematrix, r_viewup, up); - // a single autosprite surface can contain multiple sprites... - for (j = 0;j < surface->num_vertices - 3;j += 4) + if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2) + { + forward[0] = rsurface_modelorg[0] - center[0]; + forward[1] = rsurface_modelorg[1] - center[1]; + forward[2] = 0; + VectorNormalize(forward); + right[0] = forward[1]; + right[1] = -forward[0]; + right[2] = 0; + VectorSet(up, 0, 0, 1); + } + // make deformed versions of only the vertices used by the specified surfaces + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - VectorClear(center); - for (i = 0;i < 4;i++) - VectorAdd(center, (vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center); - VectorScale(center, 0.25f, center); - // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out? - Matrix4x4_FromVectors(&matrix1, (normal3f + 3 * surface->num_firstvertex) + j*3, (svector3f + 3 * surface->num_firstvertex) + j*3, (tvector3f + 3 * surface->num_firstvertex) + j*3, center); - Matrix4x4_Invert_Simple(&imatrix1, &matrix1); - for (i = 0;i < 4;i++) - Matrix4x4_Transform(&imatrix1, (vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); - if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2) + int i, j; + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + // a single autosprite surface can contain multiple sprites... + for (j = 0;j < surface->num_vertices - 3;j += 4) { - forward[0] = rsurface_modelorg[0] - center[0]; - forward[1] = rsurface_modelorg[1] - center[1]; - forward[2] = 0; - VectorNormalize(forward); - right[0] = forward[1]; - right[1] = -forward[0]; - right[2] = 0; - VectorSet(up, 0, 0, 1); + VectorClear(center); + for (i = 0;i < 4;i++) + VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center); + VectorScale(center, 0.25f, center); + // FIXME: calculate vectors from triangle edges instead of using texture vectors as an easy way out? + Matrix4x4_FromVectors(&matrix1, (rsurface_normal3f + 3 * surface->num_firstvertex) + j*3, (rsurface_svector3f + 3 * surface->num_firstvertex) + j*3, (rsurface_tvector3f + 3 * surface->num_firstvertex) + j*3, center); + Matrix4x4_Invert_Simple(&imatrix1, &matrix1); + for (i = 0;i < 4;i++) + Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); + for (i = 0;i < 4;i++) + VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3); } - for (i = 0;i < 4;i++) - VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, rsurface_array_vertex3f + (surface->num_firstvertex+i+j) * 3); + Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); + Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_normal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, r_smoothnormals_areaweighting.integer); } - Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_array_vertex3f, model->surfmesh.data_texcoordtexture2f, model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_svector3f, rsurface_array_tvector3f, rsurface_array_normal3f, r_smoothnormals_areaweighting.integer); + rsurface_vertex3f = rsurface_array_vertex3f; + rsurface_svector3f = rsurface_array_svector3f; + rsurface_tvector3f = rsurface_array_tvector3f; + rsurface_normal3f = rsurface_array_normal3f; } + R_Mesh_VertexPointer(rsurface_vertex3f); } static void RSurf_Draw(const msurface_t *surface) { GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); } static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog) @@ -2732,11 +2668,10 @@ static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, floa RSurf_Draw(surface); } -static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg) +static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, rtexture_t *lightmaptexture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg) { int texturesurfaceindex; int lightmode; - const msurface_t *surface; model_t *model = ent->model; qboolean applycolor; qboolean applyfog; @@ -2750,8 +2685,22 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text GL_DepthTest(!(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST)); if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE)) qglDisable(GL_CULL_FACE); - RSurf_PrepareForBatch(ent, texture, modelorg); - if (texture->currentmaterialflags & MATERIALFLAG_SKY) + if (r_showsurfaces.integer) + { + GL_DepthMask(true); + GL_BlendFunc(GL_ONE, GL_ZERO); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); + RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist); + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + int k = (int)(((size_t)surface) / sizeof(msurface_t)); + GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f); + RSurf_Draw(surface); + } + } + else if (texture->currentmaterialflags & MATERIALFLAG_SKY) { // transparent sky would be ridiculous if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) @@ -2773,8 +2722,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text if (model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_worldnovis) { GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); if (skyrendermasked) { // depth-only (masking) @@ -2788,12 +2737,10 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text // fog sky GL_BlendFunc(GL_ONE, GL_ZERO); } - RSurf_SetPointersForPass(false, false); + RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, false, texturenumsurfaces, texturesurfacelist); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; RSurf_Draw(surface); } if (skyrendermasked) @@ -2819,62 +2766,47 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text GL_DepthMask(true); } - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], texture->currentalpha); - R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2); + R_SetupSurfaceShader(ent, texture, lightmaptexture, modelorg, vec3_origin, lightmode == 2); if (!r_glsl_permutation) return; - RSurf_SetPointersForPass(false, true); - if (lightmode == 2) + RSurf_PrepareVerticesForBatch(ent, texture, modelorg, true, true, texturenumsurfaces, texturesurfacelist); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); + R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f); + R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f); + R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f); + if (lightmode != 2) { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f); + if (lightmaptexture) { - surface = texturesurfacelist[texturesurfaceindex]; - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f); - R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f); - R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f); - RSurf_Draw(surface); + R_Mesh_TexBind(7, R_GetTexture(lightmaptexture)); + if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) + R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture)); + R_Mesh_ColorPointer(NULL); } - } - else - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + else { - surface = texturesurfacelist[texturesurfaceindex]; - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f); - R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f); - R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f); - R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture)); - if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) - R_Mesh_TexBind(8, R_GetTexture(surface->deluxemaptexture)); - R_Mesh_ColorPointer(NULL); - } - else - { - R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); - if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) - R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); - R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f); - } - RSurf_Draw(surface); + R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); + if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) + R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); + R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f); } } + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + RSurf_Draw(surface); + } qglUseProgramObjectARB(0); } else if (texture->currentnumlayers) { int layerindex; texturelayer_t *layer; + RSurf_PrepareVerticesForBatch(ent, texture, modelorg, true, false, texturenumsurfaces, texturesurfacelist); for (layerindex = 0, layer = texture->currentlayers;layerindex < texture->currentnumlayers;layerindex++, layer++) { vec4_t layercolor; @@ -2897,6 +2829,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text VectorScale(layer->color, 1.0f, layercolor); } layercolor[3] = layer->color[3]; + R_Mesh_ColorPointer(NULL); GL_Color(layercolor[0], layercolor[1], layercolor[2], layercolor[3]); applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1; applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0; @@ -2904,44 +2837,37 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text { case TEXTURELAYERTYPE_LITTEXTURE_COMBINE: memset(&m, 0, sizeof(m)); + m.pointer_texcoord[0] = model->surfmesh.data_texcoordlightmap2f; m.tex[1] = R_GetTexture(layer->texture); m.texmatrix[1] = layer->texmatrix; m.texrgbscale[1] = layertexrgbscale; - m.pointer_color = rsurface_array_color4f; - R_Mesh_State(&m); - RSurf_SetPointersForPass(lightmode == 2, false); + m.pointer_texcoord[1] = model->surfmesh.data_texcoordtexture2f; + R_Mesh_TextureState(&m); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, model->surfmesh.data_texcoordtexture2f); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); } } + else if (lightmaptexture) + { + R_Mesh_TexBind(0, R_GetTexture(lightmaptexture)); + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); + } + } else { + R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, model->surfmesh.data_texcoordtexture2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); - } - else - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); - } + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); } } break; @@ -2949,56 +2875,47 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; - m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; - R_Mesh_State(&m); - RSurf_SetPointersForPass(lightmode == 2, false); + m.pointer_texcoord[0] = model->surfmesh.data_texcoordlightmap2f; + R_Mesh_TextureState(&m); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false); } } + else if (lightmaptexture) + { + R_Mesh_TexBind(0, R_GetTexture(lightmaptexture)); + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false); + } + } else { + R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false); - } - else - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false); - } + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; + RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false); } } + GL_LockArrays(0, 0); GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; - m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; - R_Mesh_State(&m); - RSurf_SetPointersForPass(false, false); + m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f; + R_Mesh_TextureState(&m); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false); } break; @@ -3007,17 +2924,13 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; m.texrgbscale[0] = layertexrgbscale; - m.pointer_color = rsurface_array_color4f; - R_Mesh_State(&m); - RSurf_SetPointersForPass(lightmode == 2, false); + m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f; + R_Mesh_TextureState(&m); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); } } @@ -3025,10 +2938,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); } } @@ -3037,38 +2947,32 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; - m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; - R_Mesh_State(&m); - RSurf_SetPointersForPass(false, false); + m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f; + R_Mesh_TextureState(&m); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); } break; case TEXTURELAYERTYPE_FOG: - memset(&m, 0, sizeof(m)); + R_Mesh_ColorPointer(rsurface_array_color4f); if (layer->texture) { + memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; + m.pointer_texcoord[0] = model->surfmesh.data_texcoordtexture2f; + R_Mesh_TextureState(&m); } - R_Mesh_State(&m); - RSurf_SetPointersForPass(false, false); + else + R_Mesh_ResetTextureState(); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { int i; float f, *v, *c; - surface = texturesurfacelist[texturesurfaceindex]; - if (layer->texture) - R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); - R_Mesh_ColorPointer(rsurface_array_color4f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) { f = VERTEXFOGTABLE(VectorDistance(v, modelorg)); @@ -3083,34 +2987,34 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text default: Con_Printf("R_DrawTextureSurfaceList: unknown layer type %i\n", layer->type); } + GL_LockArrays(0, 0); // if trying to do overbright on first pass of an opaque surface // when combine is not supported, brighten as a post process if (layertexrgbscale > 1 && !gl_combine.integer && layer->depthmask) { int scale; GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + R_Mesh_ColorPointer(NULL); GL_Color(1, 1, 1, 1); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); - RSurf_SetPointersForPass(false, false); + R_Mesh_ResetTextureState(); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; for (scale = 1;scale < layertexrgbscale;scale <<= 1) RSurf_Draw(surface); } + GL_LockArrays(0, 0); } } } + GL_LockArrays(0, 0); if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE)) qglEnable(GL_CULL_FACE); } static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int surfacenumber, const rtlight_t *rtlight) { - const msurface_t *surface = ent->model->data_surfaces + surfacenumber; + msurface_t *surface = ent->model->data_surfaces + surfacenumber; vec3_t modelorg; texture_t *texture; @@ -3121,13 +3025,12 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, int su R_Mesh_Matrix(&ent->matrix); Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg); - R_DrawTextureSurfaceList(ent, texture->currentframe, 1, &surface, modelorg); + R_DrawTextureSurfaceList(ent, texture->currentframe, surface->lightmaptexture, 1, &surface, modelorg); } -void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg) +void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, rtexture_t *lightmaptexture, int texturenumsurfaces, msurface_t **texturesurfacelist, const vec3_t modelorg) { int texturesurfaceindex; - const msurface_t *surface; vec3_t tempcenter, center; if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) { @@ -3136,7 +3039,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - surface = texturesurfacelist[texturesurfaceindex]; + const msurface_t *surface = texturesurfacelist[texturesurfaceindex]; tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; @@ -3146,7 +3049,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex } } else - R_DrawTextureSurfaceList(ent, texture, texturenumsurfaces, texturesurfacelist, modelorg); + R_DrawTextureSurfaceList(ent, texture, lightmaptexture, texturenumsurfaces, texturesurfacelist, modelorg); } extern void R_BuildLightMap(const entity_render_t *ent, msurface_t *surface); @@ -3154,13 +3057,13 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) { int i, j, f, flagsmask; int counttriangles = 0; - msurface_t *surface, **surfacechain; texture_t *t, *texture; + rtexture_t *lmap; model_t *model = ent->model; vec3_t modelorg; const int maxsurfacelist = 1024; int numsurfacelist = 0; - const msurface_t *surfacelist[1024]; + msurface_t *surfacelist[1024]; if (model == NULL) return; R_Mesh_Matrix(&ent->matrix); @@ -3169,6 +3072,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) // update light styles if (!skysurfaces && model->brushq1.light_styleupdatechains) { + msurface_t *surface, **surfacechain; for (i = 0;i < model->brushq1.light_styles;i++) { if (model->brushq1.light_stylevalue[i] != r_refdef.lightstylevalue[model->brushq1.light_style[i]]) @@ -3185,54 +3089,25 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) flagsmask = skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL); f = 0; t = NULL; + lmap = NULL; texture = NULL; numsurfacelist = 0; - if (r_showsurfaces.integer) - { - rmeshstate_t m; - GL_DepthTest(true); - GL_DepthMask(true); - GL_BlendFunc(GL_ONE, GL_ZERO); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); - t = NULL; - for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) - { - if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j]) - continue; - if (t != surface->texture) - { - t = surface->texture; - texture = t->currentframe; - RSurf_PrepareForBatch(ent, texture, modelorg); - RSurf_SetPointersForPass(false, false); - } - if ((texture->currentmaterialflags & flagsmask) && surface->num_triangles) - { - int k = (int)(((size_t)surface) / sizeof(msurface_t)); - GL_Color((k & 15) * (1.0f / 16.0f), ((k >> 4) & 15) * (1.0f / 16.0f), ((k >> 8) & 15) * (1.0f / 16.0f), 0.2f); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); - RSurf_Draw(surface); - renderstats.entities_triangles += surface->num_triangles; - } - renderstats.entities_surfaces++; - } - } - else if (ent == r_refdef.worldentity) + if (ent == r_refdef.worldentity) { + msurface_t *surface; for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) { if (!r_worldsurfacevisible[j]) continue; - if (t != surface->texture) + if (t != surface->texture || lmap != surface->lightmaptexture) { if (numsurfacelist) { - R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); + R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg); numsurfacelist = 0; } t = surface->texture; + lmap = surface->lightmaptexture; texture = t->currentframe; f = texture->currentmaterialflags & flagsmask; } @@ -3246,7 +3121,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) counttriangles += surface->num_triangles; if (numsurfacelist >= maxsurfacelist) { - R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); + R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg); numsurfacelist = 0; } } @@ -3254,16 +3129,18 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) } else { + msurface_t *surface; for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) { - if (t != surface->texture) + if (t != surface->texture || lmap != surface->lightmaptexture) { if (numsurfacelist) { - R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); + R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg); numsurfacelist = 0; } t = surface->texture; + lmap = surface->lightmaptexture; texture = t->currentframe; f = texture->currentmaterialflags & flagsmask; } @@ -3277,14 +3154,14 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) counttriangles += surface->num_triangles; if (numsurfacelist >= maxsurfacelist) { - R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); + R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg); numsurfacelist = 0; } } } } if (numsurfacelist) - R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); + R_QueueTextureSurfaceList(ent, texture, lmap, numsurfacelist, surfacelist, modelorg); renderstats.entities_triangles += counttriangles; if (gl_support_fragment_shader) qglUseProgramObjectARB(0); @@ -3292,9 +3169,11 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces) { int i; - msurface_t *surface; + const msurface_t *surface; q3mbrush_t *brush; R_Mesh_Matrix(&ent->matrix); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); GL_DepthTest(!r_showdisabledepthtest.integer); @@ -3311,16 +3190,16 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) if (r_showtris.integer || r_shownormals.integer) { int k, l; + msurface_t *surface; const int *elements; - rmeshstate_t m; vec3_t v; GL_DepthTest(true); GL_DepthMask(true); if (r_showdisabledepthtest.integer) qglDepthFunc(GL_ALWAYS); GL_BlendFunc(GL_ONE, GL_ZERO); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); + R_Mesh_ColorPointer(NULL); + R_Mesh_ResetTextureState(); for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) { if (ent == r_refdef.worldentity && !r_worldsurfacevisible[j]) @@ -3328,10 +3207,7 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) texture = surface->texture->currentframe; if ((texture->currentmaterialflags & flagsmask) && surface->num_triangles) { - RSurf_PrepareForBatch(ent, texture, modelorg); - RSurf_SetPointersForPass(false, r_shownormals.integer != 0); - if (rsurface_dynamicvertex) - RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_PrepareVerticesForBatch(ent, texture, modelorg, false, r_shownormals.integer != 0, 1, &surface); if (r_showtris.integer) { if (!texture->currentlayers->depthmask)