diff --git a/doomsday/build/win32/doomsday_cl.rsp b/doomsday/build/win32/doomsday_cl.rsp index 4bda33e52f..8846b27f91 100644 --- a/doomsday/build/win32/doomsday_cl.rsp +++ b/doomsday/build/win32/doomsday_cl.rsp @@ -31,6 +31,7 @@ ./../../engine/portable/src/gl_hq2x.c ./../../engine/portable/src/gl_font.c ./../../engine/portable/src/gl_draw.c + ./../../engine/portable/src/rend_console.c ./../../engine/portable/src/rend_bias.c ./../../engine/portable/src/edit_bias.c ./../../engine/portable/src/rend_sprite.c @@ -104,6 +105,7 @@ ./../../engine/portable/src/sys_direc.c ./../../engine/win32/src/sys_console.c ./../../engine/portable/src/con_start.c + ./../../engine/portable/src/con_data.c ./../../engine/portable/src/con_main.c ./../../engine/portable/src/con_config.c ./../../engine/portable/src/con_bind.c diff --git a/doomsday/engine/data/cphelp.txt b/doomsday/engine/data/cphelp.txt index 71a5e223a7..a4ec2377c1 100644 --- a/doomsday/engine/data/cphelp.txt +++ b/doomsday/engine/data/cphelp.txt @@ -576,14 +576,17 @@ desc = 1=Render player view in wireframe mode. desc = Frame counter. [rend-info-lums] -desc = =Print lumobj count after rendering a frame. +desc = 1=Print lumobj count after rendering a frame. -[rend-light-ambient] -desc = Ambient light level. +[rend-info-rendpolys] +desc = 1=Print rendpoly pool state after rendering a frame. [rend-light] desc = 1=Render dynamic lights. +[rend-light-ambient] +desc = Ambient light level. + [rend-light-blend] desc = Dynamic lights color blending mode: 0=normal, 1=additive, 2=no blending. diff --git a/doomsday/engine/portable/include/dd_help.h b/doomsday/engine/portable/include/dd_help.h index b6787a2608..a5001a7722 100644 --- a/doomsday/engine/portable/include/dd_help.h +++ b/doomsday/engine/portable/include/dd_help.h @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ @@ -30,14 +30,14 @@ // Help string types. enum { - HST_DESCRIPTION, - HST_CONSOLE_VARIABLE, - HST_DEFAULT_VALUE + HST_DESCRIPTION, + HST_CONSOLE_VARIABLE, + HST_DEFAULT_VALUE }; void DD_InitHelp(void); void DD_ShutdownHelp(void); -void *DH_Find(char *id); +void *DH_Find(const char *id); char *DH_GetString(void *found, int type); #endif diff --git a/doomsday/engine/portable/include/r_data.h b/doomsday/engine/portable/include/r_data.h index 0f9891db57..8ca5ea8ba6 100644 --- a/doomsday/engine/portable/include/r_data.h +++ b/doomsday/engine/portable/include/r_data.h @@ -135,7 +135,6 @@ typedef struct glcommand_vertex_s { int index; } glcommand_vertex_t; -#define RL_MAX_POLY_SIDES 64 #define RL_MAX_DIVS 64 // Rendpoly flags. @@ -163,6 +162,14 @@ typedef struct { float dist; // Distance to the vertex. } rendpoly_vertex_t; +typedef struct rendpoly_wall_s { + float length; + struct div_t { + byte num; + float pos[RL_MAX_DIVS]; + } divs[2]; // For wall segments (two vertices). +} rendpoly_wall_t; + // rendpoly_t is only for convenience; the data written in the rendering // list data buffer is taken from this struct. typedef struct rendpoly_s { @@ -181,16 +188,9 @@ typedef struct rendpoly_s { // The geometry: byte numvertices; // Number of vertices for the poly. - rendpoly_vertex_t vertices[RL_MAX_POLY_SIDES]; - - // Wall specific data - struct rendpoly_wall_s { - float length; - struct div_t { - byte num; - float pos[RL_MAX_DIVS]; - } divs[2]; // For wall segments (two vertices). - } wall; + rendpoly_vertex_t *vertices; + + rendpoly_wall_t *wall; // Wall specific data if any. } rendpoly_t; // This is the dummy mobj_t used for blockring roots. @@ -429,6 +429,12 @@ extern int levelFullBright; extern int glowingTextures; extern byte precacheSprites, precacheSkins; +void R_InitRendPolyPool(void); +rendpoly_t *R_AllocRendPoly(rendpolytype_t type, boolean isWall, + unsigned int numverts); +void R_FreeRendPoly(rendpoly_t *poly); +void R_InfoRendPolys(void); + void R_InitData(void); void R_UpdateData(void); void R_ShutdownData(void); diff --git a/doomsday/engine/portable/include/r_world.h b/doomsday/engine/portable/include/r_world.h index 11a7901749..004e6a70e4 100644 --- a/doomsday/engine/portable/include/r_world.h +++ b/doomsday/engine/portable/include/r_world.h @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ @@ -45,7 +45,6 @@ void R_SetupLevel(char *level_id, int flags); void R_InitLinks(void); void R_SetupFog(void); void R_SetupSky(void); -void R_SetSectorLinks(sector_t *sec); sector_t *R_GetLinkedSector(sector_t *startsec, int plane); void R_UpdatePlanes(void); void R_ClearSectorFlags(void); diff --git a/doomsday/engine/portable/include/rend_dyn.h b/doomsday/engine/portable/include/rend_dyn.h index e1f6ea6ad6..4b689be591 100644 --- a/doomsday/engine/portable/include/rend_dyn.h +++ b/doomsday/engine/portable/include/rend_dyn.h @@ -103,8 +103,6 @@ void DL_InitForNewFrame(); int DL_NewLuminous(void); lumobj_t *DL_GetLuminous(int index); void DL_ProcessSubsector(subsector_t *ssec); -void DL_ProcessWallSeg(lumobj_t * lum, seg_t *seg, - sector_t *frontsector); dynlight_t *DL_GetSegLightLinks(int seg, int whichpart); dynlight_t *DL_GetSubSecLightLinks(int ssec, int plane); diff --git a/doomsday/engine/portable/src/net_main.c b/doomsday/engine/portable/src/net_main.c index d830475dc1..c20ad6de5b 100644 --- a/doomsday/engine/portable/src/net_main.c +++ b/doomsday/engine/portable/src/net_main.c @@ -44,6 +44,7 @@ #include "de_ui.h" #include "rend_bias.h" +#include "rend_console.h" #include "r_lgrid.h" // MACROS ------------------------------------------------------------------ @@ -816,24 +817,7 @@ void Net_Drawer(void) FR_TextOut(buf, 10, 10+10*(i+1)); } */ } - if(consoleShowFPS) - { - int x, y = 30, w, h; - - // If the ui is active draw the counter a bit further down - if(ui_active) - y += 20; - - sprintf(buf, "%.1f FPS", DD_GetFrameRate()); - w = FR_TextWidth(buf) + 16; - h = FR_TextHeight(buf) + 16; - x = glScreenWidth - w - 10; - UI_GradientEx(x, y, w, h, 6, UI_COL(UIC_BG_MEDIUM), - UI_COL(UIC_BG_LIGHT), .5f, .5f); - UI_DrawRectEx(x, y, w, h, 6, false, UI_COL(UIC_BRD_HI), NULL, .5f, -1); - UI_Color(UI_COL(UIC_TEXT)); - UI_TextOutEx(buf, x + 8, y + h / 2, false, true, UI_COL(UIC_TITLE), 1); - } + Rend_ConsoleFPS(); // Restore original matrix. gl.MatrixMode(DGL_PROJECTION); diff --git a/doomsday/engine/portable/src/r_data.c b/doomsday/engine/portable/src/r_data.c index 6ad3fd53a9..656d01e784 100644 --- a/doomsday/engine/portable/src/r_data.c +++ b/doomsday/engine/portable/src/r_data.c @@ -47,6 +47,12 @@ typedef struct flathash_s { flat_t *first; } flathash_t; +typedef struct { + boolean inUse; + unsigned int numVerts; + rendpoly_t poly; +} rendpolydata_t; + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -77,10 +83,198 @@ animgroup_t *groups; // Glowing textures are always rendered fullbright. int glowingTextures = true; +byte rendInfoRPolys = 0; + // PRIVATE DATA DEFINITIONS ------------------------------------------------ +static unsigned int numrendpolys = 0; +static unsigned int maxrendpolys = 0; +static rendpolydata_t **rendPolys; + // CODE -------------------------------------------------------------------- +void R_InfoRendPolys(void) +{ + unsigned int i; + + if(!rendInfoRPolys) + return; + + Con_Printf("RP Count: %-4i\n", numrendpolys); + + for(i = 0; i < numrendpolys; ++i) + { + Con_Printf("RP: %-4i %c %c (vtxs=%i)\n", i, + rendPolys[i]->inUse? 'Y':'N', + rendPolys[i]->poly.isWall? 'w':'p', + rendPolys[i]->numVerts); + } +} + +/** + * Called at the start of each level. + */ +void R_InitRendPolyPool(void) +{ + int i; + rendpoly_t *p; + + numrendpolys = maxrendpolys = 0; + rendPolys = NULL; + + // Allocate the common ones to get us started. + p = R_AllocRendPoly(RP_QUAD, true, 4); // wall + R_FreeRendPoly(p); // mark unused. + + // sprites/models use rendpolys with 1/2 vtxs to unify lighting. + for(i = 1; i < 16; ++i) + { + p = R_AllocRendPoly(i < 3? RP_NONE:RP_FLAT, false, i); + R_FreeRendPoly(p); // mark unused. + } +} + +/** + * Re-uses existing rendpolys whenever possible, there are a few conditions + * which prevent this: + * + * There is no unused rendpoly which: + * a) has enough vertices. + * b) matches the "isWall" specification. + * + * @param numverts The number of verts required. + * @param isWall true= wall data is required. + * + * @return Ptr to a suitable rendpoly. + */ +static rendpoly_t *R_NewRendPoly(unsigned int numverts, boolean isWall) +{ + unsigned int idx; + rendpoly_t *p; + boolean found = false; + + for(idx = 0; idx < maxrendpolys; ++idx) + { + if(rendPolys[idx]->inUse) + continue; + + if(rendPolys[idx]->numVerts == numverts && + rendPolys[idx]->poly.isWall == isWall) + { + // Use this one. + rendPolys[idx]->inUse = true; + return &rendPolys[idx]->poly; + } + else if(rendPolys[idx]->numVerts == 0) + { + // There is an unused one but we haven't allocated verts yet. + numrendpolys++; + found = true; + break; + } + } + + if(!found) + { + // We may need to allocate more. + if(++numrendpolys > maxrendpolys) + { + unsigned int i, newCount; + rendpolydata_t *newPolyData, *ptr; + + maxrendpolys = (maxrendpolys > 0? maxrendpolys * 2 : 8); + + rendPolys = + Z_Realloc(rendPolys, sizeof(rendpolydata_t*) * maxrendpolys, + PU_LEVEL); + + newCount = maxrendpolys - numrendpolys + 1; + + newPolyData = + Z_Malloc(sizeof(rendpolydata_t) * newCount, PU_LEVEL, 0); + + ptr = newPolyData; + for(i = numrendpolys-1; i < maxrendpolys; ++i, ptr++) + { + ptr->inUse = false; + ptr->numVerts = 0; + rendPolys[i] = ptr; + } + } + idx = numrendpolys - 1; + } + + p = &rendPolys[idx]->poly; + rendPolys[idx]->inUse = true; + rendPolys[idx]->numVerts = numverts; + + p->numvertices = numverts; + p->vertices = Z_Malloc(sizeof(rendpoly_vertex_t) * p->numvertices, + PU_LEVEL, 0); + p->isWall = isWall; + + if(p->isWall) // Its a wall so allocate the wall data. + p->wall = Z_Malloc(sizeof(rendpoly_wall_t), PU_LEVEL, 0); + else + p->wall = NULL; + + return p; +} + +/** + * Retrieves a suitable rendpoly. Possibly allocates a new one if necessary. + * + * @param type The type of the poly to create. + * @param isWall true= wall data is required for this poly. + * @param numverts The number of verts required. + * + * @return Ptr to a suitable rendpoly. + */ +rendpoly_t *R_AllocRendPoly(rendpolytype_t type, boolean isWall, + unsigned int numverts) +{ + rendpoly_t *poly = R_NewRendPoly(numverts, isWall); + + poly->type = type; + + poly->flags = 0; + poly->texoffx = 0; + poly->texoffy = 0; + poly->interpos = 0; + poly->lights = 0; + poly->decorlightmap = 0; + poly->sector = 0; + poly->blendmode = BM_NORMAL; + + return poly; +} + +/** + * Doesn't actually free anything. Instead, mark it as unused ready for the + * next time a rendpoly with this number of verts is needed. + * + * @param poly Ptr to the poly to mark unused. + */ +void R_FreeRendPoly(rendpoly_t *poly) +{ + unsigned int i; + + if(!poly) + return; + + for(i = 0; i < numrendpolys; ++i) + { + if(&rendPolys[i]->poly == poly) + { + rendPolys[i]->inUse = false; + return; + } + } +#if _DEBUG + Con_Message("R_FreeRendPoly: Dangling poly ptr!\n"); +#endif +} + void R_ShutdownData(void) { } diff --git a/doomsday/engine/portable/src/r_main.c b/doomsday/engine/portable/src/r_main.c index b30f778f25..b5d5e6eef9 100644 --- a/doomsday/engine/portable/src/r_main.c +++ b/doomsday/engine/portable/src/r_main.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ @@ -70,6 +70,8 @@ void Rend_RetrieveLightSample(void); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- +extern byte rendInfoRPolys; + // PUBLIC DATA DEFINITIONS ------------------------------------------------- int viewangleoffset = 0; @@ -125,25 +127,22 @@ static int bspFactor = 7; */ void R_Register(void) { - C_VAR_INT("rend-info-tris", &rendInfoTris, 0, 0, 1); - - C_VAR_BYTE("rend-info-frametime", &showFrameTimePos, 0, 0, 1); - - C_VAR_INT("rend-camera-smooth", &rend_camera_smooth, CVF_HIDE, 0, 1); C_VAR_INT("bsp-build", &bspBuild, 0, 0, 1); - C_VAR_INT("bsp-cache", &bspCache, 0, 0, 1); - C_VAR_INT("bsp-factor", &bspFactor, CVF_NO_MAX, 0, 0); C_VAR_INT("con-show-during-setup", &loadInStartupMode, 0, 0, 1); - C_VAR_INT("rend-vsync", &useVSync, 0, 0, 1); - + C_VAR_INT("rend-camera-smooth", &rend_camera_smooth, CVF_HIDE, 0, 1); + C_VAR_BYTE("rend-info-deltas-angles", &showViewAngleDeltas, 0, 0, 1); - C_VAR_BYTE("rend-info-deltas-pos", &showViewPosDeltas, 0, 0, 1); + C_VAR_BYTE("rend-info-frametime", &showFrameTimePos, 0, 0, 1); + C_VAR_BYTE("rend-info-rendpolys", &rendInfoRPolys, CVF_NO_ARCHIVE, 0, 1); + C_VAR_INT("rend-info-tris", &rendInfoTris, 0, 0, 1); + +// C_VAR_INT("rend-vsync", &useVSync, 0, 0, 1); } /** @@ -533,7 +532,7 @@ void R_SetupFrame(ddplayer_t *player) yaw - oldyaw, smoothView.pitch - oldpitch, (yaw - oldyaw) / (sysTime - oldtime), - (smoothView.pitch - oldpitch) / (sysTime - oldtime)); + (smoothView.pitch - oldpitch) / (sysTime - oldtime)); oldyaw = yaw; oldpitch = smoothView.pitch; oldtime = sysTime; @@ -676,6 +675,8 @@ void R_RenderPlayerView(ddplayer_t *player) Con_Printf("LumObjs: %-4i\n", numLuminous); } + R_InfoRendPolys(); + // View border? if(BorderNeedRefresh) { diff --git a/doomsday/engine/portable/src/r_world.c b/doomsday/engine/portable/src/r_world.c index c80a26c9fe..9ea5d39dc8 100644 --- a/doomsday/engine/portable/src/r_world.c +++ b/doomsday/engine/portable/src/r_world.c @@ -85,14 +85,15 @@ static float mapBounds[4]; # pragma optimize("g", off) #endif -/* +/** * We mustn't create links which form loops. This will start looking * from destlink, and if it finds startsec we're in trouble. */ -boolean R_IsValidLink(sector_t *startsec, sector_t *destlink, int plane) +static boolean R_IsValidLink(sector_t *startsec, sector_t *destlink, + int plane) { - sector_t *sec = destlink; - sector_t *link; + sector_t *sec = destlink; + sector_t *link; for(;;) { @@ -106,11 +107,12 @@ boolean R_IsValidLink(sector_t *startsec, sector_t *destlink, int plane) return false; sec = link; } + // No problems encountered. return true; } -/* +/** * Called whenever the sector changes. * * This routine handles plane hacks where all of the sector's @@ -120,13 +122,14 @@ boolean R_IsValidLink(sector_t *startsec, sector_t *destlink, int plane) * lines (eg a sector with a "control" sector such as the * forcefields in ETERNAL.WAD MAP01). */ -void R_SetSectorLinks(sector_t *sec) +static void R_SetSectorLinks(sector_t *sec) { - int k; - sector_t *back; - boolean hackfloor, hackceil; - side_t *sid, *frontsid, *backsid; - sector_t *floorlink_candidate = 0, *ceillink_candidate = 0; + int k; + sector_t *back; + line_t *lin; + boolean hackfloor, hackceil; + side_t *sid, *frontsid, *backsid; + sector_t *floorlink_candidate = 0, *ceillink_candidate = 0; //return; //---DEBUG--- // Must have a valid sector! @@ -135,31 +138,31 @@ void R_SetSectorLinks(sector_t *sec) hackfloor = (!R_IsSkySurface(&sec->SP_floorsurface)); hackceil = (!R_IsSkySurface(&sec->SP_ceilsurface)); - for(k = 0; k < sec->linecount; k++) + for(k = 0; k < sec->linecount; ++k) { + lin = sec->Lines[k]; if(!hackfloor && !hackceil) break; // We are only interested in two-sided lines. - if(!(sec->Lines[k]->frontsector && sec->Lines[k]->backsector)) + if(!(lin->frontsector && lin->backsector)) continue; // Check the vertex line owners for both verts. // We are only interested in lines that do NOT share either vertex // with a one-sided line (ie, its not "anchored"). - if(sec->Lines[k]->v1->info->anchored || - sec->Lines[k]->v2->info->anchored) + if(lin->v1->info->anchored || lin->v2->info->anchored) return; // Check which way the line is facing. - sid = SIDE_PTR(sec->Lines[k]->sidenum[0]); + sid = SIDE_PTR(lin->sidenum[0]); if(sid->sector == sec) { frontsid = sid; - backsid = SIDE_PTR(sec->Lines[k]->sidenum[1]); + backsid = SIDE_PTR(lin->sidenum[1]); } else { - frontsid = SIDE_PTR(sec->Lines[k]->sidenum[1]); + frontsid = SIDE_PTR(lin->sidenum[1]); backsid = sid; } back = backsid->sector; @@ -228,29 +231,29 @@ void R_SetSectorLinks(sector_t *sec) # pragma optimize("", on) #endif -/* +/** * Returns a pointer to the list of points. It must be used. */ -fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, int numclippers, - fdivline_t * clippers) +static fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, + int numclippers, fdivline_t * clippers) { unsigned char sidelist[MAX_POLY_SIDES]; int i, k, num = *numpoints; // We'll clip the polygon with each of the divlines. The left side of // each divline is discarded. - for(i = 0; i < numclippers; i++) + for(i = 0; i < numclippers; ++i) { fdivline_t *curclip = clippers + i; // First we'll determine the side of each vertex. Points are allowed // to be on the line. - for(k = 0; k < num; k++) + for(k = 0; k < num; ++k) { sidelist[k] = P_FloatPointOnLineSide(points + k, curclip); } - for(k = 0; k < num; k++) + for(k = 0; k < num; ++k) { int startIdx = k, endIdx = k + 1; @@ -269,7 +272,7 @@ fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, int numclippers, // Add the new vertex. Also modify the sidelist. points = - (fvertex_t *) realloc(points, (++num) * sizeof(fvertex_t)); + (fvertex_t *) M_Realloc(points, (++num) * sizeof(fvertex_t)); if(num >= MAX_POLY_SIDES) Con_Error("Too many points in clipper.\n"); @@ -288,7 +291,7 @@ fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, int numclippers, } // Now we must discard the points that are on the wrong side. - for(k = 0; k < num; k++) + for(k = 0; k < num; ++k) if(!sidelist[k]) { memmove(points + k, points + k + 1, @@ -298,8 +301,9 @@ fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, int numclippers, k--; } } + // Screen out consecutive identical points. - for(i = 0; i < num; i++) + for(i = 0; i < num; ++i) { int previdx = i - 1; @@ -319,38 +323,39 @@ fvertex_t *edgeClipper(int *numpoints, fvertex_t * points, int numclippers, return points; } -void R_ConvexClipper(subsector_t *ssec, int num, divline_t * list) +static void R_ConvexClipper(subsector_t *ssec, int num, divline_t * list) { - int numclippers = num + ssec->linecount; - int i, numedgepoints; - fvertex_t *edgepoints; - fdivline_t *clippers = - Z_Malloc(numclippers * sizeof(fdivline_t), PU_STATIC, 0); + int i, numedgepoints; + int numclippers = num + ssec->linecount; + fvertex_t *edgepoints; + fdivline_t *clippers, *clip; + + clippers = Z_Malloc(numclippers * sizeof(fdivline_t), PU_STATIC, 0); // Convert the divlines to float, in reverse order. - for(i = 0; i < numclippers; i++) + for(i = 0, clip = clippers; i < numclippers; clip++, ++i) { if(i < num) { - clippers[i].x = FIX2FLT(list[num - i - 1].x); - clippers[i].y = FIX2FLT(list[num - i - 1].y); - clippers[i].dx = FIX2FLT(list[num - i - 1].dx); - clippers[i].dy = FIX2FLT(list[num - i - 1].dy); + clip->x = FIX2FLT(list[num - i - 1].x); + clip->y = FIX2FLT(list[num - i - 1].y); + clip->dx = FIX2FLT(list[num - i - 1].dx); + clip->dy = FIX2FLT(list[num - i - 1].dy); } else { seg_t *seg = SEG_PTR(ssec->firstline + i - num); - clippers[i].x = FIX2FLT(seg->v1->x); - clippers[i].y = FIX2FLT(seg->v1->y); - clippers[i].dx = FIX2FLT(seg->v2->x - seg->v1->x); - clippers[i].dy = FIX2FLT(seg->v2->y - seg->v1->y); + clip->x = FIX2FLT(seg->v1->x); + clip->y = FIX2FLT(seg->v1->y); + clip->dx = FIX2FLT(seg->v2->x - seg->v1->x); + clip->dy = FIX2FLT(seg->v2->y - seg->v1->y); } } // Setup the 'worldwide' polygon. numedgepoints = 4; - edgepoints = malloc(numedgepoints * sizeof(fvertex_t)); + edgepoints = M_Malloc(numedgepoints * sizeof(fvertex_t)); edgepoints[0].x = -32768; edgepoints[0].y = 32768; @@ -389,52 +394,56 @@ void R_ConvexClipper(subsector_t *ssec, int num, divline_t * list) } // We're done, free the edgepoints memory. - free(edgepoints); + M_Free(edgepoints); Z_Free(clippers); } -void R_PrepareSubsector(subsector_t *sub) +static void R_PrepareSubsector(subsector_t *sub) { - int j, num = sub->numverts; + int j, num = sub->numverts; + fvertex_t *vtx = sub->verts; // Find the center point. First calculate the bounding box. - sub->bbox[0].x = sub->bbox[1].x = sub->verts[0].x; - sub->bbox[0].y = sub->bbox[1].y = sub->verts[0].y; - sub->midpoint.x = sub->verts[0].x; - sub->midpoint.y = sub->verts[0].y; - for(j = 1; j < num; j++) - { - if(sub->verts[j].x < sub->bbox[0].x) - sub->bbox[0].x = sub->verts[j].x; - if(sub->verts[j].y < sub->bbox[0].y) - sub->bbox[0].y = sub->verts[j].y; - if(sub->verts[j].x > sub->bbox[1].x) - sub->bbox[1].x = sub->verts[j].x; - if(sub->verts[j].y > sub->bbox[1].y) - sub->bbox[1].y = sub->verts[j].y; - sub->midpoint.x += sub->verts[j].x; - sub->midpoint.y += sub->verts[j].y; + sub->bbox[0].x = sub->bbox[1].x = sub->midpoint.x = vtx->x; + sub->bbox[0].y = sub->bbox[1].y = sub->midpoint.y = vtx->y; + + for(j = 1, vtx++; j < num; ++j, vtx++) + { + if(vtx->x < sub->bbox[0].x) + sub->bbox[0].x = vtx->x; + if(vtx->y < sub->bbox[0].y) + sub->bbox[0].y = vtx->y; + if(vtx->x > sub->bbox[1].x) + sub->bbox[1].x = vtx->x; + if(vtx->y > sub->bbox[1].y) + sub->bbox[1].y = vtx->y; + + sub->midpoint.x += vtx->x; + sub->midpoint.y += vtx->y; } sub->midpoint.x /= num; sub->midpoint.y /= num; } -void R_PolygonizeWithoutCarving() +static void R_PolygonizeWithoutCarving(void) { - int i; - int j; + int i, j, num; + fvertex_t *vtx; subsector_t *sub; + seg_t *seg; for(i = numsubsectors -1; i >= 0; --i) { sub = SUBSECTOR_PTR(i); - sub->numverts = sub->linecount; - sub->verts = Z_Malloc(sizeof(fvertex_t) * sub->linecount, - PU_LEVELSTATIC, 0); - for(j = 0; j < sub->linecount; j++) + num = sub->numverts = sub->linecount; + vtx = sub->verts = + Z_Malloc(sizeof(fvertex_t) * sub->linecount, PU_LEVELSTATIC, 0); + + seg = SEG_PTR(sub->firstline); + for(j = 0; j < num; ++j, seg++, vtx++) { - sub->verts[j].x = FIX2FLT(SEG_PTR(sub->firstline + j)->v1->x); - sub->verts[j].y = FIX2FLT(SEG_PTR(sub->firstline + j)->v1->y); + vtx->x = FIX2FLT(seg->v1->x); + vtx->y = FIX2FLT(seg->v1->y); } R_PrepareSubsector(sub); @@ -794,57 +803,73 @@ void R_SkyFix(boolean fixFloors, boolean fixCeilings) static float TriangleArea(fvertex_t * o, fvertex_t * s, fvertex_t * t) { - fvertex_t a = { s->x - o->x, s->y - o->y }, b = - { - t->x - o->x, t->y - o->y}; + fvertex_t a = { s->x - o->x, s->y - o->y }; + fvertex_t b = { t->x - o->x, t->y - o->y }; float area = (a.x * b.y - b.x * a.y) / 2; if(area < 0) - area = -area; - return area; + return -area; + else + return area; } -/* +/** * Returns true if 'base' is a good tri-fan base. */ -int R_TestTriFan(subsector_t *sub, int base) +static int R_TestTriFan(subsector_t *sub, int base) { #define TRIFAN_LIMIT 0.1 - int i, a, b; + int i, a, b, num = sub->numverts; + fvertex_t *verts = sub->verts; - if(sub->numverts == 3) + if(num == 3) return true; // They're all valid. + // Higher vertex counts need checking. - for(i = 0; i < sub->numverts - 2; i++) + for(i = 0; i < num - 2; ++i) { a = base + 1 + i; b = a + 1; - if(a >= sub->numverts) - a -= sub->numverts; - if(b >= sub->numverts) - b -= sub->numverts; - if(TriangleArea(sub->verts + base, sub->verts + a, sub->verts + b) <= - TRIFAN_LIMIT) + + if(a >= num) a -= num; + if(b >= num) b -= num; + + if(TriangleArea(&verts[base], &verts[a], &verts[b]) <= TRIFAN_LIMIT) return false; } + // Whole triangle fan checked out OK, must be good. return true; +#undef TRIFAN_LIMIT } -void R_SubsectorPlanes(void) +static void R_SubsectorPlanes(void) { - int i, k, num; + int i; + unsigned int k, num, bufSize = 0; subsector_t *sub; - fvertex_t buf[RL_MAX_POLY_SIDES]; + fvertex_t *verts; + fvertex_t *buf; + size_t size = sizeof(fvertex_t); + boolean valid; - for(i = 0; i < numsubsectors; i++) + buf = M_Malloc(size * 64); + + for(i = 0, sub = subsectors; i < numsubsectors; sub++, ++i) { - sub = SUBSECTOR_PTR(i); num = sub->numverts; + verts = sub->verts; + + if(num > bufSize) + { + bufSize = num; + buf = M_Realloc(buf, size * bufSize); + } + // We need to find a good tri-fan base vertex. // (One that doesn't generate zero-area triangles). // We'll test each one and pick the first good one. - for(k = 0; k < num; k++) + for(k = 0; k < num; ++k) { if(R_TestTriFan(sub, k)) { @@ -852,23 +877,28 @@ void R_SubsectorPlanes(void) // vertices so that k comes first. if(k) // Need to change? { - memcpy(buf, sub->verts, sizeof(fvertex_t) * num); - memcpy(sub->verts, buf + k, sizeof(fvertex_t) * (num - k)); - memcpy(sub->verts + (num - k), buf, sizeof(fvertex_t) * k); + memcpy(buf, verts, size * num); + memcpy(verts, &buf[k], size * (num - k)); + memcpy(&verts[num - k], buf, size * k); } - goto ddSP_NextSubSctr; + valid = true; + break; } } - // There was no match. Bugger. We need to use the subsector - // midpoint as the base. It's always valid. - sub->flags |= DDSUBF_MIDPOINT; - //Con_Message("Using midpoint for subsctr %i.\n", i); - ddSP_NextSubSctr:; + if(!valid) + { + // There was no match. Bugger. We need to use the subsector + // midpoint as the base. It's always valid. + sub->flags |= DDSUBF_MIDPOINT; + //Con_Message("Using midpoint for subsctr %i.\n", i); + } } + + M_Free(buf); } -void R_SetVertexOwner(vertex_t *vtx, sector_t *secptr) +static void R_SetVertexOwner(vertex_t *vtx, sector_t *secptr) { int i; int *list; @@ -879,7 +909,7 @@ void R_SetVertexOwner(vertex_t *vtx, sector_t *secptr) sector = GET_SECTOR_IDX(secptr); // Has this sector been already registered? - for(i = 0; i < vtx->info->num; i++) + for(i = 0; i < vtx->info->num; ++i) if(vtx->info->list[i] == sector) return; // Yes, we can exit. @@ -899,7 +929,7 @@ void R_SetVertexOwner(vertex_t *vtx, sector_t *secptr) vtx->info->list[vtx->info->num - 1] = sector; } -void R_SetVertexLineOwner(vertex_t *vtx, line_t *lineptr) +static void R_SetVertexLineOwner(vertex_t *vtx, line_t *lineptr) { int i; int *list; @@ -935,7 +965,7 @@ void R_SetVertexLineOwner(vertex_t *vtx, line_t *lineptr) } static vertex_t *rootVtx; -/* +/** * Compares the angles of two lines that share a common vertex. * * pre: rootVtx must point to the vertex common between a and b @@ -975,7 +1005,7 @@ static int C_DECL lineAngleSorter(const void *a, const void *b) return (angleB - angleA); } -/* +/** * Generates an array of sector references for each vertex. The list * includes all the sectors the vertex belongs to. * @@ -983,12 +1013,13 @@ static int C_DECL lineAngleSorter(const void *a, const void *b) * includes all the lines the vertex belongs to sorted by angle. * (the list is arranged in clockwise order, east = 0). */ -void R_InitVertexOwners(void) +static void R_InitVertexOwners(void) { - int i, k, p; - sector_t *sec; - vertex_t *v[2]; - vertexinfo_t *own; + int i, k, p; + sector_t *sec; + line_t *line; + vertex_t *v[2]; + vertexinfo_t *own; // Allocate enough memory. own = Z_Malloc(sizeof(vertexinfo_t) * numvertexes, PU_LEVELSTATIC, 0); @@ -1002,10 +1033,11 @@ void R_InitVertexOwners(void) // Traversing the line list will do fine. for(k = 0; k < sec->linecount; ++k) { - line_t* line = sec->Lines[k]; + line = sec->Lines[k]; v[0] = line->v1; v[1] = line->v2; - for(p = 0; p < 2; p++) + + for(p = 0; p < 2; ++p) { R_SetVertexOwner(v[p], line->frontsector); R_SetVertexOwner(v[p], line->backsector); @@ -1061,29 +1093,31 @@ void R_InitVertexOwners(void) return true; } */ -/* +/** * The test is done on subsectors. */ -sector_t *R_GetContainingSectorOf(sector_t *sec) +static sector_t *R_GetContainingSectorOf(sector_t *sec) { - int i; - float cdiff = -1, diff; - float inner[4], outer[4]; - sector_t *other, *closest = NULL; + int i; + float cdiff = -1, diff; + float inner[4], outer[4]; + sector_t *other, *closest = NULL; memcpy(inner, sec->info->bounds, sizeof(inner)); // Try all sectors that fit in the bounding box. - for(i = 0; i < numsectors; ++i) + for(i = 0, other = sectors; i < numsectors; other++, ++i) { - other = SECTOR_PTR(i); if(!other->linecount || SECT_INFO(other)->unclosed) continue; if(other == sec) continue; // Don't try on self! + memcpy(outer, other->info->bounds, sizeof(outer)); - if(inner[BLEFT] >= outer[BLEFT] && inner[BRIGHT] <= outer[BRIGHT] && - inner[BTOP] >= outer[BTOP] && inner[BBOTTOM] <= outer[BBOTTOM]) + if(inner[BLEFT] >= outer[BLEFT] && + inner[BRIGHT] <= outer[BRIGHT] && + inner[BTOP] >= outer[BTOP] && + inner[BBOTTOM]<= outer[BBOTTOM]) { // Inside! Now we must test each of the subsectors. Otherwise // we can't be sure... @@ -1102,22 +1136,20 @@ sector_t *R_GetContainingSectorOf(sector_t *sec) return closest; } -void R_InitSectorInfo(void) +static void R_InitSectorInfo(void) { - int i, k; + int i, k; sectorinfo_t *secinfo; - sector_t *sec, *other; - line_t *lin; - boolean dohack; - boolean unclosed; + sector_t *sec, *other; + line_t *lin; + boolean dohack, unclosed; secinfo = Z_Calloc(sizeof(sectorinfo_t) * numsectors, PU_LEVELSTATIC, 0); // Calculate bounding boxes for all sectors. // Check for unclosed sectors. - for(i = 0; i < numsectors; ++i, secinfo++) + for(i = 0, sec = sectors; i < numsectors; ++i, sec++, secinfo++) { - sec = SECTOR_PTR(i); sec->info = secinfo; for(k = 0; k < sec->planecount; ++k) @@ -1154,9 +1186,8 @@ void R_InitSectorInfo(void) sec->info->unclosed = true; } - for(i = 0; i < numsectors; ++i) + for(i = 0, sec = sectors; i < numsectors; sec++, ++i) { - sec = SECTOR_PTR(i); if(!sec->linecount) continue; @@ -1164,12 +1195,11 @@ void R_InitSectorInfo(void) sec->info->containsector = R_GetContainingSectorOf(sec); dohack = true; - for(k = 0; k < sec->linecount; k++) + for(k = 0; k < sec->linecount; ++k) { lin = sec->Lines[k]; - if(!lin->frontsector || !lin->backsector || - lin->frontsector != lin->backsector) + lin->frontsector != lin->backsector) { dohack = false; break; @@ -1196,12 +1226,13 @@ void R_InitSectorInfo(void) sec->info->bounds[BBOTTOM] - sec->info->bounds[BTOP] > DOMINANT_SIZE) { // All sectors touching this one will be affected. - for(k = 0; k < sec->linecount; k++) + for(k = 0; k < sec->linecount; ++k) { - other = sec->Lines[k]->frontsector; + lin = sec->Lines[k]; + other = lin->frontsector; if(!other || other == sec) { - other = sec->Lines[k]->backsector; + other = lin->backsector; if(!other || other == sec) continue; } @@ -1211,16 +1242,17 @@ void R_InitSectorInfo(void) } } -void R_InitSegInfo(void) +static void R_InitSegInfo(void) { - int i, k, j, n; - seginfo_t *inf; + int i, k, j, n; + seg_t *seg; + seginfo_t *inf; inf = Z_Calloc(numsegs * sizeof(seginfo_t), PU_LEVELSTATIC, NULL); - for(i = 0; i < numsegs; ++i, ++inf) + for(i = 0, seg = segs; i < numsegs; ++i, seg++, inf++) { - SEG_PTR(i)->info = inf; + seg->info = inf; for(k = 0; k < 4; ++k) { /* inf->illum[0][k].front = @@ -1240,16 +1272,19 @@ void R_InitSegInfo(void) } } -void R_InitPlaneIllumination(subsector_t *sub, int planeid) +static void R_InitPlaneIllumination(subsector_t *sub, int planeid) { - int i, j; + int i, j; + int num; subsectorinfo_t *ssecinfo = SUBSECT_INFO(sub); subplaneinfo_t *plane = ssecinfo->planes[planeid]; - plane->illumination = Z_Calloc(ssecinfo->numvertices * sizeof(vertexillum_t), - PU_LEVELSTATIC, NULL); + num = ssecinfo->numvertices; - for(i = 0; i < ssecinfo->numvertices; ++i) + plane->illumination = + Z_Calloc(num * sizeof(vertexillum_t), PU_LEVELSTATIC, NULL); + + for(i = 0; i < num; ++i) { plane->illumination[i].flags |= VIF_STILL_UNSEEN; @@ -1258,10 +1293,10 @@ void R_InitPlaneIllumination(subsector_t *sub, int planeid) } } -void R_InitPlanePolys(subsector_t *subsector) +static void R_InitPlanePolys(subsector_t *subsector) { - int numvrts, i; - fvertex_t *vrts, *vtx, *pv; + int numvrts, i; + fvertex_t *vrts, *vtx, *pv; subsectorinfo_t *ssecinfo = SUBSECT_INFO(subsector); // Take the subsector's vertices. @@ -1424,9 +1459,8 @@ void R_RationalizeSectors(void) // Allocate some memory for the line "run" (line list). collectedLines = M_Malloc(maxNumLines * sizeof(line_t*)); - for(i = 0; i < numsectors; ++i) + for(i = 0, sec = sectors; i < numsectors; sec++, ++i) { - sec = SECTOR_PTR(i); if(!sec->linecount) continue; @@ -1438,7 +1472,7 @@ void R_RationalizeSectors(void) for(k = 0; k < sec->linecount; ++k) { lin = sec->Lines[k]; - linfo = LINE_INFO(lin); + linfo = lin->info; if(lin->frontsector && lin->backsector && lin->frontsector == lin->backsector && @@ -1572,7 +1606,7 @@ void R_RationalizeSectors(void) for(k = 0; k < sec->linecount; ++k) { lin = sec->Lines[k]; - linfo = LINE_INFO(lin); + linfo = lin->info; if(!linfo->selfrefhackroot) continue; @@ -1732,7 +1766,7 @@ void R_RationalizeSectors(void) M_Free(collectedLines); } -/* +/** * Mapinfo must be set. */ void R_SetupSky(void) @@ -1758,7 +1792,7 @@ void R_SetupSky(void) Rend_SkyParams(DD_SKY, DD_HEIGHT, mapinfo->sky_height); Rend_SkyParams(DD_SKY, DD_HORIZON, mapinfo->horizon_offset); - for(i = 0; i < 2; i++) + for(i = 0; i < 2; ++i) { k = mapinfo->sky_layers[i].flags; if(k & SLF_ENABLED) @@ -1791,7 +1825,7 @@ void R_SetupSky(void) // How about the sky color? noSkyColorGiven = true; - for(i = 0; i < 3; i++) + for(i = 0; i < 3; ++i) { skyColorRGB[i] = (byte) (255 * mapinfo->sky_color[i]); if(mapinfo->sky_color[i] > 0) @@ -1815,7 +1849,7 @@ void R_SetupSky(void) } } -/* +/** * Returns pointers to the line's vertices in such a fashion that * verts[0] is the leftmost vertex and verts[1] is the rightmost * vertex, when the line lies at the edge of `sector.' @@ -1834,23 +1868,23 @@ void R_OrderVertices(line_t *line, const sector_t *sector, vertex_t *verts[2]) } } -/* +/** * A neighbour is a line that shares a vertex with 'line', and faces * the specified sector. Finds both the left and right neighbours. */ -void R_FindLineNeighbors(sector_t *sector, line_t *line, - struct line_s **neighbors, int alignment) +static void R_FindLineNeighbors(sector_t *sector, line_t *line, + line_t **neighbors, int alignment) { - struct line_s *other; - vertex_t *vtx[2]; - int j; + int j; + line_t *other; + vertex_t *vtx[2]; // We want to know which vertex is the leftmost/rightmost one. R_OrderVertices(line, sector, vtx); // Find the real neighbours, which are in the same sector // as this line. - for(j = 0; j < sector->linecount; j++) + for(j = 0; j < sector->linecount; ++j) { other = sector->Lines[j]; if(other == line) @@ -2382,6 +2416,8 @@ void R_SetupLevel(char *level_id, int flags) // Initialize the lighting grid. LG_Init(); + R_InitRendPolyPool(); + Con_Progress(10, 0); // 50%. } diff --git a/doomsday/engine/portable/src/rend_decor.c b/doomsday/engine/portable/src/rend_decor.c index cbd4bf69a9..a9d0116321 100644 --- a/doomsday/engine/portable/src/rend_decor.c +++ b/doomsday/engine/portable/src/rend_decor.c @@ -618,7 +618,7 @@ void Rend_DecorateLine(int index) // textures, this looks a bit silly. /*if(line->sidenum[0] >= 0 && (side = SIDE_PTR(line->sidenum[0]))->midtexture) { - rendpoly_t quad; + rendpoly_t *quad = R_AllocRendPoly(RP_QUAD, true, 4); // If there is an opening, process it. if(side->middle.texture.isflat) @@ -626,15 +626,16 @@ void Rend_DecorateLine(int index) else GL_GetTextureInfo(side->middle.texture); - quad.top = MIN_OF(frontCeil, backCeil); - quad.bottom = MAX_OF(frontFloor, backFloor); - quad.texoffy = FIX2FLT(side->textureoffset); - if(Rend_MidTexturePos(&quad.top, &quad.bottom, &quad.texoffy, 0, + quad->top = MIN_OF(frontCeil, backCeil); + quad->bottom = MAX_OF(frontFloor, backFloor); + quad->texoffy = FIX2FLT(side->textureoffset); + if(Rend_MidTexturePos(&quad->top, &quad->bottom, &quad->texoffy, 0, (line->flags & ML_DONTPEGBOTTOM) != 0)) { Rend_DecorateLineSection(line, side, &side->middle, - quad.top, quad.bottom, quad.texoffy); + quad->top, quad->bottom, quad->texoffy); } + R_FreeRendPoly(quad); }*/ } else diff --git a/doomsday/engine/portable/src/rend_fakeradio.c b/doomsday/engine/portable/src/rend_fakeradio.c index 829267f30a..c55aadaa79 100644 --- a/doomsday/engine/portable/src/rend_fakeradio.c +++ b/doomsday/engine/portable/src/rend_fakeradio.c @@ -678,7 +678,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { sector_t *backSector; float bFloor, bCeil, limit, size, segOffset; - rendpoly_t quad, *q = &quad; + rendpoly_t *quad; int i, texture = 0, sideNum; lineinfo_t *info; shadowcorner_t topCn[2], botCn[2], sideCn[2]; @@ -724,25 +724,27 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) // DJS - Re above: // Unfortunetly, in practice this doesn't seem to make much // difference. On my system I gain about +1.4FPS on average. - memcpy(q, origQuad, sizeof(rendpoly_t)); + quad = R_AllocRendPoly(RP_QUAD, true, 4); + memcpy(quad, origQuad, sizeof(rendpoly_t)); // Init the quad. - q->flags = RPF_SHADOW; - q->texoffx = segOffset; - q->texoffy = 0; - q->tex.id = GL_PrepareLSTexture(LST_RADIO_CC); - q->tex.detail = NULL; - q->tex.width = info->length; - q->tex.height = shadowSize; - q->lights = NULL; - q->intertex.id = 0; - q->intertex.detail = NULL; + quad->flags = RPF_SHADOW; + quad->texoffx = segOffset; + quad->texoffy = 0; + quad->tex.id = GL_PrepareLSTexture(LST_RADIO_CC); + quad->tex.detail = NULL; + quad->tex.width = info->length; + quad->tex.height = shadowSize; + quad->lights = NULL; + quad->intertex.id = 0; + quad->intertex.detail = NULL; // Fade the shadow out if the height is below the min height. - if(q->vertices[2].pos[VZ] - q->vertices[0].pos[VZ] < EDGE_OPEN_THRESHOLD) - Rend_RadioSetColor(q, shadowDark * ((q->vertices[2].pos[VZ] - q->vertices[0].pos[VZ]) / EDGE_OPEN_THRESHOLD)); + if(quad->vertices[2].pos[VZ] - quad->vertices[0].pos[VZ] < EDGE_OPEN_THRESHOLD) + Rend_RadioSetColor(quad, shadowDark * + ((quad->vertices[2].pos[VZ] - quad->vertices[0].pos[VZ]) / EDGE_OPEN_THRESHOLD)); else - Rend_RadioSetColor(q, shadowDark); + Rend_RadioSetColor(quad, shadowDark); /* * Top Shadow @@ -750,16 +752,16 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) // The top shadow will reach this far down. size = shadowSize + Rend_RadioLongWallBonus(ceilSpan->length); limit = fCeil - size; - if((q->vertices[2].pos[VZ] > limit && q->vertices[0].pos[VZ] < fCeil) && + if((quad->vertices[2].pos[VZ] > limit && quad->vertices[0].pos[VZ] < fCeil) && Rend_RadioNonGlowingFlat(frontSector, PLN_CEILING)) { - Rend_RadioTexCoordY(q, size); + Rend_RadioTexCoordY(quad, size); texture = LST_RADIO_OO; // Corners without a neighbour backsector if(sideCn[0].corner == -1 || sideCn[1].corner == -1) { // At least one corner faces outwards texture = LST_RADIO_OO; - Rend_RadioTexCoordX(q, ceilSpan->length, ceilSpan->shift); + Rend_RadioTexCoordX(quad, ceilSpan->length, ceilSpan->shift); if((sideCn[0].corner == -1 && sideCn[1].corner == -1) || (topCn[0].corner == -1 && topCn[1].corner == -1) ) @@ -770,7 +772,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { // right corner faces outwards if(-topCn[0].pOffset < 0 && botCn[0].pHeight < fCeil) {// Must flip horizontally! - Rend_RadioTexCoordX(q, -ceilSpan->length, ceilSpan->shift); + Rend_RadioTexCoordX(quad, -ceilSpan->length, ceilSpan->shift); texture = LST_RADIO_OE; } } @@ -784,7 +786,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } else { // Corners WITH a neighbour backsector - Rend_RadioTexCoordX(q, ceilSpan->length, ceilSpan->shift); + Rend_RadioTexCoordX(quad, ceilSpan->length, ceilSpan->shift); if(topCn[0].corner == -1 && topCn[1].corner == -1) { // Both corners face outwards texture = LST_RADIO_OO;//CC; @@ -812,14 +814,14 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) if(-topCn[0].pOffset < INDIFF) texture = LST_RADIO_OE; else - Rend_RadioTexCoordY(q, -topCn[0].pOffset); + Rend_RadioTexCoordY(quad, -topCn[0].pOffset); } } else if(-topCn[0].pOffset < 0 && -topCn[1].pOffset >= 0) { // Must flip horizontally! texture = LST_RADIO_CO; - Rend_RadioTexCoordX(q, -ceilSpan->length, ceilSpan->shift); + Rend_RadioTexCoordX(quad, -ceilSpan->length, ceilSpan->shift); // The shadow can't go over the higher edge. if(size > -topCn[1].pOffset) @@ -827,7 +829,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) if(-topCn[1].pOffset < INDIFF) texture = LST_RADIO_OE; else - Rend_RadioTexCoordY(q, -topCn[1].pOffset); + Rend_RadioTexCoordY(quad, -topCn[1].pOffset); } } } @@ -837,7 +839,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { // Must flip horizontally! texture = LST_RADIO_OE; - Rend_RadioTexCoordX(q, -floorSpan->length, + Rend_RadioTexCoordX(quad, -floorSpan->length, floorSpan->shift); } else if(-topCn[1].pOffset < -MINDIFF) @@ -852,7 +854,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) texture = LST_RADIO_OO; // Must flip horizontally! - Rend_RadioTexCoordX(q, -ceilSpan->length, ceilSpan->shift); + Rend_RadioTexCoordX(quad, -ceilSpan->length, ceilSpan->shift); } else if(topCn[1].corner <= MIN_OPEN) { @@ -867,8 +869,8 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } } - q->tex.id = GL_PrepareLSTexture(texture); - RL_AddPoly(q); + quad->tex.id = GL_PrepareLSTexture(texture); + RL_AddPoly(quad); } /* @@ -876,16 +878,16 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) */ size = shadowSize + Rend_RadioLongWallBonus(floorSpan->length) / 2; limit = fFloor + size; - if((q->vertices[0].pos[VZ] < limit && q->vertices[2].pos[VZ] > fFloor) && + if((quad->vertices[0].pos[VZ] < limit && quad->vertices[2].pos[VZ] > fFloor) && Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR)) { - Rend_RadioTexCoordY(q, -size); + Rend_RadioTexCoordY(quad, -size); texture = LST_RADIO_OO; // Corners without a neighbour backsector if(sideCn[0].corner == -1 || sideCn[1].corner == -1) { // At least one corner faces outwards texture = LST_RADIO_OO; - Rend_RadioTexCoordX(q, floorSpan->length, floorSpan->shift); + Rend_RadioTexCoordX(quad, floorSpan->length, floorSpan->shift); if((sideCn[0].corner == -1 && sideCn[1].corner == -1) || (botCn[0].corner == -1 && botCn[1].corner == -1) ) @@ -896,7 +898,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { if(botCn[0].pOffset < 0 && topCn[0].pHeight > fFloor) { // Must flip horizontally! - Rend_RadioTexCoordX(q, -floorSpan->length, floorSpan->shift); + Rend_RadioTexCoordX(quad, -floorSpan->length, floorSpan->shift); texture = LST_RADIO_OE; } } @@ -910,7 +912,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } else { // Corners WITH a neighbour backsector - Rend_RadioTexCoordX(q, floorSpan->length, floorSpan->shift); + Rend_RadioTexCoordX(quad, floorSpan->length, floorSpan->shift); if(botCn[0].corner == -1 && botCn[1].corner == -1) { // Both corners face outwards texture = LST_RADIO_OO;//CC; @@ -939,14 +941,14 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) if(botCn[0].pOffset < INDIFF) texture = LST_RADIO_OE; else - Rend_RadioTexCoordY(q, -botCn[0].pOffset); + Rend_RadioTexCoordY(quad, -botCn[0].pOffset); } } else if(botCn[0].pOffset < 0 && botCn[1].pOffset >= 0) { // Must flip horizontally! texture = LST_RADIO_CO; - Rend_RadioTexCoordX(q, -floorSpan->length, + Rend_RadioTexCoordX(quad, -floorSpan->length, floorSpan->shift); if(size > botCn[1].pOffset) @@ -954,7 +956,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) if(botCn[1].pOffset < INDIFF) texture = LST_RADIO_OE; else - Rend_RadioTexCoordY(q, -botCn[1].pOffset); + Rend_RadioTexCoordY(quad, -botCn[1].pOffset); } } } @@ -964,7 +966,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { // Must flip horizontally! texture = LST_RADIO_OE; - Rend_RadioTexCoordX(q, -floorSpan->length, + Rend_RadioTexCoordX(quad, -floorSpan->length, floorSpan->shift); } else if(botCn[1].pOffset < -MINDIFF) @@ -979,7 +981,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) texture = LST_RADIO_OO; // Must flip horizontally! - Rend_RadioTexCoordX(q, -floorSpan->length, floorSpan->shift); + Rend_RadioTexCoordX(quad, -floorSpan->length, floorSpan->shift); } else if(botCn[1].corner <= MIN_OPEN) // Left Corner is closed { @@ -994,15 +996,18 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } } - q->tex.id = GL_PrepareLSTexture(texture); - RL_AddPoly(q); + quad->tex.id = GL_PrepareLSTexture(texture); + RL_AddPoly(quad); } // Walls with glowing floor & ceiling get no side shadows. // Is there anything better we can do? if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR)) && !(Rend_RadioNonGlowingFlat(frontSector, PLN_CEILING))) + { + R_FreeRendPoly(quad); return; + } /* * Left/Right Shadows @@ -1010,26 +1015,26 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) size = shadowSize + Rend_RadioLongWallBonus(info->length); for(i = 0; i < 2; ++i) { - q->flags |= RPF_HORIZONTAL; - q->texoffy = q->vertices[0].pos[VZ] - fFloor; - q->tex.height = fCeil - fFloor; + quad->flags |= RPF_HORIZONTAL; + quad->texoffy = quad->vertices[0].pos[VZ] - fFloor; + quad->tex.height = fCeil - fFloor; // Left Shadow if(i == 0) { if(sideCn[0].corner > 0 && segOffset < size) { - q->texoffx = segOffset; + quad->texoffx = segOffset; // Make sure the shadow isn't too big if(size > info->length) { if(sideCn[1].corner <= MIN_OPEN) - q->tex.width = info->length; + quad->tex.width = info->length; else - q->tex.width = info->length/2; + quad->tex.width = info->length/2; } else - q->tex.width = size; + quad->tex.width = size; } else continue; // Don't draw a left shadow @@ -1038,17 +1043,17 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { if(sideCn[1].corner > 0 && segOffset + seg->length > info->length - size) { - q->texoffx = -info->length + segOffset; + quad->texoffx = -info->length + segOffset; // Make sure the shadow isn't too big if(size > info->length) { if(sideCn[0].corner <= MIN_OPEN) - q->tex.width = -info->length; + quad->tex.width = -info->length; else - q->tex.width = -(info->length/2); + quad->tex.width = -(info->length/2); } else - q->tex.width = -size; + quad->tex.width = -size; } else continue; // Don't draw a right shadow @@ -1065,8 +1070,8 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } else if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR))) { - q->texoffy = q->vertices[0].pos[VZ] - fCeil; - q->tex.height = -(fCeil - fFloor); + quad->texoffy = quad->vertices[0].pos[VZ] - fCeil; + quad->tex.height = -(fCeil - fFloor); texture = LST_RADIO_CO; } else @@ -1081,8 +1086,8 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } else if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR))) { - q->texoffy = q->vertices[0].pos[VZ] - fCeil; - q->tex.height = -(fCeil - fFloor); + quad->texoffy = quad->vertices[0].pos[VZ] - fCeil; + quad->tex.height = -(fCeil - fFloor); texture = LST_RADIO_CO; } else @@ -1097,8 +1102,8 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) } else if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR))) { - q->texoffy = q->vertices[0].pos[VZ] - fCeil; - q->tex.height = -(fCeil - fFloor); + quad->texoffy = quad->vertices[0].pos[VZ] - fCeil; + quad->tex.height = -(fCeil - fFloor); texture = LST_RADIO_CO; } else @@ -1109,7 +1114,7 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) { if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_FLOOR))) { - Rend_RadioTexCoordY(q, -(fCeil - fFloor)); + Rend_RadioTexCoordY(quad, -(fCeil - fFloor)); texture = LST_RADIO_CO; } else if(!(Rend_RadioNonGlowingFlat(frontSector, PLN_CEILING))) @@ -1118,11 +1123,12 @@ void Rend_RadioWallSection(const seg_t *seg, rendpoly_t *origQuad) texture = LST_RADIO_CC; } - q->tex.id = GL_PrepareLSTexture(texture); + quad->tex.id = GL_PrepareLSTexture(texture); - Rend_RadioSetColor(q, sideCn[i].corner * shadowDark); - RL_AddPoly(q); + Rend_RadioSetColor(quad, sideCn[i].corner * shadowDark); + RL_AddPoly(quad); } + R_FreeRendPoly(quad); } /* @@ -1212,7 +1218,7 @@ float Rend_RadioEdgeOpenness(line_t *line, boolean frontside, boolean isCeiling) void Rend_RadioAddShadowEdge(shadowpoly_t *shadow, boolean isCeiling, float darkness, float sideOpen[2]) { - rendpoly_t q; + rendpoly_t *q; rendpoly_vertex_t *vtx; sector_t *sector; float z, pos; @@ -1258,19 +1264,16 @@ void Rend_RadioAddShadowEdge(shadowpoly_t *shadow, boolean isCeiling, } // Initialize the rendpoly. - q.type = RP_FLAT; - q.isWall = false; - q.flags = RPF_SHADOW; - memset(&q.tex, 0, sizeof(q.tex)); - memset(&q.intertex, 0, sizeof(q.intertex)); - q.interpos = 0; - q.lights = NULL; - q.sector = NULL; - - q.numvertices = 4; - memset(q.vertices, 0, q.numvertices * sizeof(rendpoly_vertex_t)); - - vtx = q.vertices; + q = R_AllocRendPoly(RP_FLAT, false, 4); + q->flags = RPF_SHADOW; + memset(&q->tex, 0, sizeof(q->tex)); + memset(&q->intertex, 0, sizeof(q->intertex)); + q->interpos = 0; + q->lights = NULL; + q->sector = NULL; + memset(q->vertices, 0, q->numvertices * sizeof(rendpoly_vertex_t)); + + vtx = q->vertices; idx = (isCeiling ? ceilIndices : floorIndices); // Left outer corner. @@ -1301,7 +1304,8 @@ void Rend_RadioAddShadowEdge(shadowpoly_t *shadow, boolean isCeiling, vtx[idx[3]].pos[VY] = vtx[idx[0]].pos[VY] + inner[0][VY]; vtx[idx[3]].pos[VZ] = z; - RL_AddPoly(&q); + RL_AddPoly(q); + R_FreeRendPoly(q); } /* diff --git a/doomsday/engine/portable/src/rend_list.c b/doomsday/engine/portable/src/rend_list.c index 33283ff5bb..ecdf3656e1 100644 --- a/doomsday/engine/portable/src/rend_list.c +++ b/doomsday/engine/portable/src/rend_list.c @@ -18,7 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ @@ -116,7 +116,7 @@ enum { // TYPES ------------------------------------------------------------------- -/* +/** * Each primhdr begins a block of polygon data that ends up as one or * more triangles on the screen. Note that there are pointers to the * rendering list itself here; they will need to be properly restored @@ -156,7 +156,7 @@ typedef struct primhdr_s { #define RLF_LIGHTS 0x1 // Primitives are dynamic lights. #define RLF_BLENDED 0x2 // List contains only texblended prims. -/* +/** * The rendering list. When the list is resized, pointers in the primitives * need to be restored so that they point to the new list. */ @@ -220,7 +220,7 @@ int maxArrayLights = 1; // PRIVATE DATA DEFINITIONS ------------------------------------------------ -/* +/** * The vertex arrays. */ static gl_vertex_t *vertices; @@ -229,7 +229,7 @@ static gl_color_t *colors; static uint numVertices, maxVertices; -/* +/** * The rendering lists. */ // Surfaces without lights. @@ -258,7 +258,7 @@ void RL_Register(void) C_VAR_BYTE("rend-dev-sky", &debugSky, 0, 0, 1); } -/* +/** * This doesn't create a rendering primitive but a vissprite! The vissprite * represents the masked poly and will be rendered during the rendering * of sprites. This is necessary because all masked polygons must be @@ -275,12 +275,12 @@ void RL_AddMaskedPoly(rendpoly_t *poly) vis->distance = (poly->vertices[0].dist + poly->vertices[1].dist) / 2; vis->data.wall.texture = poly->tex.id; vis->data.wall.masked = texmask; // Store texmask status in flip. - for(i = 0; i < 4; i++) + for(i = 0; i < 4; ++i) { vis->data.wall.vertices[i].pos[VX] = poly->vertices[i].pos[VX]; vis->data.wall.vertices[i].pos[VY] = poly->vertices[i].pos[VY]; vis->data.wall.vertices[i].pos[VZ] = poly->vertices[i].pos[VZ]; - for(c = 0; c < 4; c++) + for(c = 0; c < 4; ++c) { vis->data.wall.vertices[i].color[c] = poly->vertices[i].color.rgba[c]; @@ -289,7 +289,7 @@ void RL_AddMaskedPoly(rendpoly_t *poly) } vis->data.wall.texc[0][VX] = poly->texoffx / (float) poly->tex.width; vis->data.wall.texc[1][VX] = - vis->data.wall.texc[0][VX] + poly->wall.length / poly->tex.width; + vis->data.wall.texc[0][VX] + poly->wall->length / poly->tex.width; vis->data.wall.texc[0][VY] = poly->texoffy / (float) poly->tex.height; vis->data.wall.texc[1][VY] = vis->data.wall.texc[0][VY] + (poly->vertices[2].pos[VZ] - @@ -319,13 +319,13 @@ void RL_AddMaskedPoly(rendpoly_t *poly) } } -/* +/** * Color distance attenuation, extralight, fixedcolormap. * "Torchlight" is white, regardless of the original RGB. */ void RL_VertexColors(rendpoly_t *poly, int lightlevel, const byte *rgb) { - int i; + int i, num; float light, real, minimum; rendpoly_vertex_t *vtx; boolean usewhite; @@ -335,7 +335,7 @@ void RL_VertexColors(rendpoly_t *poly, int lightlevel, const byte *rgb) // Do a lighting adjustment based on orientation. lightlevel += (poly->vertices[1].pos[VY] - - poly->vertices[0].pos[VY]) / poly->wall.length * 18 * + poly->vertices[0].pos[VY]) / poly->wall->length * 18 * rend_light_wall_angle; if(lightlevel < 0) lightlevel = 0; @@ -344,8 +344,8 @@ void RL_VertexColors(rendpoly_t *poly, int lightlevel, const byte *rgb) } light = lightlevel / 255.0f; - - for(i = 0, vtx = poly->vertices; i < poly->numvertices; i++, vtx++) + num = poly->numvertices; + for(i = 0, vtx = poly->vertices; i < num; ++i, vtx++) { usewhite = false; @@ -396,7 +396,7 @@ void RL_VertexColors(rendpoly_t *poly, int lightlevel, const byte *rgb) void RL_PreparePlane(subplaneinfo_t *plane, rendpoly_t *poly, float height, subsector_t *subsector) { - int i, vid, sectorlight; + int i, num, vid, sectorlight; const byte *pLightColor; byte vColor[] = { 0, 0, 0, 0}; subsectorinfo_t *ssecinfo = SUBSECT_INFO(subsector); @@ -410,7 +410,8 @@ void RL_PreparePlane(subplaneinfo_t *plane, rendpoly_t *poly, float height, vid = 0; // Calculate the distance to each vertex. - for(i = 0; i < ssecinfo->numvertices; i++) + num = ssecinfo->numvertices; + for(i = 0; i < num; ++i) { poly->vertices[i].pos[VX] = ssecinfo->vertices[vid].x; poly->vertices[i].pos[VY] = ssecinfo->vertices[vid].y; @@ -430,7 +431,7 @@ void RL_PreparePlane(subplaneinfo_t *plane, rendpoly_t *poly, float height, poly->sector->planes[plane->type]->surface.rgba[2] < 255 ) { // Blend sector light+color+planecolor - for(i = 0; i < 3; i++) + for(i = 0; i < 3; ++i) { vColor[i] = (byte) (((poly->sector->planes[plane->type]->surface.rgba[i]/ 255.0f)) * pLightColor[i]); } @@ -444,7 +445,7 @@ void RL_PreparePlane(subplaneinfo_t *plane, rendpoly_t *poly, float height, } } -/* +/** * The first selected unit is active after this call. */ void RL_SelectTexUnits(int count) @@ -496,7 +497,7 @@ void RL_ClearHash(listhash_t * hash) memset(hash, 0, sizeof(listhash_t) * RL_HASH_SIZE); } -/* +/** * Called only once, from R_Init -> Rend_Init. */ void RL_Init(void) @@ -520,18 +521,18 @@ void RL_DestroyVertices(void) int i; numVertices = maxVertices = 0; - free(vertices); + M_Free(vertices); vertices = NULL; - free(colors); + M_Free(colors); colors = NULL; - for(i = 0; i < NUM_TEXCOORD_ARRAYS; i++) + for(i = 0; i < NUM_TEXCOORD_ARRAYS; ++i) { - free(texCoords[i]); + M_Free(texCoords[i]); texCoords[i] = NULL; } } -/* +/** * Allocate vertices from the global vertex array. */ uint RL_AllocateVertices(uint count) @@ -551,12 +552,12 @@ uint RL_AllocateVertices(uint count) maxVertices *= 2; } - vertices = realloc(vertices, sizeof(gl_vertex_t) * maxVertices); - colors = realloc(colors, sizeof(gl_color_t) * maxVertices); - for(i = 0; i < NUM_TEXCOORD_ARRAYS; i++) + vertices = M_Realloc(vertices, sizeof(gl_vertex_t) * maxVertices); + colors = M_Realloc(colors, sizeof(gl_color_t) * maxVertices); + for(i = 0; i < NUM_TEXCOORD_ARRAYS; ++i) { texCoords[i] = - realloc(texCoords[i], sizeof(gl_texcoord_t) * maxVertices); + M_Realloc(texCoords[i], sizeof(gl_texcoord_t) * maxVertices); } } return base; @@ -586,7 +587,7 @@ void RL_DeleteHash(listhash_t * hash) int i; rendlist_t *list, *next; - for(i = 0; i < RL_HASH_SIZE; i++) + for(i = 0; i < RL_HASH_SIZE; ++i) { for(list = hash[i].first; list; list = next) { @@ -598,7 +599,7 @@ void RL_DeleteHash(listhash_t * hash) RL_ClearHash(hash); } -/* +/** * All lists will be destroyed. */ void RL_DeleteLists(void) @@ -619,7 +620,7 @@ void RL_DeleteLists(void) #endif } -/* +/** * Set the R/W cursor to the beginning. */ void RL_RewindList(rendlist_t * rl) @@ -640,14 +641,14 @@ void RL_RewindHash(listhash_t * hash) int i; rendlist_t *list; - for(i = 0; i < RL_HASH_SIZE; i++) + for(i = 0; i < RL_HASH_SIZE; ++i) { for(list = hash[i].first; list; list = list->next) RL_RewindList(list); } } -/* +/** * Called before rendering a frame. */ void RL_ClearLists(void) @@ -779,7 +780,7 @@ rendlist_t *RL_GetLightListFor(DGLuint texture) return dest; } -/* +/** * Returns a pointer to the start of the allocated data. */ void *RL_AllocateData(rendlist_t *list, int bytes) @@ -881,7 +882,7 @@ void RL_QuadTexCoords(gl_texcoord_t *tc, rendpoly_t *poly, gltexture_t *tex) tc[3].st[1] = tc[0].st[1] = poly->texoffx / width; tc[0].st[0] = tc[3].st[0] + (poly->vertices[2].pos[VZ] - poly->vertices[0].pos[VZ]) / height; tc[1].st[0] = tc[3].st[0] + (poly->vertices[3].pos[VZ] - poly->vertices[1].pos[VZ]) / height; - tc[1].st[1] = tc[2].st[1] = tc[3].st[1] + poly->wall.length / width; + tc[1].st[1] = tc[2].st[1] = tc[3].st[1] + poly->wall->length / width; return; } } @@ -895,7 +896,7 @@ void RL_QuadTexCoords(gl_texcoord_t *tc, rendpoly_t *poly, gltexture_t *tex) tc[0].st[0] = tc[3].st[0] = poly->texoffx / width; tc[0].st[1] = tc[1].st[1] = poly->texoffy / height; - tc[1].st[0] = tc[2].st[0] = tc[0].st[0] + poly->wall.length / width; + tc[1].st[0] = tc[2].st[0] = tc[0].st[0] + poly->wall->length / width; tc[2].st[1] = tc[0].st[1] + (poly->vertices[2].pos[VZ] - poly->vertices[0].pos[VZ]) / height; tc[3].st[1] = tc[0].st[1] + (poly->vertices[3].pos[VZ] - poly->vertices[1].pos[VZ]) / height; } @@ -916,9 +917,9 @@ void RL_QuadShinyTexCoords(gl_texcoord_t *tc, rendpoly_t *poly, // Quad surface vector. V2_Set(surface, (poly->vertices[1].pos[VX] - poly->vertices[0].pos[VX]) / - poly->wall.length, + poly->wall->length, (poly->vertices[1].pos[VY] - poly->vertices[0].pos[VY]) / - poly->wall.length); + poly->wall->length); V2_Set(normal, surface[VY], -surface[VX]); @@ -974,7 +975,7 @@ void RL_QuadDetailTexCoords(gl_texcoord_t * tc, rendpoly_t *poly, tc[0].st[0] = tc[3].st[0] = poly->texoffx / tex->detail->width; tc[0].st[1] = tc[1].st[1] = poly->texoffy / tex->detail->height; tc[1].st[0] = tc[2].st[0] = - (tc[0].st[0] + poly->wall.length / tex->detail->width) * mul; + (tc[0].st[0] + poly->wall->length / tex->detail->width) * mul; tc[2].st[1] = (tc[0].st[1] + (poly->vertices[2].pos[VZ] - poly->vertices[0].pos[VZ]) / tex->detail->height) * mul; tc[3].st[1] = @@ -1078,7 +1079,7 @@ void RL_FlatDetailTexCoords(gl_texcoord_t * tc, float xy[2], rendpoly_t *poly, tex->detail->scale; } -/* +/** * Inter = 0 in the bottom. Only 's' is affected. */ void RL_InterpolateTexCoordS(gl_texcoord_t * tc, uint index, uint top, @@ -1090,7 +1091,7 @@ void RL_InterpolateTexCoordS(gl_texcoord_t * tc, uint index, uint top, tc[index].st[0] += (tc[top].st[0] - tc[bottom].st[0]) * inter; } -/* +/** * Inter = 0 in the bottom. Only 't' is affected. */ void RL_InterpolateTexCoordT(gl_texcoord_t * tc, uint index, uint top, @@ -1202,11 +1203,11 @@ void RL_WriteDivQuad(rendlist_t * list, rendpoly_t *poly) list->last->type = PT_DOUBLE_FAN; // A divquad is composed of two triangle fans. - list->last->primSize = 4 + poly->wall.divs[0].num + poly->wall.divs[1].num; + list->last->primSize = 4 + poly->wall->divs[0].num + poly->wall->divs[1].num; base = RL_AllocateVertices(list->last->primSize); // Allocate the indices. - RL_AllocateIndices(list, 3 + poly->wall.divs[1].num + 3 + poly->wall.divs[0].num); + RL_AllocateIndices(list, 3 + poly->wall->divs[1].num + 3 + poly->wall->divs[0].num); hdr = list->last; hdr->indices[0] = base; @@ -1258,11 +1259,13 @@ void RL_WriteDivQuad(rendlist_t * list, rendpoly_t *poly) // First vertices of each side (1=right, 0=left). sideBase[1] = base + 4; - sideBase[0] = sideBase[1] + poly->wall.divs[1].num; + sideBase[0] = sideBase[1] + poly->wall->divs[1].num; // Set the rest of the indices and init the division vertices. - for(side = 0; side < 2; side++) // Left->right is side zero. + for(side = 0; side < 2; ++side) // Left->right is side zero. { + int num; + other = !side; // The actual top/bottom corner vertex. @@ -1280,13 +1283,14 @@ void RL_WriteDivQuad(rendlist_t * list, rendpoly_t *poly) hdr->indices[index++] = base + (!side ? 1 : 3); // The division vertices. - for(i = 0; i < poly->wall.divs[other].num; i++) + num = poly->wall->divs[other].num; + for(i = 0; i < num; ++i) { // A division vertex of the other side. hdr->indices[index++] = div = sideBase[other] + i; // Division height of this vertex. - z = poly->wall.divs[other].pos[i]; + z = poly->wall->divs[other].pos[i]; // We'll init this vertex by interpolating. inter = (z - poly->vertices[side].pos[VZ]) / height[side]; @@ -1360,7 +1364,7 @@ void RL_WriteFlat(rendlist_t *list, rendpoly_t *poly) gl_texcoord_t *tc; gl_vertex_t *v; uint base; - int i; + int i, num; // A flat is composed of N triangles, where N = poly->numvertices - 2. list->last->primSize = poly->numvertices; @@ -1370,7 +1374,8 @@ void RL_WriteFlat(rendlist_t *list, rendpoly_t *poly) RL_AllocateIndices(list, poly->numvertices); // Setup indices in a triangle fan. - for(i = 0; i < poly->numvertices; i++) + num = poly->numvertices; + for(i = 0; i < num; ++i) { list->last->indices[i] = base + i; } @@ -1378,7 +1383,7 @@ void RL_WriteFlat(rendlist_t *list, rendpoly_t *poly) // Primitive-specific blending mode. list->last->blendMode = poly->blendmode; - for(i = 0, vtx = poly->vertices; i < poly->numvertices; i++, vtx++) + for(i = 0, vtx = poly->vertices; i < num; ++i, vtx++) { // Coordinates. v = &vertices[base + i]; @@ -1486,6 +1491,7 @@ void RL_EndWrite(rendlist_t * list) void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, rendpoly_t *poly) { + int num; uint i, base; gl_texcoord_t *tc; gl_color_t *col; @@ -1509,12 +1515,14 @@ void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, prim->primSize * sizeof(gl_vertex_t)); // Copy the vertex order from the original. - for(i = 0; i < prim->numIndices; i++) + num = prim->numIndices; + for(i = 0; i < num; ++i) { list->last->indices[i] = base + prim->indices[i] - prim->indices[0]; } - for(i = 0; i < prim->primSize; i++) + num = prim->primSize; + for(i = 0; i < prim->primSize; ++i) { // Each vertex uses the light's color. col = &colors[base + i]; @@ -1526,7 +1534,8 @@ void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, tc = &texCoords[TCA_MAIN][base]; if(poly->type == RP_FLAT) { - for(i = 0; i < prim->primSize; i++) + num = prim->primSize; + for(i = 0; i < num; ++i) { tc[i].st[0] = (vertices[base + i].xyz[0] + dyn->s[0]) * dyn->s[1]; tc[i].st[1] = (-vertices[base + i].xyz[2] + dyn->t[0]) * dyn->t[1]; @@ -1546,10 +1555,10 @@ void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, // First vertices of each side (1=right, 0=left). sideBase[1] = base + 4; - sideBase[0] = sideBase[1] + poly->wall.divs[1].num; + sideBase[0] = sideBase[1] + poly->wall->divs[1].num; // Set the rest of the indices and init the division vertices. - for(side = 0; side < 2; side++) // Left->right is side zero. + for(side = 0; side < 2; ++side) // Left->right is side zero. { other = !side; @@ -1558,12 +1567,13 @@ void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, bottom = base + (!side ? 2 : 3); // Number of vertices per side: 2 + numdivs - for(i = 1; i <= poly->wall.divs[other].num; i++) + num = poly->wall->divs[other].num; + for(i = 1; i <= num; ++i) { RL_InterpolateTexCoordT(texCoords[TCA_MAIN], sideBase[other] + i - 1, top, bottom, - (poly->wall.divs[other].pos[i - 1] - + (poly->wall->divs[other].pos[i - 1] - poly->vertices[side].pos[VZ]) / height[side]); } } @@ -1574,7 +1584,7 @@ void RL_WriteDynLight(rendlist_t * list, dynlight_t *dyn, primhdr_t * prim, RL_EndWrite(list); } -/* +/** * Adds the given poly onto the correct list. */ void RL_AddPoly(rendpoly_t *poly) @@ -1613,7 +1623,7 @@ void RL_AddPoly(rendpoly_t *poly) // In multiplicative mode, glowing surfaces are fullbright. // Rendering lights on them would be pointless. if(!IS_MUL || - !(poly->flags & RPF_GLOW || + !((poly->flags & RPF_GLOW) || (poly->sector && poly->sector->lightlevel >= 250))) { // Surfaces lit by dynamic lights may need to be rendered @@ -1677,14 +1687,14 @@ void RL_FloatRGB(byte *rgb, float *dest) { int i; - for(i = 0; i < 3; i++) + for(i = 0; i < 3; ++i) { dest[i] = rgb[i] / 255.0f; } dest[3] = 1; } -/* +/** * Draws the privitives that match the conditions. If no condition bits * are given, all primitives are considered eligible. */ @@ -1699,11 +1709,11 @@ void RL_DrawPrimitives(int conditions, rendlist_t * list) return; // Is blending allowed? - if(conditions & DCF_NO_BLEND && list->intertex.id) + if((conditions & DCF_NO_BLEND) && list->intertex.id) return; // Should all blended primitives be included? - if(conditions & DCF_BLEND && list->intertex.id) + if((conditions & DCF_BLEND) && list->intertex.id) { // The other conditions will be bypassed. bypass = true; @@ -1716,10 +1726,10 @@ void RL_DrawPrimitives(int conditions, rendlist_t * list) // Check for skip conditions. if(!bypass) { - if(conditions & DCF_JUST_ONE_LIGHT && hdr->light->next) + if((conditions & DCF_JUST_ONE_LIGHT) && hdr->light->next) continue; - if(conditions & DCF_MANY_LIGHTS && !hdr->light->next) + if((conditions & DCF_MANY_LIGHTS) && !hdr->light->next) continue; } @@ -1783,7 +1793,7 @@ void RL_DetailFogState(void) gl.Fogv(DGL_FOG_COLOR, midGray); } -/* +/** * Set per-list GL state. * Returns the conditions to select primitives. */ @@ -1997,7 +2007,7 @@ void RL_FinishListState(listmode_t mode, rendlist_t *list) } } -/* +/** * Setup GL state for an entire rendering pass (compassing multiple lists). */ void RL_SetupPassState(listmode_t mode) @@ -2279,7 +2289,7 @@ void RL_SetupPassState(listmode_t mode) } } -/* +/** * Renders the given lists. They must not be empty. */ void RL_RenderLists(listmode_t mode, rendlist_t ** lists, int num) @@ -2295,7 +2305,7 @@ void RL_RenderLists(listmode_t mode, rendlist_t ** lists, int num) RL_SetupPassState(mode); // Draw each given list. - for(i = 0; i < num; i++) + for(i = 0; i < num; ++i) { // Setup GL state for this list, and // draw the necessary subset of primitives on the list. @@ -2306,7 +2316,7 @@ void RL_RenderLists(listmode_t mode, rendlist_t ** lists, int num) } } -/* +/** * Extracts a selection of lists from the hash. */ uint RL_CollectLists(listhash_t * table, rendlist_t ** lists) @@ -2315,7 +2325,7 @@ uint RL_CollectLists(listhash_t * table, rendlist_t ** lists) uint i, count = 0; // Collect a list of rendering lists. - for(i = 0; i < RL_HASH_SIZE; i++) + for(i = 0; i < RL_HASH_SIZE; ++i) { for(it = table[i].first; it; it = it->next) { @@ -2354,7 +2364,7 @@ void RL_UnlockVertices(void) //gl.UnlockArrays(); } -/* +/** * We have several different paths to accommodate both multitextured * details and dynamic lights. Details take precedence (they always cover * entire primitives, and usually *all* of the surfaces in a scene). diff --git a/doomsday/engine/portable/src/rend_main.c b/doomsday/engine/portable/src/rend_main.c index ca72ed14c9..5776f1c943 100644 --- a/doomsday/engine/portable/src/rend_main.c +++ b/doomsday/engine/portable/src/rend_main.c @@ -183,6 +183,7 @@ void Rend_Register(void) Rend_ShadowRegister(); Rend_SkyRegister(); Rend_SpriteRegister(); + Rend_ConsoleRegister(); } float Rend_SignedPointDist2D(float c[2]) @@ -611,25 +612,26 @@ int Rend_PrepareTextureForPoly(rendpoly_t *poly, surface_t *surface) } } -/* +/** * Returns true if the quad has a division at the specified height. */ int Rend_CheckDiv(rendpoly_t *quad, int side, float height) { int i; + int num = quad->wall->divs[side].num; - for(i = 0; i < quad->wall.divs[side].num; ++i) - if(quad->wall.divs[side].pos[i] == height) + for(i = 0; i < num; ++i) + if(quad->wall->divs[side].pos[i] == height) return true; return false; } -/* +/** * Division will only happen if it must be done. * Converts quads to divquads. */ -void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, sector_t *frontsec, - int mode) +void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, + sector_t *frontsec, int mode) { int i, k; vertex_t *vtx[2]; // Vertexes @@ -638,7 +640,7 @@ void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, sector_t *front float hi, low; float sceil, sfloor; - switch (mode) + switch(mode) { case SEG_MIDDLE: hi = SECT_CEIL(frontsec); @@ -665,8 +667,8 @@ void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, sector_t *front vtx[0] = seg->v1; vtx[1] = seg->v2; - quad->wall.divs[0].num = 0; - quad->wall.divs[1].num = 0; + quad->wall->divs[0].num = 0; + quad->wall->divs[1].num = 0; // Check both ends. for(i = 0; i < 2; ++i) @@ -691,10 +693,10 @@ void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, sector_t *front { quad->type = RP_DIVQUAD; if(!Rend_CheckDiv(quad, i, sceil)) - quad->wall.divs[i].pos[quad->wall.divs[i].num++] = sceil; + quad->wall->divs[i].pos[quad->wall->divs[i].num++] = sceil; } // Do we need to break? - if(quad->wall.divs[i].num == RL_MAX_DIVS) + if(quad->wall->divs[i].num == RL_MAX_DIVS) break; // Divide at the sector's floor height? @@ -702,27 +704,27 @@ void Rend_WallHeightDivision(rendpoly_t *quad, const seg_t *seg, sector_t *front { quad->type = RP_DIVQUAD; if(!Rend_CheckDiv(quad, i, sfloor)) - quad->wall.divs[i].pos[quad->wall.divs[i].num++] = sfloor; + quad->wall->divs[i].pos[quad->wall->divs[i].num++] = sfloor; } // Do we need to break? - if(quad->wall.divs[i].num == RL_MAX_DIVS) + if(quad->wall->divs[i].num == RL_MAX_DIVS) break; } // We need to sort the divisions for the renderer. - if(quad->wall.divs[i].num > 1) + if(quad->wall->divs[i].num > 1) { // Sorting is required. This shouldn't take too long... // There seldom are more than one or two divisions. - qsort(quad->wall.divs[i].pos, quad->wall.divs[i].num, sizeof(float), + qsort(quad->wall->divs[i].pos, quad->wall->divs[i].num, sizeof(float), i ? DivSortDescend : DivSortAscend); } #ifdef RANGECHECK - for(k = 0; k < quad->wall.divs[i].num; ++k) - if(quad->wall.divs[i].pos[k] > hi || quad->wall.divs[i].pos[k] < low) + for(k = 0; k < quad->wall->divs[i].num; ++k) + if(quad->wall->divs[i].pos[k] > hi || quad->wall->divs[i].pos[k] < low) { Con_Error("DivQuad: i=%i, pos (%f), hi (%f), " - "low (%f), num=%i\n", i, quad->wall.divs[i].pos[k], - hi, low, quad->wall.divs[i].num); + "low (%f), num=%i\n", i, quad->wall->divs[i].pos[k], + hi, low, quad->wall->divs[i].num); } #endif } @@ -896,12 +898,15 @@ static void Rend_RenderWallSection(rendpoly_t *quad, const seg_t *seg, side_t *s if(shiny) // Render Shiny polys for this seg? { - rendpoly_t q; + rendpoly_t *q = R_AllocRendPoly(RP_QUAD, true, 4); // We're going to modify the polygon quite a bit. - memcpy(&q, quad, sizeof(rendpoly_t)); + memcpy(q, quad, sizeof(rendpoly_t)); + memcpy(q->vertices, quad->vertices, sizeof(rendpoly_vertex_t) * q->numvertices); + + Rend_AddShinyPoly(surface->texture, surface->isflat, q); - Rend_AddShinyPoly(surface->texture, surface->isflat, &q); + R_FreeRendPoly(q); } } @@ -970,7 +975,7 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) side_t *sid, *backsid, *side; line_t *ldef; float ffloor, fceil, bfloor, bceil, fsh, bsh; - rendpoly_t quad; + rendpoly_t *quad; float *vBL, *vBR, *vTL, *vTR; boolean backSide = true; boolean backsecSkyFix = false; @@ -1012,18 +1017,16 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) bfloor = bceil = bsh = 0; // Init the quad. - quad.type = RP_QUAD; - quad.flags = 0; - quad.tex.detail = NULL; - quad.intertex.detail = NULL; - quad.sector = frontsec; - quad.numvertices = 4; - quad.isWall = true; - - vBL = quad.vertices[0].pos; - vBR = quad.vertices[1].pos; - vTL = quad.vertices[2].pos; - vTR = quad.vertices[3].pos; + quad = R_AllocRendPoly(RP_QUAD, true, 4); + quad->flags = 0; + quad->tex.detail = NULL; + quad->intertex.detail = NULL; + quad->sector = frontsec; + + vBL = quad->vertices[0].pos; + vBR = quad->vertices[1].pos; + vTL = quad->vertices[2].pos; + vTR = quad->vertices[3].pos; // Get the start and end vertices, left then right. Top and bottom. vBL[VX] = vTL[VX] = FIX2FLT(seg->v1->x); @@ -1032,10 +1035,10 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) vBR[VY] = vTR[VY] = FIX2FLT(seg->v2->y); // Calculate the distances. - quad.vertices[0].dist = quad.vertices[2].dist = Rend_PointDist2D(vBL); - quad.vertices[1].dist = quad.vertices[3].dist = Rend_PointDist2D(vBR); + quad->vertices[0].dist = quad->vertices[2].dist = Rend_PointDist2D(vBL); + quad->vertices[1].dist = quad->vertices[3].dist = Rend_PointDist2D(vBR); - quad.wall.length = seg->length; + quad->wall->length = seg->length; // Top wall section color offset? if(side->top.rgba[0] < 255 || side->top.rgba[1] < 255 || side->top.rgba[2] < 255) @@ -1079,13 +1082,13 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) (bceil + backsec->skyfix[PLN_CEILING].offset < fceil + frontsec->skyfix[PLN_CEILING].offset))) { - quad.flags = RPF_SKY_MASK; + quad->flags = RPF_SKY_MASK; vTL[VZ] = vTR[VZ] = fceil + frontsec->skyfix[PLN_CEILING].offset; vBL[VZ] = vBR[VZ] = fceil; - quad.tex.id = 0; - quad.lights = NULL; - quad.intertex.id = 0; - RL_AddPoly(&quad); + quad->tex.id = 0; + quad->lights = NULL; + quad->intertex.id = 0; + RL_AddPoly(quad); } } // Floor skyfix @@ -1097,13 +1100,13 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) (bfloor + backsec->skyfix[PLN_FLOOR].offset > ffloor + frontsec->skyfix[PLN_FLOOR].offset))) { - quad.flags = RPF_SKY_MASK; + quad->flags = RPF_SKY_MASK; vTL[VZ] = vTR[VZ] = ffloor; vBL[VZ] = vBR[VZ] = ffloor + frontsec->skyfix[PLN_FLOOR].offset; - quad.tex.id = 0; - quad.lights = NULL; - quad.intertex.id = 0; - RL_AddPoly(&quad); + quad->tex.id = 0; + quad->lights = NULL; + quad->intertex.id = 0; + RL_AddPoly(quad); } } @@ -1116,15 +1119,15 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) { if(backsec->skyfix[PLN_FLOOR].offset < 0) { - quad.flags = RPF_SKY_MASK; - quad.tex.id = 0; - quad.lights = NULL; - quad.intertex.id = 0; + quad->flags = RPF_SKY_MASK; + quad->tex.id = 0; + quad->lights = NULL; + quad->intertex.id = 0; vTL[VZ] = vTR[VZ] = bfloor; vBL[VZ] = vBR[VZ] = bfloor + backsec->skyfix[PLN_FLOOR].offset; - RL_AddPoly(&quad); + RL_AddPoly(quad); } backsecSkyFix = true; // ensure we add a solid view seg. @@ -1136,15 +1139,15 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) { if(backsec->skyfix[PLN_CEILING].offset > 0) { - quad.flags = RPF_SKY_MASK; - quad.tex.id = 0; - quad.lights = NULL; - quad.intertex.id = 0; + quad->flags = RPF_SKY_MASK; + quad->tex.id = 0; + quad->lights = NULL; + quad->intertex.id = 0; vTL[VZ] = vTR[VZ] = bceil + backsec->skyfix[PLN_CEILING].offset; vBL[VZ] = vBR[VZ] = bceil; - RL_AddPoly(&quad); + RL_AddPoly(quad); } backsecSkyFix = true; // ensure we add a solid view seg. @@ -1160,22 +1163,22 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) if(Rend_IsWallSectionPVisible(seg->linedef, SEG_MIDDLE, backSide)) { surface = &side->middle; - surfaceFlags = Rend_PrepareTextureForPoly(&quad, surface); + surfaceFlags = Rend_PrepareTextureForPoly(quad, surface); // Is there a visible surface? if(surfaceFlags != -1) { // Fill in the remaining quad data. - quad.flags = 0; + quad->flags = 0; vTL[VZ] = vTR[VZ] = fceil; vBL[VZ] = vBR[VZ] = ffloor; - quad.texoffx = side->middle.offx + FIX2FLT(seg->offset); - quad.texoffy = side->middle.offy; + quad->texoffx = side->middle.offx + FIX2FLT(seg->offset); + quad->texoffy = side->middle.offy; if(ldef->flags & ML_DONTPEGBOTTOM) - quad.texoffy += texh - fsh; + quad->texoffy += texh - fsh; - Rend_RenderWallSection(&quad, seg, side, frontsec, surface, SEG_MIDDLE, + Rend_RenderWallSection(quad, seg, side, frontsec, surface, SEG_MIDDLE, /*Alpha*/ 255, /*Shadow?*/ !(flags & RWSF_NO_RADIO), /*Shiny?*/ (surface->texture != -1), @@ -1186,15 +1189,15 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) if(R_IsSkySurface(&frontsec->SP_ceilsurface) && R_IsSkySurface(&frontsec->SP_floorsurface)) { // We'll mask this. - quad.flags = RPF_SKY_MASK; - quad.tex.id = 0; - quad.lights = NULL; - quad.intertex.id = 0; + quad->flags = RPF_SKY_MASK; + quad->tex.id = 0; + quad->lights = NULL; + quad->intertex.id = 0; vTL[VZ] = vTR[VZ] = fceil; vBL[VZ] = vBR[VZ] = ffloor; - RL_AddPoly(&quad); + RL_AddPoly(quad); } } @@ -1221,7 +1224,7 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) byte alpha = side->middle.rgba[3]; surface = &side->middle; - surfaceFlags = Rend_PrepareTextureForPoly(&quad, surface); + surfaceFlags = Rend_PrepareTextureForPoly(quad, surface); // Is there a visible surface? if(surfaceFlags != -1) @@ -1230,11 +1233,11 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) vTL[VZ] = vTR[VZ] = gaptop = MIN_OF(rbceil, rfceil); vBL[VZ] = vBR[VZ] = gapbottom = MAX_OF(rbfloor, rffloor); - quad.texoffx = side->middle.offx + FIX2FLT(seg->offset); + quad->texoffx = side->middle.offx + FIX2FLT(seg->offset); if(Rend_MidTexturePos (&vBL[VZ], &vBR[VZ], &vTL[VZ], &vTR[VZ], - &quad.texoffy, side->middle.offy, + &quad->texoffy, side->middle.offy, 0 != (ldef->flags & ML_DONTPEGBOTTOM))) { // Should a solid segment be added here? @@ -1291,17 +1294,17 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) // Blendmode if(sid->blendmode == BM_NORMAL && noSpriteTrans) - quad.blendmode = BM_ZEROALPHA; // "no translucency" mode + quad->blendmode = BM_ZEROALPHA; // "no translucency" mode else - quad.blendmode = sid->blendmode; + quad->blendmode = sid->blendmode; // If alpha, masked or blended we must render as a vissprite if(alpha < 255 || texmask || side->blendmode > 0) - quad.flags = RPF_MASKED; + quad->flags = RPF_MASKED; else - quad.flags = 0; + quad->flags = 0; - Rend_RenderWallSection(&quad, seg, side, frontsec, surface, SEG_MIDDLE, + Rend_RenderWallSection(quad, seg, side, frontsec, surface, SEG_MIDDLE, /*Alpha*/ alpha, /*Shadow?*/ (solidSeg && !(flags & RWSF_NO_RADIO) && !texmask), /*Shiny?*/ (solidSeg && surface->texture != -1 && !texmask), @@ -1311,13 +1314,13 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) } // Restore original type, height division may change this. - quad.type = RP_QUAD; + quad->type = RP_QUAD; // Upper wall. if(Rend_IsWallSectionPVisible(seg->linedef, SEG_TOP, backSide)) { surface = &side->top; - surfaceFlags = Rend_PrepareTextureForPoly(&quad, surface); + surfaceFlags = Rend_PrepareTextureForPoly(quad, surface); // Is there a visible surface? if(surfaceFlags != -1) @@ -1327,10 +1330,10 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) float tcyoff; // Calculate texture coordinates. - quad.texoffx = side->top.offx + FIX2FLT(seg->offset); + quad->texoffx = side->top.offx + FIX2FLT(seg->offset); tcyoff = side->middle.offy; - quad.flags = 0; + quad->flags = 0; /* if(side->flags & SDF_MIDTEXUPPER) { @@ -1345,22 +1348,22 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) vTL[VZ] = vTR[VZ] = relOffset; vBL[VZ] = vBR[VZ] = relOffset - texh; - quad.texoffy = 0; + quad->texoffy = 0; // We allow all properties normally associated with // middle textures on mid texture uppers. // Blendmode if(sid->blendmode == BM_NORMAL && noSpriteTrans) - quad.blendmode = BM_ZEROALPHA; // "no translucency" mode + quad->blendmode = BM_ZEROALPHA; // "no translucency" mode else - quad.blendmode = sid->blendmode; + quad->blendmode = sid->blendmode; alpha = side->middle.rgba[3]; // If alpha, masked or blended we must render as a vissprite if(alpha < 255 || texmask || side->blendmode > 0) - quad.flags = RPF_MASKED; + quad->flags = RPF_MASKED; } else isVisible = false; @@ -1370,9 +1373,9 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) vTL[VZ] = vTR[VZ] = fceil; vBL[VZ] = vBR[VZ] = bceil; - quad.texoffy = tcyoff; + quad->texoffy = tcyoff; if(!(ldef->flags & ML_DONTPEGTOP)) // Normal alignment to bottom. - quad.texoffy += texh - (fceil - bceil); + quad->texoffy += texh - (fceil - bceil); alpha = 255; } @@ -1384,7 +1387,7 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) } if(isVisible) - Rend_RenderWallSection(&quad, seg, side, frontsec, surface, SEG_TOP, + Rend_RenderWallSection(quad, seg, side, frontsec, surface, SEG_TOP, /*Alpha*/ alpha, /*Shadow?*/ !(flags & RWSF_NO_RADIO), /*Shiny?*/ (surface->texture != -1), @@ -1393,34 +1396,34 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) } // Restore original type, height division may change this. - quad.type = RP_QUAD; + quad->type = RP_QUAD; // Lower wall. if(Rend_IsWallSectionPVisible(seg->linedef, SEG_BOTTOM, backSide)) { surface = &side->bottom; - surfaceFlags = Rend_PrepareTextureForPoly(&quad, surface); + surfaceFlags = Rend_PrepareTextureForPoly(quad, surface); // Is there a visible surface? if(surfaceFlags != -1) { // Calculate texture coordinates. - quad.texoffx = side->bottom.offx + FIX2FLT(seg->offset); - quad.texoffy = side->bottom.offy; + quad->texoffx = side->bottom.offx + FIX2FLT(seg->offset); + quad->texoffy = side->bottom.offy; if(ldef->flags & ML_DONTPEGBOTTOM) - quad.texoffy += fceil - bfloor; // Align with normal middle texture. + quad->texoffy += fceil - bfloor; // Align with normal middle texture. - quad.flags = 0; + quad->flags = 0; vTL[VZ] = vTR[VZ] = bfloor; vBL[VZ] = vBR[VZ] = ffloor; if(vTL[VZ] > fceil) { // Can't go over front ceiling, would induce polygon flaws. - quad.texoffy += vTL[VZ] - fceil; + quad->texoffy += vTL[VZ] - fceil; vTL[VZ] = vTR[VZ] = fceil; } - Rend_RenderWallSection(&quad, seg, side, frontsec, surface, SEG_BOTTOM, + Rend_RenderWallSection(quad, seg, side, frontsec, surface, SEG_BOTTOM, /*Alpha*/ 255, /*Shadow?*/ !(flags & RWSF_NO_RADIO), /*Shiny?*/ (surface->texture != -1), @@ -1431,7 +1434,10 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) // Can we make this a solid segment in the clipper? if(solidSeg == -1) + { + R_FreeRendPoly(quad); return; // NEVER (we have a hole we couldn't fix). + } if(solidSeg) { @@ -1465,6 +1471,8 @@ void Rend_RenderWallSeg(const seg_t *seg, sector_t *frontsec, int flags) if(solidSeg) C_AddViewRelSeg(vBL[VX], vBL[VY], vBR[VX], vBR[VY]); } + + R_FreeRendPoly(quad); } int Rend_SectorLight(sector_t *sec) @@ -1559,17 +1567,18 @@ void Rend_OccludeSubsector(subsector_t *sub, boolean forward_facing) void Rend_RenderPlane(subplaneinfo_t *plane, subsector_t *subsector) { - rendpoly_t poly; - sector_t *sector = subsector->sector, *link = NULL; - int surfaceFlags; - float height; - surface_t *surface; + sector_t *sector = subsector->sector, *link = NULL; + int surfaceFlags; + float height; + surface_t *surface; planeinfo_t *pinfo = subsector->sector->planes[plane->type]->info; + int flags; + sector_t *polySector; // Determine the height of the plane. if(pinfo->linked) { - poly.sector = link = + polySector = link = R_GetLinkedSector(pinfo->linked, plane->type); height = SECT_PLANE_HEIGHT(link, plane->type); @@ -1580,7 +1589,7 @@ void Rend_RenderPlane(subplaneinfo_t *plane, subsector_t *subsector) } else { - poly.sector = sector; + polySector = sector; height = pinfo->visheight; // Add the skyfix height += sector->skyfix[plane->type].offset; @@ -1593,39 +1602,43 @@ void Rend_RenderPlane(subplaneinfo_t *plane, subsector_t *subsector) if(sector->info->unclosed && R_IsSkySurface(surface)) return; - poly.flags = 0; + flags = 0; // The sky? if(R_IsSkySurface(surface)) - poly.flags |= RPF_SKY_MASK; + flags |= RPF_SKY_MASK; // Is the plane visible? if((plane->type == PLN_FLOOR && vy > height) || (plane->type == PLN_CEILING && vy < height)) { - surfaceFlags = - Rend_PrepareTextureForPoly(&poly, surface); + rendpoly_t *poly = + R_AllocRendPoly(RP_FLAT, false, subsector->numverts); + + surfaceFlags = Rend_PrepareTextureForPoly(poly, surface); // Is there a visible surface? if(surfaceFlags != -1) { // Fill in the remaining quad data. - poly.type = RP_FLAT; // We're creating a flat. - poly.isWall = false; + poly->flags = flags; + poly->sector = polySector; // Check for sky. if(!R_IsSkySurface(surface)) { - poly.texoffx = sector->planes[plane->type]->surface.offx; - poly.texoffy = sector->planes[plane->type]->surface.offy; + poly->texoffx = sector->planes[plane->type]->surface.offx; + poly->texoffy = sector->planes[plane->type]->surface.offy; } - Rend_DoRenderPlane(&poly, subsector, plane, surface, height, + Rend_DoRenderPlane(poly, subsector, plane, surface, height, /*Alpha*/ 255, /*Shadow?*/ false, // unused /*Shiny?*/ (surface->texture != -1), /*Glow?*/ (surfaceFlags & SUF_GLOW)); } + + R_FreeRendPoly(poly); } } @@ -1793,7 +1806,6 @@ void Rend_RenderMap(void) // We don't want subsector clipchecking for the first subsector. firstsubsector = true; - Rend_RenderNode(numnodes - 1); // Make vissprites of all the visible decorations. diff --git a/doomsday/engine/portable/src/rend_model.c b/doomsday/engine/portable/src/rend_model.c index 0b2b83caea..c604b2f1b6 100644 --- a/doomsday/engine/portable/src/rend_model.c +++ b/doomsday/engine/portable/src/rend_model.c @@ -1011,7 +1011,7 @@ void Mod_GlowLightSetup(mlight_t * light) void Rend_RenderModel(vissprite_t * spr) { modeldef_t *mf = spr->data.mo.mf; - rendpoly_t quad; + rendpoly_t *quad; int i; int lightLevel = spr->data.mo.lightlevel; float dist; @@ -1023,16 +1023,17 @@ void Rend_RenderModel(vissprite_t * spr) numLights = 0; // This way the distance darkening has an effect. - quad.vertices[0].dist = Rend_PointDist2D(spr->data.mo.v1); - quad.numvertices = 1; - quad.isWall = false; + quad = R_AllocRendPoly(RP_NONE, false, 1); + quad->vertices[0].dist = Rend_PointDist2D(spr->data.mo.v1); Rend_ApplyLightAdaptation(&lightLevel); - RL_VertexColors(&quad, lightLevel, spr->data.mo.rgb); + RL_VertexColors(quad, lightLevel, spr->data.mo.rgb); // Determine the ambient light affecting the model. for(i = 0; i < 3; ++i) - ambientColor[i] = quad.vertices[0].color.rgba[i] / 255.0f; + ambientColor[i] = quad->vertices[0].color.rgba[i] / 255.0f; + + R_FreeRendPoly(quad); if(modelLight) { diff --git a/doomsday/engine/portable/src/rend_shadow.c b/doomsday/engine/portable/src/rend_shadow.c index 50f8584089..b42d4159b6 100644 --- a/doomsday/engine/portable/src/rend_shadow.c +++ b/doomsday/engine/portable/src/rend_shadow.c @@ -93,7 +93,7 @@ static void Rend_ProcessThingShadow(mobj_t *mo) float height, moh, halfmoh, color, pos[2], floor; sector_t *sec = mo->subsector->sector; int radius, i; - rendpoly_t poly; + rendpoly_t *poly; float distance; // Is this too far? @@ -165,37 +165,36 @@ static void Rend_ProcessThingShadow(mobj_t *mo) return; // Prepare the poly. - memset(&poly, 0, sizeof(poly)); - poly.type = RP_FLAT; - poly.flags = RPF_SHADOW; - poly.isWall = false; - poly.tex.id = GL_PrepareLSTexture(LST_DYNAMIC); - poly.tex.width = poly.tex.height = radius * 2; - poly.texoffx = -pos[VX] + radius; - poly.texoffy = -pos[VY] - radius; + poly = R_AllocRendPoly(RP_FLAT, false, 4); + poly->flags = RPF_SHADOW; + poly->tex.id = GL_PrepareLSTexture(LST_DYNAMIC); + poly->tex.width = poly->tex.height = radius * 2; + poly->texoffx = -pos[VX] + radius; + poly->texoffy = -pos[VY] - radius; floor += 0.2f; // A bit above the floor. - poly.numvertices = 4; - poly.vertices[0].pos[VX] = pos[VX] - radius; - poly.vertices[0].pos[VY] = pos[VY] + radius; - poly.vertices[0].pos[VZ] = floor; - poly.vertices[1].pos[VX] = pos[VX] + radius; - poly.vertices[1].pos[VY] = pos[VY] + radius; - poly.vertices[1].pos[VZ] = floor; - poly.vertices[2].pos[VX] = pos[VX] + radius; - poly.vertices[2].pos[VY] = pos[VY] - radius; - poly.vertices[2].pos[VZ] = floor; - poly.vertices[3].pos[VX] = pos[VX] - radius; - poly.vertices[3].pos[VY] = pos[VY] - radius; - poly.vertices[3].pos[VZ] = floor; - for(i = 0; i < 4; i++) + poly->vertices[0].pos[VX] = pos[VX] - radius; + poly->vertices[0].pos[VY] = pos[VY] + radius; + poly->vertices[0].pos[VZ] = floor; + poly->vertices[1].pos[VX] = pos[VX] + radius; + poly->vertices[1].pos[VY] = pos[VY] + radius; + poly->vertices[1].pos[VZ] = floor; + poly->vertices[2].pos[VX] = pos[VX] + radius; + poly->vertices[2].pos[VY] = pos[VY] - radius; + poly->vertices[2].pos[VZ] = floor; + poly->vertices[3].pos[VX] = pos[VX] - radius; + poly->vertices[3].pos[VY] = pos[VY] - radius; + poly->vertices[3].pos[VZ] = floor; + + for(i = 0; i < 4; ++i) { // Shadows are black. - memset(poly.vertices[i].color.rgba, 0, 3); - poly.vertices[i].color.rgba[3] = color * 255; + memset(poly->vertices[i].color.rgba, 0, 3); + poly->vertices[i].color.rgba[3] = color * 255; } - RL_AddPoly(&poly); + RL_AddPoly(poly); + R_FreeRendPoly(poly); } void Rend_RenderShadows(void) diff --git a/doomsday/engine/portable/src/rend_sprite.c b/doomsday/engine/portable/src/rend_sprite.c index dbc065d14f..270dae703f 100644 --- a/doomsday/engine/portable/src/rend_sprite.c +++ b/doomsday/engine/portable/src/rend_sprite.c @@ -272,7 +272,7 @@ void Rend_DrawPlayerSprites(void) float offScaleY = weaponOffsetScaleY / 1000.0f; byte somethingVisible = false; byte isFullBright = (levelFullBright != 0); - rendpoly_t tempquad; + rendpoly_t *tempquad = NULL; // Cameramen have no psprites. if((viewplayer->flags & DDPF_CAMERA) || (viewplayer->flags & DDPF_CHASECAM)) @@ -339,9 +339,8 @@ void Rend_DrawPlayerSprites(void) LG_Evaluate(point, secbRGB); } - tempquad.numvertices = 1; - tempquad.vertices[0].dist = 1; - tempquad.isWall = false; + tempquad = R_AllocRendPoly(RP_NONE, false, 2); + tempquad->vertices[0].dist = tempquad->vertices[1].dist = 1; // Draw as separate sprites. for(i = 0; i < DDMAXPSPRITES; ++i) @@ -379,22 +378,23 @@ void Rend_DrawPlayerSprites(void) } rgba[CA] = psp[i].alpha * 255.0f; - RL_VertexColors(&tempquad, light, rgba); + RL_VertexColors(tempquad, light, rgba); // Add extra light using dynamic lights. if(litSprites) - Rend_DoLightSprite(vispsprites +i, &tempquad); + Rend_DoLightSprite(vispsprites +i, tempquad); - tempquad.vertices[0].color.rgba[CA] = - tempquad.vertices[1].color.rgba[CA] = rgba[CA]; + tempquad->vertices[0].color.rgba[CA] = + tempquad->vertices[1].color.rgba[CA] = rgba[CA]; Rend_DrawPSprite(psp[i].x - info[i].offset + offx, offScaleY * psp[i].y + (1 - offScaleY) * 32 - info[i].topOffset + offy, - &tempquad.vertices[0].color.rgba[0], - &tempquad.vertices[1].color.rgba[0], + &tempquad->vertices[0].color.rgba[0], + &tempquad->vertices[1].color.rgba[0], 1, info[i].flip, info[i].lump); } + R_FreeRendPoly(tempquad); } } @@ -782,7 +782,7 @@ void Rend_RenderSprite(vissprite_t *spr) DGLubyte alpha; boolean additiveBlending = false, flip, restoreMatrix = false; boolean usingSRVO = false, restoreZ = false; - rendpoly_t tempquad; + rendpoly_t *tempquad = NULL; if(!renderTextures) { @@ -842,19 +842,20 @@ void Rend_RenderSprite(vissprite_t *spr) v1[VX] = Q_FIX2FLT(spr->data.mo.gx); v1[VY] = Q_FIX2FLT(spr->data.mo.gy); - tempquad.vertices[0].dist = Rend_PointDist2D(v1); - tempquad.numvertices = 1; - tempquad.isWall = false; - RL_VertexColors(&tempquad, lightLevel, spr->data.mo.rgb); + tempquad = R_AllocRendPoly(RP_NONE, false, 2); + tempquad->vertices[0].dist = + tempquad->vertices[1].dist = Rend_PointDist2D(v1); + + RL_VertexColors(tempquad, lightLevel, spr->data.mo.rgb); // Add extra light using dynamic lights. if(litSprites) - Rend_DoLightSprite(spr, &tempquad); + Rend_DoLightSprite(spr, tempquad); - tempquad.vertices[0].color.rgba[CA] = - tempquad.vertices[1].color.rgba[CA] = alpha; - gl.Color4ubv(tempquad.vertices[0].color.rgba); + tempquad->vertices[0].color.rgba[CA] = + tempquad->vertices[1].color.rgba[CA] = alpha; + gl.Color4ubv(tempquad->vertices[0].color.rgba); } // We must find the correct positioning using the sector floor and ceiling @@ -972,7 +973,7 @@ void Rend_RenderSprite(vissprite_t *spr) Rend_SpriteTexCoord (patch, flip, 0); gl.Vertex3f(spr->data.mo.v1[VX], top, spr->data.mo.v1[VY]); - gl.Color4ubv(tempquad.vertices[1].color.rgba); + gl.Color4ubv(tempquad->vertices[1].color.rgba); Rend_SpriteTexCoord (patch, !flip, 0); gl.Vertex3f(spr->data.mo.v2[VX], top, spr->data.mo.v2[VY]); @@ -1001,9 +1002,9 @@ void Rend_RenderSprite(vissprite_t *spr) // Draw a "test mirroring". gl.Begin(DGL_QUADS); - gl.Color4ub(tempquad.vertices[0].color.rgba[0], - tempquad.vertices[0].color.rgba[1], - tempquad.vertices[0].color.rgba[2], + gl.Color4ub(tempquad->vertices[0].color.rgba[0], + tempquad->vertices[0].color.rgba[1], + tempquad->vertices[0].color.rgba[2], alpha/3); gl.TexCoord2f(flip, 0); gl.Vertex3f(spr->data.mo.v1[VX], 2*spr->data.mo.secfloor - top, spr->data.mo.v1[VY]); @@ -1038,4 +1039,6 @@ void Rend_RenderSprite(vissprite_t *spr) // Enable Z-writing again. gl.Enable(DGL_DEPTH_WRITE); } + if(tempquad) + R_FreeRendPoly(tempquad); }