X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_rmain.c;h=e9ed8aafa0c7072ae63f20a6406d075d9a7e7b5e;hp=c4f2b1fc97e86dafb6c43afd3a719bdfd46a02d1;hb=3fabadf7d463a554e908a698c692e24ea927cb9a;hpb=d825f40374cf6c88ca0087a23f9a75b8deba26f2 diff --git a/gl_rmain.c b/gl_rmain.c index c4f2b1fc..e9ed8aaf 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -48,9 +48,6 @@ qboolean r_rtdlight; qboolean r_rtdlightshadows; -// forces all rendering to draw triangle outlines -int r_showtrispass; - // view origin vec3_t r_vieworigin; vec3_t r_viewforward; @@ -64,15 +61,18 @@ int r_view_width; int r_view_height; int r_view_depth; matrix4x4_t r_view_matrix; - +float r_polygonfactor; +float r_polygonoffset; +float r_shadowpolygonfactor; +float r_shadowpolygonoffset; // // screen size info // refdef_t r_refdef; cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip plane" }; +cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "shows surfaces as different colors"}; cvar_t r_showtris = {0, "r_showtris", "0", "shows triangle outlines, value controls brightness (can be above 1)"}; -cvar_t r_showtris_polygonoffset = {0, "r_showtris_polygonoffset", "-10", "nudges triangle outlines in hardware depth units, used to make outlines appear infront of walls"}; cvar_t r_shownormals = {0, "r_shownormals", "0", "shows per-vertex surface normals and tangent vectors for bumpmapped lighting"}; cvar_t r_showlighting = {0, "r_showlighting", "0", "shows areas lit by lights, useful for finding out why some areas of a map render slowly (bright orange = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"}; cvar_t r_showshadowvolumes = {0, "r_showshadowvolumes", "0", "shows areas shadowed by lights, useful for finding out why some areas of a map render slowly (bright blue = lots of passes = slow), a value of 2 disables depth testing which can be interesting but not very useful"}; @@ -1168,8 +1168,8 @@ void GL_Main_Init(void) Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n"); FOG_registercvars(); // FIXME: move this fog stuff to client? Cvar_RegisterVariable(&r_nearclip); + Cvar_RegisterVariable(&r_showsurfaces); Cvar_RegisterVariable(&r_showtris); - Cvar_RegisterVariable(&r_showtris_polygonoffset); Cvar_RegisterVariable(&r_shownormals); Cvar_RegisterVariable(&r_showlighting); Cvar_RegisterVariable(&r_showshadowvolumes); @@ -1825,6 +1825,18 @@ void R_RenderView(void) r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer; r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil; r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + r_polygonfactor = 0; + r_polygonoffset = 0; + r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value; + r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value; + if (r_showsurfaces.integer) + { + r_rtworld = false; + r_rtworldshadows = false; + r_rtdlight = false; + r_rtdlightshadows = false; + r_lightmapintensity = 0; + } // GL is weird because it's bottom to top, r_view_y is top to bottom qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); @@ -1838,12 +1850,12 @@ void R_RenderView(void) R_TimeReport("setup"); qglDepthFunc(GL_LEQUAL); - qglPolygonOffset(0, 0); + qglPolygonOffset(r_polygonfactor, r_polygonoffset); qglEnable(GL_POLYGON_OFFSET_FILL); R_RenderScene(); - qglPolygonOffset(0, 0); + qglPolygonOffset(r_polygonfactor, r_polygonoffset); qglDisable(GL_POLYGON_OFFSET_FILL); R_BlendView(); @@ -1873,6 +1885,18 @@ void CSQC_R_ClearScreen (void) r_rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer; r_rtdlightshadows = r_rtdlight && (r_rtworld ? r_shadow_realtime_world_dlightshadows.integer : r_shadow_realtime_dlight_shadows.integer) && gl_stencil; r_lightmapintensity = r_rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + r_polygonfactor = 0; + r_polygonoffset = 0; + r_shadowpolygonfactor = r_polygonfactor + r_shadow_shadow_polygonfactor.value; + r_shadowpolygonoffset = r_polygonoffset + r_shadow_shadow_polygonoffset.value; + if (r_showsurfaces.integer) + { + r_rtworld = false; + r_rtworldshadows = false; + r_rtdlight = false; + r_rtdlightshadows = false; + r_lightmapintensity = 0; + } // GL is weird because it's bottom to top, r_view_y is top to bottom qglViewport(r_view_x, vid.height - (r_view_y + r_view_height), r_view_width, r_view_height); @@ -1890,12 +1914,12 @@ void CSQC_R_ClearScreen (void) void CSQC_R_RenderScene (void) { qglDepthFunc(GL_LEQUAL); - qglPolygonOffset(0, 0); + qglPolygonOffset(r_polygonfactor, r_polygonoffset); qglEnable(GL_POLYGON_OFFSET_FILL); R_RenderScene(); - qglPolygonOffset(0, 0); + qglPolygonOffset(r_polygonfactor, r_polygonoffset); qglDisable(GL_POLYGON_OFFSET_FILL); R_BlendView(); @@ -1949,123 +1973,85 @@ void R_RenderScene(void) R_Shadow_UpdateWorldLightSelection(); - for (r_showtrispass = 0;r_showtrispass <= (r_showtris.value > 0);r_showtrispass++) + if (cl.csqc_vidvars.drawworld) { - if (r_showtrispass) - { - rmeshstate_t m; - r_showtrispass = 0; - GL_BlendFunc(GL_ONE, GL_ONE); - GL_DepthTest(!r_showdisabledepthtest.integer); - GL_DepthMask(GL_FALSE); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); - //qglEnable(GL_LINE_SMOOTH); - qglEnable(GL_POLYGON_OFFSET_LINE); - qglPolygonOffset(0, r_showtris_polygonoffset.value); - r_showtrispass = 1; - } - - if (cl.csqc_vidvars.drawworld) - { - // don't let sound skip if going slow - if (r_refdef.extraupdate) - S_ExtraUpdate (); - - if (r_showtrispass) - GL_ShowTrisColor(0.025, 0.025, 0, 1); - if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky) - { - r_refdef.worldmodel->DrawSky(r_refdef.worldentity); - if (r_timereport_active) - R_TimeReport("worldsky"); - } - - if (R_DrawBrushModelsSky() && r_timereport_active) - R_TimeReport("bmodelsky"); - - if (r_showtrispass) - GL_ShowTrisColor(0.05, 0.05, 0.05, 1); - if (r_refdef.worldmodel && r_refdef.worldmodel->Draw) - { - r_refdef.worldmodel->Draw(r_refdef.worldentity); - if (r_timereport_active) - R_TimeReport("world"); - } - } - // don't let sound skip if going slow if (r_refdef.extraupdate) S_ExtraUpdate (); - if (r_showtrispass) - GL_ShowTrisColor(0, 0.015, 0, 1); + if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky) + { + r_refdef.worldmodel->DrawSky(r_refdef.worldentity); + if (r_timereport_active) + R_TimeReport("worldsky"); + } - R_DrawModels(); - if (r_timereport_active) - R_TimeReport("models"); + if (R_DrawBrushModelsSky() && r_timereport_active) + R_TimeReport("bmodelsky"); - // don't let sound skip if going slow - if (r_refdef.extraupdate) - S_ExtraUpdate (); - - if (r_showtrispass) - GL_ShowTrisColor(0, 0, 0.033, 1); - R_ShadowVolumeLighting(false); - if (r_timereport_active) - R_TimeReport("rtlights"); + if (r_refdef.worldmodel && r_refdef.worldmodel->Draw) + { + r_refdef.worldmodel->Draw(r_refdef.worldentity); + if (r_timereport_active) + R_TimeReport("world"); + } + } - // don't let sound skip if going slow - if (r_refdef.extraupdate) - S_ExtraUpdate (); + // don't let sound skip if going slow + if (r_refdef.extraupdate) + S_ExtraUpdate (); - if (r_showtrispass) - GL_ShowTrisColor(0.1, 0, 0, 1); + R_DrawModels(); + if (r_timereport_active) + R_TimeReport("models"); - if (cl.csqc_vidvars.drawworld) - { - R_DrawLightningBeams(); - if (r_timereport_active) - R_TimeReport("lightning"); + // don't let sound skip if going slow + if (r_refdef.extraupdate) + S_ExtraUpdate (); - R_DrawParticles(); - if (r_timereport_active) - R_TimeReport("particles"); + R_ShadowVolumeLighting(false); + if (r_timereport_active) + R_TimeReport("rtlights"); - R_DrawExplosions(); - if (r_timereport_active) - R_TimeReport("explosions"); - } + // don't let sound skip if going slow + if (r_refdef.extraupdate) + S_ExtraUpdate (); - R_MeshQueue_RenderTransparent(); + if (cl.csqc_vidvars.drawworld) + { + R_DrawLightningBeams(); if (r_timereport_active) - R_TimeReport("drawtrans"); + R_TimeReport("lightning"); - if (cl.csqc_vidvars.drawworld) - { - R_DrawCoronas(); - if (r_timereport_active) - R_TimeReport("coronas"); - } - if(cl.csqc_vidvars.drawcrosshair) - { - R_DrawWorldCrosshair(); - if (r_timereport_active) - R_TimeReport("crosshair"); - } + R_DrawParticles(); + if (r_timereport_active) + R_TimeReport("particles"); - VM_AddPolygonsToMeshQueue(); + R_DrawExplosions(); + if (r_timereport_active) + R_TimeReport("explosions"); + } - R_MeshQueue_Render(); + R_MeshQueue_RenderTransparent(); + if (r_timereport_active) + R_TimeReport("drawtrans"); - if (r_showtrispass) - { - //qglDisable(GL_LINE_SMOOTH); - qglDisable(GL_POLYGON_OFFSET_LINE); - } + if (cl.csqc_vidvars.drawworld) + { + R_DrawCoronas(); + if (r_timereport_active) + R_TimeReport("coronas"); + } + if(cl.csqc_vidvars.drawcrosshair) + { + R_DrawWorldCrosshair(); + if (r_timereport_active) + R_TimeReport("crosshair"); } - r_showtrispass = 0; + VM_AddPolygonsToMeshQueue(); + + R_MeshQueue_Render(); R_MeshQueue_EndScene(); @@ -2354,6 +2340,36 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane } } +static void R_DrawCollisionBrush(colbrushf_t *brush) +{ + int i; + rmeshstate_t m; + memset(&m, 0, sizeof(m)); + m.pointer_vertex = brush->points->v; + R_Mesh_State(&m); + 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); + R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements); + GL_LockArrays(0, 0); +} + +static void R_DrawCollisionSurface(entity_render_t *ent, 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); + 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); + R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i); + GL_LockArrays(0, 0); +} + static void R_Texture_AddLayer(texture_t *t, qboolean depthmask, int blendfunc1, int blendfunc2, texturelayertype_t type, rtexture_t *texture, const matrix4x4_t *matrix, float r, float g, float b, float a) { texturelayer_t *layer; @@ -2562,21 +2578,40 @@ 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) +{ + VectorCopy(modelorg, rsurface_modelorg); + rsurface_entity = ent; + rsurface_model = ent->model; + rsurface_texture = texture; +} -void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, qboolean generatenormals, qboolean generatetangents) +void RSurf_SetPointersForPass(qboolean generatenormals, qboolean generatetangents) { - if (rsurface_array_size < surface->groupmesh->num_vertices) - R_Mesh_ResizeArrays(surface->groupmesh->num_vertices); - if ((ent->frameblend[0].lerp != 1 || ent->frameblend[0].frame != 0) && (surface->groupmesh->data_morphvertex3f || surface->groupmesh->data_vertexboneweights)) + 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; - Mod_Alias_GetMesh_Vertex3f(ent->model, ent->frameblend, surface->groupmesh, rsurface_vertex3f); - if (generatetangents || (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))) + if (generatetangents || (rsurface_texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))) { + rsurface_generatetangents = true; rsurface_svector3f = rsurface_array_svector3f; rsurface_tvector3f = rsurface_array_tvector3f; rsurface_normal3f = rsurface_array_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); } else { @@ -2584,8 +2619,8 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture rsurface_tvector3f = NULL; if (generatenormals) { + rsurface_generatenormals = true; rsurface_normal3f = rsurface_array_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); } else rsurface_normal3f = NULL; @@ -2593,35 +2628,80 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture } 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; + 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; + rsurface_normal3f = rsurface_model->surfmesh.data_normal3f; + } + 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 (texture->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2)) + if (rsurface_deformvertex) { int i, j; float center[3], forward[3], right[3], up[3], v[4][3]; matrix4x4_t matrix1, imatrix1; - Matrix4x4_Transform(&ent->inversematrix, r_viewforward, forward); - Matrix4x4_Transform(&ent->inversematrix, r_viewright, right); - Matrix4x4_Transform(&ent->inversematrix, r_viewup, up); + 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) { VectorClear(center); for (i = 0;i < 4;i++) - VectorAdd(center, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i) * 3, center); + 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, (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_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, (rsurface_vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); - if (texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2) + Matrix4x4_Transform(&imatrix1, (vertex3f + 3 * surface->num_firstvertex) + (j+i)*3, v[i]); + if (rsurface_texture->textureflags & Q3TEXTUREFLAG_AUTOSPRITE2) { - forward[0] = modelorg[0] - center[0]; - forward[1] = modelorg[1] - center[1]; + forward[0] = rsurface_modelorg[0] - center[0]; + forward[1] = rsurface_modelorg[1] - center[1]; forward[2] = 0; VectorNormalize(forward); right[0] = forward[1]; @@ -2632,41 +2712,35 @@ void RSurf_SetVertexPointer(const entity_render_t *ent, const texture_t *texture 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); } - rsurface_vertex3f = rsurface_array_vertex3f; - rsurface_svector3f = rsurface_array_svector3f; - rsurface_tvector3f = rsurface_array_tvector3f; - rsurface_normal3f = rsurface_array_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); + 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); } - 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, (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle)); + 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 entity_render_t *ent, const texture_t *texture, const msurface_t *surface, const vec3_t modelorg, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog) +static void RSurf_DrawLightmap(const msurface_t *surface, float r, float g, float b, float a, int lightmode, qboolean applycolor, qboolean applyfog) { int i; float f; float *v, *c, *c2; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, lightmode >= 2, false); if (lightmode >= 2) { // model lighting vec3_t ambientcolor; vec3_t diffusecolor; vec3_t lightdir; - VectorCopy(ent->modellight_lightdir, lightdir); - ambientcolor[0] = ent->modellight_ambient[0] * r * 0.5f; - ambientcolor[1] = ent->modellight_ambient[1] * g * 0.5f; - ambientcolor[2] = ent->modellight_ambient[2] * b * 0.5f; - diffusecolor[0] = ent->modellight_diffuse[0] * r * 0.5f; - diffusecolor[1] = ent->modellight_diffuse[1] * g * 0.5f; - diffusecolor[2] = ent->modellight_diffuse[2] * b * 0.5f; + VectorCopy(rsurface_entity->modellight_lightdir, lightdir); + ambientcolor[0] = rsurface_entity->modellight_ambient[0] * r * 0.5f; + ambientcolor[1] = rsurface_entity->modellight_ambient[1] * g * 0.5f; + ambientcolor[2] = rsurface_entity->modellight_ambient[2] * b * 0.5f; + diffusecolor[0] = rsurface_entity->modellight_diffuse[0] * r * 0.5f; + diffusecolor[1] = rsurface_entity->modellight_diffuse[1] * g * 0.5f; + diffusecolor[2] = rsurface_entity->modellight_diffuse[2] * b * 0.5f; if (VectorLength2(diffusecolor) > 0) { int numverts = surface->num_vertices; @@ -2705,7 +2779,7 @@ static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *text { if (surface->lightmapinfo->samples) { - const unsigned char *lm = surface->lightmapinfo->samples + (surface->groupmesh->data_lightmapoffsets + surface->num_firstvertex)[i]; + const unsigned char *lm = surface->lightmapinfo->samples + (rsurface_model->surfmesh.data_lightmapoffsets + surface->num_firstvertex)[i]; float scale = r_refdef.lightstylevalue[surface->lightmapinfo->styles[0]] * (1.0f / 32768.0f); VectorScale(lm, scale, c); if (surface->lightmapinfo->styles[1] != 255) @@ -2734,7 +2808,7 @@ static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *text rsurface_lightmapcolor4f = rsurface_array_color4f; } else - rsurface_lightmapcolor4f = surface->groupmesh->data_lightmapcolor4f; + rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f; } else rsurface_lightmapcolor4f = NULL; @@ -2744,7 +2818,7 @@ static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *text { for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c = (rsurface_lightmapcolor4f + 4 * surface->num_firstvertex), c2 = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c += 4, c2 += 4) { - f = 1 - VERTEXFOGTABLE(VectorDistance(v, modelorg)); + f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); c2[0] = c[0] * f; c2[1] = c[1] * f; c2[2] = c[2] * f; @@ -2755,7 +2829,7 @@ static void RSurf_DrawLightmap(const entity_render_t *ent, const texture_t *text { for (i = 0, v = (rsurface_vertex3f + 3 * surface->num_firstvertex), c2 = (rsurface_array_color4f + 4 * surface->num_firstvertex);i < surface->num_vertices;i++, v += 3, c2 += 4) { - f = 1 - VERTEXFOGTABLE(VectorDistance(v, modelorg)); + f = 1 - VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); c2[0] = f; c2[1] = f; c2[2] = f; @@ -2785,6 +2859,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text int texturesurfaceindex; int lightmode; const msurface_t *surface; + model_t *model = ent->model; qboolean applycolor; qboolean applyfog; rmeshstate_t m; @@ -2792,11 +2867,12 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text return; r_shadow_rtlight = NULL; renderstats.entities_surfaces += texturenumsurfaces; - // FIXME: identify models using a better check than ent->model->brush.shadowmesh - lightmode = ((ent->effects & EF_FULLBRIGHT) || ent->model->brush.shadowmesh) ? 0 : 2; + // FIXME: identify models using a better check than model->brush.shadowmesh + lightmode = ((ent->effects & EF_FULLBRIGHT) || model->brush.shadowmesh) ? 0 : 2; 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) { // transparent sky would be ridiculous @@ -2811,7 +2887,10 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text } GL_DepthMask(true); // LordHavoc: HalfLife maps have freaky skypolys... - //if (!ent->model->brush.ishlbsp) + // LordHavoc: Quake3 never did sky masking (unlike software Quake + // and Quake2), so disable the sky masking in Quake3 maps as it + // causes problems with q3map2 sky tricks + if (!model->brush.ishlbsp && model->type != mod_brushq3) { GL_Color(fogcolor[0], fogcolor[1], fogcolor[2], 1); memset(&m, 0, sizeof(m)); @@ -2829,10 +2908,12 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text // fog sky GL_BlendFunc(GL_ONE, GL_ZERO); } + RSurf_SetPointersForPass(false, false); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); RSurf_Draw(surface); } if (skyrendermasked) @@ -2864,13 +2945,15 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text R_SetupSurfaceShader(ent, texture, modelorg, vec3_origin, lightmode == 2); if (!r_glsl_permutation) return; + RSurf_SetPointersForPass(false, true); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + 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); @@ -2882,12 +2965,13 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true); - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + 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, surface->groupmesh->data_texcoordlightmap2f); + R_Mesh_TexCoordPointer(4, 2, model->surfmesh.data_texcoordlightmap2f); if (surface->lightmaptexture) { R_Mesh_TexBind(7, R_GetTexture(surface->lightmaptexture)); @@ -2900,7 +2984,7 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text 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(surface->groupmesh->data_lightmapcolor4f); + R_Mesh_ColorPointer(model->surfmesh.data_lightmapcolor4f); } RSurf_Draw(surface); } @@ -2945,15 +3029,18 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.texrgbscale[1] = layertexrgbscale; m.pointer_color = rsurface_array_color4f; R_Mesh_State(&m); + RSurf_SetPointersForPass(lightmode == 2, false); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); + R_Mesh_TexCoordPointer(1, 2, model->surfmesh.data_texcoordtexture2f); R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); } } else @@ -2961,17 +3048,19 @@ 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, surface->groupmesh->data_texcoordlightmap2f); - R_Mesh_TexCoordPointer(1, 2, surface->groupmesh->data_texcoordtexture2f); + 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(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); + 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(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); } } } @@ -2983,14 +3072,17 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; R_Mesh_State(&m); + RSurf_SetPointersForPass(lightmode == 2, false); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordlightmap2f); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordlightmap2f); R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - RSurf_DrawLightmap(ent, texture, surface, modelorg, 1, 1, 1, 1, 2, false, false); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, 1, 1, 1, 1, 2, false, false); } } else @@ -2998,16 +3090,18 @@ 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, surface->groupmesh->data_texcoordlightmap2f); + 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(ent, texture, surface, modelorg, 1, 1, 1, 1, 0, false, false); + RSurf_DrawLightmap(surface, 1, 1, 1, 1, 0, false, false); } else { R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - RSurf_DrawLightmap(ent, texture, surface, modelorg, 1, 1, 1, 1, 1, false, false); + RSurf_DrawLightmap(surface, 1, 1, 1, 1, 1, false, false); } } } @@ -3018,11 +3112,14 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; R_Mesh_State(&m); + RSurf_SetPointersForPass(false, false); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, false); } break; case TEXTURELAYERTYPE_LITTEXTURE_VERTEX: @@ -3032,13 +3129,16 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.texrgbscale[0] = layertexrgbscale; m.pointer_color = rsurface_array_color4f; R_Mesh_State(&m); + RSurf_SetPointersForPass(lightmode == 2, false); if (lightmode == 2) { for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 2, applycolor, applyfog); } } else @@ -3046,8 +3146,10 @@ 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, surface->groupmesh->data_texcoordtexture2f); - RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 1, applycolor, applyfog); } } break; @@ -3058,11 +3160,14 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.pointer_color = rsurface_array_color4f; m.texrgbscale[0] = layertexrgbscale; R_Mesh_State(&m); + RSurf_SetPointersForPass(false, false); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); - RSurf_DrawLightmap(ent, texture, surface, modelorg, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); + RSurf_DrawLightmap(surface, layercolor[0], layercolor[1], layercolor[2], layercolor[3], 0, applycolor, applyfog); } break; case TEXTURELAYERTYPE_FOG: @@ -3073,15 +3178,17 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text m.texmatrix[0] = layer->texmatrix; } R_Mesh_State(&m); + RSurf_SetPointersForPass(false, false); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { int i; float f, *v, *c; surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false); if (layer->texture) - R_Mesh_TexCoordPointer(0, 2, surface->groupmesh->data_texcoordtexture2f); + R_Mesh_TexCoordPointer(0, 2, model->surfmesh.data_texcoordtexture2f); R_Mesh_ColorPointer(rsurface_array_color4f); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); 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)); @@ -3105,56 +3212,17 @@ static void R_DrawTextureSurfaceList(const entity_render_t *ent, texture_t *text GL_Color(1, 1, 1, 1); memset(&m, 0, sizeof(m)); R_Mesh_State(&m); + RSurf_SetPointersForPass(false, false); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, false); + if (rsurface_dynamicvertex) + RSurf_PrepareDynamicSurfaceVertices(surface); for (scale = 1;scale < layertexrgbscale;scale <<= 1) RSurf_Draw(surface); } } } - if (r_shownormals.integer && !r_showtrispass) - { - int j, k; - float v[3]; - GL_DepthTest(!r_showdisabledepthtest.integer); - GL_DepthMask(texture->currentlayers->depthmask); - GL_BlendFunc(texture->currentlayers->blendfunc1, texture->currentlayers->blendfunc2); - memset(&m, 0, sizeof(m)); - R_Mesh_State(&m); - for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) - { - surface = texturesurfacelist[texturesurfaceindex]; - RSurf_SetVertexPointer(ent, texture, surface, modelorg, false, true); - GL_Color(1, 0, 0, 1); - qglBegin(GL_LINES); - for (j = 0, k = surface->num_firstvertex;j < surface->num_vertices;j++, k++) - { - VectorCopy(rsurface_vertex3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - VectorMA(v, 8, rsurface_svector3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - } - GL_Color(0, 0, 1, 1); - for (j = 0, k = surface->num_firstvertex;j < surface->num_vertices;j++, k++) - { - VectorCopy(rsurface_vertex3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - VectorMA(v, 8, rsurface_tvector3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - } - GL_Color(0, 1, 0, 1); - for (j = 0, k = surface->num_firstvertex;j < surface->num_vertices;j++, k++) - { - VectorCopy(rsurface_vertex3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - VectorMA(v, 8, rsurface_normal3f + k * 3, v); - qglVertex3f(v[0], v[1], v[2]); - } - qglEnd(); - } - } } if ((texture->textureflags & Q3TEXTUREFLAG_TWOSIDED) || (ent->flags & RENDER_NOCULLFACE)) qglEnable(GL_CULL_FACE); @@ -3239,7 +3307,33 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) t = NULL; texture = NULL; numsurfacelist = 0; - if (ent == r_refdef.worldentity) + 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); + RSurf_SetPointersForPass(false, false); + 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; + texture = surface->texture->currentframe; + 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) { for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) { @@ -3305,9 +3399,108 @@ void R_DrawSurfaces(entity_render_t *ent, qboolean skysurfaces) } if (numsurfacelist) R_QueueTextureSurfaceList(ent, texture, numsurfacelist, surfacelist, modelorg); - if (!r_showtrispass) - renderstats.entities_triangles += counttriangles; + renderstats.entities_triangles += counttriangles; if (gl_support_fragment_shader) qglUseProgramObjectARB(0); + + if (r_showcollisionbrushes.integer && model->brush.num_brushes && !skysurfaces) + { + int i; + msurface_t *surface; + q3mbrush_t *brush; + R_Mesh_Matrix(&ent->matrix); + GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); + GL_DepthMask(false); + GL_DepthTest(!r_showdisabledepthtest.integer); + qglPolygonOffset(r_polygonfactor + r_showcollisionbrushes_polygonfactor.value, r_polygonoffset + r_showcollisionbrushes_polygonoffset.value); + for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++) + if (brush->colbrushf && brush->colbrushf->numtriangles) + R_DrawCollisionBrush(brush->colbrushf); + for (i = 0, surface = model->data_surfaces + model->firstmodelsurface;i < model->nummodelsurfaces;i++, surface++) + if (surface->num_collisiontriangles) + R_DrawCollisionSurface(ent, surface); + qglPolygonOffset(r_polygonfactor, r_polygonoffset); + } + + if (r_showtris.integer || r_shownormals.integer) + { + int k, l; + 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); + 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; + 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); + if (r_showtris.integer) + { + if (!texture->currentlayers->depthmask) + GL_Color(r_showtris.value, 0, 0, 1); + else if (ent == r_refdef.worldentity) + GL_Color(r_showtris.value, r_showtris.value, r_showtris.value, 1); + else + GL_Color(0, r_showtris.value, 0, 1); + elements = (ent->model->surfmesh.data_element3i + 3 * surface->num_firsttriangle); + qglBegin(GL_LINES); + for (k = 0;k < surface->num_triangles;k++, elements += 3) + { + qglArrayElement(elements[0]);qglArrayElement(elements[1]); + qglArrayElement(elements[1]);qglArrayElement(elements[2]); + qglArrayElement(elements[2]);qglArrayElement(elements[0]); + } + qglEnd(); + } + if (r_shownormals.integer) + { + GL_Color(r_shownormals.value, 0, 0, 1); + qglBegin(GL_LINES); + for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++) + { + VectorCopy(rsurface_vertex3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + VectorMA(v, 8, rsurface_svector3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + } + qglEnd(); + GL_Color(0, 0, r_shownormals.value, 1); + qglBegin(GL_LINES); + for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++) + { + VectorCopy(rsurface_vertex3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + VectorMA(v, 8, rsurface_tvector3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + } + qglEnd(); + GL_Color(0, r_shownormals.value, 0, 1); + qglBegin(GL_LINES); + for (k = 0, l = surface->num_firstvertex;k < surface->num_vertices;k++, l++) + { + VectorCopy(rsurface_vertex3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + VectorMA(v, 8, rsurface_normal3f + l * 3, v); + qglVertex3f(v[0], v[1], v[2]); + } + qglEnd(); + } + } + } + if (r_showdisabledepthtest.integer) + qglDepthFunc(GL_LEQUAL); + } }