NepDisk 2026-03-07 14:14:33 -05:00
parent a739573ca1
commit 0b1854ed3d
12 changed files with 161 additions and 177 deletions

View file

@ -33,8 +33,6 @@ typedef struct
GLMipmap_t *current_texture = NULL;
GLMipmap_t *current_brightmap = NULL;
//boolean currently_batching = false;
// Dynamic arrays for:
// - unsorted draw calls
// - unsorted vertices
@ -55,7 +53,7 @@ typedef struct
#define STATE_STACK_SIZE 2
BatchingState stateStack[STATE_STACK_SIZE] = {0};
int stateStackLevel = 0; // currently used level in state stack
BatchingState *curState = &stateStack[0];
BatchingState *cst = &stateStack[0];
// Dynamic arrays for:
// - sorted order of draw calls
@ -64,20 +62,10 @@ BatchingState *curState = &stateStack[0];
// These are only used during HWR_RenderBatches so they don't need
// to be in the state stac
// contains the draw calls from DrawPolygon, waiting to be processed
/*DrawCallInfo* drawCalls = NULL;
int drawCallsSize = 0;
int drawCallsCapacity = 65536;*/
// contains sorted order (array indices) for drawCalls
// (therefore size and capacity shared with it)
UINT32* drawCallOrder = NULL;
// contains unsorted vertices and texture coordinates from DrawPolygon
/*FOutVector* unsortedVertices = NULL;
int unsortedVerticesSize = 0;
int unsortedVerticesCapacity = 65536;*/
// contains subset of sorted vertices and texture coordinates to be sent to gpu
FOutVector* finalVertices = NULL;
int finalVerticesSize = 0;
@ -92,36 +80,36 @@ int finalIndicesSize = 0;
// Call HWR_RenderBatches to render all the collected geometry.
void HWR_StartBatching(void)
{
if (curState->currently_batching)
if (cst->currently_batching)
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
// init arrays if that has not been done yet
if (!curState->drawCalls)
if (!cst->drawCalls)
{
curState->drawCallsCapacity = curState->unsortedVerticesCapacity = 65536;
curState->drawCalls = malloc(
curState->drawCallsCapacity * sizeof(DrawCallInfo));
curState->unsortedVertices = malloc(
curState->unsortedVerticesCapacity * sizeof(FOutVector));
cst->drawCallsCapacity = cst->unsortedVerticesCapacity = 65536;
cst->drawCalls = malloc(
cst->drawCallsCapacity * sizeof(DrawCallInfo));
cst->unsortedVertices = malloc(
cst->unsortedVerticesCapacity * sizeof(FOutVector));
}
if (!finalVertices)
{
finalVertices = malloc(finalVerticesCapacity * sizeof(FOutVector));
finalIndices = malloc(finalVerticesCapacity * 3 * sizeof(UINT32));
drawCallOrder = malloc(curState->drawCallsCapacity * sizeof(UINT32));
drawCallOrder = malloc(cst->drawCallsCapacity * sizeof(UINT32));
}
curState->currently_batching = true;
cst->currently_batching = true;
}
// Disable batching while keeping collected draw calls.
// Call HWR_StartBatching again to resume.
void HWR_PauseBatching(void)
{
if (!curState->currently_batching)
if (!cst->currently_batching)
I_Error("HWR_PauseBatching: batching not started");
curState->currently_batching = false;
cst->currently_batching = false;
}
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
@ -129,7 +117,7 @@ void HWR_PauseBatching(void)
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (curState->currently_batching)
if (cst->currently_batching)
{
if (texture != NULL)
{
@ -151,48 +139,48 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
static void HWR_CollectDrawCallInfo(FSurfaceInfo *pSurf, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial)
{
// make sure dynamic array has capacity
if (curState->drawCallsSize == curState->drawCallsCapacity)
if (cst->drawCallsSize == cst->drawCallsCapacity)
{
DrawCallInfo* new_array;
// ran out of space, make new array double the size
curState->drawCallsCapacity *= 2;
new_array = malloc(curState->drawCallsCapacity * sizeof(DrawCallInfo));
memcpy(new_array, curState->drawCalls, curState->drawCallsSize * sizeof(DrawCallInfo));
free(curState->drawCalls);
curState->drawCalls = new_array;
cst->drawCallsCapacity *= 2;
new_array = malloc(cst->drawCallsCapacity * sizeof(DrawCallInfo));
memcpy(new_array, cst->drawCalls, cst->drawCallsSize * sizeof(DrawCallInfo));
free(cst->drawCalls);
cst->drawCalls = new_array;
// also need to redo the index array, dont need to copy it though
free(drawCallOrder);
drawCallOrder = malloc(curState->drawCallsCapacity * sizeof(UINT32));
drawCallOrder = malloc(cst->drawCallsCapacity * sizeof(UINT32));
}
// add entry to array
curState->drawCalls[curState->drawCallsSize].surf = *pSurf;
curState->drawCalls[curState->drawCallsSize].vertsIndex = curState->unsortedVerticesSize;
curState->drawCalls[curState->drawCallsSize].numVerts = iNumPts;
curState->drawCalls[curState->drawCallsSize].polyFlags = PolyFlags;
curState->drawCalls[curState->drawCallsSize].texture = current_texture;
curState->drawCalls[curState->drawCallsSize].brightmap = current_brightmap;
curState->drawCalls[curState->drawCallsSize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
curState->drawCalls[curState->drawCallsSize].horizonSpecial = horizonSpecial;
curState->drawCallsSize++;
cst->drawCalls[cst->drawCallsSize].surf = *pSurf;
cst->drawCalls[cst->drawCallsSize].vertsIndex = cst->unsortedVerticesSize;
cst->drawCalls[cst->drawCallsSize].numVerts = iNumPts;
cst->drawCalls[cst->drawCallsSize].polyFlags = PolyFlags;
cst->drawCalls[cst->drawCallsSize].texture = current_texture;
cst->drawCalls[cst->drawCallsSize].brightmap = current_brightmap;
cst->drawCalls[cst->drawCallsSize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
cst->drawCalls[cst->drawCallsSize].horizonSpecial = horizonSpecial;
cst->drawCallsSize++;
}
static void HWR_CollectDrawCallVertices(FOutVector *pOutVerts, FUINT iNumPts)
{
// make sure dynamic array has capacity
while (curState->unsortedVerticesSize + (int)iNumPts >
curState->unsortedVerticesCapacity)
while (cst->unsortedVerticesSize + (int)iNumPts >
cst->unsortedVerticesCapacity)
{
FOutVector* new_array;
// need more space for vertices in unsortedVertices
curState->unsortedVerticesCapacity *= 2;
new_array = malloc(curState->unsortedVerticesCapacity * sizeof(FOutVector));
memcpy(new_array, curState->unsortedVertices, curState->unsortedVerticesSize * sizeof(FOutVector));
free(curState->unsortedVertices);
curState->unsortedVertices = new_array;
cst->unsortedVerticesCapacity *= 2;
new_array = malloc(cst->unsortedVerticesCapacity * sizeof(FOutVector));
memcpy(new_array, cst->unsortedVertices, cst->unsortedVerticesSize * sizeof(FOutVector));
free(cst->unsortedVertices);
cst->unsortedVertices = new_array;
}
// add vertices to array
memcpy(&curState->unsortedVertices[curState->unsortedVerticesSize], pOutVerts, iNumPts * sizeof(FOutVector));
curState->unsortedVerticesSize += iNumPts;
memcpy(&cst->unsortedVertices[cst->unsortedVerticesSize], pOutVerts, iNumPts * sizeof(FOutVector));
cst->unsortedVerticesSize += iNumPts;
}
// If batching is enabled, this function collects the polygon data and the chosen texture
@ -200,7 +188,7 @@ static void HWR_CollectDrawCallVertices(FOutVector *pOutVerts, FUINT iNumPts)
// render the polygon immediately.
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader_target, boolean horizonSpecial)
{
if (curState->currently_batching)
if (cst->currently_batching)
{
if (!pSurf)
{
@ -218,33 +206,30 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
}
}
// TODO could alternatively save drawCalls and unsortedVertices variables here
// instead of having "curState->" everywhere
void HWR_PushBatchingState(void)
{
if (stateStackLevel == STATE_STACK_SIZE - 1)
I_Error("HWR_PushBatchingState: State stack overflow");
stateStackLevel++;
curState++;
cst++;
}
// TODO as above
void HWR_PopBatchingState(void)
{
if (stateStackLevel == 0)
I_Error("HWR_PopBatchingState: State stack underflow");
stateStackLevel--;
curState--;
cst--;
}
static int compareDrawCalls(const void *p1, const void *p2)
{
UINT32 index1 = *(const UINT32*)p1;
UINT32 index2 = *(const UINT32*)p2;
DrawCallInfo* poly1 = &curState->drawCalls[index1];
DrawCallInfo* poly2 = &curState->drawCalls[index2];
DrawCallInfo* poly1 = &cst->drawCalls[index1];
DrawCallInfo* poly2 = &cst->drawCalls[index2];
int diff;
INT64 diff64;
UINT32 downloaded1 = 0;
@ -306,8 +291,8 @@ static int compareDrawCallsNoShaders(const void *p1, const void *p2)
{
unsigned int index1 = *(const unsigned int*)p1;
unsigned int index2 = *(const unsigned int*)p2;
DrawCallInfo* poly1 = &curState->drawCalls[index1];
DrawCallInfo* poly2 = &curState->drawCalls[index2];
DrawCallInfo* poly1 = &cst->drawCalls[index1];
DrawCallInfo* poly2 = &cst->drawCalls[index2];
int diff;
INT64 diff64;
@ -363,7 +348,7 @@ static void HWR_CollectVerticesIntoBatch(DrawCallInfo *drawCall)
finalIndices = new_index_array;
}
// write the vertices of the polygon
memcpy(&finalVertices[finalVerticesSize], &curState->unsortedVertices[drawCall->vertsIndex],
memcpy(&finalVertices[finalVerticesSize], &cst->unsortedVertices[drawCall->vertsIndex],
numVerts * sizeof(FOutVector));
// write the indexes, pointing to the fan vertexes but in triangles format
firstVIndex = finalVerticesSize;
@ -461,7 +446,7 @@ static void HWR_ExecuteStateChanges(unsigned int stateChanges, DrawCallInfo *dc)
static void HWR_InitBatchingStats(void)
{
ps_hw_numpolys = curState->drawCallsSize;
ps_hw_numpolys = cst->drawCallsSize;
ps_hw_numcalls = ps_hw_numverts
= ps_hw_numshaders = ps_hw_numtextures
= ps_hw_numpolyflags = ps_hw_numcolors = 0;
@ -474,26 +459,26 @@ void HWR_RenderBatches(void)
int drawCallReadPos = 0; // position in drawCallOrder
int i;
if (!curState->currently_batching)
if (!cst->currently_batching)
I_Error("HWR_RenderBatches called without starting batching");
curState->currently_batching = false; // no longer collecting batches
cst->currently_batching = false; // no longer collecting batches
HWR_InitBatchingStats();
if (!curState->drawCallsSize)
if (!cst->drawCallsSize)
return; // nothing to draw
// init drawCallOrder
for (i = 0; i < curState->drawCallsSize; i++)
for (i = 0; i < cst->drawCallsSize; i++)
drawCallOrder[i] = i;
// sort the draw calls
ps_hw_batchsorttime = I_GetPreciseTime();
if (cv_glshaders.value && gl_shadersavailable)
qs22j(drawCallOrder, curState->drawCallsSize, sizeof(UINT32), compareDrawCalls);
qs22j(drawCallOrder, cst->drawCallsSize, sizeof(UINT32), compareDrawCalls);
else
qs22j(drawCallOrder, curState->drawCallsSize, sizeof(UINT32), compareDrawCallsNoShaders);
qs22j(drawCallOrder, cst->drawCallsSize, sizeof(UINT32), compareDrawCallsNoShaders);
ps_hw_batchsorttime = I_GetPreciseTime() - ps_hw_batchsorttime;
// sort grouping order
// 1. shader
@ -506,7 +491,7 @@ void HWR_RenderBatches(void)
ps_hw_batchdrawtime = I_GetPreciseTime();
// set state for first batch
HWR_ExecuteStateChanges(0xFFFF, &curState->drawCalls[drawCallOrder[0]]);
HWR_ExecuteStateChanges(0xFFFF, &cst->drawCalls[drawCallOrder[0]]);
// - iterate through draw calls
// - accumulate converted vertices and indices into finalVertices and finalIndices
@ -527,18 +512,18 @@ void HWR_RenderBatches(void)
// repeat loop
unsigned int stateChanges = 0; // flags defined above HWR_MarkStateChanges
DrawCallInfo *currentDrawCall = &curState->drawCalls[drawCallOrder[drawCallReadPos++]];
DrawCallInfo *currentDrawCall = &cst->drawCalls[drawCallOrder[drawCallReadPos++]];
DrawCallInfo *nextDrawCall = NULL;
HWR_CollectVerticesIntoBatch(currentDrawCall);
if (drawCallReadPos >= curState->drawCallsSize) // was that the last draw call?
if (drawCallReadPos >= cst->drawCallsSize) // was that the last draw call?
{
stopFlag = true;
}
else
{
nextDrawCall = &curState->drawCalls[drawCallOrder[drawCallReadPos]];
nextDrawCall = &cst->drawCalls[drawCallOrder[drawCallReadPos]];
stateChanges = HWR_MarkStateChanges(currentDrawCall, nextDrawCall);
}
@ -564,8 +549,8 @@ void HWR_RenderBatches(void)
HWR_ExecuteStateChanges(stateChanges, nextDrawCall);
}
// reset the arrays (set sizes to 0)
curState->drawCallsSize = 0;
curState->unsortedVerticesSize = 0;
cst->drawCallsSize = 0;
cst->unsortedVerticesSize = 0;
ps_hw_batchdrawtime = I_GetPreciseTime() - ps_hw_batchdrawtime;
}

View file

@ -225,7 +225,7 @@ static boolean HWR_PortalCheckPointSide(fixed_t x, fixed_t y)
P_ClosestPointOnLine(x, y, gl_portalclipline, &closest_point);
if (closest_point.x != x || closest_point.y != y)
{
if (P_PointOnLineSide(x, y, gl_portalclipline) != gl_portalviewside)
if (P_PointOnLineSide(x, y, gl_portalclipline) != 1)
return true;
}
return false;

View file

@ -309,9 +309,7 @@ enum hwdsetspecialstate
HWD_SET_SHADERS,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
HWD_SET_STENCIL_MODE,
HWD_SET_STENCIL_LEVEL, // must set mode afterwards for level to come into effect
HWD_NUMSTATE // (TODO could create separate stencil function in r_opengl.c to avoid hacky behaviour like this)
HWD_NUMSTATE
};
typedef enum hwdsetspecialstate hwdspecialstate_t;
@ -323,8 +321,8 @@ enum hwdshaderstage
typedef enum hwdshaderstage hwdshaderstage_t;
// stencil modes
enum
// Modes for SetStencilMode
enum hwdstencilmode
{
HWD_STENCIL_INACTIVE,
HWD_STENCIL_PORTAL_BEGIN,
@ -332,6 +330,8 @@ enum
HWD_STENCIL_PORTAL_FINISH
};
typedef enum hwdstencilmode hwdstencilmode_t;
// Lactozilla: Shader info
// Generally set at the start of the frame.
enum hwdshaderinfo

View file

@ -82,9 +82,6 @@ typedef struct
// initial size of drawnode array
#define DRAWNODES_INIT_SIZE 64
/*gl_drawnode_t *drawnodes = NULL;
INT32 numdrawnodes = 0;
INT32 alloceddrawnodes = 0;*/
typedef struct
{
@ -93,10 +90,9 @@ typedef struct
INT32 alloceddrawnodes;
} gl_drawnode_state_t;
// todo magic number 16
// portal rendering will push and pop this stack
// to keep multiple drawnode lists around until they're needed
static gl_drawnode_state_t state_stack[16] = {0};
static gl_drawnode_state_t state_stack[MAXPORTALS_CAP+1] = {0};
static int stack_level = 0;
static gl_drawnode_state_t *cst = &state_stack[0]; // current state
@ -183,8 +179,7 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse
// pushes all drawnode rendering state to stack
void HWR_PushDrawNodeState(void)
{
// todo magic number 16
if (stack_level == 15)
if (stack_level == MAXPORTALS_CAP)
I_Error("HWR_PushDrawNodeState: State stack overflow");
stack_level++;
@ -208,7 +203,6 @@ static int CompareDrawNodePlanes(const void *p1, const void *p2)
return ABS(cst->drawnodes[n2].u.plane.fixedheight - viewz) - ABS(cst->drawnodes[n1].u.plane.fixedheight - viewz);
}
// HWR_RenderDrawNodes
// Sorts and renders the list of drawnodes for the scene being rendered.
void HWR_RenderDrawNodes(void)
{

View file

@ -40,6 +40,7 @@ void GL_GClipRect(INT32 minx, INT32 miny, INT32 maxx, INT32 maxy, float nearclip
void GL_ClearMipMapCache(void);
void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value);
void GL_SetStencilMode(hwdstencilmode_t mode, INT32 ref);
// Hurdler: added for new development
void GL_DrawModel(model_t *model, INT32 frameIndex, float duration, float tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface);

View file

@ -157,14 +157,13 @@ typedef struct
} gl_portal_array_t;
// TODO magic number 16
gl_portal_array_t gl_portal_arrays[16] = {0};
gl_portal_array_t gl_portal_arrays[MAXPORTALS_CAP+1] = {0};
INT32 gl_portal_level = 0; // portal recursion level
boolean gl_drawing_stencil = false; // used when drawing segs to stencil buffer
sector_t *gl_portalcullsector = NULL;
line_t *gl_portalclipline = NULL;
INT32 gl_portalviewside = 0;
// debug tools
boolean gl_printportals = false; // print info about portals on this frame
@ -186,9 +185,6 @@ static void HWR_PortalFrame(gl_portal_t *portal, boolean set_culling)
{
gl_portalcullsector = portal->clipline->frontsector;
gl_portalclipline = portal->clipline;
gl_portalviewside = P_PointOnLineSide(viewx, viewy, gl_portalclipline);
// TODO check is gl_portalviewside always the same value?
// if it is then it's not needed to have this variable
}
}
@ -201,6 +197,38 @@ static gl_portal_array_t *HWR_GetPortalArray(void)
return &gl_portal_arrays[level];
}
// TODO move to r_main.c next to fixed point functions?
// More precise version of R_PointToAngle2 using floats and atan2.
static angle_t R_PointToAngle2Precise(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
{
fixed_t dx = x - pviewx;
fixed_t dy = y - pviewy;
float radians;
if (!dx && !dy)
return 0;
// no need for correct scale with FIXED_TO_FLOAT here
// since we're just calculating the angle
radians = atan2(dy, dx);
return (angle_t)(radians / M_PI * ANGLE_180);
}
// More precise version of R_PointToDist2 using floats and sqrt.
static fixed_t R_PointToDist2Precise(fixed_t px2, fixed_t py2, fixed_t px1, fixed_t py1)
{
// float-fixed conversions can be omitted here
// because they cancel each other out in this case
float dx = px1 - px2;
float dy = py1 - py2;
double result = sqrt(dx*dx + dy*dy);
return (fixed_t)result;
}
boolean HWR_AddPortal(line_t *start, line_t *dest, seg_t *seg)
{
gl_portal_array_t *array;
@ -212,8 +240,8 @@ boolean HWR_AddPortal(line_t *start, line_t *dest, seg_t *seg)
vertex_t dest_c, start_c;
if ((gl_portal_level + gl_rendering_skybox) >= cv_maxportals.value ||
(gl_debugportal &&
(gl_debugportal != (start-lines) || gl_portal_level)))
(gl_debugportal &&
(gl_debugportal != (start-lines) || gl_portal_level)))
{
return false;
}
@ -227,45 +255,51 @@ boolean HWR_AddPortal(line_t *start, line_t *dest, seg_t *seg)
{
array->capacity = INIT_PORTAL_ARRAY_SIZE;
array->portals = Z_Malloc(sizeof(gl_portal_t) * array->capacity, PU_LEVEL,
&array->portals);
&array->portals);
}
else if (array->size == array->capacity)
{
array->capacity *= 2;
array->portals = Z_Realloc(array->portals, sizeof(gl_portal_t) * array->capacity,
PU_LEVEL, &array->portals);
PU_LEVEL, &array->portals);
}
portal = &array->portals[array->size++];
dangle = R_PointToAngle2(0,0,dest->dx,dest->dy) - R_PointToAngle2(start->dx,start->dy,0,0);
// using this order of operations change fixes ante station island portal
// Most fixed-point calculations and trigonometric function tables are replaced by
// floats and cmath library calls in this part to improve the precision of the
// location and angle of the new viewpoint.
//
// This reduces artefacts on the edges of portals, showing thin lines/pixels
// of the underlying graphics. (for example the sky texture) It's not 100%
// perfectly aligned and artefact-free, but looks noticeably
// better than the original code. I'm not even sure if it's this
// code or the nodebuilder or hw_map or something else causing the remaining issues..
//#define R_PointToAngle2Precise R_PointToAngle2
//#define R_PointToDist2Precise R_PointToDist2
dangle = R_PointToAngle2Precise(0,0,dest->dx,dest->dy) - R_PointToAngle2Precise(start->dx,start->dy,0,0);
// looking glass center
//start_c.x = (start->v1->x + start->v2->x) / 2;
//start_c.y = (start->v1->y + start->v2->y) / 2;
start_c.x = start->v1->x/2 + start->v2->x/2;
start_c.y = start->v1->y/2 + start->v2->y/2;
// other side center
//dest_c.x = (dest->v1->x + dest->v2->x) / 2;
//dest_c.y = (dest->v1->y + dest->v2->y) / 2;
dest_c.x = dest->v1->x/2 + dest->v2->x/2;
dest_c.y = dest->v1->y/2 + dest->v2->y/2;
disttopoint = R_PointToDist2(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2(start_c.x, start_c.y, viewx, viewy);
disttopoint = R_PointToDist2Precise(start_c.x, start_c.y, viewx, viewy);
angtopoint = R_PointToAngle2Precise(start_c.x, start_c.y, viewx, viewy);
angtopoint += dangle;
// could using float or double here help with the slight impreciseness of
// the view coordinates?
//float fang = ((float)angtopoint / 4294967296.0f) * 2.0f * M_PI;
float fang = ((float)angtopoint / 4294967296.0f) * 2.0f * M_PI;
portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
//portal->viewx = dest_c.x + FixedMul(FINECOSINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
//portal->viewy = dest_c.y + FixedMul(FINESINE(angtopoint>>ANGLETOFINESHIFT), disttopoint);
//portal->viewx = dest_c.x + FixedMul(FLOAT_TO_FIXED(cos(fang)), disttopoint);
//portal->viewy = dest_c.y + FixedMul(FLOAT_TO_FIXED(sin(fang)), disttopoint);
// cos and sin are just scaling disttopoint so no need for float-fixed conversions
portal->viewx = dest_c.x + (fixed_t)(cos(fang) * disttopoint);
portal->viewy = dest_c.y + (fixed_t)(sin(fang) * disttopoint);
portal->viewz = viewz + dest->frontsector->floorheight - start->frontsector->floorheight;
portal->viewangle = viewangle + dangle;
portal->seg = seg;
@ -437,7 +471,7 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if
realcolor.rgba = (colormap != NULL) ? colormap->rgba : GL_DEFAULTMIX;
if (cv_glshaders.value && gl_shadersavailable)
if (HWR_UseShader())
{
surfcolor.s.alpha = (255 - light);
}
@ -565,20 +599,6 @@ boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
return true;
}
// -----------------+
// HWR_ClearView : clear the viewwindow, with maximum z value
// -----------------+
/*static inline void HWR_ClearView(void)
{
GL_GClipRect((INT32)gl_viewwindowx,
(INT32)gl_viewwindowy,
(INT32)(gl_viewwindowx + gl_viewwidth),
(INT32)(gl_viewwindowy + gl_viewheight),
ZCLIP_PLANE);
GL_ClearBuffer(false, true, true, 0)
}*/
// -----------------+
// HWR_SetViewSize : set projection and scaling values
// -----------------+
@ -680,6 +700,7 @@ static void HWR_PortalClipping(gl_portal_t *portal)
gld_clipper_SafeAddClipRange(portal->angle1, portal->angle2);
}
// Tells the backend are shaders being used for 3d rendering.
static void HWR_SetShaderState(void)
{
GL_SetSpecialState(HWD_SET_SHADERS, (INT32)HWR_UseShader());
@ -741,9 +762,6 @@ static void HWR_EnterSkyboxState(void)
HWR_PushBatchingState();
HWR_PushSpriteState();
HWR_PushDrawNodeState();
// need to use the next level in the portal arrays
// so skybox doesn't interfere with previously collected portals
//gl_portal_level++;
gl_rendering_skybox = true;
}
@ -752,8 +770,6 @@ static void HWR_LeaveSkyboxState(void)
HWR_PopBatchingState();
HWR_PopSpriteState();
HWR_PopDrawNodeState();
// see above comment
//gl_portal_level--;
gl_rendering_skybox = false;
}
@ -767,16 +783,12 @@ static void HWR_RenderPortalSeg(seg_t *seg)
gl_drawing_stencil = false;
// need to work around the r_opengl PF_Invisible bug with this call
// similarly as in the linkdraw hack in HWR_DrawSprites
// TODO not completely sure if this is needed, check it? (try without)
GL_SetBlend(PF_Translucent|PF_Occlude|PF_Masked);
}
static void HWR_SetStencilState(INT32 state)
{
// this order of calls must be used for the stencil
// level to take effect correctly
GL_SetSpecialState(HWD_SET_STENCIL_LEVEL, gl_portal_level);
GL_SetSpecialState(HWD_SET_STENCIL_MODE, state);
GL_SetStencilMode(state, gl_portal_level);
}
// clear the depth buffer from the stenciled area so portal
@ -784,7 +796,7 @@ static void HWR_SetStencilState(INT32 state)
// (glClear ignores the stencil buffer so can't be used for this purpose)
static void HWR_RenderDepthEraser(boolean visible)
{
FOutVector verts[4] = {0}; // TODO not sure if PF_NoAlphaTest is needed?
FOutVector verts[4] = {0};
FBITFIELD blendflags = PF_Occlude|PF_NoDepthTest|PF_NoTexture|PF_NoAlphaTest;
if (!visible)
blendflags |= PF_Invisible;
@ -897,7 +909,6 @@ static void HWR_RenderViewpoint(player_t *player, boolean drawSkyTexture, boolea
{
//if (gl_printportals)
// CONS_Printf("drawing a skybox\n");
// TODO NOTE this probably wont set correct position under portals?
R_SkyboxFrame(viewssnum);
// render skybox while keeping batches, sprites and drawnodes
// from the regular viewpoint stashed in the state stacks
@ -1250,6 +1261,9 @@ void CV_glpalettedepth_OnChange(void);
consvar_t cv_glpaletterendering = CVAR_INIT ("gr_paletteshader", "Off", CV_CALL|CV_SAVE, CV_OnOff, CV_glpaletterendering_OnChange);
consvar_t cv_glpalettedepth = CVAR_INIT ("gr_palettedepth", "16 bits", CV_SAVE|CV_CALL, glpalettedepth_cons_t, CV_glpalettedepth_OnChange);
// Isolates rendering to one of the top level portals.
// (Stencil cutting of the portal is also disabled)
// Use gr_printportals to find the number to use.
consvar_t cv_gldebugportal = CVAR_INIT ("gr_debugportal", "0", 0, CV_Unsigned, NULL);
consvar_t cv_glskydebug = CVAR_INIT ("gr_skydebug", "0", 0, CV_Unsigned, NULL);

View file

@ -177,7 +177,6 @@ extern INT32 gl_portal_level;
extern boolean gl_drawing_stencil;
extern sector_t *gl_portalcullsector;
extern line_t *gl_portalclipline;
extern INT32 gl_portalviewside;
extern boolean gl_printportals;
extern INT32 gl_debugportal;

View file

@ -479,9 +479,9 @@ static void HWR_ProcessTwoSidedSegMiddle(FOutVector *wallVerts, FSurfaceInfo *Su
sector_t *front, *back;
fixed_t h, l; // 2s middle textures
fixed_t hS, lS;
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t popentop, popenbottom, polytop, polybottom, lowcut, highcut;
fixed_t popentopslope, popenbottomslope, polytopslope, polybottomslope, lowcutslope, highcutslope;
fixed_t texturevpeg = 0;
fixed_t texturevpeg = 0;
INT32 repeats;
fixed_t midtexheight = 0;
fixed_t texturevpegslope = 0;

View file

@ -28,9 +28,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
// sprites are drawn after all wall and planes are rendered, so that
// sprite translucency effects apply on the rendered view (instead of the background sky!!)
//UINT32 gl_visspritecount;
//static gl_vissprite_t *gl_visspritechunks[MAXVISSPRITES >> VISSPRITECHUNKBITS] = {NULL};
typedef struct
{
FOutVector verts[4];
@ -47,8 +44,7 @@ typedef struct
// TODO this array is ~3 megabytes because of linkdrawlist...
// maybe turn that into a dynamic array
// TODO magic number 16
static gl_sprite_state_t state_stack[16] = {0};
static gl_sprite_state_t state_stack[MAXPORTALS_CAP+1] = {0};
static int stack_level = 0;
static gl_sprite_state_t *cst = &state_stack[0]; // current state
@ -64,8 +60,7 @@ void HWR_ClearSprites(void)
// pushes all sprite rendering state to stack
void HWR_PushSpriteState(void)
{
// todo magic number 16
if (stack_level == 15)
if (stack_level == MAXPORTALS_CAP)
I_Error("HWR_PushSpriteState: State stack overflow");
stack_level++;
@ -111,11 +106,6 @@ static gl_vissprite_t *HWR_NewVisSprite(void)
// NOTE: This will no longer be necessary once full translucent sorting is implemented, where
// translucent sprites and surfaces are sorted together.
/*
// this list is used to store data about linkdraw sprites
zbuffersprite_t linkdrawlist[MAXVISSPRITES];
UINT32 linkdrawcount = 0;*/
// add the necessary data to the list for delayed z-buffer drawing
static void HWR_LinkDrawHackAdd(FOutVector *verts, gl_vissprite_t *spr)
{

View file

@ -73,7 +73,6 @@ static GLuint tex_downloaded = 0;
static GLuint lt_downloaded = 0; // currently bound lighttable texture
static GLfloat fov = 90.0f;
static FBITFIELD CurrentPolyFlags;
static GLint gl_stencil_ref = 0;
// Linked list of all textures.
static FTextureInfo *TexCacheTail = NULL;
@ -2400,33 +2399,32 @@ void GL_SetSpecialState(hwdspecialstate_t IdState, INT32 Value)
Flush(); //??? if we want to change filter mode by texture, remove this
break;
case HWD_SET_STENCIL_MODE:
switch (Value)
{
case HWD_STENCIL_INACTIVE:
pglStencilFunc(GL_ALWAYS, gl_stencil_ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
break;
case HWD_STENCIL_PORTAL_BEGIN:
pglStencilFunc(GL_EQUAL, gl_stencil_ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
break;
case HWD_STENCIL_PORTAL_INSIDE:
pglStencilFunc(GL_EQUAL, gl_stencil_ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
break;
case HWD_STENCIL_PORTAL_FINISH:
pglStencilFunc(GL_EQUAL, gl_stencil_ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
break;
}
default:
break;
}
}
case HWD_SET_STENCIL_LEVEL:
gl_stencil_ref = Value;
void GL_SetStencilMode(hwdstencilmode_t mode, INT32 ref)
{
switch (mode)
{
case HWD_STENCIL_INACTIVE:
pglStencilFunc(GL_ALWAYS, ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
break;
default:
case HWD_STENCIL_PORTAL_BEGIN:
pglStencilFunc(GL_EQUAL, ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
break;
case HWD_STENCIL_PORTAL_INSIDE:
pglStencilFunc(GL_EQUAL, ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
break;
case HWD_STENCIL_PORTAL_FINISH:
pglStencilFunc(GL_EQUAL, ref, 0xFF);
pglStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
break;
}
}

View file

@ -138,7 +138,7 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}};
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {MAXPORTALS_CAP, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
static CV_PossibleValue_t secbright_cons_t[] = {{0, "MIN"}, {255, "MAX"}, {0, NULL}};

View file

@ -108,6 +108,9 @@ extern player_t *viewplayer;
extern mobj_t *r_viewmobj;
extern consvar_t cv_allowmlook;
// maximum value for maxportals cvar
#define MAXPORTALS_CAP 12
extern consvar_t cv_maxportals;
extern angle_t clipangle[MAXSPLITSCREENPLAYERS];