Put hw drawnode code to hw_drawnodes.c
https://git.do.srb2.org/STJr/SRB2/-/merge_requests/1773/diffs\?commit_id\=be5574a4c717b6e68efe9cd7c6666bbd9223a7f9
This commit is contained in:
parent
9df4b20b08
commit
07a059c915
6 changed files with 359 additions and 338 deletions
|
|
@ -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
|
||||
|
|
|
|||
344
src/hardware/hw_drawnodes.c
Normal file
344
src/hardware/hw_drawnodes.c
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
// --------
|
||||
|
|
|
|||
|
|
@ -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
|
||||
// -----------------+
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue