From 87b78e553316ef9fda9af0a4c797a5d9436eec11 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 17 Dec 2011 19:14:14 +0900 Subject: [PATCH] Move the surface chain links out of the surfaces. The links are now in "instance surfaces". For non-instanced models (world, doors, plats etc (ie, world and its sub-models)), there will be one instance surface per model surface. However, for instanced models (ammo boxes etc), there will be many, dynamically allocated (not yet implemented). This commit gets the static instance surfaces working. --- include/QF/GL/qf_sky.h | 2 +- include/QF/model.h | 27 +++++- include/r_local.h | 5 +- libs/video/renderer/gl/gl_rmain.c | 4 +- libs/video/renderer/gl/gl_rmisc.c | 36 +------ libs/video/renderer/gl/gl_rsurf.c | 139 +++++++++++++++++++++------ libs/video/renderer/gl/gl_sky_clip.c | 73 +++++++++----- 7 files changed, 196 insertions(+), 90 deletions(-) diff --git a/include/QF/GL/qf_sky.h b/include/QF/GL/qf_sky.h index bfb99744f..181778993 100644 --- a/include/QF/GL/qf_sky.h +++ b/include/QF/GL/qf_sky.h @@ -38,6 +38,6 @@ extern qboolean skyloaded; extern vec5_t skyvec[6][4]; void R_DrawSky (void); -void R_DrawSkyChain (const msurface_t *s); +void R_DrawSkyChain (const instsurf_t *s); #endif // __QF_GL_sky_h diff --git a/include/QF/model.h b/include/QF/model.h index e5fa57602..3a0f11692 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -68,13 +68,33 @@ typedef struct { vec3_t position; } mvertex_t; +/** Instanced surface data. + + There will be one of these for each surface in the world model. This + covers the sub-models in the world model. These instanced surfaces will + be allocated in one block at map load time and then never freed until + the next map load. + + However, for instanced brush models (ammo boxes, health boxes, etc), an + instanced surface will be allocated for each surface for each model + once per frame. These instanced surfaces will be mass-freed each frame. +*/ +typedef struct instsurf_s { + struct instsurf_s *next; ///< next in free/alloc list + struct instsurf_s *tex_chain; ///< next in texture chain + struct instsurf_s *lm_chain; ///< next in lightmap chain + struct msurface_s *surface; ///< surface to render + vec_t *transform; + float *color; +} instsurf_t; + typedef struct texture_s { char name[16]; unsigned int width, height; int gl_texturenum; int gl_fb_texturenum; - struct msurface_s *texturechain; // for gl_texsort drawing - struct msurface_s **texturechain_tail; + instsurf_t *tex_chain; // for gl_texsort drawing + instsurf_t **tex_chain_tail; int anim_total; // total tenths in sequence ( 0 = no) int anim_min, anim_max; // time for this frame min <=time< max struct texture_s *anim_next; // in the animation sequence @@ -136,8 +156,7 @@ typedef struct msurface_s { int light_s, light_t; // gl lightmap coordinates glpoly_t *polys; // multiple if warped - struct msurface_s *texturechain; -// struct msurface_s *lightmapchain; // Quake 2 ??? + instsurf_t *instsurf; ///< null if not part of world model/sub-model mtexinfo_t *texinfo; diff --git a/include/r_local.h b/include/r_local.h index 0999c6bc8..26be09c45 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -178,6 +178,9 @@ void D_DrawSurfaces (void); void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist); void R_StepActiveU (edge_t *pedge); void R_RemoveEdges (edge_t *pedge); +void R_AddTexture (texture_t *tex); +void R_ClearTextures (void); +void R_InitSurfaceChains (model_t *model); extern void R_Surf8Start (void); extern void R_Surf8End (void); @@ -191,8 +194,6 @@ extern int r_polycount; extern int r_wholepolycount; extern model_t *cl_worldmodel; -extern texture_t **r_texture_chains; -extern int r_num_texture_chains; extern int *pfrustum_indexes[4]; diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index c8af45387..cf581fc0b 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -545,7 +545,7 @@ static void R_Mirror (void) { float d; - msurface_t *s; +// msurface_t *s; // if (!mirror) // FIXME: Broken return; @@ -590,6 +590,7 @@ R_Mirror (void) color_white[3] = r_mirroralpha->value * 255; qfglColor4ubv (color_white); +#if 0//FIXME s = r_worldentity.model->textures[mirrortexturenum]->texturechain; for (; s; s = s->texturechain) { texture_t *tex; @@ -611,6 +612,7 @@ R_Mirror (void) // R_RenderBrushPoly (s, tex); // FIXME: Need to move R_Mirror to gl_rsurf.c, and uncommment this line! } r_worldentity.model->textures[mirrortexturenum]->texturechain = NULL; +#endif qfglColor3ubv (color_white); } diff --git a/libs/video/renderer/gl/gl_rmisc.c b/libs/video/renderer/gl/gl_rmisc.c index 7de2da56c..5659fd09f 100644 --- a/libs/video/renderer/gl/gl_rmisc.c +++ b/libs/video/renderer/gl/gl_rmisc.c @@ -66,32 +66,6 @@ static __attribute__ ((used)) const char rcsid[] = int r_init = 0; -texture_t **r_texture_chains; -int r_num_texture_chains; -static int max_texture_chains; - -static void -R_AddTexture (texture_t *tex) -{ - int i; - if (r_num_texture_chains == max_texture_chains) { - max_texture_chains += 64; - r_texture_chains = realloc (r_texture_chains, - max_texture_chains * sizeof (texture_t *)); - for (i = r_num_texture_chains; i < max_texture_chains; i++) - r_texture_chains[i] = 0; - } - r_texture_chains[r_num_texture_chains++] = tex; - tex->texturechain = NULL; - tex->texturechain_tail = &tex->texturechain; -} - -static void -R_ClearTextures (void) -{ - r_num_texture_chains = 0; -} - /* R_Envmap_f @@ -196,8 +170,6 @@ register_textures (model_t *model) tex = model->textures[i]; if (!tex) continue; - if (tex->texturechain_tail) - continue; R_AddTexture (tex); } } @@ -240,16 +212,18 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models) if (!strncmp (tex->name, "window02_1", 10)) mirrortexturenum = i; } + + R_InitSurfaceChains (r_worldentity.model); + R_AddTexture (r_notexture_mip); register_textures (r_worldentity.model); for (i = 0; i < num_models; i++) { if (!models[i]) continue; + if (*models[i]->name == '*') + continue; if (models[i] != r_worldentity.model && models[i]->type == mod_brush) register_textures (models[i]); } - tex = r_notexture_mip; - tex->texturechain = NULL; - tex->texturechain_tail = &tex->texturechain; } void diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index 9c49b1a91..2c39f5a20 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -62,22 +62,26 @@ int skytexturenum; glpoly_t *fullbright_polys[MAX_GLTEXTURES]; -msurface_t *waterchain = NULL; -msurface_t **waterchain_tail = &waterchain; -msurface_t *sky_chain; -msurface_t **sky_chain_tail; +instsurf_t *waterchain = NULL; +instsurf_t **waterchain_tail = &waterchain; +instsurf_t *sky_chain; +instsurf_t **sky_chain_tail; #define CHAIN_SURF_F2B(surf,chain) \ do { \ - *(chain##_tail) = (surf); \ - (chain##_tail) = &(surf)->texturechain; \ + instsurf_t *inst = (surf)->instsurf; \ + inst->surface = (surf); \ + *(chain##_tail) = inst; \ + (chain##_tail) = &inst->tex_chain; \ *(chain##_tail) = 0; \ } while (0) #define CHAIN_SURF_B2F(surf,chain) \ do { \ - (surf)->texturechain = (chain); \ - (chain) = (surf); \ + instsurf_t *inst = (surf)->instsurf; \ + inst->surface = (surf); \ + inst->tex_chain = (chain); \ + (chain) = inst; \ } while (0) extern int lightmap_textures; @@ -85,6 +89,46 @@ extern qboolean lightmap_modified[MAX_LIGHTMAPS]; extern glpoly_t *lightmap_polys[MAX_LIGHTMAPS]; extern glRect_t lightmap_rectchange[MAX_LIGHTMAPS]; +static texture_t **r_texture_chains; +static int r_num_texture_chains; +static int max_texture_chains; +static instsurf_t *static_chains; + +void +R_AddTexture (texture_t *tex) +{ + int i; + if (r_num_texture_chains == max_texture_chains) { + max_texture_chains += 64; + r_texture_chains = realloc (r_texture_chains, + max_texture_chains * sizeof (texture_t *)); + for (i = r_num_texture_chains; i < max_texture_chains; i++) + r_texture_chains[i] = 0; + } + r_texture_chains[r_num_texture_chains++] = tex; + tex->tex_chain = NULL; + tex->tex_chain_tail = &tex->tex_chain; +} + +void +R_InitSurfaceChains (model_t *model) +{ + int i; + + if (static_chains) + free (static_chains); + static_chains = calloc (model->nummodelsurfaces, sizeof (instsurf_t)); + for (i = 0; i < model->nummodelsurfaces; i++) + model->surfaces[i].instsurf = static_chains + i; + +} + +void +R_ClearTextures (void) +{ + r_num_texture_chains = 0; +} + /* R_TextureAnimation @@ -247,7 +291,8 @@ void R_DrawWaterSurfaces (void) { int i; - msurface_t *s; + instsurf_t *s; + msurface_t *fa; if (!waterchain) return; @@ -262,13 +307,19 @@ R_DrawWaterSurfaces (void) } i = -1; - for (s = waterchain; s; s = s->texturechain) { - if (i != s->texinfo->texture->gl_texturenum) { - i = s->texinfo->texture->gl_texturenum; + for (s = waterchain; s; s = s->tex_chain) { + fa = s->surface; + if (s->transform) + qfglLoadMatrixf (s->transform); + else + qfglLoadMatrixf (r_world_matrix); + if (i != fa->texinfo->texture->gl_texturenum) { + i = fa->texinfo->texture->gl_texturenum; qfglBindTexture (GL_TEXTURE_2D, i); } - EmitWaterPolys (s); + EmitWaterPolys (fa); } + qfglLoadMatrixf (r_world_matrix); waterchain = NULL; waterchain_tail = &waterchain; @@ -283,7 +334,8 @@ static inline void DrawTextureChains (int disable_blend, int do_bind) { int i; - msurface_t *s; + instsurf_t *s; + msurface_t *fa; texture_t *tex; if (gl_mtex_active_tmus >= 2) { @@ -307,11 +359,22 @@ DrawTextureChains (int disable_blend, int do_bind) qfglBindTexture (GL_TEXTURE_2D, tex->gl_fb_texturenum); qglActiveTexture (gl_mtex_enum + 1); - for (s = tex->texturechain; s; s = s->texturechain) { + for (s = tex->tex_chain; s; s = s->tex_chain) { + fa = s->surface; + if (s->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (s->transform); + } + if (s->color && do_bind) + qfglColor4fv (s->color); qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + - s->lightmaptexturenum); + fa->lightmaptexturenum); + if (s->transform) + qfglPopMatrix (); + if (s->color && do_bind) + qfglColor3ubv (color_white); - R_RenderBrushPoly_3 (s); + R_RenderBrushPoly_3 (fa); } qglActiveTexture (gl_mtex_enum + 2); @@ -320,11 +383,23 @@ DrawTextureChains (int disable_blend, int do_bind) qglActiveTexture (gl_mtex_enum + 0); } else { qglActiveTexture (gl_mtex_enum + 1); - for (s = tex->texturechain; s; s = s->texturechain) { + for (s = tex->tex_chain; s; s = s->tex_chain) { + fa = s->surface; qfglBindTexture (GL_TEXTURE_2D, lightmap_textures + - s->lightmaptexturenum); + fa->lightmaptexturenum); - R_RenderBrushPoly_2 (s); + if (s->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (s->transform); + } + if (s->color && do_bind) + qfglColor4fv (s->color); + R_RenderBrushPoly_2 (fa); + + if (s->transform) + qfglPopMatrix (); + if (s->color && do_bind) + qfglColor3ubv (color_white); } qglActiveTexture (gl_mtex_enum + 0); @@ -347,8 +422,18 @@ DrawTextureChains (int disable_blend, int do_bind) if (do_bind) qfglBindTexture (GL_TEXTURE_2D, tex->gl_texturenum); - for (s = tex->texturechain; s; s = s->texturechain) - R_RenderBrushPoly_1 (s); + for (s = tex->tex_chain; s; s = s->tex_chain) { + if (s->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (s->transform); + } + R_RenderBrushPoly_1 (s->surface); + + if (s->transform) + qfglPopMatrix (); + if (s->color && do_bind) + qfglColor3ubv (color_white); + } } if (disable_blend) qfglEnable (GL_BLEND); @@ -365,12 +450,12 @@ clear_texture_chains (void) tex = r_texture_chains[i]; if (!tex) continue; - tex->texturechain = NULL; - tex->texturechain_tail = &tex->texturechain; + tex->tex_chain = NULL; + tex->tex_chain_tail = &tex->tex_chain; } tex = r_notexture_mip; - tex->texturechain = NULL; - tex->texturechain_tail = &tex->texturechain; + tex->tex_chain = NULL; + tex->tex_chain_tail = &tex->tex_chain; } static inline void @@ -395,7 +480,7 @@ chain_surface (msurface_t *surf) fullbright_polys[tex->gl_fb_texturenum]; fullbright_polys[tex->gl_fb_texturenum] = surf->polys; } - CHAIN_SURF_F2B (surf, tex->texturechain); + CHAIN_SURF_F2B (surf, tex->tex_chain); } } diff --git a/libs/video/renderer/gl/gl_sky_clip.c b/libs/video/renderer/gl/gl_sky_clip.c index ede8c3bdf..e99f0f390 100644 --- a/libs/video/renderer/gl/gl_sky_clip.c +++ b/libs/video/renderer/gl/gl_sky_clip.c @@ -639,14 +639,16 @@ R_DrawSkyBoxPoly (const glpoly_t *poly) } static void -EmitSkyPolys (float speedscale, const msurface_t *fa) +EmitSkyPolys (float speedscale, const instsurf_t *sc) { float length, s, t; float *v; int i; glpoly_t *p; vec3_t dir; + msurface_t *fa = sc->surface; + //FIXME transform/color for (p = fa->polys; p; p = p->next) { qfglBegin (GL_POLYGON); for (i = 0, v = p->verts[0]; i < p->numverts; i++, v += VERTEXSIZE) { @@ -682,21 +684,27 @@ draw_poly (const glpoly_t *poly) } static void -draw_black_sky_polys (const msurface_t *sky_chain) +draw_black_sky_polys (const instsurf_t *sky_chain) { - const msurface_t *sc = sky_chain; + const instsurf_t *sc = sky_chain; qfglDisable (GL_BLEND); qfglDisable (GL_TEXTURE_2D); qfglColor3ubv (color_black); while (sc) { - glpoly_t *p = sc->polys; + glpoly_t *p = sc->surface->polys; + if (sc->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (sc->transform); + } while (p) { draw_poly (p); p = p->next; } - sc = sc->texturechain; + if (sc->transform) + qfglPushMatrix (); + sc = sc->tex_chain; } qfglEnable (GL_TEXTURE_2D); qfglEnable (GL_BLEND); @@ -704,36 +712,37 @@ draw_black_sky_polys (const msurface_t *sky_chain) } static void -draw_skybox_sky_polys (const msurface_t *sky_chain) +draw_skybox_sky_polys (const instsurf_t *sky_chain) { - const msurface_t *sc = sky_chain; + const instsurf_t *sc = sky_chain; qfglDepthMask (GL_FALSE); qfglDisable (GL_DEPTH_TEST); while (sc) { - glpoly_t *p = sc->polys; + glpoly_t *p = sc->surface->polys; + //FIXME transform/color while (p) { R_DrawSkyBoxPoly (p); p = p->next; } - sc = sc->texturechain; + sc = sc->tex_chain; } qfglEnable (GL_DEPTH_TEST); qfglDepthMask (GL_TRUE); } static void -draw_skydome_sky_polys (const msurface_t *sky_chain) +draw_skydome_sky_polys (const instsurf_t *sky_chain) { // this function is not yet implemented so just draw black draw_black_sky_polys (sky_chain); } static void -draw_id_sky_polys (const msurface_t *sky_chain) +draw_id_sky_polys (const instsurf_t *sky_chain) { - const msurface_t *sc = sky_chain; + const instsurf_t *sc = sky_chain; float speedscale; speedscale = r_realtime / 16; @@ -742,7 +751,7 @@ draw_id_sky_polys (const msurface_t *sky_chain) qfglBindTexture (GL_TEXTURE_2D, solidskytexture); while (sc) { EmitSkyPolys (speedscale, sc); - sc = sc->texturechain; + sc = sc->tex_chain; } if (gl_sky_multipass->int_val) { @@ -754,28 +763,34 @@ draw_id_sky_polys (const msurface_t *sky_chain) qfglBindTexture (GL_TEXTURE_2D, alphaskytexture); while (sc) { EmitSkyPolys (speedscale, sc); - sc = sc->texturechain; + sc = sc->tex_chain; } } } static void -draw_z_sky_polys (const msurface_t *sky_chain) +draw_z_sky_polys (const instsurf_t *sky_chain) { - const msurface_t *sc = sky_chain; + const instsurf_t *sc = sky_chain; qfglColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); qfglDisable (GL_BLEND); qfglDisable (GL_TEXTURE_2D); qfglColor3ubv (color_black); while (sc) { - glpoly_t *p = sc->polys; + glpoly_t *p = sc->surface->polys; + if (sc->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (sc->transform); + } while (p) { draw_poly (p); p = p->next; } - sc = sc->texturechain; + if (sc->transform) + qfglPopMatrix (); + sc = sc->tex_chain; } qfglColor3ubv (color_white); qfglEnable (GL_TEXTURE_2D); @@ -784,7 +799,7 @@ draw_z_sky_polys (const msurface_t *sky_chain) } void -R_DrawSkyChain (const msurface_t *sky_chain) +R_DrawSkyChain (const instsurf_t *sky_chain) { if (gl_sky_clip->int_val > 2) { draw_black_sky_polys (sky_chain); @@ -807,15 +822,19 @@ R_DrawSkyChain (const msurface_t *sky_chain) } if (gl_sky_debug->int_val) { - const msurface_t *sc; + const instsurf_t *sc; qfglDisable (GL_TEXTURE_2D); if (gl_sky_debug->int_val & 1) { sc = sky_chain; qfglColor3ub (255, 255, 255); while (sc) { - glpoly_t *p = sc->polys; + glpoly_t *p = sc->surface->polys; + if (sc->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (sc->transform); + } while (p) { int i; @@ -826,7 +845,7 @@ R_DrawSkyChain (const msurface_t *sky_chain) qfglEnd (); p = p->next; } - sc = sc->texturechain; + sc = sc->tex_chain; } } if (gl_sky_debug->int_val & 2) { @@ -834,8 +853,12 @@ R_DrawSkyChain (const msurface_t *sky_chain) qfglColor3ub (0, 255, 0); qfglBegin (GL_POINTS); while (sc) { - glpoly_t *p = sc->polys; + glpoly_t *p = sc->surface->polys; + if (sc->transform) { + qfglPushMatrix (); + qfglLoadMatrixf (sc->transform); + } while (p) { int i; vec3_t x, c = { 0, 0, 0 }; @@ -849,7 +872,9 @@ R_DrawSkyChain (const msurface_t *sky_chain) qfglVertex3fv (c); p = p->next; } - sc = sc->texturechain; + if (sc->transform) + qfglPopMatrix (); + sc = sc->tex_chain; } qfglEnd (); }