mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-04-22 02:00:11 +00:00
OpenGL sprite+model directional light
This commit is contained in:
parent
83e3401806
commit
9382031337
10 changed files with 246 additions and 104 deletions
|
|
@ -202,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;
|
||||
}
|
||||
|
||||
|
|
@ -269,6 +273,7 @@ void HWR_RenderBatches(void)
|
|||
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)
|
||||
|
|
@ -424,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;
|
||||
|
|
|
|||
|
|
@ -277,6 +277,7 @@ struct FLightInfo
|
|||
FUINT light_level;
|
||||
FUINT fade_start;
|
||||
FUINT fade_end;
|
||||
boolean directional;
|
||||
};
|
||||
typedef struct FLightInfo FLightInfo;
|
||||
|
||||
|
|
@ -321,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);
|
||||
|
|
|
|||
|
|
@ -1355,10 +1355,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;
|
||||
|
|
|
|||
|
|
@ -591,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,
|
||||
|
|
@ -621,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);
|
||||
|
|
@ -629,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" \
|
||||
|
|
@ -707,7 +665,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"}\n"
|
||||
|
||||
#define GLSL_SOFTWARE_FADE_EQUATION \
|
||||
"float darkness = R_DoomLightingEquation(lighting + light_gain);\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" \
|
||||
|
|
@ -746,7 +704,68 @@ 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" \
|
||||
|
|
@ -765,6 +784,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"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" \
|
||||
|
|
@ -779,7 +799,6 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"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 \
|
||||
|
|
@ -788,11 +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 - lighting) * brightmap_mix;\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"
|
||||
|
|
@ -830,6 +850,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"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" \
|
||||
|
|
@ -855,6 +876,7 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f};
|
|||
"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" \
|
||||
|
|
@ -1036,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;
|
||||
}
|
||||
|
|
@ -2121,12 +2158,35 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
|
|||
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
|
||||
|
|
@ -2228,6 +2288,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");
|
||||
|
|
@ -2820,13 +2883,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