X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=gl_rmain.c;h=0a1dbd8472eea49295e2541878b8b2f79750b903;hb=07240220e19550d1b8cd85cdac1b6140e0936495;hp=834017cae8af6736bd08af3ec35b7cd4ac091089;hpb=902f14e9a4773dd27a338562511f418763b903f7;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 834017ca..0a1dbd84 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -105,7 +105,9 @@ cvar_t r_bloom_blur = {CVAR_SAVE, "r_bloom_blur", "8"}; cvar_t r_bloom_resolution = {CVAR_SAVE, "r_bloom_resolution", "320"}; cvar_t r_bloom_power = {CVAR_SAVE, "r_bloom_power", "4"}; -cvar_t developer_texturelogging = {0, "developer_texturelogging", "1"}; +cvar_t r_smoothnormals_areaweighting = {0, "r_smoothnormals_areaweighting", "1"}; + +cvar_t developer_texturelogging = {0, "developer_texturelogging", "0"}; cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"}; @@ -473,7 +475,7 @@ void gl_main_newmap(void) if (cl.worldmodel) { strlcpy(entname, cl.worldmodel->name, sizeof(entname)); - l = strlen(entname) - 4; + l = (int)strlen(entname) - 4; if (l >= 0 && !strcmp(entname + l, ".bsp")) { strcpy(entname + l, ".ent"); @@ -513,6 +515,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_bloom_blur); Cvar_RegisterVariable(&r_bloom_resolution); Cvar_RegisterVariable(&r_bloom_power); + Cvar_RegisterVariable(&r_smoothnormals_areaweighting); Cvar_RegisterVariable(&developer_texturelogging); Cvar_RegisterVariable(&gl_lightmaps); if (gamemode == GAME_NEHAHRA || gamemode == GAME_NEXUIZ || gamemode == GAME_TENEBRAE) @@ -579,7 +582,6 @@ void Render_Init(void) { gl_backend_init(); R_Textures_Init(); - Mod_RenderInit(); R_MeshQueue_Init(); GL_Main_Init(); GL_Draw_Init(); @@ -593,6 +595,7 @@ void Render_Init(void) UI_Init(); Sbar_Init(); R_LightningBeams_Init(); + Mod_RenderInit(); } /* @@ -606,7 +609,7 @@ void GL_Init (void) VID_CheckExtensions(); // LordHavoc: report supported extensions - Con_DPrintf("\nengine extensions: %s\n", ENGINE_EXTENSIONS); + Con_DPrintf("\nengine extensions: %s\n", vm_sv_extensions ); // clear to black (loading plaque will be seen over this) qglClearColor(0,0,0,1); @@ -814,8 +817,8 @@ static void R_BlendView(void) // set the (poorly named) screenwidth and screenheight variables to // a power of 2 at least as large as the screen, these will define the // size of the texture to allocate - for (screenwidth = 1;screenwidth < vid.realwidth;screenwidth *= 2); - for (screenheight = 1;screenheight < vid.realheight;screenheight *= 2); + for (screenwidth = 1;screenwidth < vid.width;screenwidth *= 2); + for (screenheight = 1;screenheight < vid.height;screenheight *= 2); // allocate textures as needed if (!r_bloom_texture_screen) r_bloom_texture_screen = R_LoadTexture2D(r_main_texturepool, "screen", screenwidth, screenheight, NULL, TEXTYPE_RGBA, TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL); @@ -852,14 +855,14 @@ static void R_BlendView(void) R_Mesh_State(&m); // copy view into the full resolution screen image texture GL_ActiveTexture(0); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); c_bloomcopies++; c_bloomcopypixels += r_view_width * r_view_height; // now scale it down to the bloom size and raise to a power of itself // to darken it (this leaves the really bright stuff bright, and // everything else becomes very dark) // TODO: optimize with multitexture or GLSL - qglViewport(r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight); + qglViewport(r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight); GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(1, 1, 1, 1); R_Mesh_Draw(0, 4, 2, polygonelements); @@ -881,7 +884,7 @@ static void R_BlendView(void) m.pointer_texcoord[0] = varray_texcoord2f[2]; R_Mesh_State(&m); GL_ActiveTexture(0); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight); c_bloomcopies++; c_bloomcopypixels += bloomwidth * bloomheight; // blend on at multiple vertical offsets to achieve a vertical blur @@ -915,7 +918,7 @@ static void R_BlendView(void) } // copy the vertically blurred bloom view to a texture GL_ActiveTexture(0); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight); c_bloomcopies++; c_bloomcopypixels += bloomwidth * bloomheight; // blend the vertically blurred image at multiple offsets horizontally @@ -950,11 +953,11 @@ static void R_BlendView(void) } // copy the blurred bloom view to a texture GL_ActiveTexture(0); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.height - (r_view_y + bloomheight), bloomwidth, bloomheight); c_bloomcopies++; c_bloomcopypixels += bloomwidth * bloomheight; // go back to full view area - qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height); + 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)); @@ -1022,11 +1025,11 @@ void R_RenderView(void) if (!r_refdef.entities/* || !r_refdef.worldmodel*/) return; //Host_Error ("R_RenderView: NULL worldmodel"); - r_view_width = bound(0, r_refdef.width, vid.realwidth); - r_view_height = bound(0, r_refdef.height, vid.realheight); + r_view_width = bound(0, r_refdef.width, vid.width); + r_view_height = bound(0, r_refdef.height, vid.height); r_view_depth = 1; - r_view_x = bound(0, r_refdef.x, vid.realwidth - r_refdef.width); - r_view_y = bound(0, r_refdef.y, vid.realheight - r_refdef.height); + r_view_x = bound(0, r_refdef.x, vid.width - r_refdef.width); + r_view_y = bound(0, r_refdef.y, vid.height - r_refdef.height); r_view_z = 0; r_view_fov_x = bound(1, r_refdef.fov_x, 170); r_view_fov_y = bound(1, r_refdef.fov_y, 170); @@ -1039,7 +1042,7 @@ void R_RenderView(void) r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1; // GL is weird because it's bottom to top, r_view_y is top to bottom - qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height); + qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); GL_Scissor(r_view_x, r_view_y, r_view_width, r_view_height); GL_ScissorTest(true); GL_DepthMask(true); @@ -1061,7 +1064,7 @@ void R_RenderView(void) R_BlendView(); R_TimeReport("blendview"); - GL_Scissor(0, 0, vid.realwidth, vid.realheight); + GL_Scissor(0, 0, vid.width, vid.height); GL_ScissorTest(false); } @@ -1453,13 +1456,25 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) { - // we don't need to set currentframe if t->animated is false because - // it was already set up by the texture loader for non-animating - if (t->animated) + texture_t *texture = t; + model_t *model = ent->model; + int s = ent->skinnum; + if ((unsigned int)s >= (unsigned int)model->numskins) + s = 0; + if (s >= 1) + c_models++; + if (model->skinscenes) { - t->currentframe = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0]; - t = t->currentframe; + if (model->skinscenes[s].framecount > 1) + s = model->skinscenes[s].firstframe + (unsigned int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount; + else + s = model->skinscenes[s].firstframe; } + if (s > 0) + t = t + s * model->num_surfaces; + if (t->animated) + t = t->anim_frames[ent->frame != 0][(t->anim_total[ent->frame != 0] >= 2) ? ((int)(r_refdef.time * 5.0f) % t->anim_total[ent->frame != 0]) : 0]; + texture->currentframe = t; t->currentmaterialflags = t->basematerialflags; t->currentalpha = ent->alpha; if (t->basematerialflags & MATERIALFLAG_WATERALPHA) @@ -1470,6 +1485,8 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->currentmaterialflags |= MATERIALFLAG_ADD | MATERIALFLAG_TRANSPARENT; else if (t->currentalpha < 1) t->currentmaterialflags |= MATERIALFLAG_ALPHA | MATERIALFLAG_TRANSPARENT; + if (ent->effects & EF_NODEPTHTEST) + t->currentmaterialflags |= MATERIALFLAG_NODEPTHTEST; } void R_UpdateAllTextureInfo(entity_render_t *ent) @@ -1480,13 +1497,41 @@ void R_UpdateAllTextureInfo(entity_render_t *ent) R_UpdateTextureInfo(ent, ent->model->data_textures + i); } -static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg) +float *rsurface_vertex3f; +float *rsurface_svector3f; +float *rsurface_tvector3f; +float *rsurface_normal3f; +float *rsurface_lightmapcolor4f; + +void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg) { int i, j; float center[3], forward[3], right[3], up[3], v[4][3]; matrix4x4_t matrix1, imatrix1; + if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights)) + { + rsurface_vertex3f = varray_vertex3f; + rsurface_svector3f = NULL; + rsurface_tvector3f = NULL; + rsurface_normal3f = NULL; + Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f); + } + else + { + rsurface_vertex3f = surface->groupmesh->data_vertex3f; + rsurface_svector3f = surface->groupmesh->data_svector3f; + rsurface_tvector3f = surface->groupmesh->data_tvector3f; + rsurface_normal3f = surface->groupmesh->data_normal3f; + } if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2) { + if (!rsurface_svector3f) + { + rsurface_svector3f = varray_svector3f; + rsurface_tvector3f = varray_tvector3f; + rsurface_normal3f = varray_normal3f; + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer); + } // a single autosprite surface can contain multiple sprites... VectorClear(forward); VectorClear(right); @@ -1495,13 +1540,13 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te { VectorClear(center); for (i = 0;i < 4;i++) - VectorAdd(center, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center); + 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, (surface->groupmesh->data_normal3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_svector3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_tvector3f + 3 * surface->num_firstvertex) + j*3, center); + 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, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); + Matrix4x4_Transform(&imatrix1, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); forward[0] = modelorg[0] - center[0]; forward[1] = modelorg[1] - center[1]; VectorNormalize(forward); @@ -1510,9 +1555,20 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te for (i = 0;i < 4;i++) VectorMAMAMAM(1, center, v[i][0], forward, v[i][1], right, v[i][2], up, varray_vertex3f + (surface->num_firstvertex+i+j) * 3); } + rsurface_vertex3f = varray_vertex3f; + rsurface_svector3f = NULL; + rsurface_tvector3f = NULL; + rsurface_normal3f = NULL; } else if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE) { + if (!rsurface_svector3f) + { + rsurface_svector3f = varray_svector3f; + rsurface_tvector3f = varray_tvector3f; + rsurface_normal3f = varray_normal3f; + Mod_BuildTextureVectorsAndNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_texcoordtexture2f, surface->groupmesh->data_element3i + surface->num_firsttriangle * 3, rsurface_svector3f, rsurface_tvector3f, rsurface_normal3f, r_smoothnormals_areaweighting.integer); + } Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward); Matrix4x4_Transform(&ent->inversematrix, r_viewright, right); Matrix4x4_Transform(&ent->inversematrix, r_viewup, up); @@ -1521,62 +1577,169 @@ static void RSurf_DeformVertices(const entity_render_t *ent, const texture_t *te { VectorClear(center); for (i = 0;i < 4;i++) - VectorAdd(center, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center); + 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, (surface->groupmesh->data_normal3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_svector3f + 3 * surface->num_firstvertex) + j*3, (surface->groupmesh->data_tvector3f + 3 * surface->num_firstvertex) + j*3, center); + 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, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[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, varray_vertex3f + (surface->num_firstvertex+i+j) * 3); } + rsurface_vertex3f = varray_vertex3f; + rsurface_svector3f = NULL; + rsurface_tvector3f = NULL; + rsurface_normal3f = NULL; } - else - memcpy((varray_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), sizeof(float[3]) * surface->num_vertices); + R_Mesh_VertexPointer(rsurface_vertex3f); } -// any sort of deformvertices call is *VERY* rare, so this must be optimized -// to skip deformvertices quickly! -#if 1 -#define RSurf_GetVertexPointer(ent, texture, surface, modelorg) ((texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) ? (RSurf_DeformVertices(ent, texture, surface, modelorg), varray_vertex3f) : surface->groupmesh->data_vertex3f) -#else -static float *RSurf_GetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg) +void RSurf_SetColorPointer(const entity_render_t *ent, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog) { - if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + int i; + float f; + float *v, *c, *c2; + vec3_t diff; + if (lightmode >= 2) { - RSurf_DeformVertices(ent, texture, surface, modelorg); - return varray_vertex3f; + vec4_t ambientcolor4f; + vec3_t diffusecolor; + vec3_t diffusenormal; + if (R_LightModel(ambientcolor4f, diffusecolor, diffusenormal, ent, r*0.5f, g*0.5f, b*0.5f, a, false)) + { + rsurface_lightmapcolor4f = varray_color4f; + if (rsurface_normal3f == NULL) + { + rsurface_normal3f = varray_normal3f; + Mod_BuildNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_vertex3f, surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle, rsurface_normal3f, r_smoothnormals_areaweighting.integer); + } + R_LightModel_CalcVertexColors(ambientcolor4f, diffusecolor, diffusenormal, surface->groupmesh->num_vertices, rsurface_vertex3f + 3 * surface->num_firstvertex, rsurface_normal3f + 3 * surface->num_firstvertex, rsurface_lightmapcolor4f + 4 * surface->num_firstvertex); + r = 1; + g = 1; + b = 1; + a = 1; + applycolor = false; + } + else + { + r = ambientcolor4f[0]; + g = ambientcolor4f[1]; + b = ambientcolor4f[2]; + a = ambientcolor4f[3]; + rsurface_lightmapcolor4f = NULL; + } + } + else if (lightmode >= 1) + { + if (surface->lightmapinfo) + { + rsurface_lightmapcolor4f = varray_color4f; + for (i = 0, c = rsurface_lightmapcolor4f + 4 * surface->num_firstvertex;i < surface->num_vertices;i++, c += 4) + { + const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i]; + float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f); + VectorScale(lm, scale, c); + if (surface->lightmapinfo->styles[1] != 255) + { + int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3; + lm += size3; + scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f); + VectorMA(c, scale, lm, c); + if (surface->lightmapinfo->styles[2] != 255) + { + lm += size3; + scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f); + VectorMA(c, scale, lm, c); + if (surface->lightmapinfo->styles[3] != 255) + { + lm += size3; + scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f); + VectorMA(c, scale, lm, c); + } + } + } + } + } + else + rsurface_lightmapcolor4f = surface->groupmesh->data_lightmapcolor4f; } else - return surface->groupmesh->data_vertex3f; + rsurface_lightmapcolor4f = NULL; + if (applyfog) + { + if (rsurface_lightmapcolor4f) + { + for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4) + { + VectorSubtract(v, modelorg, diff); + f = 1 - exp(fogdensity/DotProduct(diff, diff)); + c2[0] = c[0] * f; + c2[1] = c[1] * f; + c2[2] = c[2] * f; + c2[3] = c[3]; + } + } + else + { + for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4) + { + VectorSubtract(v, modelorg, diff); + f = 1 - exp(fogdensity/DotProduct(diff, diff)); + c2[0] = f; + c2[1] = f; + c2[2] = f; + c2[3] = 1; + } + } + rsurface_lightmapcolor4f = varray_color4f; + } + if (applycolor && rsurface_lightmapcolor4f) + { + for (i = 0, c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4, c2 += 4) + { + c2[0] = c[0] * r; + c2[1] = c[1] * g; + c2[2] = c[2] * b; + c2[3] = c[3] * a; + } + } + R_Mesh_ColorPointer(rsurface_lightmapcolor4f); + GL_Color(r, g, b, a); } -#endif + static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *texture, int texturenumsurfaces, const msurface_t **texturesurfacelist, const vec3_t modelorg) { int i; int texturesurfaceindex; - const float *v, *vertex3f; + const float *v; float *c; float diff[3]; - float f, r, g, b, a, base, colorscale; + float colorpants[3], colorshirt[3]; + float f, r, g, b, a, colorscale; const msurface_t *surface; qboolean dolightmap; - qboolean dobase; qboolean doambient; qboolean dodetail; qboolean doglow; qboolean dofogpass; qboolean fogallpasses; qboolean waterscrolling; - surfmesh_t *groupmesh; - rtexture_t *lightmaptexture; + qboolean dopants; + qboolean doshirt; + qboolean dofullbrightpants; + qboolean dofullbrightshirt; + qboolean applycolor; + qboolean lightmode = 0; + rtexture_t *basetexture; rmeshstate_t m; - texture = texture->currentframe; if (texture->currentmaterialflags & MATERIALFLAG_NODRAW) return; c_faces += texturenumsurfaces; + // FIXME: identify models using a better check than ent->model->shadowmesh + if (!(ent->effects & EF_FULLBRIGHT) && !ent->model->brush.shadowmesh) + lightmode = 2; // gl_lightmaps debugging mode skips normal texturing if (gl_lightmaps.integer) { @@ -1592,8 +1755,8 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text surface = texturesurfacelist[texturesurfaceindex]; R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_ColorPointer(surface->lightmaptexture ? NULL : surface->groupmesh->data_lightmapcolor4f); - R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + RSurf_SetColorPointer(ent, surface, modelorg, 1, 1, 1, 1, lightmode ? lightmode : !surface->lightmaptexture, false, false); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); @@ -1646,7 +1809,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); @@ -1679,7 +1842,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg)); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); @@ -1694,585 +1857,284 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text else if (texture->currentmaterialflags & (MATERIALFLAG_WATER | MATERIALFLAG_WALL)) { // normal surface (wall or water) - dobase = true; dolightmap = !(texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT); doambient = r_ambient.value >= (1/64.0f); dodetail = r_detailtextures.integer && texture->skin.detail != NULL && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT); doglow = texture->skin.glow != NULL; dofogpass = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_ADD); fogallpasses = fogenabled && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT); - if (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) + if (ent->colormap >= 0) { - if (dobase && dolightmap && gl_combine.integer) - { - dobase = false; - memset(&m, 0, sizeof(m)); - m.tex[1] = R_GetTexture(texture->skin.base); - if (waterscrolling) - m.texmatrix[1] = r_waterscrollmatrix; - m.texrgbscale[1] = 2; - m.pointer_color = varray_color4f; - R_Mesh_State(&m); + int b; + qbyte *bcolor; + basetexture = texture->skin.base; + dopants = texture->skin.pants != NULL; + doshirt = texture->skin.shirt != NULL; + // 128-224 are backwards ranges + b = (ent->colormap & 0xF) << 4;b += (b >= 128 && b < 224) ? 4 : 12; + dofullbrightpants = b >= 224; + bcolor = (qbyte *) (&palette_complete[b]); + VectorScale(bcolor, (1.0f / 255.0f), colorpants); + // 128-224 are backwards ranges + b = (ent->colormap & 0xF0);b += (b >= 128 && b < 224) ? 4 : 12; + dofullbrightshirt = b >= 224; + bcolor = (qbyte *) (&palette_complete[b]); + VectorScale(bcolor, (1.0f / 255.0f), colorshirt); + } + else + { + basetexture = texture->skin.merged ? texture->skin.merged : texture->skin.base; + dopants = false; + doshirt = false; + dofullbrightshirt = false; + dofullbrightpants = false; + } + if (dolightmap && r_textureunits.integer >= 2 && gl_combine.integer) + { + memset(&m, 0, sizeof(m)); + m.tex[1] = R_GetTexture(basetexture); + if (waterscrolling) + m.texmatrix[1] = r_waterscrollmatrix; + m.texrgbscale[1] = 2; + m.pointer_color = varray_color4f; + R_Mesh_State(&m); + // transparent is not affected by r_lightmapintensity + if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) + colorscale = r_lightmapintensity; + else colorscale = 1; - r = ent->colormod[0] * colorscale; - g = ent->colormod[1] * colorscale; - b = ent->colormod[2] * colorscale; - a = texture->currentalpha; - base = r_ambient.value * (1.0f / 64.0f); - // q3bsp has no lightmap updates, so the lightstylevalue that - // would normally be baked into the lightmaptexture must be - // applied to the color - if (ent->model->brushq1.lightdata) + // q3bsp has no lightmap updates, so the lightstylevalue that + // would normally be baked into the lightmaptexture must be + // applied to the color + if (ent->model->type == mod_brushq3) + colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f); + r = ent->colormod[0] * colorscale; + g = ent->colormod[1] * colorscale; + b = ent->colormod[2] * colorscale; + a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); + R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); + if (surface->lightmaptexture) + R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); + else + R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode ? lightmode : !surface->lightmaptexture, applycolor, fogallpasses); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); + } + } + else if (dolightmap && !(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT) && !lightmode) + { + // single texture + GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthMask(true); + GL_Color(1, 1, 1, 1); + memset(&m, 0, sizeof(m)); + R_Mesh_State(&m); + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); + if (surface->lightmaptexture) { - float scale = d_lightstylevalue[0] * (1.0f / 128.0f); - r *= scale; - g *= scale; - b *= scale; + R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); + R_Mesh_ColorPointer(NULL); } + else + { + R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); + R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f); + } + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); + } + GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + GL_DepthMask(false); + GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1); + memset(&m, 0, sizeof(m)); + m.tex[0] = R_GetTexture(basetexture); + if (waterscrolling) + m.texmatrix[0] = r_waterscrollmatrix; + R_Mesh_State(&m); + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) + { + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); + } + } + else + { + memset(&m, 0, sizeof(m)); + m.tex[0] = R_GetTexture(basetexture); + if (waterscrolling) + m.texmatrix[0] = r_waterscrollmatrix; + m.pointer_color = varray_color4f; + colorscale = 2; + if (gl_combine.integer) + { + m.texrgbscale[0] = 2; + colorscale = 1; + } + // transparent is not affected by r_lightmapintensity + if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) + colorscale *= r_lightmapintensity; + // q3bsp has no lightmap updates, so the lightstylevalue that + // would normally be baked into the lightmaptexture must be + // applied to the color + if (dolightmap && ent->model->type == mod_brushq3) + colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f); + R_Mesh_State(&m); + r = ent->colormod[0] * colorscale; + g = ent->colormod[1] * colorscale; + b = ent->colormod[2] * colorscale; + a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; + if (dolightmap) + { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - if (fogallpasses) - { - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - c[0] = f * r; - c[1] = f * g; - c[2] = f * b; - c[3] = a; - } - } - else - { - R_Mesh_ColorPointer(NULL); - GL_Color(r, g, b, a); - } - } - else - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(varray_color4f); - if (!surface->lightmaptexture) - { - for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4) - { - c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r; - c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g; - c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - } - if (fogallpasses) - { - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - VectorScale(c, f, c); - } - } - } - else - { - R_Mesh_ColorPointer(NULL); - GL_Color(0, 0, 0, a); - } - } + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); } } - if (dobase) + else { - dobase = false; - memset(&m, 0, sizeof(m)); - m.tex[0] = R_GetTexture(texture->skin.base); - if (waterscrolling) - m.texmatrix[0] = r_waterscrollmatrix; - m.pointer_color = varray_color4f; - colorscale = 1; - if (gl_combine.integer) - { - m.texrgbscale[0] = 4; - colorscale *= 0.25f; - } - R_Mesh_State(&m); - r = ent->colormod[0] * colorscale; - g = ent->colormod[1] * colorscale; - b = ent->colormod[2] * colorscale; - a = texture->currentalpha; - if (dolightmap) - { - // q3bsp has no lightmap updates, so the lightstylevalue that - // would normally be baked into the lightmaptexture must be - // applied to the color - if (!ent->model->brushq1.lightdata) - { - float scale = d_lightstylevalue[0] * (1.0f / 128.0f); - r *= scale; - g *= scale; - b *= scale; - } - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - c[0] = 0; - c[1] = 0; - c[2] = 0; - if (!surface->lightmapinfo) - VectorCopy((surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex) + i*4, c); - else //if (surface->lightmapinfo) - { - const qbyte *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i]; - float scale = d_lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - if (surface->lightmapinfo->styles[1] != 255) - { - int size3 = ((surface->lightmapinfo->extents[0]>>4)+1)*((surface->lightmapinfo->extents[1]>>4)+1)*3; - lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[1]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - if (surface->lightmapinfo->styles[2] != 255) - { - lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[2]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - if (surface->lightmapinfo->styles[3] != 255) - { - lm += size3; - scale = d_lightstylevalue[surface->lightmapinfo->styles[3]] * (1.0f / 32768.0f); - VectorMA(c, scale, lm, c); - } - } - } - } - c[0] *= r; - c[1] *= g; - c[2] *= b; - if (fogallpasses) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - VectorScale(c, f, c); - } - if (!surface->lightmapinfo && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - else - c[3] = a; - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - if (fogallpasses) - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - if (!surface->lightmapinfo && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - { - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - c[0] = r * f; - c[1] = g * f; - c[2] = b * f; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - } - } - else - { - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - c[0] = r * f; - c[1] = g * f; - c[2] = b * f; - c[3] = a; - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - if (!surface->lightmaptexture && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - { - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - c[0] = r; - c[1] = g; - c[2] = b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - } - } - else - { - R_Mesh_ColorPointer(NULL); - GL_Color(r, g, b, a); - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); } } } - else + if (dopants) { - if (!dolightmap && dobase) + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); + memset(&m, 0, sizeof(m)); + m.tex[0] = R_GetTexture(texture->skin.pants); + if (waterscrolling) + m.texmatrix[0] = r_waterscrollmatrix; + m.pointer_color = varray_color4f; + colorscale = 2; + if (gl_combine.integer) + { + m.texrgbscale[0] = 2; + colorscale = 1; + } + // transparent is not affected by r_lightmapintensity + if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) + colorscale *= r_lightmapintensity; + // q3bsp has no lightmap updates, so the lightstylevalue that + // would normally be baked into the lightmaptexture must be + // applied to the color + if (dolightmap && !dofullbrightpants && ent->model->type == mod_brushq3) + colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f); + R_Mesh_State(&m); + r = ent->colormod[0] * colorpants[0] * colorscale; + g = ent->colormod[1] * colorpants[1] * colorscale; + b = ent->colormod[2] * colorpants[2] * colorscale; + a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; + if (dolightmap && !dofullbrightpants) { - dolightmap = false; - dobase = false; - GL_Color(ent->colormod[0], ent->colormod[1], ent->colormod[2], 1); - memset(&m, 0, sizeof(m)); - m.tex[0] = R_GetTexture(texture->skin.base); - if (waterscrolling) - m.texmatrix[0] = r_waterscrollmatrix; - R_Mesh_State(&m); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg)); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); } } - if (r_lightmapintensity <= 0 && dolightmap && dobase) + else { - dolightmap = false; - dobase = false; - GL_Color(0, 0, 0, 1); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg)); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); } } - if (r_textureunits.integer >= 2 && gl_combine.integer && dolightmap && dobase) + } + if (doshirt) + { + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); + memset(&m, 0, sizeof(m)); + m.tex[0] = R_GetTexture(texture->skin.shirt); + if (waterscrolling) + m.texmatrix[0] = r_waterscrollmatrix; + m.pointer_color = varray_color4f; + colorscale = 2; + if (gl_combine.integer) { - // dualtexture combine - GL_BlendFunc(GL_ONE, GL_ZERO); - GL_DepthMask(true); - dolightmap = false; - dobase = false; - memset(&m, 0, sizeof(m)); - m.tex[1] = R_GetTexture(texture->skin.base); - if (waterscrolling) - m.texmatrix[1] = r_waterscrollmatrix; - m.texrgbscale[1] = 2; - R_Mesh_State(&m); - r = ent->colormod[0] * r_lightmapintensity; - g = ent->colormod[1] * r_lightmapintensity; - b = ent->colormod[2] * r_lightmapintensity; - GL_Color(r, g, b, 1); - if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) - { - R_Mesh_VertexPointer(varray_vertex3f); - if (r == 1 && g == 1 && b == 1) - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - RSurf_DeformVertices(ent, texture, surface, modelorg); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else //if (r == 1 && g == 1 && b == 1) - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f); - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - RSurf_DeformVertices(ent, texture, surface, modelorg); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4) - { - c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r; - c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g; - c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3]; - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - } - else - { - if (r == 1 && g == 1 && b == 1) - { -#if 0 - // experimental direct state calls for measuring - // R_Mesh_ call overhead, do not use! - R_Mesh_VertexPointer(varray_vertex3f); - R_Mesh_TexCoordPointer(0, 2, varray_texcoord2f[0]); - R_Mesh_TexCoordPointer(1, 2, varray_texcoord2f[1]); - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(varray_color4f); - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - qglVertexPointer(3, GL_FLOAT, sizeof(float[3]), surface->groupmesh->data_vertex3f); - qglClientActiveTexture(GL_TEXTURE0_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->groupmesh->data_texcoordlightmap2f); - qglClientActiveTexture(GL_TEXTURE1_ARB); - qglTexCoordPointer(2, GL_FLOAT, sizeof(float[2]), surface->groupmesh->data_texcoordtexture2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - qglDisableClientState(GL_COLOR_ARRAY); - qglColor4f(r, g, b, 1); - } - else //if (r == 1 && g == 1 && b == 1) - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - qglEnableClientState(GL_COLOR_ARRAY); - qglColorPointer(4, GL_FLOAT, sizeof(float[4]), surface->groupmesh->data_lightmapcolor4f); - } - qglLockArraysEXT(0, surface->num_vertices); - qglDrawRangeElements(GL_TRIANGLES, surface->num_firstvertex, surface->num_firstvertex + surface->num_vertices, surface->num_triangles * 3, GL_UNSIGNED_INT, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - qglUnlockArraysEXT(); - } -#else - groupmesh = NULL; - lightmaptexture = NULL; - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - if (groupmesh != surface->groupmesh) - { - groupmesh = surface->groupmesh; - R_Mesh_VertexPointer(groupmesh->data_vertex3f); - R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, groupmesh->data_texcoordtexture2f); - if (!lightmaptexture) - R_Mesh_ColorPointer(groupmesh->data_lightmapcolor4f); - } - if (lightmaptexture != surface->lightmaptexture) - { - lightmaptexture = surface->lightmaptexture; - if (lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else //if (r == 1 && g == 1 && b == 1) - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f); - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } -#endif - } - else - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(surface->groupmesh->data_vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, c += 4) - { - c[0] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+0] * r; - c[1] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+1] * g; - c[2] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+2] * b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3]; - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - } + m.texrgbscale[0] = 2; + colorscale *= 1; } - // single texture - if (dolightmap) + // transparent is not affected by r_lightmapintensity + if (!(texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) + colorscale *= r_lightmapintensity; + // q3bsp has no lightmap updates, so the lightstylevalue that + // would normally be baked into the lightmaptexture must be + // applied to the color + if (dolightmap && !dofullbrightshirt && ent->model->type == mod_brushq3) + colorscale *= d_lightstylevalue[0] * (1.0f / 128.0f); + R_Mesh_State(&m); + r = ent->colormod[0] * colorshirt[0] * colorscale; + g = ent->colormod[1] * colorshirt[1] * colorscale; + b = ent->colormod[2] * colorshirt[2] * colorscale; + a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; + if (dolightmap && !dofullbrightshirt) { - GL_BlendFunc(GL_ONE, GL_ZERO); - GL_DepthMask(true); - GL_Color(1, 1, 1, 1); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); - if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) - { - R_Mesh_VertexPointer(varray_vertex3f); - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - RSurf_DeformVertices(ent, texture, surface, modelorg); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - if (surface->lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(surface->lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else //if (r == 1 && g == 1 && b == 1) - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f); - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - groupmesh = NULL; - lightmaptexture = NULL; - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - if (groupmesh != surface->groupmesh) - { - groupmesh = surface->groupmesh; - R_Mesh_VertexPointer(groupmesh->data_vertex3f); - R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordlightmap2f); - if (!lightmaptexture) - R_Mesh_ColorPointer(groupmesh->data_lightmapcolor4f); - } - if (lightmaptexture != surface->lightmaptexture) - { - lightmaptexture = surface->lightmaptexture; - if (lightmaptexture) - { - R_Mesh_TexBind(0, R_GetTexture(lightmaptexture)); - R_Mesh_ColorPointer(NULL); - } - else //if (r == 1 && g == 1 && b == 1) - { - R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_ColorPointer(surface->groupmesh->data_lightmapcolor4f); - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, lightmode, applycolor, fogallpasses); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); } } - if (dobase) + else { - GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); - GL_DepthMask(false); - GL_Color(r_lightmapintensity * ent->colormod[0], r_lightmapintensity * ent->colormod[1], r_lightmapintensity * ent->colormod[2], 1); - memset(&m, 0, sizeof(m)); - m.tex[0] = R_GetTexture(texture->skin.base); - if (waterscrolling) - m.texmatrix[0] = r_waterscrollmatrix; - R_Mesh_State(&m); - if (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) - { - R_Mesh_VertexPointer(varray_vertex3f); - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - RSurf_DeformVertices(ent, texture, surface, modelorg); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - groupmesh = NULL; - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - if (groupmesh != surface->groupmesh) - { - groupmesh = surface->groupmesh; - R_Mesh_VertexPointer(groupmesh->data_vertex3f); - R_Mesh_TexCoordPointer(0, 2, groupmesh->data_texcoordtexture2f); - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); } } } @@ -2287,39 +2149,24 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.texmatrix[0] = r_waterscrollmatrix; m.pointer_color = varray_color4f; colorscale = 1; - if (gl_combine.integer) + if (gl_combine.integer && (ent->colormod[0] > 1 || ent->colormod[1] > 1 || ent->colormod[2] > 1)) { m.texrgbscale[0] = 4; - colorscale *= 0.25f; + colorscale = 0.25f; } R_Mesh_State(&m); - base = r_ambient.value * (1.0f / 64.0f); - r = ent->colormod[0] * colorscale * base; - g = ent->colormod[1] * colorscale * base; - b = ent->colormod[2] * colorscale * base; + colorscale *= r_ambient.value * (1.0f / 64.0f); + r = ent->colormod[0] * colorscale; + g = ent->colormod[1] * colorscale; + b = ent->colormod[2] * colorscale; a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - c[0] = r; - c[1] = g; - c[2] = b; - if (fogallpasses) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - VectorScale(c, f, c); - } - if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - else - c[3] = a; - } + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); GL_LockArrays(0, 0); @@ -2336,7 +2183,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_VertexPointer(RSurf_GetVertexPointer(ent, texture, surface, modelorg)); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoorddetail2f); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); @@ -2354,77 +2201,20 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.texmatrix[0] = r_waterscrollmatrix; m.pointer_color = varray_color4f; R_Mesh_State(&m); - colorscale = 1; - r = ent->colormod[0] * colorscale; - g = ent->colormod[1] * colorscale; - b = ent->colormod[2] * colorscale; + r = 1; + g = 1; + b = 1; a = texture->currentalpha; - if (fogallpasses) - { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - R_Mesh_ColorPointer(varray_color4f); - if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - { - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - c[0] = f * r; - c[1] = f * g; - c[2] = f * b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - } - } - else - { - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - VectorSubtract(v, modelorg, diff); - f = 1 - exp(fogdensity/DotProduct(diff, diff)); - c[0] = f * r; - c[1] = f * g; - c[2] = f * b; - c[3] = a; - } - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } - } - else + applycolor = r != 1 || g != 1 || b != 1 || a != 1; + for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) - { - R_Mesh_ColorPointer(varray_color4f); - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) - { - c[0] = r; - c[1] = g; - c[2] = b; - c[3] = (surface->groupmesh->data_lightmapcolor4f + 4 * surface->num_firstvertex)[i*4+3] * a; - } - } - else - { - R_Mesh_ColorPointer(NULL); - GL_Color(r, g, b, a); - } - GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); - GL_LockArrays(0, 0); - } + surface = texturesurfacelist[texturesurfaceindex]; + RSurf_SetVertexPointer(ent, texture, surface, modelorg); + R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + RSurf_SetColorPointer(ent, surface, modelorg, r, g, b, a, 0, applycolor, fogallpasses); + GL_LockArrays(surface->num_firstvertex, surface->num_vertices); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + GL_LockArrays(0, 0); } } if (dofogpass) @@ -2440,7 +2230,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text // were darkened by fog already, and we should not add fog color // (because the background was not darkened, there is no fog color // that was lost behind it). - if (!fogallpasses) + if (fogallpasses) GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); else GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2454,17 +2244,17 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text g = fogcolor[1]; b = fogcolor[2]; a = texture->currentalpha; + applycolor = r != 1 || g != 1 || b != 1 || a != 1; for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - vertex3f = RSurf_GetVertexPointer(ent, texture, surface, modelorg); - R_Mesh_VertexPointer(vertex3f); + RSurf_SetVertexPointer(ent, texture, surface, modelorg); R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); R_Mesh_ColorPointer(varray_color4f); //RSurf_FogPassColors_Vertex3f_Color4f((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), varray_color4f, fogcolor[0], fogcolor[1], fogcolor[2], texture->currentalpha, 1, surface->num_vertices, modelorg); if (!surface->lightmaptexture && surface->groupmesh->data_lightmapcolor4f && (texture->currentmaterialflags & MATERIALFLAG_TRANSPARENT)) { - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) + for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) { VectorSubtract(v, modelorg, diff); f = exp(fogdensity/DotProduct(diff, diff)); @@ -2476,7 +2266,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text } else { - for (i = 0, v = (vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) + for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (varray_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4) { VectorSubtract(v, modelorg, diff); f = exp(fogdensity/DotProduct(diff, diff)); @@ -2530,7 +2320,7 @@ void R_QueueTextureSurfaceList(entity_render_t *ent, texture_t *texture, int tex tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; Matrix4x4_Transform(&ent->matrix, tempcenter, center); - R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->data_surfaces); + R_MeshQueue_AddTransparent(texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_vieworigin : center, RSurfShader_Transparent_Callback, ent, surface - ent->model->data_surfaces); } } } @@ -2589,8 +2379,8 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) numsurfacelist = 0; } t = surface->texture; - f = t->currentmaterialflags & flagsmask; texture = t->currentframe; + f = texture->currentmaterialflags & flagsmask; } if (f && surface->num_triangles) { @@ -2619,8 +2409,8 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) numsurfacelist = 0; } t = surface->texture; - f = t->currentmaterialflags & flagsmask; texture = t->currentframe; + f = texture->currentmaterialflags & flagsmask; } if (f && surface->num_triangles) {