Add transparent with alpha test surface support

Based on surface flag from kmquake2 and rerelease documatation

https://github.com/id-Software/quake2-rerelease-dll#surf_alphatest-bit-25
This commit is contained in:
Denis Pauk 2023-10-16 00:35:33 +03:00
parent b4e78d0fa3
commit 83a31973c2
18 changed files with 72 additions and 39 deletions

View file

@ -10,7 +10,6 @@
## Quake2 ReRelease
Notes:
* mgu5m1: gl1,vk: non transparent flowers
* mgu5m2: server code: Too many models 256 (226 inline models)
| map | gl1.4 | gl3/gles3 | gl4.6 | vk | soft |

View file

@ -502,7 +502,7 @@ R_BuildLightMap(const msurface_t *surf, byte *dest, int stride, const byte *dest
float *bl;
if (surf->texinfo->flags &
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
(SURF_SKY | SURF_TRANSPARENT | SURF_WARP))
{
Com_Error(ERR_DROP, "%s called for non-lit surface", __func__);
}

View file

@ -450,7 +450,7 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
@ -576,7 +576,7 @@ Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}

View file

@ -489,8 +489,7 @@ R_RenderBrushPoly(entity_t *currententity, msurface_t *fa)
if (r_dynamic->value)
{
if (!(fa->texinfo->flags &
(SURF_SKY | SURF_TRANS33 |
SURF_TRANS66 | SURF_WARP)))
(SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
is_dynamic = true;
}
@ -573,6 +572,10 @@ R_DrawAlphaSurfaces(void)
{
glColor4f(intens, intens, intens, 0.66);
}
else if (s->texinfo->flags & SURF_ALPHATEST)
{
glColor4f(intens, intens, intens, 0.99);
}
else
{
glColor4f(intens, intens, intens, 1);
@ -672,7 +675,7 @@ R_DrawInlineBModel(entity_t *currententity, const model_t *currentmodel)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
if (psurf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
if (psurf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
psurf->texturechain = r_alpha_surfaces;
@ -897,7 +900,7 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node)
/* just adds to visible sky bounds */
RE_AddSkySurface(surf);
}
else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
else if (surf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
surf->texturechain = r_alpha_surfaces;

View file

@ -78,7 +78,7 @@ GL3_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride)
byte *lightmap;
if (surf->texinfo->flags &
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
(SURF_SKY | SURF_TRANSPARENT | SURF_WARP))
{
Com_Error(ERR_DROP, "GL3_BuildLightMap called for non-lit surface");
}

View file

@ -430,7 +430,7 @@ Mod_LoadFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
GL3_LM_CreateSurfaceLightmap(out);
}
@ -539,7 +539,7 @@ Mod_LoadQFaces(gl3model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
GL3_LM_CreateSurfaceLightmap(out);
}

View file

@ -370,6 +370,10 @@ GL3_DrawAlphaSurfaces(void)
{
alpha = 0.666f;
}
else if (s->texinfo->flags & SURF_ALPHATEST)
{
alpha = 0.999f;
}
if(alpha != gl3state.uni3DData.alpha)
{
gl3state.uni3DData.alpha = alpha;
@ -446,7 +450,7 @@ RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE] = {0};
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
assert((surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)) == 0
assert((surf->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)) == 0
&& "RenderLightMappedPoly mustn't be called with transparent, sky or warping surfaces!");
// Any dynamic lights on this surface?
@ -512,7 +516,7 @@ DrawInlineBModel(entity_t *currententity, gl3model_t *currentmodel)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
if (psurf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
if (psurf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
psurf->texturechain = gl3_alpha_surfaces;
@ -725,7 +729,7 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node)
/* just adds to visible sky bounds */
RE_AddSkySurface(surf);
}
else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
else if (surf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
surf->texturechain = gl3_alpha_surfaces;

View file

@ -78,7 +78,7 @@ GL4_BuildLightMap(msurface_t *surf, int offsetInLMbuf, int stride)
byte *lightmap;
if (surf->texinfo->flags &
(SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP))
(SURF_SKY | SURF_TRANSPARENT | SURF_WARP))
{
Com_Error(ERR_DROP, "GL4_BuildLightMap called for non-lit surface");
}

View file

@ -428,7 +428,7 @@ Mod_LoadFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
GL4_LM_CreateSurfaceLightmap(out);
}
@ -537,7 +537,7 @@ Mod_LoadQFaces(gl4model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
GL4_LM_CreateSurfaceLightmap(out);
}

View file

@ -370,6 +370,11 @@ GL4_DrawAlphaSurfaces(void)
{
alpha = 0.666f;
}
else if (s->texinfo->flags & SURF_ALPHATEST)
{
alpha = 0.999f;
}
if(alpha != gl4state.uni3DData.alpha)
{
gl4state.uni3DData.alpha = alpha;
@ -446,7 +451,7 @@ RenderLightmappedPoly(entity_t *currententity, msurface_t *surf)
hmm_vec4 lmScales[MAX_LIGHTMAPS_PER_SURFACE] = {0};
lmScales[0] = HMM_Vec4(1.0f, 1.0f, 1.0f, 1.0f);
assert((surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)) == 0
assert((surf->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)) == 0
&& "RenderLightMappedPoly mustn't be called with transparent, sky or warping surfaces!");
// Any dynamic lights on this surface?
@ -511,7 +516,7 @@ DrawInlineBModel(entity_t *currententity, gl4model_t *currentmodel)
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
if (psurf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
if (psurf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
psurf->texturechain = gl4_alpha_surfaces;
@ -724,7 +729,7 @@ RecursiveWorldNode(entity_t *currententity, mnode_t *node)
/* just adds to visible sky bounds */
GL4_AddSkySurface(surf);
}
else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
else if (surf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
surf->texturechain = gl4_alpha_surfaces;

View file

@ -394,7 +394,7 @@ R_DrawSolidClippedSubmodelPolygons(entity_t *currententity, const model_t *curre
pbedge[j-1].pnext = NULL; // mark end of edges
if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ))
if ( !( psurf->texinfo->flags & SURF_TRANSPARENT ))
{
// FIXME: Fan broken in borehole
// teleport: 1231.000000 770.250000 -579.375000

View file

@ -1236,9 +1236,9 @@ R_DrawAlphaSurfaces(const entity_t *currententity)
// pass down all the texinfo flags, not just SURF_WARP.
if (s->texinfo->flags & SURF_TRANS66)
R_ClipAndDrawPoly( 0.60f, (s->texinfo->flags & (SURF_WARP|SURF_FLOWING)), true );
R_ClipAndDrawPoly( 0.60f, (s->texinfo->flags & (SURF_WARP | SURF_FLOWING)), true );
else
R_ClipAndDrawPoly( 0.30f, (s->texinfo->flags & (SURF_WARP|SURF_FLOWING)), true );
R_ClipAndDrawPoly( 0.30f, (s->texinfo->flags & (SURF_WARP | SURF_FLOWING)), true );
s = s->nextalphasurface;
}

View file

@ -532,7 +532,7 @@ R_RenderFace (entity_t *currententity, const model_t *currentmodel, msurface_t *
qboolean r_nearzionly;
// translucent surfaces are not drawn by the edge renderer
if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
if (fa->texinfo->flags & SURF_TRANSPARENT)
{
fa->nextalphasurface = r_alpha_surfaces;
r_alpha_surfaces = fa;
@ -756,7 +756,7 @@ R_RenderBmodelFace(entity_t *currententity, bedge_t *pedges, msurface_t *psurf,
qboolean makeleftedge, makerightedge;
qboolean r_nearzionly;
if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
if (psurf->texinfo->flags & SURF_TRANSPARENT)
{
psurf->nextalphasurface = r_alpha_surfaces;
r_alpha_surfaces = psurf;

View file

@ -261,18 +261,22 @@ void
R_InitCaches (void)
{
int size;
// calculate size to allocate
int pix;
// surface cache size at 320X240
size = 1024*768;
pix = vid_buffer_width*vid_buffer_height;
if (pix > 64000)
size += (pix-64000)*3;
{
size += (pix - 64000) * 3;
}
if (r_farsee->value > 0)
{
size *= 2;
}
if (sw_surfcacheoverride->value > size)
{
@ -299,7 +303,6 @@ R_InitCaches (void)
sc_base->size = sc_size;
}
/*
==================
D_FlushCaches
@ -331,7 +334,7 @@ D_SCAlloc
=================
*/
static surfcache_t *
D_SCAlloc (int width, int size)
D_SCAlloc(int width, int size)
{
surfcache_t *new;
@ -345,7 +348,7 @@ D_SCAlloc (int width, int size)
Com_Error(ERR_FATAL, "%s: bad cache size %d\n", __func__, size);
}
// Add header size
/* Add header size */
size += ((char*)sc_base->data - (char*)sc_base);
size = (size + 3) & ~3;
if (size > sc_size)
@ -353,27 +356,33 @@ D_SCAlloc (int width, int size)
Com_Error(ERR_FATAL, "%s: %i > cache size of %i", __func__, size, sc_size);
}
// if there is not size bytes after the rover, reset to the start
/* if there is not size bytes after the rover, reset to the start */
if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
{
sc_rover = sc_base;
}
// colect and free surfcache_t blocks until the rover block is large enough
/* colect and free surfcache_t blocks until the rover block is large enough */
new = sc_rover;
if (sc_rover->owner)
{
*sc_rover->owner = NULL;
}
while (new->size < size)
{
// free another
/* free another */
sc_rover = sc_rover->next;
if (!sc_rover)
{
Com_Error(ERR_FATAL, "%s: hit the end of memory", __func__);
}
if (sc_rover->owner)
{
*sc_rover->owner = NULL;
}
new->size += sc_rover->size;
new->next = sc_rover->next;
@ -391,12 +400,17 @@ D_SCAlloc (int width, int size)
new->size = size;
}
else
{
sc_rover = new->next;
}
new->width = width;
// DEBUG
if (width > 0)
{
new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
}
new->owner = NULL; // should be set properly after return

View file

@ -420,7 +420,7 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
Vk_CreateSurfaceLightmap(out);
}
@ -546,7 +546,7 @@ Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
Vk_CreateSurfaceLightmap(out);
}

View file

@ -230,7 +230,7 @@ R_RenderBrushPoly(msurface_t *fa, float *modelMatrix, float alpha, entity_t *cur
dynamic:
if (r_dynamic->value)
{
if (!(fa->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(fa->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
is_dynamic = true;
}
@ -306,6 +306,10 @@ R_DrawAlphaSurfaces(void)
{
color[3] = 0.66f;
}
else if (s->texinfo->flags & SURF_ALPHATEST)
{
color[3] = 0.99f;
}
if (s->flags & SURF_DRAWTURB)
{
@ -434,7 +438,7 @@ Vk_RenderLightmappedPoly(msurface_t *surf, float *modelMatrix, float alpha, enti
dynamic:
if (r_dynamic->value)
{
if (!(surf->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
if (!(surf->texinfo->flags & (SURF_SKY | SURF_TRANSPARENT | SURF_WARP)))
{
is_dynamic = true;
}
@ -642,7 +646,7 @@ R_DrawInlineBModel(entity_t *currententity, const model_t *currentmodel, float *
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
{
if (psurf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
if (psurf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
psurf->texturechain = r_alpha_surfaces;
@ -835,7 +839,7 @@ R_RecursiveWorldNode(entity_t *currententity, mnode_t *node)
/* just adds to visible sky bounds */
RE_AddSkySurface(surf);
}
else if (surf->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66))
else if (surf->texinfo->flags & SURF_TRANSPARENT)
{
/* add to the translucent chain */
surf->texturechain = r_alpha_surfaces;

View file

@ -511,6 +511,7 @@ typedef struct
#define SURF_TRANS66 0x20
#define SURF_FLOWING 0x40 /* scroll towards angle */
#define SURF_NODRAW 0x80 /* don't bother referencing the texture */
#define SURF_ALPHATEST 0x02000000
typedef struct
{

View file

@ -497,6 +497,9 @@ typedef struct cvar_s
#define SURF_TRANS66 0x20
#define SURF_FLOWING 0x40 /* scroll towards angle */
#define SURF_NODRAW 0x80 /* don't bother referencing the texture */
#define SURF_ALPHATEST 0x02000000 /* KMQUAKE2 Alpha test flag */
/* Transparnet but not explicitly warp */
#define SURF_TRANSPARENT (SURF_TRANS33 | SURF_TRANS66 | SURF_ALPHATEST)
/* content masks */
#define MASK_ALL (-1)