diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt index 9ae96fb97..a149f67b7 100644 --- a/src/hardware/CMakeLists.txt +++ b/src/hardware/CMakeLists.txt @@ -13,6 +13,7 @@ target_sources(BLANKART PRIVATE hw_model.c u_list.c hw_batching.c + hw_drawnodes.c hw_plane.c hw_segs.c hw_shaders.c diff --git a/src/hardware/hw_drawnodes.c b/src/hardware/hw_drawnodes.c new file mode 100644 index 000000000..dca49c1e1 --- /dev/null +++ b/src/hardware/hw_drawnodes.c @@ -0,0 +1,344 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2022 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file hw_drawnodes.c +/// \brief Sorting and rendering translucent surfaces with gl drawnodes + +#ifdef HWRENDER +#include "hw_glob.h" +#include "hw_gpu.h" +#include "../i_system.h" +#include "../r_local.h" +#include "../qs22j.h" +#include "../z_zone.h" + +#define ABS(x) ((x) < 0 ? -(x) : (x)) + +// A drawnode is something that points to a 3D floor, 3D side, or masked +// middle texture. This is used for sorting with sprites. +typedef struct +{ + FOutVector wallVerts[4]; + FSurfaceInfo Surf; + INT32 texnum; + FBITFIELD blend; + INT32 drawcount; + boolean fogwall; + boolean noencore; + INT32 lightlevel; + extracolormap_t *wallcolormap; // Doing the lighting in HWR_RenderWall now for correct fog after sorting +} wallinfo_t; + +static wallinfo_t *wallinfo = NULL; +size_t numwalls = 0; // a list of transparent walls to be drawn + +#define MAX_TRANSPARENTWALL 256 + +typedef struct +{ + extrasubsector_t *xsub; + boolean isceiling; + fixed_t fixedheight; + INT32 lightlevel; + levelflat_t *levelflat; + INT32 alpha; + sector_t *FOFSector; + FBITFIELD blend; + boolean fogplane; + extracolormap_t *planecolormap; + INT32 drawcount; +} planeinfo_t; + +size_t numplanes = 0; // a list of transparent floors to be drawn +static planeinfo_t *planeinfo = NULL; + +typedef struct +{ + polyobj_t *polysector; + boolean isceiling; + fixed_t fixedheight; + INT32 lightlevel; + levelflat_t *levelflat; + INT32 alpha; + sector_t *FOFSector; + FBITFIELD blend; + extracolormap_t *planecolormap; + INT32 drawcount; +} polyplaneinfo_t; + +size_t numpolyplanes = 0; // a list of transparent poyobject floors to be drawn +static polyplaneinfo_t *polyplaneinfo = NULL; + +//Hurdler: 3D water sutffs +typedef struct gl_drawnode_s +{ + planeinfo_t *plane; + polyplaneinfo_t *polyplane; + wallinfo_t *wall; + gl_vissprite_t *sprite; + +// struct gl_drawnode_s *next; +// struct gl_drawnode_s *prev; +} gl_drawnode_t; + +INT32 drawcount = 0; + +void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) +{ + static size_t allocedwalls = 0; + + // Force realloc if buffer has been freed + if (!wallinfo) + allocedwalls = 0; + + if (allocedwalls < numwalls + 1) + { + allocedwalls += MAX_TRANSPARENTWALL; + Z_Realloc(wallinfo, allocedwalls * sizeof (*wallinfo), PU_LEVEL, &wallinfo); + } + + memcpy(wallinfo[numwalls].wallVerts, wallVerts, sizeof (wallinfo[numwalls].wallVerts)); + memcpy(&wallinfo[numwalls].Surf, pSurf, sizeof (FSurfaceInfo)); + wallinfo[numwalls].texnum = texnum; + wallinfo[numwalls].blend = blend; + wallinfo[numwalls].noencore = noencore; + wallinfo[numwalls].drawcount = drawcount++; + wallinfo[numwalls].fogwall = fogwall; + wallinfo[numwalls].lightlevel = lightlevel; + wallinfo[numwalls].wallcolormap = wallcolormap; + numwalls++; +} + +#define MAX_TRANSPARENTFLOOR 512 + +// This will likely turn into a copy of HWR_Add3DWater and replace it. +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) +{ + static size_t allocedplanes = 0; + + // Force realloc if buffer has been freed + if (!planeinfo) + allocedplanes = 0; + + if (allocedplanes < numplanes + 1) + { + allocedplanes += MAX_TRANSPARENTFLOOR; + Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo); + } + + planeinfo[numplanes].isceiling = isceiling; + planeinfo[numplanes].fixedheight = fixedheight; + planeinfo[numplanes].lightlevel = ((planecolormap && (planecolormap->flags & CMF_FOG)) || mapnamespace == MNS_SRB2KART) ? lightlevel : 255; + planeinfo[numplanes].levelflat = levelflat; + planeinfo[numplanes].xsub = xsub; + planeinfo[numplanes].alpha = alpha; + planeinfo[numplanes].FOFSector = FOFSector; + planeinfo[numplanes].blend = blend; + planeinfo[numplanes].fogplane = fogplane; + planeinfo[numplanes].planecolormap = planecolormap; + planeinfo[numplanes].drawcount = drawcount++; + + numplanes++; +} + +// Adding this for now until I can create extrasubsector info for polyobjects +// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane +void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) +{ + static size_t allocedpolyplanes = 0; + + // Force realloc if buffer has been freed + if (!polyplaneinfo) + allocedpolyplanes = 0; + + if (allocedpolyplanes < numpolyplanes + 1) + { + allocedpolyplanes += MAX_TRANSPARENTFLOOR; + Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo); + } + + polyplaneinfo[numpolyplanes].isceiling = isceiling; + polyplaneinfo[numpolyplanes].fixedheight = fixedheight; + polyplaneinfo[numpolyplanes].lightlevel = ((planecolormap && (planecolormap->flags & CMF_FOG)) || mapnamespace == MNS_SRB2KART) ? lightlevel : 255; + polyplaneinfo[numpolyplanes].levelflat = levelflat; + polyplaneinfo[numpolyplanes].polysector = polysector; + polyplaneinfo[numpolyplanes].alpha = alpha; + polyplaneinfo[numpolyplanes].FOFSector = FOFSector; + polyplaneinfo[numpolyplanes].blend = blend; + polyplaneinfo[numpolyplanes].planecolormap = planecolormap; + polyplaneinfo[numpolyplanes].drawcount = drawcount++; + numpolyplanes++; +} + +// putting sortindex and sortnode here so the comparator function can see them +gl_drawnode_t *sortnode; +size_t *sortindex; + +static int CompareDrawNodes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + INT32 v1 = 0; + INT32 v2 = 0; + INT32 diff; + if (sortnode[n1].plane) + v1 = sortnode[n1].plane->drawcount; + else if (sortnode[n1].polyplane) + v1 = sortnode[n1].polyplane->drawcount; + else if (sortnode[n1].wall) + v1 = sortnode[n1].wall->drawcount; + else I_Error("CompareDrawNodes: n1 unknown"); + + if (sortnode[n2].plane) + v2 = sortnode[n2].plane->drawcount; + else if (sortnode[n2].polyplane) + v2 = sortnode[n2].polyplane->drawcount; + else if (sortnode[n2].wall) + v2 = sortnode[n2].wall->drawcount; + else I_Error("CompareDrawNodes: n2 unknown"); + + diff = v2 - v1; + if (diff == 0) I_Error("CompareDrawNodes: diff is zero"); + return diff; +} + +static int CompareDrawNodePlanes(const void *p1, const void *p2) +{ + size_t n1 = *(const size_t*)p1; + size_t n2 = *(const size_t*)p2; + if (!sortnode[n1].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n1)"); + if (!sortnode[n2].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n2)"); + return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); +} + +// +// HWR_CreateDrawNodes +// Creates and sorts a list of drawnodes for the scene being rendered. +void HWR_CreateDrawNodes(void) +{ + UINT32 i = 0, p = 0; + size_t run_start = 0; + + // Dump EVERYTHING into a huge drawnode list. Then we'll sort it! + // Could this be optimized into _AddTransparentWall/_AddTransparentPlane? + // Hell yes! But sort algorithm must be modified to use a linked list. + sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) + + (sizeof(polyplaneinfo_t)*numpolyplanes) + + (sizeof(wallinfo_t)*numwalls) + ,PU_STATIC, NULL); + // todo: + // However, in reality we shouldn't be re-copying and shifting all this information + // that is already lying around. This should all be in some sort of linked list or lists. + sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); + + ps_hw_nodesorttime = I_GetPreciseTime(); + + for (i = 0; i < numplanes; i++, p++) + { + sortnode[p].plane = &planeinfo[i]; + sortindex[p] = p; + } + + for (i = 0; i < numpolyplanes; i++, p++) + { + sortnode[p].polyplane = &polyplaneinfo[i]; + sortindex[p] = p; + } + + for (i = 0; i < numwalls; i++, p++) + { + sortnode[p].wall = &wallinfo[i]; + sortindex[p] = p; + } + + ps_numdrawnodes = p; + + // p is the number of stuff to sort + + // sort the list based on the value of the 'drawcount' member of the drawnodes. + qs22j(sortindex, p, sizeof(size_t), CompareDrawNodes); + + // an additional pass is needed to correct the order of consecutive planes in the list. + // for each consecutive run of planes in the list, sort that run based on plane height and view height. + while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count + { + // locate run start + if (sortnode[sortindex[run_start]].plane) + { + // found it, now look for run end + size_t run_end;// (inclusive) + for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though.. + { + if (!sortnode[sortindex[i]].plane) break; + } + run_end = i-1; + if (run_end > run_start)// if there are multiple consecutive planes, not just one + { + // consecutive run of planes found, now sort it + qs22j(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes); + } + run_start = run_end + 1;// continue looking for runs coming right after this one + } + else + { + // this wasnt the run start, try next one + run_start++; + } + } + + ps_hw_nodesorttime = I_GetPreciseTime() - ps_hw_nodesorttime; + + ps_hw_nodedrawtime = I_GetPreciseTime(); + + // Okay! Let's draw it all! Woo! + GL_SetTransform(&atransform); + + for (i = 0; i < p; i++) + { + if (sortnode[sortindex[i]].plane) + { + // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. + gl_frontsector = NULL; + + if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) + HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, R_NoEncore(sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->isceiling)); + HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, + sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); + } + else if (sortnode[sortindex[i]].polyplane) + { + // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. + gl_frontsector = NULL; + + if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) + HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, R_NoEncore(sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->isceiling)); + HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, + sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); + } + else if (sortnode[sortindex[i]].wall) + { + if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture)) + HWR_GetTexture(sortnode[sortindex[i]].wall->texnum, sortnode[sortindex[i]].wall->noencore); + HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall, + sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); + } + } + + ps_hw_nodedrawtime = I_GetPreciseTime() - ps_hw_nodedrawtime; + + numwalls = 0; + numplanes = 0; + numpolyplanes = 0; + + // No mem leaks, please. + Z_Free(sortnode); + Z_Free(sortindex); +} + +#endif diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 01c1dc8db..9b4fb5a58 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -175,6 +175,20 @@ void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, boolean isc void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, levelflat_t *levelflat, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap); + +// -------- +// hw_drawnodes.c +// -------- +void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); +void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); +void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, + INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); +void HWR_CreateDrawNodes(void); +extern INT32 drawcount; +extern size_t numplanes; +extern size_t numwalls; +extern size_t numpolyplanes; + // -------- // hw_segs.c // -------- diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ad86ae9b7..53b87a605 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -57,16 +57,6 @@ // the hardware driver object // ========================================================================== -// ========================================================================== -// PROTOS -// ========================================================================== - -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); -void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, - INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); - -#define ABS(x) ((x) < 0 ? -(x) : (x)) - // ========================================================================== // GLOBALS // ========================================================================== @@ -1222,284 +1212,6 @@ static void HWR_RenderBSPNode(INT32 bspnum) HWR_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } -wallinfo_t *wallinfo = NULL; -size_t numwalls = 0; // a list of transparent walls to be drawn - -typedef struct -{ - extrasubsector_t *xsub; - boolean isceiling; - fixed_t fixedheight; - INT32 lightlevel; - levelflat_t *levelflat; - INT32 alpha; - sector_t *FOFSector; - FBITFIELD blend; - boolean fogplane; - extracolormap_t *planecolormap; - INT32 drawcount; -} planeinfo_t; - -static size_t numplanes = 0; // a list of transparent floors to be drawn -static planeinfo_t *planeinfo = NULL; - -typedef struct -{ - polyobj_t *polysector; - boolean isceiling; - fixed_t fixedheight; - INT32 lightlevel; - levelflat_t *levelflat; - INT32 alpha; - sector_t *FOFSector; - FBITFIELD blend; - extracolormap_t *planecolormap; - INT32 drawcount; -} polyplaneinfo_t; - -static size_t numpolyplanes = 0; // a list of transparent poyobject floors to be drawn -static polyplaneinfo_t *polyplaneinfo = NULL; - -//Hurdler: 3D water sutffs -typedef struct gl_drawnode_s -{ - planeinfo_t *plane; - polyplaneinfo_t *polyplane; - wallinfo_t *wall; - gl_vissprite_t *sprite; - -// struct gl_drawnode_s *next; -// struct gl_drawnode_s *prev; -} gl_drawnode_t; - -INT32 drawcount = 0; - -#define MAX_TRANSPARENTFLOOR 512 - -// This will likely turn into a copy of HWR_Add3DWater and replace it. -void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) -{ - static size_t allocedplanes = 0; - - // Force realloc if buffer has been freed - if (!planeinfo) - allocedplanes = 0; - - if (allocedplanes < numplanes + 1) - { - allocedplanes += MAX_TRANSPARENTFLOOR; - Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo); - } - - planeinfo[numplanes].isceiling = isceiling; - planeinfo[numplanes].fixedheight = fixedheight; - planeinfo[numplanes].lightlevel = ((planecolormap && (planecolormap->flags & CMF_FOG)) || mapnamespace == MNS_SRB2KART) ? lightlevel : 255; - planeinfo[numplanes].levelflat = levelflat; - planeinfo[numplanes].xsub = xsub; - planeinfo[numplanes].alpha = alpha; - planeinfo[numplanes].FOFSector = FOFSector; - planeinfo[numplanes].blend = blend; - planeinfo[numplanes].fogplane = fogplane; - planeinfo[numplanes].planecolormap = planecolormap; - planeinfo[numplanes].drawcount = drawcount++; - - numplanes++; -} - -// Adding this for now until I can create extrasubsector info for polyobjects -// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane -void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) -{ - static size_t allocedpolyplanes = 0; - - // Force realloc if buffer has been freed - if (!polyplaneinfo) - allocedpolyplanes = 0; - - if (allocedpolyplanes < numpolyplanes + 1) - { - allocedpolyplanes += MAX_TRANSPARENTFLOOR; - Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo); - } - - polyplaneinfo[numpolyplanes].isceiling = isceiling; - polyplaneinfo[numpolyplanes].fixedheight = fixedheight; - polyplaneinfo[numpolyplanes].lightlevel = ((planecolormap && (planecolormap->flags & CMF_FOG)) || mapnamespace == MNS_SRB2KART) ? lightlevel : 255; - polyplaneinfo[numpolyplanes].levelflat = levelflat; - polyplaneinfo[numpolyplanes].polysector = polysector; - polyplaneinfo[numpolyplanes].alpha = alpha; - polyplaneinfo[numpolyplanes].FOFSector = FOFSector; - polyplaneinfo[numpolyplanes].blend = blend; - polyplaneinfo[numpolyplanes].planecolormap = planecolormap; - polyplaneinfo[numpolyplanes].drawcount = drawcount++; - numpolyplanes++; -} - -// putting sortindex and sortnode here so the comparator function can see them -gl_drawnode_t *sortnode; -size_t *sortindex; - -static int CompareDrawNodes(const void *p1, const void *p2) -{ - size_t n1 = *(const size_t*)p1; - size_t n2 = *(const size_t*)p2; - INT32 v1 = 0; - INT32 v2 = 0; - INT32 diff; - if (sortnode[n1].plane) - v1 = sortnode[n1].plane->drawcount; - else if (sortnode[n1].polyplane) - v1 = sortnode[n1].polyplane->drawcount; - else if (sortnode[n1].wall) - v1 = sortnode[n1].wall->drawcount; - else I_Error("CompareDrawNodes: n1 unknown"); - - if (sortnode[n2].plane) - v2 = sortnode[n2].plane->drawcount; - else if (sortnode[n2].polyplane) - v2 = sortnode[n2].polyplane->drawcount; - else if (sortnode[n2].wall) - v2 = sortnode[n2].wall->drawcount; - else I_Error("CompareDrawNodes: n2 unknown"); - - diff = v2 - v1; - if (diff == 0) I_Error("CompareDrawNodes: diff is zero"); - return diff; -} - -static int CompareDrawNodePlanes(const void *p1, const void *p2) -{ - size_t n1 = *(const size_t*)p1; - size_t n2 = *(const size_t*)p2; - if (!sortnode[n1].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n1)"); - if (!sortnode[n2].plane) I_Error("CompareDrawNodePlanes: Uh.. This isn't a plane! (n2)"); - return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz); -} - -// -// HWR_CreateDrawNodes -// Creates and sorts a list of drawnodes for the scene being rendered. -static void HWR_CreateDrawNodes(void) -{ - UINT32 i = 0, p = 0; - size_t run_start = 0; - - // Dump EVERYTHING into a huge drawnode list. Then we'll sort it! - // Could this be optimized into _AddTransparentWall/_AddTransparentPlane? - // Hell yes! But sort algorithm must be modified to use a linked list. - sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes) - + (sizeof(polyplaneinfo_t)*numpolyplanes) - + (sizeof(wallinfo_t)*numwalls) - ,PU_STATIC, NULL); - // todo: - // However, in reality we shouldn't be re-copying and shifting all this information - // that is already lying around. This should all be in some sort of linked list or lists. - sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL); - - ps_hw_nodesorttime = I_GetPreciseTime(); - - for (i = 0; i < numplanes; i++, p++) - { - sortnode[p].plane = &planeinfo[i]; - sortindex[p] = p; - } - - for (i = 0; i < numpolyplanes; i++, p++) - { - sortnode[p].polyplane = &polyplaneinfo[i]; - sortindex[p] = p; - } - - for (i = 0; i < numwalls; i++, p++) - { - sortnode[p].wall = &wallinfo[i]; - sortindex[p] = p; - } - - ps_numdrawnodes = p; - - // p is the number of stuff to sort - - // sort the list based on the value of the 'drawcount' member of the drawnodes. - qs22j(sortindex, p, sizeof(size_t), CompareDrawNodes); - - // an additional pass is needed to correct the order of consecutive planes in the list. - // for each consecutive run of planes in the list, sort that run based on plane height and view height. - while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count - { - // locate run start - if (sortnode[sortindex[run_start]].plane) - { - // found it, now look for run end - size_t run_end;// (inclusive) - for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though.. - { - if (!sortnode[sortindex[i]].plane) break; - } - run_end = i-1; - if (run_end > run_start)// if there are multiple consecutive planes, not just one - { - // consecutive run of planes found, now sort it - qs22j(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes); - } - run_start = run_end + 1;// continue looking for runs coming right after this one - } - else - { - // this wasnt the run start, try next one - run_start++; - } - } - - ps_hw_nodesorttime = I_GetPreciseTime() - ps_hw_nodesorttime; - - ps_hw_nodedrawtime = I_GetPreciseTime(); - - // Okay! Let's draw it all! Woo! - GL_SetTransform(&atransform); - - for (i = 0; i < p; i++) - { - if (sortnode[sortindex[i]].plane) - { - // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. - gl_frontsector = NULL; - - if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].plane->levelflat, R_NoEncore(sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->isceiling)); - HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, - sortnode[sortindex[i]].plane->levelflat, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->planecolormap); - } - else if (sortnode[sortindex[i]].polyplane) - { - // We aren't traversing the BSP tree, so make gl_frontsector null to avoid crashes. - gl_frontsector = NULL; - - if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) - HWR_GetLevelFlat(sortnode[sortindex[i]].polyplane->levelflat, R_NoEncore(sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->isceiling)); - HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, - sortnode[sortindex[i]].polyplane->levelflat, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); - } - else if (sortnode[sortindex[i]].wall) - { - if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture)) - HWR_GetTexture(sortnode[sortindex[i]].wall->texnum, sortnode[sortindex[i]].wall->noencore); - HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall, - sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); - } - } - - ps_hw_nodedrawtime = I_GetPreciseTime() - ps_hw_nodedrawtime; - - numwalls = 0; - numplanes = 0; - numpolyplanes = 0; - - // No mem leaks, please. - Z_Free(sortnode); - Z_Free(sortindex); -} - // -----------------+ // HWR_ClearView : clear the viewwindow, with maximum z value // -----------------+ diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 87178ede7..87f0dd883 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -81,8 +81,6 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast); FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); -void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap); - boolean HWR_ShouldUsePaletteRendering(void); extern CV_PossibleValue_t glanisotropicmode_cons_t[]; @@ -143,28 +141,6 @@ extern float gl_viewsin, gl_viewcos; extern float gl_viewludsin, gl_viewludcos; -extern INT32 drawcount; - -// A drawnode is something that points to a 3D floor, 3D side, or masked -// middle texture. This is used for sorting with sprites. -typedef struct -{ - FOutVector wallVerts[4]; - FSurfaceInfo Surf; - INT32 texnum; - FBITFIELD blend; - INT32 drawcount; - boolean fogwall; - boolean noencore; - INT32 lightlevel; - extracolormap_t *wallcolormap; // Doing the lighting in HWR_RenderWall now for correct fog after sorting -} wallinfo_t; - -extern wallinfo_t *wallinfo; -extern size_t numwalls; // a list of transparent walls to be drawn - -#define MAX_TRANSPARENTWALL 256 - // Render stats extern precise_t ps_hw_skyboxtime; extern precise_t ps_hw_nodesorttime; diff --git a/src/hardware/hw_segs.c b/src/hardware/hw_segs.c index c49daafa1..f5f18ae06 100644 --- a/src/hardware/hw_segs.c +++ b/src/hardware/hw_segs.c @@ -33,32 +33,6 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg) return (FUINT)finallight; } -void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, INT32 texnum, boolean noencore, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) -{ - static size_t allocedwalls = 0; - - // Force realloc if buffer has been freed - if (!wallinfo) - allocedwalls = 0; - - if (allocedwalls < numwalls + 1) - { - allocedwalls += MAX_TRANSPARENTWALL; - Z_Realloc(wallinfo, allocedwalls * sizeof (*wallinfo), PU_LEVEL, &wallinfo); - } - - memcpy(wallinfo[numwalls].wallVerts, wallVerts, sizeof (wallinfo[numwalls].wallVerts)); - memcpy(&wallinfo[numwalls].Surf, pSurf, sizeof (FSurfaceInfo)); - wallinfo[numwalls].texnum = texnum; - wallinfo[numwalls].blend = blend; - wallinfo[numwalls].noencore = noencore; - wallinfo[numwalls].drawcount = drawcount++; - wallinfo[numwalls].fogwall = fogwall; - wallinfo[numwalls].lightlevel = lightlevel; - wallinfo[numwalls].wallcolormap = wallcolormap; - numwalls++; -} - void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap) { FBITFIELD blendmode = blend;