mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-13 06:36:56 +00:00
Merge branch 'opengl-brightmaps' into 'master'
OpenGL BRIGHTMAPs + sprite/model directional lighting See merge request KartKrew/Kart!1485
This commit is contained in:
commit
fb20f7b036
12 changed files with 411 additions and 143 deletions
|
|
@ -17,6 +17,7 @@
|
|||
// The texture for the next polygon given to HWR_ProcessPolygon.
|
||||
// Set with HWR_SetCurrentTexture.
|
||||
GLMipmap_t *current_texture = NULL;
|
||||
GLMipmap_t *current_brightmap = NULL;
|
||||
|
||||
boolean currently_batching = false;
|
||||
|
||||
|
|
@ -42,10 +43,10 @@ int unsortedVertexArrayAllocSize = 65536;
|
|||
// Call HWR_RenderBatches to render all the collected geometry.
|
||||
void HWR_StartBatching(void)
|
||||
{
|
||||
if (currently_batching)
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
if (currently_batching)
|
||||
I_Error("Repeat call to HWR_StartBatching without HWR_RenderBatches");
|
||||
|
||||
// init arrays if that has not been done yet
|
||||
// init arrays if that has not been done yet
|
||||
if (!finalVertexArray)
|
||||
{
|
||||
finalVertexArray = malloc(finalVertexArrayAllocSize * sizeof(FOutVector));
|
||||
|
|
@ -55,7 +56,7 @@ void HWR_StartBatching(void)
|
|||
unsortedVertexArray = malloc(unsortedVertexArrayAllocSize * sizeof(FOutVector));
|
||||
}
|
||||
|
||||
currently_batching = true;
|
||||
currently_batching = true;
|
||||
}
|
||||
|
||||
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
|
||||
|
|
@ -63,14 +64,29 @@ void HWR_StartBatching(void)
|
|||
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
|
||||
void HWR_SetCurrentTexture(GLMipmap_t *texture)
|
||||
{
|
||||
if (currently_batching)
|
||||
{
|
||||
current_texture = texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
HWD.pfnSetTexture(texture);
|
||||
}
|
||||
if (currently_batching)
|
||||
{
|
||||
if (texture != NULL)
|
||||
{
|
||||
if (texture->flags & TF_BRIGHTMAP)
|
||||
{
|
||||
current_brightmap = texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_texture = texture;
|
||||
current_brightmap = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current_texture = current_brightmap = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HWD.pfnSetTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
// If batching is enabled, this function collects the polygon data and the chosen texture
|
||||
|
|
@ -78,7 +94,7 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
|
|||
// render the polygon immediately.
|
||||
void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags, int shader, boolean horizonSpecial)
|
||||
{
|
||||
if (currently_batching)
|
||||
if (currently_batching)
|
||||
{
|
||||
if (!pSurf)
|
||||
I_Error("Got a null FSurfaceInfo in batching");// nulls should not come in the stuff that batching currently applies to
|
||||
|
|
@ -114,6 +130,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
polygonArray[polygonArraySize].numVerts = iNumPts;
|
||||
polygonArray[polygonArraySize].polyFlags = PolyFlags;
|
||||
polygonArray[polygonArraySize].texture = current_texture;
|
||||
polygonArray[polygonArraySize].brightmap = current_brightmap;
|
||||
polygonArray[polygonArraySize].shader = shader;
|
||||
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
|
||||
polygonArraySize++;
|
||||
|
|
@ -123,10 +140,10 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
|
|||
}
|
||||
else
|
||||
{
|
||||
if (shader)
|
||||
HWD.pfnSetShader(shader);
|
||||
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
|
||||
}
|
||||
if (shader)
|
||||
HWD.pfnSetShader(shader);
|
||||
HWD.pfnDrawPolygon(pSurf, pOutVerts, iNumPts, PolyFlags);
|
||||
}
|
||||
}
|
||||
|
||||
static int comparePolygons(const void *p1, const void *p2)
|
||||
|
|
@ -161,6 +178,15 @@ static int comparePolygons(const void *p1, const void *p2)
|
|||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
downloaded1 = 0;
|
||||
downloaded2 = 0;
|
||||
if (poly1->brightmap)
|
||||
downloaded1 = poly1->brightmap->downloaded; // there should be a opengl texture name here, usable for comparisons
|
||||
if (poly2->brightmap)
|
||||
downloaded2 = poly2->brightmap->downloaded;
|
||||
diff64 = downloaded1 - downloaded2;
|
||||
if (diff64 != 0) return diff64;
|
||||
|
||||
diff = poly1->polyFlags - poly2->polyFlags;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
|
|
@ -176,6 +202,10 @@ static int comparePolygons(const void *p1, const void *p2)
|
|||
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
|
||||
|
||||
diff = poly1->surf.LightInfo.directional - poly2->surf.LightInfo.directional;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
|
@ -219,15 +249,17 @@ static int comparePolygonsNoShaders(const void *p1, const void *p2)
|
|||
// the rendering backend to draw them.
|
||||
void HWR_RenderBatches(void)
|
||||
{
|
||||
int finalVertexWritePos = 0;// position in finalVertexArray
|
||||
int finalVertexWritePos = 0;// position in finalVertexArray
|
||||
int finalIndexWritePos = 0;// position in finalVertexIndexArray
|
||||
|
||||
int polygonReadPos = 0;// position in polygonIndexArray
|
||||
|
||||
int currentShader;
|
||||
int nextShader = 0;
|
||||
GLMipmap_t *currentTexture;
|
||||
GLMipmap_t *currentTexture = NULL;
|
||||
GLMipmap_t *nextTexture = NULL;
|
||||
GLMipmap_t *currentBrightmap = NULL;
|
||||
GLMipmap_t *nextBrightmap = NULL;
|
||||
FBITFIELD currentPolyFlags = 0;
|
||||
FBITFIELD nextPolyFlags = 0;
|
||||
FSurfaceInfo currentSurfaceInfo;
|
||||
|
|
@ -235,12 +267,13 @@ void HWR_RenderBatches(void)
|
|||
|
||||
int i;
|
||||
|
||||
if (!currently_batching)
|
||||
if (!currently_batching)
|
||||
I_Error("HWR_RenderBatches called without starting batching");
|
||||
|
||||
nextSurfaceInfo.LightInfo.fade_end = 0;
|
||||
nextSurfaceInfo.LightInfo.fade_start = 0;
|
||||
nextSurfaceInfo.LightInfo.light_level = 0;
|
||||
nextSurfaceInfo.LightInfo.directional = false;
|
||||
|
||||
currently_batching = false;// no longer collecting batches
|
||||
if (!polygonArraySize)
|
||||
|
|
@ -268,14 +301,16 @@ void HWR_RenderBatches(void)
|
|||
// sort order
|
||||
// 1. shader
|
||||
// 2. texture
|
||||
// 3. polyflags
|
||||
// 4. colors + light level
|
||||
// 3. brightmap
|
||||
// 4. polyflags
|
||||
// 5. colors + light level
|
||||
// not sure about what order of the last 2 should be, or if it even matters
|
||||
|
||||
ps_hw_batchdrawtime = I_GetPreciseTime();
|
||||
|
||||
currentShader = polygonArray[polygonIndexArray[0]].shader;
|
||||
currentTexture = polygonArray[polygonIndexArray[0]].texture;
|
||||
currentBrightmap = polygonArray[polygonIndexArray[0]].brightmap;
|
||||
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
|
||||
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
|
||||
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
|
||||
|
|
@ -289,9 +324,15 @@ void HWR_RenderBatches(void)
|
|||
}
|
||||
|
||||
if (currentPolyFlags & PF_NoTexture)
|
||||
currentTexture = NULL;
|
||||
else
|
||||
HWD.pfnSetTexture(currentTexture);
|
||||
{
|
||||
currentTexture = currentBrightmap = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
HWD.pfnSetTexture(currentTexture);
|
||||
if (currentBrightmap)
|
||||
HWD.pfnSetTexture(currentBrightmap);
|
||||
}
|
||||
|
||||
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
|
||||
{
|
||||
|
|
@ -361,16 +402,17 @@ void HWR_RenderBatches(void)
|
|||
int nextIndex = polygonIndexArray[polygonReadPos];
|
||||
nextShader = polygonArray[nextIndex].shader;
|
||||
nextTexture = polygonArray[nextIndex].texture;
|
||||
nextBrightmap = polygonArray[nextIndex].brightmap;
|
||||
nextPolyFlags = polygonArray[nextIndex].polyFlags;
|
||||
nextSurfaceInfo = polygonArray[nextIndex].surf;
|
||||
if (nextPolyFlags & PF_NoTexture)
|
||||
nextTexture = 0;
|
||||
nextTexture = nextBrightmap = 0;
|
||||
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
|
||||
{
|
||||
changeState = true;
|
||||
changeShader = true;
|
||||
}
|
||||
if (currentTexture != nextTexture)
|
||||
if (currentTexture != nextTexture || currentBrightmap != nextBrightmap)
|
||||
{
|
||||
changeState = true;
|
||||
changeTexture = true;
|
||||
|
|
@ -387,7 +429,8 @@ void HWR_RenderBatches(void)
|
|||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
|
||||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
|
||||
currentSurfaceInfo.LightInfo.directional != nextSurfaceInfo.LightInfo.directional)
|
||||
{
|
||||
changeState = true;
|
||||
changeSurfaceInfo = true;
|
||||
|
|
@ -406,7 +449,7 @@ void HWR_RenderBatches(void)
|
|||
if (changeState || stopFlag)
|
||||
{
|
||||
// execute draw call
|
||||
HWD.pfnDrawIndexedTriangles(¤tSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
|
||||
HWD.pfnDrawIndexedTriangles(¤tSurfaceInfo, finalVertexArray, finalIndexWritePos, currentPolyFlags, finalVertexIndexArray);
|
||||
// update stats
|
||||
ps_hw_numcalls++;
|
||||
ps_hw_numverts += finalIndexWritePos;
|
||||
|
|
@ -431,10 +474,14 @@ void HWR_RenderBatches(void)
|
|||
if (changeTexture)
|
||||
{
|
||||
// texture should be already ready for use from calls to SetTexture during batch collection
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
HWD.pfnSetTexture(nextTexture);
|
||||
currentTexture = nextTexture;
|
||||
changeTexture = false;
|
||||
|
||||
if (nextBrightmap)
|
||||
HWD.pfnSetTexture(nextBrightmap);
|
||||
currentBrightmap = nextBrightmap;
|
||||
|
||||
changeTexture = false;
|
||||
ps_hw_numtextures++;
|
||||
}
|
||||
if (changePolyFlags)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ typedef struct
|
|||
FUINT numVerts;
|
||||
FBITFIELD polyFlags;
|
||||
GLMipmap_t *texture;
|
||||
GLMipmap_t *brightmap;
|
||||
int shader;
|
||||
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
|
||||
boolean horizonSpecial;
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
|
|||
// Create a composite texture from patches, adapt the texture size to a power of 2
|
||||
// height and width for the hardware texture cache.
|
||||
//
|
||||
static void HWR_GenerateTexture(INT32 texnum, INT32 basetexnum, GLMapTexture_t *grtex)
|
||||
static void HWR_GenerateTexture(GLMapTexture_t *grtex, INT32 texnum, boolean noencoremap)
|
||||
{
|
||||
UINT8 *block;
|
||||
texture_t *texture;
|
||||
|
|
@ -477,7 +477,7 @@ static void HWR_GenerateTexture(INT32 texnum, INT32 basetexnum, GLMapTexture_t *
|
|||
grtex->mipmap.height = (UINT16)texture->height;
|
||||
grtex->mipmap.format = textureformat;
|
||||
|
||||
if (encoremap && R_TextureCanRemap(basetexnum))
|
||||
if (!noencoremap && encoremap)
|
||||
colormap += COLORMAP_REMAPOFFSET;
|
||||
|
||||
grtex->mipmap.colormap = Z_Calloc(sizeof(*grtex->mipmap.colormap), PU_HWRPATCHCOLMIPMAP, NULL);
|
||||
|
|
@ -797,7 +797,7 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, INT32 basetex)
|
|||
|
||||
// Generate texture if missing from the cache
|
||||
if (!grtex->mipmap.data && !grtex->mipmap.downloaded)
|
||||
HWR_GenerateTexture(tex, basetex, grtex);
|
||||
HWR_GenerateTexture(grtex, tex, !R_TextureCanRemap(basetex));
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtex->mipmap.downloaded)
|
||||
|
|
@ -807,6 +807,29 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, INT32 basetex)
|
|||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
if (R_GetTextureBrightmap(tex))
|
||||
{
|
||||
GLMapTexture_t *grtexbright;
|
||||
|
||||
// Every texture in memory, stored in the
|
||||
// hardware renderer's bit depth format. Wow!
|
||||
grtexbright = &gl_textures[R_GetTextureBrightmap(tex)];
|
||||
|
||||
// Generate texture if missing from the cache
|
||||
if (!grtexbright->mipmap.data && !grtexbright->mipmap.downloaded)
|
||||
HWR_GenerateTexture(grtexbright, R_GetTextureBrightmap(tex), true);
|
||||
|
||||
grtexbright->mipmap.flags |= TF_BRIGHTMAP;
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtexbright->mipmap.downloaded)
|
||||
HWD.pfnSetTexture(&grtexbright->mipmap);
|
||||
HWR_SetCurrentTexture(&grtexbright->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtexbright->mipmap.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
|
||||
return grtex;
|
||||
}
|
||||
|
||||
|
|
@ -966,6 +989,26 @@ void HWR_GetLevelFlat(levelflat_t *levelflat, boolean noencoremap)
|
|||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED);
|
||||
|
||||
if ((texturenum = R_GetTextureBrightmap(texturenum)))
|
||||
{
|
||||
// Every texture in memory, stored as a 8-bit flat. Wow!
|
||||
grtex = &gl_flats[texturenum];
|
||||
|
||||
// Generate flat if missing from the cache
|
||||
if (!grtex->mipmap.data && !grtex->mipmap.downloaded)
|
||||
HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum, true);
|
||||
|
||||
grtex->mipmap.flags |= TF_BRIGHTMAP;
|
||||
|
||||
// If hardware does not have the texture, then call pfnSetTexture to upload it
|
||||
if (!grtex->mipmap.downloaded)
|
||||
HWD.pfnSetTexture(&grtex->mipmap);
|
||||
HWR_SetCurrentTexture(&grtex->mipmap);
|
||||
|
||||
// The system-memory data can be purged now.
|
||||
Z_ChangeTag(grtex->mipmap.data, PU_HWRCACHE_UNLOCKED);
|
||||
}
|
||||
}
|
||||
else if (levelflat->type == LEVELFLAT_PATCH)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ enum ETextureFlags
|
|||
TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy
|
||||
TF_CHROMAKEYED = 0x00000010,
|
||||
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
|
||||
TF_BRIGHTMAP = 0x00000080,
|
||||
};
|
||||
|
||||
struct FTextureInfo
|
||||
|
|
@ -276,6 +277,7 @@ struct FLightInfo
|
|||
FUINT light_level;
|
||||
FUINT fade_start;
|
||||
FUINT fade_end;
|
||||
boolean directional;
|
||||
};
|
||||
typedef struct FLightInfo FLightInfo;
|
||||
|
||||
|
|
@ -320,6 +322,11 @@ typedef enum hwdshaderoption hwdshaderoption_t;
|
|||
enum hwdshaderinfo
|
||||
{
|
||||
HWD_SHADERINFO_LEVELTIME = 1,
|
||||
HWD_SHADERINFO_LIGHT_X,
|
||||
HWD_SHADERINFO_LIGHT_Y,
|
||||
HWD_SHADERINFO_LIGHT_Z,
|
||||
HWD_SHADERINFO_LIGHT_CONTRAST,
|
||||
HWD_SHADERINFO_LIGHT_BACKLIGHT,
|
||||
};
|
||||
|
||||
typedef enum hwdshaderinfo hwdshaderinfo_t;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,8 @@ typedef struct gl_vissprite_s
|
|||
mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out.
|
||||
} gl_vissprite_t;
|
||||
|
||||
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model);
|
||||
|
||||
// --------
|
||||
// hw_bsp.c
|
||||
// --------
|
||||
|
|
|
|||
|
|
@ -199,13 +199,68 @@ boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel)
|
|||
*lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(thing))
|
||||
*lightlevel = 0;
|
||||
else if (thing->renderflags & RF_ABSOLUTELIGHTLEVEL)
|
||||
*lightlevel = R_ThingLightLevel(thing);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
|
||||
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model)
|
||||
{
|
||||
const boolean semibright = R_ThingIsSemiBright(spr->mobj);
|
||||
const boolean papersprite = R_ThingIsPaperSprite(spr->mobj);
|
||||
|
||||
*lightlevel += R_ThingLightLevel(spr->mobj);
|
||||
|
||||
if (maplighting.directional == true && P_SectorUsesDirectionalLighting(sector))
|
||||
{
|
||||
if (model == false) // this is implemented by shader
|
||||
{
|
||||
fixed_t extralight = R_GetSpriteDirectionalLighting(
|
||||
papersprite
|
||||
? spr->angle + (spr->flip ? -ANGLE_90 : ANGLE_90)
|
||||
: R_PointToAngle(spr->mobj->x, spr->mobj->y) // fixme
|
||||
);
|
||||
|
||||
// Less change in contrast in dark sectors
|
||||
extralight = FixedMul(extralight, min(max(0, *lightlevel), 255) * FRACUNIT / 255);
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
// Papersprite contrast should match walls
|
||||
*lightlevel += FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// simple OGL approximation
|
||||
fixed_t tr = R_PointToDist(spr->mobj->x, spr->mobj->y);
|
||||
fixed_t xscale = FixedDiv((vid.width / 2) << FRACBITS, tr);
|
||||
|
||||
// Less change in contrast at further distances, to counteract DOOM diminished light
|
||||
fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT));
|
||||
extralight = FixedMul(extralight, min(n, FRACUNIT));
|
||||
|
||||
// Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance
|
||||
*lightlevel += FixedFloor((extralight * 2) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
}
|
||||
}
|
||||
|
||||
// Semibright objects will be made slightly brighter to compensate contrast
|
||||
if (semibright)
|
||||
{
|
||||
*lightlevel += 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (semibright)
|
||||
{
|
||||
*lightlevel = 192 + (*lightlevel >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional)
|
||||
{
|
||||
RGBA_t poly_color, tint_color, fade_color;
|
||||
|
||||
|
|
@ -256,9 +311,12 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
|||
Surface->PolyColor.rgba = poly_color.rgba;
|
||||
Surface->TintColor.rgba = tint_color.rgba;
|
||||
Surface->FadeColor.rgba = fade_color.rgba;
|
||||
|
||||
Surface->LightInfo.light_level = light_level;
|
||||
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
|
||||
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
|
||||
|
||||
Surface->LightInfo.directional = (maplighting.directional == true && directional == true);
|
||||
}
|
||||
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if this can work
|
||||
|
|
@ -306,13 +364,13 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg)
|
|||
return (FUINT)finallight;
|
||||
}
|
||||
|
||||
static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t *sector)
|
||||
static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t *sector, const boolean fof)
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
|
||||
if (slope != NULL && sector != NULL && P_ApplyLightOffsetFine(lightnum, sector))
|
||||
{
|
||||
finallight += slope->hwLightOffset;
|
||||
finallight += (fof ? -slope->hwLightOffset : slope->hwLightOffset);
|
||||
|
||||
if (finallight > 255) finallight = 255;
|
||||
if (finallight < 0) finallight = 0;
|
||||
|
|
@ -504,8 +562,8 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
|||
for (i = 0, v3d = planeVerts; i < nrPlaneVerts; i++,v3d++,pv++)
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector);
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap);
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
if (PolyFlags & PF_EnvironmentTrans)
|
||||
{
|
||||
|
|
@ -744,7 +802,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
|
|||
{
|
||||
INT32 shader = SHADER_DEFAULT;
|
||||
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
|
|
@ -2267,7 +2325,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
|||
v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y);
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap);
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting((FOFsector != NULL) ? FOFsector : gl_frontsector));
|
||||
|
||||
if (blendmode & PF_Translucent)
|
||||
{
|
||||
|
|
@ -3151,7 +3209,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
|
|||
colormap = thing->subsector->sector->extra_colormap;
|
||||
}
|
||||
|
||||
HWR_Lighting(&sSurf, 255, colormap);
|
||||
HWR_Lighting(&sSurf, 255, colormap, P_SectorUsesDirectionalLighting(thing->subsector->sector));
|
||||
sSurf.PolyColor.s.alpha = 255;
|
||||
|
||||
if (thing->whiteshadow == true)
|
||||
|
|
@ -3394,8 +3452,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
}
|
||||
}
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 192 + (lightlevel>>1);
|
||||
if (!lightset)
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
|
||||
for (i = 0; i < sector->numlights; i++)
|
||||
{
|
||||
|
|
@ -3408,9 +3466,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
if (!lightset)
|
||||
{
|
||||
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 192 + (lightlevel>>1);
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
}
|
||||
|
||||
if (!R_ThingIsFullBright(spr->mobj) && !(spr->mobj->renderflags & RF_NOCOLORMAPS))
|
||||
|
|
@ -3477,7 +3533,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(spr->mobj));
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
|
|
@ -3506,7 +3562,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
|
|||
wallVerts[0].y = bot;
|
||||
wallVerts[1].y = endbot;
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector));
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
|
|
@ -3582,7 +3638,9 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
if (!spr->mobj->subsector)
|
||||
return;
|
||||
|
||||
if (spr->mobj->subsector->sector->numlights && !splat)
|
||||
if (spr->mobj->subsector->sector->numlights
|
||||
&& (spr->mobj->renderflags & RF_ABSOLUTELIGHTLEVEL) == 0
|
||||
&& !splat)
|
||||
{
|
||||
HWR_SplitSprite(spr);
|
||||
return;
|
||||
|
|
@ -3796,10 +3854,10 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
|||
else if (!lightset)
|
||||
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
if (!lightset)
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(spr->mobj));
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -3946,7 +4004,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
|||
|
||||
//lightlevel = 128 + (lightlevel>>1);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector));
|
||||
}
|
||||
|
||||
// Determine the blendmode and translucency value
|
||||
|
|
@ -4410,7 +4468,7 @@ static void HWR_DrawSprites(void)
|
|||
#ifdef BAD_MODEL_OPTIONS
|
||||
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_glmodellighting.value);
|
||||
#else
|
||||
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, false);
|
||||
HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, 1);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < gl_visspritecount; i++)
|
||||
|
|
@ -5867,8 +5925,18 @@ void HWR_RenderPlayerView(void)
|
|||
ClearColor.alpha = 1.0f;
|
||||
|
||||
if (cv_glshaders.value)
|
||||
{
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
|
||||
|
||||
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
|
||||
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
|
||||
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
|
||||
}
|
||||
|
||||
if (viewssnum == 0) // Only do it if it's the first screen being rendered
|
||||
HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
|
||||
|
||||
|
|
@ -6072,7 +6140,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
|
|||
INT32 shader = SHADER_DEFAULT;
|
||||
|
||||
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void HWR_DrawScreenFinalTexture(int width, int height);
|
|||
|
||||
// This stuff is put here so models can use them
|
||||
boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel);
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional);
|
||||
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
|
||||
|
||||
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
|
||||
|
|
|
|||
|
|
@ -1359,10 +1359,10 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
|
|||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
if (!lightset)
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, true);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(spr->mobj));
|
||||
}
|
||||
else
|
||||
Surf.PolyColor.rgba = 0xFFFFFFFF;
|
||||
|
|
|
|||
|
|
@ -580,6 +580,10 @@ static PFNglGetUniformLocation pglGetUniformLocation;
|
|||
// 13062019
|
||||
typedef enum
|
||||
{
|
||||
// textures
|
||||
gluniform_tex,
|
||||
gluniform_brightmap,
|
||||
|
||||
// lighting
|
||||
gluniform_poly_color,
|
||||
gluniform_tint_color,
|
||||
|
|
@ -587,6 +591,9 @@ typedef enum
|
|||
gluniform_lighting,
|
||||
gluniform_fade_start,
|
||||
gluniform_fade_end,
|
||||
gluniform_light_dir,
|
||||
gluniform_light_contrast,
|
||||
gluniform_light_backlight,
|
||||
|
||||
// misc. (custom shaders)
|
||||
gluniform_leveltime,
|
||||
|
|
@ -617,6 +624,11 @@ static gl_shaderstate_t gl_shaderstate;
|
|||
|
||||
// Shader info
|
||||
static INT32 shader_leveltime = 0;
|
||||
static float shader_light_x = 0.0f;
|
||||
static float shader_light_y = 0.0f;
|
||||
static float shader_light_z = 0.0f;
|
||||
static INT32 shader_light_contrast = 0;
|
||||
static INT32 shader_light_backlight = 0;
|
||||
|
||||
// Lactozilla: Shader functions
|
||||
static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar *vert_shader, const GLchar *frag_shader);
|
||||
|
|
@ -625,56 +637,6 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
|||
|
||||
static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
// ================
|
||||
// Vertex shaders
|
||||
// ================
|
||||
|
||||
//
|
||||
// Generic vertex shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// replicates the way fixed function lighting is used by the model lighting option,
|
||||
// stores the lighting result to gl_Color
|
||||
// (ambient lighting of 0.75 and diffuse lighting from above)
|
||||
#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"float nDotVP = dot(gl_Normal, vec3(0, 1, 0));\n" \
|
||||
"float light = 0.75 + max(nDotVP, 0.0);\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
|
||||
//
|
||||
// Generic fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Software fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_DOOM_COLORMAP \
|
||||
"float R_DoomColormap(float light, float z)\n" \
|
||||
"{\n" \
|
||||
|
|
@ -694,17 +656,17 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"}\n"
|
||||
|
||||
#define GLSL_SOFTWARE_TINT_EQUATION \
|
||||
"if (tint_color.a > 0.0) {\n" \
|
||||
"if (mix(tint_color.a, 0.0, brightmap_mix) > 0.0) {\n" \
|
||||
"float color_bright = sqrt((base_color.r * base_color.r) + (base_color.g * base_color.g) + (base_color.b * base_color.b));\n" \
|
||||
"float strength = sqrt(9.0 * tint_color.a);\n" \
|
||||
"float strength = sqrt(9.0 * mix(tint_color.a, 0.0, brightmap_mix));\n" \
|
||||
"final_color.r = clamp((color_bright * (tint_color.r * strength)) + (base_color.r * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.g = clamp((color_bright * (tint_color.g * strength)) + (base_color.g * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"final_color.b = clamp((color_bright * (tint_color.b * strength)) + (base_color.b * (1.0 - strength)), 0.0, 1.0);\n" \
|
||||
"}\n"
|
||||
|
||||
#define GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"float darkness = R_DoomLightingEquation(lighting);\n" \
|
||||
"if (fade_start != 0.0 || fade_end != 31.0) {\n" \
|
||||
"float darkness = R_DoomLightingEquation(final_lighting);\n" \
|
||||
"if (fade_start > 0.0 || fade_end < 31.0) {\n" \
|
||||
"float fs = fade_start / 31.0;\n" \
|
||||
"float fe = fade_end / 31.0;\n" \
|
||||
"float fd = fe - fs;\n" \
|
||||
|
|
@ -742,10 +704,72 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"final_color.b += colorIntensity;\n" \
|
||||
"} else {\n" \
|
||||
"final_color.b -= colorIntensity;\n" \
|
||||
"}\n" \
|
||||
"}\n"
|
||||
|
||||
// ================
|
||||
// Vertex shaders
|
||||
// ================
|
||||
|
||||
//
|
||||
// Generic vertex shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_VERTEX_SHADER \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"gl_FrontColor = gl_Color;\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// reinterpretation of sprite lighting for models
|
||||
// it's a combination of how it works for normal sprites & papersprites
|
||||
#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform vec3 light_dir;\n" \
|
||||
"uniform float light_contrast;\n" \
|
||||
"uniform float light_backlight;\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"float light = lighting;\n" \
|
||||
"if (length(light_dir) > 0.000001) {\n" \
|
||||
"mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \
|
||||
"mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \
|
||||
"float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \
|
||||
"extralight *= light_contrast - light_backlight;\n" \
|
||||
"extralight *= lighting / 255.0;\n" \
|
||||
"light += extralight * 2.5;\n" \
|
||||
"}\n" \
|
||||
"light = clamp(light / 255.0, 0.0, 1.0);\n" \
|
||||
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
|
||||
//
|
||||
// Generic fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_DEFAULT_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"void main(void) {\n" \
|
||||
"gl_FragColor = texture2D(tex, gl_TexCoord[0].st) * poly_color;\n" \
|
||||
"}\0"
|
||||
|
||||
//
|
||||
// Software fragment shader
|
||||
//
|
||||
|
||||
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler2D brightmap;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
|
|
@ -758,6 +782,9 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
"float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \
|
||||
"float light_gain = (255.0 - lighting) * brightmap_mix;\n" \
|
||||
"float final_lighting = lighting + light_gain;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
|
|
@ -768,10 +795,10 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
// accompanying vertex shader (stored in gl_Color)
|
||||
#define GLSL_SOFTWARE_MODEL_LIGHTING_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler2D brightmap;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform float fade_start;\n" \
|
||||
"uniform float fade_end;\n" \
|
||||
GLSL_DOOM_COLORMAP \
|
||||
|
|
@ -780,9 +807,12 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
"float final_lighting = gl_Color.r * 255.0;\n" \
|
||||
"float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \
|
||||
"float light_gain = (255.0 - final_lighting) * brightmap_mix;\n" \
|
||||
"final_lighting += light_gain;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color *= gl_Color;\n" \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
"}\0"
|
||||
|
|
@ -796,6 +826,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
|
||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||
"uniform sampler2D tex;\n" \
|
||||
"uniform sampler2D brightmap;\n" \
|
||||
"uniform vec4 poly_color;\n" \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
|
|
@ -817,6 +848,9 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n" \
|
||||
"vec4 base_color = texel * poly_color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
"float brightmap_mix = floor(texture2D(brightmap, gl_TexCoord[0].st).r);\n" \
|
||||
"float light_gain = (255.0 - lighting) * brightmap_mix;\n" \
|
||||
"float final_lighting = lighting + light_gain;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"final_color.a = texel.a * poly_color.a;\n" \
|
||||
|
|
@ -840,6 +874,9 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"void main(void) {\n" \
|
||||
"vec4 base_color = gl_Color;\n" \
|
||||
"vec4 final_color = base_color;\n" \
|
||||
"float brightmap_mix = 0.0;\n" \
|
||||
"float light_gain = 0.0;\n" \
|
||||
"float final_lighting = lighting + light_gain;\n" \
|
||||
GLSL_SOFTWARE_TINT_EQUATION \
|
||||
GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"gl_FragColor = final_color;\n" \
|
||||
|
|
@ -1021,6 +1058,21 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
|
|||
case HWD_SHADERINFO_LEVELTIME:
|
||||
shader_leveltime = value;
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_X:
|
||||
shader_light_x = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_Y:
|
||||
shader_light_y = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_Z:
|
||||
shader_light_z = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_CONTRAST:
|
||||
shader_light_contrast = value;
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_BACKLIGHT:
|
||||
shader_light_backlight = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1154,14 +1206,16 @@ EXPORT void HWRAPI(CleanShaders) (void)
|
|||
// -----------------+
|
||||
// SetNoTexture : Disable texture
|
||||
// -----------------+
|
||||
static void SetNoTexture(void)
|
||||
static void SetNoTexture(GLenum texture)
|
||||
{
|
||||
// Disable texture.
|
||||
if (tex_downloaded != NOTEXTURE_NUM)
|
||||
{
|
||||
if (NOTEXTURE_NUM == 0)
|
||||
pglGenTextures(1, &NOTEXTURE_NUM);
|
||||
pglActiveTexture(texture);
|
||||
pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
tex_downloaded = NOTEXTURE_NUM;
|
||||
}
|
||||
}
|
||||
|
|
@ -1307,7 +1361,7 @@ void SetStates(void)
|
|||
SetBlend(0);
|
||||
|
||||
tex_downloaded = 0;
|
||||
SetNoTexture();
|
||||
SetNoTexture(GL_TEXTURE0);
|
||||
|
||||
pglPolygonOffset(-1.0f, -1.0f);
|
||||
|
||||
|
|
@ -1782,7 +1836,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
|
|||
}
|
||||
if (PolyFlags & PF_NoTexture)
|
||||
{
|
||||
SetNoTexture();
|
||||
SetNoTexture(GL_TEXTURE0);
|
||||
}
|
||||
}
|
||||
CurrentPolyFlags = PolyFlags;
|
||||
|
|
@ -1906,6 +1960,13 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
else
|
||||
GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format);
|
||||
|
||||
if (!(pTexInfo->flags & TF_BRIGHTMAP))
|
||||
{
|
||||
tex_downloaded = 0; // force update
|
||||
SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
|
||||
}
|
||||
|
||||
pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0);
|
||||
pglBindTexture(GL_TEXTURE_2D, num);
|
||||
tex_downloaded = num;
|
||||
|
||||
|
|
@ -1996,6 +2057,8 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
|||
|
||||
if (maximumAnisotropy)
|
||||
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_filter);
|
||||
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
// -----------------+
|
||||
|
|
@ -2005,14 +2068,22 @@ EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
|
|||
{
|
||||
if (!pTexInfo)
|
||||
{
|
||||
SetNoTexture();
|
||||
SetNoTexture(GL_TEXTURE0);
|
||||
return;
|
||||
}
|
||||
else if (pTexInfo->downloaded)
|
||||
{
|
||||
if (pTexInfo->downloaded != tex_downloaded)
|
||||
{
|
||||
if (!(pTexInfo->flags & TF_BRIGHTMAP))
|
||||
{
|
||||
tex_downloaded = 0; // force update
|
||||
SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
|
||||
}
|
||||
|
||||
pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0);
|
||||
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
|
||||
pglActiveTexture(GL_TEXTURE0);
|
||||
tex_downloaded = pTexInfo->downloaded;
|
||||
}
|
||||
}
|
||||
|
|
@ -2084,15 +2155,40 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
|||
function (uniform, a, b, c, d);
|
||||
|
||||
// polygon
|
||||
UNIFORM_1(shader->uniforms[gluniform_tex], 0, pglUniform1i);
|
||||
UNIFORM_1(shader->uniforms[gluniform_brightmap], 1, pglUniform1i);
|
||||
UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f);
|
||||
UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f);
|
||||
UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f);
|
||||
|
||||
boolean directional = false;
|
||||
if (Surface != NULL)
|
||||
{
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], Surface->LightInfo.light_level, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], Surface->LightInfo.fade_start, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], Surface->LightInfo.fade_end, pglUniform1f);
|
||||
directional = Surface->LightInfo.directional;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], 255, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], 0, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], 31, pglUniform1f);
|
||||
}
|
||||
|
||||
if (directional)
|
||||
{
|
||||
UNIFORM_3(shader->uniforms[gluniform_light_dir], shader_light_x, shader_light_y, shader_light_z, pglUniform3f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_contrast], shader_light_contrast, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_backlight], shader_light_backlight, pglUniform1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIFORM_3(shader->uniforms[gluniform_light_dir], 0, 0, 0, pglUniform3f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_contrast], 0, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_backlight], 0, pglUniform1f);
|
||||
}
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], ((float)shader_leveltime) / TICRATE, pglUniform1f);
|
||||
|
||||
#undef UNIFORM_1
|
||||
|
|
@ -2183,6 +2279,10 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar
|
|||
// 13062019
|
||||
#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform);
|
||||
|
||||
// textures
|
||||
shader->uniforms[gluniform_tex] = GETUNI("tex");
|
||||
shader->uniforms[gluniform_brightmap] = GETUNI("brightmap");
|
||||
|
||||
// lighting
|
||||
shader->uniforms[gluniform_poly_color] = GETUNI("poly_color");
|
||||
shader->uniforms[gluniform_tint_color] = GETUNI("tint_color");
|
||||
|
|
@ -2190,6 +2290,9 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i, const GLchar
|
|||
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
|
||||
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
|
||||
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
|
||||
shader->uniforms[gluniform_light_dir] = GETUNI("light_dir");
|
||||
shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast");
|
||||
shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight");
|
||||
|
||||
// misc. (custom shaders)
|
||||
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
|
||||
|
|
@ -2782,13 +2885,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
|
|||
diffuse[2] = poly.blue;
|
||||
diffuse[3] = poly.alpha;
|
||||
|
||||
if (ambient[0] > 0.75f)
|
||||
ambient[0] = 0.75f;
|
||||
if (ambient[1] > 0.75f)
|
||||
ambient[1] = 0.75f;
|
||||
if (ambient[2] > 0.75f)
|
||||
ambient[2] = 0.75f;
|
||||
|
||||
pglLightfv(GL_LIGHT0, GL_POSITION, LightPos);
|
||||
|
||||
pglEnable(GL_LIGHTING);
|
||||
|
|
|
|||
|
|
@ -3658,23 +3658,26 @@ void P_UpdateSegLightOffset(seg_t *li)
|
|||
|
||||
boolean P_SectorUsesDirectionalLighting(const sector_t *sector)
|
||||
{
|
||||
// explicitly turned on
|
||||
if (sector->flags & MSF_DIRECTIONLIGHTING)
|
||||
if (sector != NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// explicitly turned on
|
||||
if (sector->flags & MSF_DIRECTIONLIGHTING)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// explicitly turned off
|
||||
if (sector->flags & MSF_FLATLIGHTING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// explicitly turned off
|
||||
if (sector->flags & MSF_FLATLIGHTING)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// automatically turned on
|
||||
if (sector->ceilingpic == skyflatnum)
|
||||
{
|
||||
// sky is visible
|
||||
return true;
|
||||
// automatically turned on
|
||||
if (sector->ceilingpic == skyflatnum)
|
||||
{
|
||||
// sky is visible
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// default is off, for indoors
|
||||
|
|
|
|||
|
|
@ -1679,7 +1679,7 @@ static void R_ProjectBoundingBox(mobj_t *thing, vissprite_t *vis)
|
|||
box->x2test = 0;
|
||||
}
|
||||
|
||||
static fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
|
||||
fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
|
||||
{
|
||||
// Copied from P_UpdateSegLightOffset
|
||||
const UINT8 contrast = std::min(std::max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ extern INT16 negonearray[MAXVIDWIDTH];
|
|||
extern INT16 screenheightarray[MAXVIDWIDTH];
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
fixed_t R_GetSpriteDirectionalLighting(angle_t angle);
|
||||
|
||||
//SoM: 6/5/2000: Light sprites correctly!
|
||||
void R_AddSprites(sector_t *sec, INT32 lightlevel);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue