mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 04:41:23 +00:00
Merge remote-tracking branch 'remotes/bird/isolatedbatching' into awful-mix
# Conflicts: # src/hardware/hw_main.c # src/hardware/r_opengl/r_opengl.c
This commit is contained in:
commit
0e78159ea1
7 changed files with 885 additions and 500 deletions
|
@ -231,6 +231,7 @@ struct FSurfaceInfo
|
||||||
{
|
{
|
||||||
FUINT PolyFlags;
|
FUINT PolyFlags;
|
||||||
RGBA_t PolyColor;
|
RGBA_t PolyColor;
|
||||||
|
RGBA_t TintColor;
|
||||||
RGBA_t FadeColor;
|
RGBA_t FadeColor;
|
||||||
FLightInfo LightInfo; // jimita 14032019
|
FLightInfo LightInfo; // jimita 14032019
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,8 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
|
||||||
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
|
EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
|
||||||
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
|
||||||
|
|
||||||
|
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
|
||||||
|
|
||||||
EXPORT void HWRAPI(FlushScreenTextures) (void);
|
EXPORT void HWRAPI(FlushScreenTextures) (void);
|
||||||
EXPORT void HWRAPI(StartScreenWipe) (void);
|
EXPORT void HWRAPI(StartScreenWipe) (void);
|
||||||
EXPORT void HWRAPI(EndScreenWipe) (void);
|
EXPORT void HWRAPI(EndScreenWipe) (void);
|
||||||
|
@ -64,7 +66,7 @@ EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
|
||||||
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
|
||||||
|
|
||||||
// jimita
|
// jimita
|
||||||
EXPORT void HWRAPI(LoadShaders) (void);
|
EXPORT boolean HWRAPI(LoadShaders) (void);
|
||||||
EXPORT void HWRAPI(KillShaders) (void);
|
EXPORT void HWRAPI(KillShaders) (void);
|
||||||
EXPORT void HWRAPI(SetShader) (int shader);
|
EXPORT void HWRAPI(SetShader) (int shader);
|
||||||
EXPORT void HWRAPI(UnSetShader) (void);
|
EXPORT void HWRAPI(UnSetShader) (void);
|
||||||
|
@ -111,6 +113,8 @@ struct hwdriver_s
|
||||||
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
|
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
|
||||||
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
|
DrawScreenFinalTexture pfnDrawScreenFinalTexture;
|
||||||
|
|
||||||
|
RenderSkyDome pfnRenderSkyDome;
|
||||||
|
|
||||||
LoadShaders pfnLoadShaders;
|
LoadShaders pfnLoadShaders;
|
||||||
KillShaders pfnKillShaders;
|
KillShaders pfnKillShaders;
|
||||||
SetShader pfnSetShader;
|
SetShader pfnSetShader;
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
#include "../p_slopes.h"
|
#include "../p_slopes.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h> // qsort
|
||||||
|
|
||||||
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -67,15 +69,16 @@ CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NU
|
||||||
|
|
||||||
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
// Unfortunately, this can no longer be saved..
|
|
||||||
consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t,
|
consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL|CV_SAVE, grfiltermode_cons_t,
|
||||||
CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL};
|
CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t,
|
consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL|CV_SAVE, granisotropicmode_cons_t,
|
||||||
CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL};
|
CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_grbatching = {"gr_batching", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static void CV_filtermode_ONChange(void)
|
static void CV_filtermode_ONChange(void)
|
||||||
{
|
{
|
||||||
|
@ -116,6 +119,8 @@ static line_t *gr_linedef;
|
||||||
static sector_t *gr_frontsector;
|
static sector_t *gr_frontsector;
|
||||||
static sector_t *gr_backsector;
|
static sector_t *gr_backsector;
|
||||||
|
|
||||||
|
boolean gr_shadersavailable = true;
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
// View position
|
// View position
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -139,6 +144,8 @@ static INT32 drawcount = 0;
|
||||||
|
|
||||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor)
|
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor)
|
||||||
{
|
{
|
||||||
|
if (!cv_grshaders.value || (cv_grshaders.value && !cv_grfog.value) || !gr_shadersavailable)
|
||||||
|
{
|
||||||
RGBA_t mix_color, fog_color, final_color;
|
RGBA_t mix_color, fog_color, final_color;
|
||||||
INT32 mix;
|
INT32 mix;
|
||||||
float fog_alpha;
|
float fog_alpha;
|
||||||
|
@ -189,10 +196,20 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UIN
|
||||||
Surface->PolyColor.rgba = final_color.rgba;
|
Surface->PolyColor.rgba = final_color.rgba;
|
||||||
Surface->FadeColor.rgba = fog_color.rgba;
|
Surface->FadeColor.rgba = fog_color.rgba;
|
||||||
Surface->LightInfo.light_level = light_level;
|
Surface->LightInfo.light_level = light_level;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Surface->PolyColor.rgba = 0xFFFFFFFF;
|
||||||
|
Surface->TintColor.rgba = mixcolor;
|
||||||
|
Surface->FadeColor.rgba = fadecolor;
|
||||||
|
Surface->LightInfo.light_level = light_level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HWR_NoColormapLighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor)
|
void HWR_NoColormapLighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mixcolor, UINT32 fadecolor)
|
||||||
{
|
{
|
||||||
|
if (!cv_grshaders.value || (cv_grshaders.value && !cv_grfog.value) || !gr_shadersavailable)
|
||||||
|
{
|
||||||
RGBA_t mix_color, fog_color, final_color;
|
RGBA_t mix_color, fog_color, final_color;
|
||||||
INT32 mix, fogmix, lightmix;
|
INT32 mix, fogmix, lightmix;
|
||||||
float fog_alpha;
|
float fog_alpha;
|
||||||
|
@ -209,10 +226,6 @@ void HWR_NoColormapLighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mix
|
||||||
mix_color.rgba = mixcolor;
|
mix_color.rgba = mixcolor;
|
||||||
fog_color.rgba = fadecolor;
|
fog_color.rgba = fadecolor;
|
||||||
|
|
||||||
// if shaders are off, or shaders are on, but fog is off:
|
|
||||||
// modulate colors by light here
|
|
||||||
if (!cv_grshaders.value || (cv_grshaders.value && !cv_grfog.value))
|
|
||||||
{
|
|
||||||
mix = (mix_color.s.alpha*255)/25;
|
mix = (mix_color.s.alpha*255)/25;
|
||||||
fogmix = (fog_color.s.alpha*255)/25;
|
fogmix = (fog_color.s.alpha*255)/25;
|
||||||
|
|
||||||
|
@ -236,11 +249,6 @@ void HWR_NoColormapLighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mix
|
||||||
final_color.s.green = final_color.s.green+((UINT8)(CALCLIGHT((0xFF-fogmix),(0xFF-lightmix))+CALCLIGHT(fog_color.s.green,(0xFF-lightmix))));
|
final_color.s.green = final_color.s.green+((UINT8)(CALCLIGHT((0xFF-fogmix),(0xFF-lightmix))+CALCLIGHT(fog_color.s.green,(0xFF-lightmix))));
|
||||||
final_color.s.blue = final_color.s.blue+((UINT8)(CALCLIGHT((0xFF-fogmix),(0xFF-lightmix))+CALCLIGHT(fog_color.s.blue,(0xFF-lightmix))));
|
final_color.s.blue = final_color.s.blue+((UINT8)(CALCLIGHT((0xFF-fogmix),(0xFF-lightmix))+CALCLIGHT(fog_color.s.blue,(0xFF-lightmix))));
|
||||||
final_color.s.alpha = 0xFF;
|
final_color.s.alpha = 0xFF;
|
||||||
}
|
|
||||||
// if shaders are on:
|
|
||||||
// modulate colors by light on the shader
|
|
||||||
else
|
|
||||||
final_color.rgba = 0xFFFFFFFF;
|
|
||||||
|
|
||||||
// Fog.
|
// Fog.
|
||||||
fog_color.rgba = fadecolor;
|
fog_color.rgba = fadecolor;
|
||||||
|
@ -254,6 +262,14 @@ void HWR_NoColormapLighting(FSurfaceInfo *Surface, INT32 light_level, UINT32 mix
|
||||||
Surface->PolyColor.rgba = final_color.rgba;
|
Surface->PolyColor.rgba = final_color.rgba;
|
||||||
Surface->FadeColor.rgba = fog_color.rgba;
|
Surface->FadeColor.rgba = fog_color.rgba;
|
||||||
Surface->LightInfo.light_level = lightmix;
|
Surface->LightInfo.light_level = lightmix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Surface->PolyColor.rgba = 0xFFFFFFFF;
|
||||||
|
Surface->TintColor.rgba = mixcolor;
|
||||||
|
Surface->FadeColor.rgba = fadecolor;
|
||||||
|
Surface->LightInfo.light_level = light_level;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work
|
UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this can work
|
||||||
|
@ -855,7 +871,7 @@ void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfa
|
||||||
|
|
||||||
// HWR_DrawSkyWalls
|
// HWR_DrawSkyWalls
|
||||||
// Draw walls into the depth buffer so that anything behind is culled properly
|
// Draw walls into the depth buffer so that anything behind is culled properly
|
||||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top)
|
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf)
|
||||||
{
|
{
|
||||||
HWD.pfnSetTexture(NULL);
|
HWD.pfnSetTexture(NULL);
|
||||||
// no texture
|
// no texture
|
||||||
|
@ -864,12 +880,6 @@ void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom,
|
||||||
wallVerts[0].s = wallVerts[3].s = 0;
|
wallVerts[0].s = wallVerts[3].s = 0;
|
||||||
wallVerts[2].s = wallVerts[1].s = 0;
|
wallVerts[2].s = wallVerts[1].s = 0;
|
||||||
|
|
||||||
if (bottom != 0 || top != 0)
|
|
||||||
{
|
|
||||||
// set top/bottom coords
|
|
||||||
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this
|
|
||||||
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall
|
|
||||||
}
|
|
||||||
HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL);
|
HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_NoTexture, 255, NULL);
|
||||||
// PF_Invisible so it's not drawn into the colour buffer
|
// PF_Invisible so it's not drawn into the colour buffer
|
||||||
// PF_NoTexture for no texture
|
// PF_NoTexture for no texture
|
||||||
|
@ -977,6 +987,109 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
worldlow = gr_backsector->floorheight;
|
worldlow = gr_backsector->floorheight;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Sky culling
|
||||||
|
if (!gr_curline->polyseg) // Don't do it for polyobjects
|
||||||
|
{
|
||||||
|
// Sky Ceilings
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
|
||||||
|
|
||||||
|
if (gr_frontsector->ceilingpic == skyflatnum)
|
||||||
|
{
|
||||||
|
if (gr_backsector->ceilingpic == skyflatnum)
|
||||||
|
{
|
||||||
|
// Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the
|
||||||
|
// backsector is lower
|
||||||
|
if ((worldhigh <= worldtop && worldhighslope <= worldtopslope)// Assuming ESLOPE is always on with my changes
|
||||||
|
&& (worldhigh != worldtop || worldhighslope != worldtopslope))
|
||||||
|
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[0].y = FIXED_TO_FLOAT(worldhigh);
|
||||||
|
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
|
||||||
|
#else
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh);
|
||||||
|
#endif
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only the frontsector is sky, just draw a skywall from the front ceiling
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||||
|
#else
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
#endif
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gr_backsector->ceilingpic == skyflatnum)
|
||||||
|
{
|
||||||
|
// Only the backsector is sky, just draw a skywall from the front ceiling
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||||
|
#else
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
#endif
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Sky Floors
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
|
||||||
|
|
||||||
|
if (gr_frontsector->floorpic == skyflatnum)
|
||||||
|
{
|
||||||
|
if (gr_backsector->floorpic == skyflatnum)
|
||||||
|
{
|
||||||
|
// Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the
|
||||||
|
// it's higher, also needs to check for bottomtexture as the floors don't usually move down
|
||||||
|
// when both sides are sky floors
|
||||||
|
if ((worldlow >= worldbottom && worldlowslope >= worldbottomslope)
|
||||||
|
&& (worldlow != worldbottom || worldlowslope != worldbottomslope)
|
||||||
|
// Removing the second line above will render more rarely visible skywalls. Example: Cave garden ceiling in Dark race
|
||||||
|
&& !(gr_sidedef->bottomtexture))
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
|
||||||
|
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
|
||||||
|
#else
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Only the backsector has sky, just draw a skywall from the back floor
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||||
|
#else
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((gr_backsector->floorpic == skyflatnum) && !(gr_sidedef->bottomtexture))
|
||||||
|
{
|
||||||
|
// Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[3].y = FIXED_TO_FLOAT(worldlow);
|
||||||
|
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
|
||||||
|
#else
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// hack to allow height changes in outdoor areas
|
// hack to allow height changes in outdoor areas
|
||||||
// This is what gets rid of the upper textures if there should be sky
|
// This is what gets rid of the upper textures if there should be sky
|
||||||
if (gr_frontsector->ceilingpic == skyflatnum &&
|
if (gr_frontsector->ceilingpic == skyflatnum &&
|
||||||
|
@ -1422,86 +1535,6 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
else
|
else
|
||||||
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
|
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Isn't this just the most lovely mess
|
|
||||||
if (!gr_curline->polyseg) // Don't do it for polyobjects
|
|
||||||
{
|
|
||||||
if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum)
|
|
||||||
{
|
|
||||||
fixed_t depthwallheight;
|
|
||||||
|
|
||||||
if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn
|
|
||||||
depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
|
|
||||||
else
|
|
||||||
depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight;
|
|
||||||
|
|
||||||
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
|
|
||||||
{
|
|
||||||
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
|
|
||||||
{
|
|
||||||
if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX);
|
|
||||||
else
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX);
|
|
||||||
}
|
|
||||||
// behind sector is not a thok barrier
|
|
||||||
else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
|
|
||||||
// gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on
|
|
||||||
}
|
|
||||||
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
|
|
||||||
{
|
|
||||||
if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height
|
|
||||||
|| gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height
|
|
||||||
|| gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
|
|
||||||
}
|
|
||||||
else // neither sectors are thok barriers
|
|
||||||
{
|
|
||||||
if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower
|
|
||||||
|| gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// And now for sky floors!
|
|
||||||
if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum)
|
|
||||||
{
|
|
||||||
fixed_t depthwallheight;
|
|
||||||
|
|
||||||
if (!gr_sidedef->bottomtexture)
|
|
||||||
depthwallheight = worldbottom > worldlow ? worldbottom : worldlow;
|
|
||||||
else
|
|
||||||
depthwallheight = worldbottom < worldlow ? worldbottom : worldlow;
|
|
||||||
|
|
||||||
if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier
|
|
||||||
{
|
|
||||||
if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier
|
|
||||||
{
|
|
||||||
if (!gr_sidedef->toptexture) // Only extend up if there's no texture
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh);
|
|
||||||
else
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh);
|
|
||||||
}
|
|
||||||
// behind sector is not a thok barrier
|
|
||||||
else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
|
|
||||||
}
|
|
||||||
else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not
|
|
||||||
{
|
|
||||||
if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height
|
|
||||||
|| gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height
|
|
||||||
|| gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
|
|
||||||
}
|
|
||||||
else // neither sectors are thok barriers
|
|
||||||
{
|
|
||||||
if (((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher
|
|
||||||
|| gr_backsector->floorpic != skyflatnum) // behind sector is not a sky
|
|
||||||
&& ABS(gr_backsector->floorheight - gr_frontsector->floorheight) > FRACUNIT*3/2) // don't draw sky walls for VERY thin differences, this makes for horrible looking slopes sometimes!
|
|
||||||
HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1569,6 +1602,53 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
|
||||||
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
//Set textures properly on single sided walls that are sloped
|
||||||
|
wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
wallVerts[0].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
|
||||||
|
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||||
|
#else
|
||||||
|
// set top/bottom coords
|
||||||
|
wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// When there's no midtexture, draw a skywall to prevent rendering behind it
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's
|
||||||
|
// a sky flat
|
||||||
|
if (!gr_curline->polyseg)
|
||||||
|
{
|
||||||
|
if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector
|
||||||
|
{
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX);
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[0].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope);
|
||||||
|
#else
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop);
|
||||||
|
#endif
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
if (gr_frontsector->floorpic == skyflatnum)
|
||||||
|
{
|
||||||
|
#ifdef ESLOPE
|
||||||
|
wallVerts[3].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope);
|
||||||
|
#else
|
||||||
|
wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom);
|
||||||
|
#endif
|
||||||
|
wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN);
|
||||||
|
|
||||||
|
HWR_DrawSkyWall(wallVerts, &Surf);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3619,96 +3699,44 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr)
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Sort vissprites by distance
|
// Sort vissprites by distance
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
static gr_vissprite_t gr_vsprsortedhead;
|
|
||||||
|
gr_vissprite_t* gr_vsprorder[MAXVISSPRITES];
|
||||||
|
|
||||||
|
// For more correct transparency the transparent sprites would need to be
|
||||||
|
// sorted and drawn together with transparent surfaces.
|
||||||
|
static int CompareVisSprites(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
gr_vissprite_t* spr1 = *(gr_vissprite_t*const*)p1;
|
||||||
|
gr_vissprite_t* spr2 = *(gr_vissprite_t*const*)p2;
|
||||||
|
int idiff;
|
||||||
|
float fdiff;
|
||||||
|
|
||||||
|
// make transparent sprites last
|
||||||
|
// "boolean to int"
|
||||||
|
|
||||||
|
int transparency1 = (spr1->mobj->flags2 & MF2_SHADOW) || (spr1->mobj->frame & FF_TRANSMASK);
|
||||||
|
int transparency2 = (spr2->mobj->flags2 & MF2_SHADOW) || (spr2->mobj->frame & FF_TRANSMASK);
|
||||||
|
idiff = transparency1 - transparency2;
|
||||||
|
if (idiff != 0) return idiff;
|
||||||
|
|
||||||
|
fdiff = spr2->tz - spr1->tz;// this order seems correct when checking with apitrace. Back to front.
|
||||||
|
if (fabsf(fdiff) < 1.0E-36f)
|
||||||
|
return spr1->dispoffset - spr2->dispoffset;// smallest dispoffset first if sprites are at (almost) same location.
|
||||||
|
else if (fdiff > 0)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void HWR_SortVisSprites(void)
|
static void HWR_SortVisSprites(void)
|
||||||
{
|
{
|
||||||
UINT32 i;
|
UINT32 i;
|
||||||
gr_vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
|
||||||
gr_vissprite_t *best = NULL;
|
|
||||||
gr_vissprite_t unsorted;
|
|
||||||
float bestdist = 0.0f;
|
|
||||||
INT32 bestdispoffset = 0;
|
|
||||||
|
|
||||||
if (!gr_visspritecount)
|
|
||||||
return;
|
|
||||||
|
|
||||||
dsfirst = HWR_GetVisSprite(0);
|
|
||||||
|
|
||||||
for (i = 0, dsnext = dsfirst, ds = NULL; i < gr_visspritecount; i++)
|
|
||||||
{
|
|
||||||
dsprev = ds;
|
|
||||||
ds = dsnext;
|
|
||||||
if (i < gr_visspritecount - 1) dsnext = HWR_GetVisSprite(i + 1);
|
|
||||||
|
|
||||||
ds->next = dsnext;
|
|
||||||
ds->prev = dsprev;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix first and last. ds still points to the last one after the loop
|
|
||||||
dsfirst->prev = &unsorted;
|
|
||||||
unsorted.next = dsfirst;
|
|
||||||
if (ds)
|
|
||||||
ds->next = &unsorted;
|
|
||||||
unsorted.prev = ds;
|
|
||||||
|
|
||||||
// pull the vissprites out by scale
|
|
||||||
gr_vsprsortedhead.next = gr_vsprsortedhead.prev = &gr_vsprsortedhead;
|
|
||||||
for (i = 0; i < gr_visspritecount; i++)
|
for (i = 0; i < gr_visspritecount; i++)
|
||||||
{
|
{
|
||||||
best = NULL;
|
gr_vsprorder[i] = HWR_GetVisSprite(i);
|
||||||
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
|
||||||
{
|
|
||||||
if (!best || ds->tz > bestdist)
|
|
||||||
{
|
|
||||||
bestdist = ds->tz;
|
|
||||||
bestdispoffset = ds->dispoffset;
|
|
||||||
best = ds;
|
|
||||||
}
|
|
||||||
// order visprites of same scale by dispoffset, smallest first
|
|
||||||
else if (fabsf(ds->tz - bestdist) < 1.0E-36f && ds->dispoffset < bestdispoffset)
|
|
||||||
{
|
|
||||||
bestdispoffset = ds->dispoffset;
|
|
||||||
best = ds;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (best)
|
|
||||||
{
|
|
||||||
best->next->prev = best->prev;
|
|
||||||
best->prev->next = best->next;
|
|
||||||
best->next = &gr_vsprsortedhead;
|
|
||||||
best->prev = gr_vsprsortedhead.prev;
|
|
||||||
}
|
|
||||||
gr_vsprsortedhead.prev->next = best;
|
|
||||||
gr_vsprsortedhead.prev = best;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sryder: Oh boy, while it's nice having ALL the sprites sorted properly, it fails when we bring MD2's into the
|
|
||||||
// mix and they want to be translucent. So let's place all the translucent sprites and MD2's AFTER
|
|
||||||
// everything else, but still ordered of course, the depth buffer can handle the opaque ones plenty fine.
|
|
||||||
// We just need to move all translucent ones to the end in order
|
|
||||||
// TODO: Fully sort all sprites and MD2s with walls and floors, this part will be unnecessary after that
|
|
||||||
best = gr_vsprsortedhead.next;
|
|
||||||
for (i = 0; i < gr_visspritecount; i++)
|
|
||||||
{
|
|
||||||
if ((best->mobj->flags2 & MF2_SHADOW) || (best->mobj->frame & FF_TRANSMASK))
|
|
||||||
{
|
|
||||||
if (best == gr_vsprsortedhead.next)
|
|
||||||
{
|
|
||||||
gr_vsprsortedhead.next = best->next;
|
|
||||||
}
|
|
||||||
best->prev->next = best->next;
|
|
||||||
best->next->prev = best->prev;
|
|
||||||
best->prev = gr_vsprsortedhead.prev;
|
|
||||||
gr_vsprsortedhead.prev->next = best;
|
|
||||||
gr_vsprsortedhead.prev = best;
|
|
||||||
ds = best;
|
|
||||||
best = best->next;
|
|
||||||
ds->next = &gr_vsprsortedhead;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
best = best->next;
|
|
||||||
}
|
}
|
||||||
|
qsort(gr_vsprorder, gr_visspritecount, sizeof(gr_vissprite_t*), CompareVisSprites);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
// A drawnode is something that points to a 3D floor, 3D side, or masked
|
||||||
|
@ -3833,27 +3861,65 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
|
||||||
numpolyplanes++;
|
numpolyplanes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// putting sortindex and sortnode here so the comparator function can see them
|
||||||
|
gr_drawnode_t *sortnode;
|
||||||
|
size_t *sortindex;
|
||||||
|
|
||||||
|
static int CompareDrawNodes(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
size_t n1 = *(const size_t*)p1;
|
||||||
|
size_t n2 = *(const size_t*)p2;
|
||||||
|
INT32 v1 = 0;
|
||||||
|
INT32 v2 = 0;
|
||||||
|
INT32 diff;
|
||||||
|
if (sortnode[n1].plane)
|
||||||
|
v1 = sortnode[n1].plane->drawcount;
|
||||||
|
else if (sortnode[n1].polyplane)
|
||||||
|
v1 = sortnode[n1].polyplane->drawcount;
|
||||||
|
else if (sortnode[n1].wall)
|
||||||
|
v1 = sortnode[n1].wall->drawcount;
|
||||||
|
else I_Error("n1 unknown");
|
||||||
|
|
||||||
|
if (sortnode[n2].plane)
|
||||||
|
v2 = sortnode[n2].plane->drawcount;
|
||||||
|
else if (sortnode[n2].polyplane)
|
||||||
|
v2 = sortnode[n2].polyplane->drawcount;
|
||||||
|
else if (sortnode[n2].wall)
|
||||||
|
v2 = sortnode[n2].wall->drawcount;
|
||||||
|
else I_Error("n2 unknown");
|
||||||
|
|
||||||
|
diff = v2 - v1;
|
||||||
|
if (diff == 0) I_Error("diff is zero");
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CompareDrawNodePlanes(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
size_t n1 = *(const size_t*)p1;
|
||||||
|
size_t n2 = *(const size_t*)p2;
|
||||||
|
if (!sortnode[n1].plane) I_Error("Uh.. This isn't a plane! (n1)");
|
||||||
|
if (!sortnode[n2].plane) I_Error("Uh.. This isn't a plane! (n2)");
|
||||||
|
return ABS(sortnode[n2].plane->fixedheight - viewz) - ABS(sortnode[n1].plane->fixedheight - viewz);
|
||||||
|
}
|
||||||
|
|
||||||
// HWR_RenderDrawNodes
|
// HWR_RenderDrawNodes
|
||||||
// Creates, sorts and renders a list of drawnodes for the current frame.
|
// Creates, sorts and renders a list of drawnodes for the current frame.
|
||||||
void HWR_RenderDrawNodes(void)
|
void HWR_RenderDrawNodes(void)
|
||||||
{
|
{
|
||||||
UINT32 i = 0, p = 0, prev = 0, loop;
|
UINT32 i = 0, p = 0;
|
||||||
const fixed_t pviewz = viewz;
|
size_t run_start = 0;
|
||||||
|
|
||||||
// Dump EVERYTHING into a huge drawnode list. Then we'll sort it!
|
// Dump EVERYTHING into a huge drawnode list. Then we'll sort it!
|
||||||
// Could this be optimized into _AddTransparentWall/_AddTransparentPlane?
|
// Could this be optimized into _AddTransparentWall/_AddTransparentPlane?
|
||||||
// Hell yes! But sort algorithm must be modified to use a linked list.
|
// Hell yes! But sort algorithm must be modified to use a linked list.
|
||||||
gr_drawnode_t *sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes)
|
sortnode = Z_Calloc((sizeof(planeinfo_t)*numplanes)
|
||||||
+ (sizeof(polyplaneinfo_t)*numpolyplanes)
|
+ (sizeof(polyplaneinfo_t)*numpolyplanes)
|
||||||
+ (sizeof(wallinfo_t)*numwalls)
|
+ (sizeof(wallinfo_t)*numwalls)
|
||||||
,PU_STATIC, NULL);
|
,PU_STATIC, NULL);
|
||||||
// todo:
|
// todo:
|
||||||
// However, in reality we shouldn't be re-copying and shifting all this information
|
// However, in reality we shouldn't be re-copying and shifting all this information
|
||||||
// that is already lying around. This should all be in some sort of linked list or lists.
|
// that is already lying around. This should all be in some sort of linked list or lists.
|
||||||
size_t *sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL);
|
sortindex = Z_Calloc(sizeof(size_t) * (numplanes + numpolyplanes + numwalls), PU_STATIC, NULL);
|
||||||
|
|
||||||
// If true, swap the draw order.
|
|
||||||
boolean shift = false;
|
|
||||||
|
|
||||||
for (i = 0; i < numplanes; i++, p++)
|
for (i = 0; i < numplanes; i++, p++)
|
||||||
{
|
{
|
||||||
|
@ -3880,99 +3946,40 @@ void HWR_RenderDrawNodes(void)
|
||||||
// through the lists of masked textures and
|
// through the lists of masked textures and
|
||||||
// translucent ffloors being drawn.
|
// translucent ffloors being drawn.
|
||||||
|
|
||||||
// This is a bubble sort! Wahoo!
|
// im not sure if this sort on the next line is needed.
|
||||||
|
// it sorts the list based on the value of the 'drawcount' member of the drawnodes.
|
||||||
|
// im thinking the list might already be in that order, but i havent bothered to check yet.
|
||||||
|
// anyway doing this sort does not hurt and does not take much time.
|
||||||
|
// the while loop after this sort is important however!
|
||||||
|
qsort(sortindex, p, sizeof(size_t), CompareDrawNodes);
|
||||||
|
|
||||||
// Stuff is sorted:
|
// try solving floor order here. for each consecutive run of floors in the list, sort that run.
|
||||||
// sortnode[sortindex[0]] = farthest away
|
while (run_start < p-1)// p-1 because a 1 plane run at the end of the list does not count
|
||||||
// sortnode[sortindex[p-1]] = closest
|
|
||||||
// "i" should be closer. "prev" should be further.
|
|
||||||
// The lower drawcount is, the further it is from the screen.
|
|
||||||
|
|
||||||
for (loop = 0; loop < p; loop++)
|
|
||||||
{
|
{
|
||||||
for (i = 1; i < p; i++)
|
// locate run start
|
||||||
|
if (sortnode[sortindex[run_start]].plane)
|
||||||
{
|
{
|
||||||
prev = i-1;
|
// found it, now look for run end
|
||||||
if (sortnode[sortindex[i]].plane)
|
size_t run_end;// (inclusive)
|
||||||
|
for (i = run_start+1; i < p; i++)// size_t and UINT32 being used mixed here... shouldnt break anything though..
|
||||||
{
|
{
|
||||||
// What are we comparing it with?
|
if (!sortnode[sortindex[i]].plane) break;
|
||||||
if (sortnode[sortindex[prev]].plane)
|
|
||||||
{
|
|
||||||
// Plane (i) is further away than plane (prev)
|
|
||||||
if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz))
|
|
||||||
shift = true;
|
|
||||||
}
|
}
|
||||||
if (sortnode[sortindex[prev]].polyplane)
|
run_end = i-1;
|
||||||
|
if (run_end > run_start)// if there are multiple consecutive planes, not just one
|
||||||
{
|
{
|
||||||
// Plane (i) is further away than polyplane (prev)
|
// consecutive run of planes found, now sort it
|
||||||
if (ABS(sortnode[sortindex[i]].plane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz))
|
// not sure how long these runs can be in reality...
|
||||||
shift = true;
|
qsort(sortindex + run_start, run_end - run_start + 1, sizeof(size_t), CompareDrawNodePlanes);
|
||||||
}
|
}
|
||||||
else if (sortnode[sortindex[prev]].wall)
|
run_start = run_end + 1;// continue looking for runs coming right after this one
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// Plane (i) is further than wall (prev)
|
// this wasnt the run start, try next one
|
||||||
if (sortnode[sortindex[i]].plane->drawcount > sortnode[sortindex[prev]].wall->drawcount)
|
run_start++;
|
||||||
shift = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sortnode[sortindex[i]].polyplane)
|
|
||||||
{
|
|
||||||
// What are we comparing it with?
|
|
||||||
if (sortnode[sortindex[prev]].plane)
|
|
||||||
{
|
|
||||||
// Plane (i) is further away than plane (prev)
|
|
||||||
if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].plane->fixedheight - pviewz))
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
if (sortnode[sortindex[prev]].polyplane)
|
|
||||||
{
|
|
||||||
// Plane (i) is further away than polyplane (prev)
|
|
||||||
if (ABS(sortnode[sortindex[i]].polyplane->fixedheight - pviewz) > ABS(sortnode[sortindex[prev]].polyplane->fixedheight - pviewz))
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
else if (sortnode[sortindex[prev]].wall)
|
|
||||||
{
|
|
||||||
// Plane (i) is further than wall (prev)
|
|
||||||
if (sortnode[sortindex[i]].polyplane->drawcount > sortnode[sortindex[prev]].wall->drawcount)
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sortnode[sortindex[i]].wall)
|
|
||||||
{
|
|
||||||
// What are we comparing it with?
|
|
||||||
if (sortnode[sortindex[prev]].plane)
|
|
||||||
{
|
|
||||||
// Wall (i) is further than plane(prev)
|
|
||||||
if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].plane->drawcount)
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
if (sortnode[sortindex[prev]].polyplane)
|
|
||||||
{
|
|
||||||
// Wall (i) is further than polyplane(prev)
|
|
||||||
if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].polyplane->drawcount)
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
else if (sortnode[sortindex[prev]].wall)
|
|
||||||
{
|
|
||||||
// Wall (i) is further than wall (prev)
|
|
||||||
if (sortnode[sortindex[i]].wall->drawcount > sortnode[sortindex[prev]].wall->drawcount)
|
|
||||||
shift = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shift)
|
|
||||||
{
|
|
||||||
size_t temp;
|
|
||||||
|
|
||||||
temp = sortindex[prev];
|
|
||||||
sortindex[prev] = sortindex[i];
|
|
||||||
sortindex[i] = temp;
|
|
||||||
|
|
||||||
shift = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} //i++
|
|
||||||
} // loop++
|
|
||||||
|
|
||||||
// Okay! Let's draw it all! Woo!
|
// Okay! Let's draw it all! Woo!
|
||||||
HWD.pfnSetTransform(&atransform);
|
HWD.pfnSetTransform(&atransform);
|
||||||
|
@ -4023,15 +4030,10 @@ void HWR_RenderDrawNodes(void)
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
void HWR_DrawSprites(void)
|
void HWR_DrawSprites(void)
|
||||||
{
|
{
|
||||||
if (gr_visspritecount > 0)
|
UINT32 i;
|
||||||
{
|
for (i = 0; i < gr_visspritecount; i++)
|
||||||
gr_vissprite_t *spr;
|
|
||||||
|
|
||||||
// draw all vissprites back to front
|
|
||||||
for (spr = gr_vsprsortedhead.next;
|
|
||||||
spr != &gr_vsprsortedhead;
|
|
||||||
spr = spr->next)
|
|
||||||
{
|
{
|
||||||
|
gr_vissprite_t *spr = gr_vsprorder[i];
|
||||||
if (spr->precip)
|
if (spr->precip)
|
||||||
HWR_DrawPrecipitationSprite(spr);
|
HWR_DrawPrecipitationSprite(spr);
|
||||||
else
|
else
|
||||||
|
@ -4051,7 +4053,6 @@ void HWR_DrawSprites(void)
|
||||||
HWR_DrawMD2(spr);
|
HWR_DrawMD2(spr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -4538,18 +4539,48 @@ void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
|
|
||||||
static boolean drewsky = false;
|
static boolean drewsky = false;
|
||||||
|
|
||||||
void HWR_DrawSkyBackground(void)
|
void HWR_DrawSkyBackground(float fpov)
|
||||||
{
|
{
|
||||||
|
if (drewsky)
|
||||||
|
return;
|
||||||
|
if (cv_grskydome.value)
|
||||||
|
{
|
||||||
|
FTransform dometransform;
|
||||||
|
|
||||||
|
memset(&dometransform, 0x00, sizeof(FTransform));
|
||||||
|
|
||||||
|
//04/01/2000: Hurdler: added for T&L
|
||||||
|
// It should replace all other gr_viewxxx when finished
|
||||||
|
if (!atransform.shearing)
|
||||||
|
dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||||
|
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||||
|
|
||||||
|
dometransform.flip = atransform.flip;
|
||||||
|
dometransform.mirror = atransform.mirror;
|
||||||
|
dometransform.shearing = atransform.shearing;
|
||||||
|
dometransform.viewaiming = atransform.viewaiming;
|
||||||
|
|
||||||
|
dometransform.scalex = 1;
|
||||||
|
dometransform.scaley = (float)vid.width/vid.height;
|
||||||
|
dometransform.scalez = 1;
|
||||||
|
dometransform.fovxangle = fpov; // Tails
|
||||||
|
dometransform.fovyangle = fpov; // Tails
|
||||||
|
dometransform.splitscreen = splitscreen;
|
||||||
|
|
||||||
|
HWR_GetTexture(texturetranslation[skytexture]);
|
||||||
|
HWD.pfnSetShader(7); // sky shader
|
||||||
|
HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, dometransform);
|
||||||
|
HWD.pfnSetShader(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
FOutVector v[4];
|
FOutVector v[4];
|
||||||
angle_t angle;
|
angle_t angle;
|
||||||
float dimensionmultiply;
|
float dimensionmultiply;
|
||||||
float aspectratio;
|
float aspectratio;
|
||||||
float angleturn;
|
float angleturn;
|
||||||
|
|
||||||
if (drewsky)
|
HWR_GetTexture(texturetranslation[skytexture]);
|
||||||
return;
|
|
||||||
|
|
||||||
HWR_GetTexture(skytexture);
|
|
||||||
aspectratio = (float)vid.width/(float)vid.height;
|
aspectratio = (float)vid.width/(float)vid.height;
|
||||||
|
|
||||||
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0
|
||||||
|
@ -4574,8 +4605,8 @@ void HWR_DrawSkyBackground(void)
|
||||||
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
|
||||||
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
|
||||||
|
|
||||||
angle = (viewangle/2 + xtoviewangle[0]);
|
angle = (viewangle + xtoviewangle[0]);
|
||||||
dimensionmultiply = ((float)textures[skytexture]->width/256.0f);
|
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
|
||||||
|
|
||||||
if (atransform.mirror)
|
if (atransform.mirror)
|
||||||
{
|
{
|
||||||
|
@ -4588,7 +4619,7 @@ void HWR_DrawSkyBackground(void)
|
||||||
|
|
||||||
// Y
|
// Y
|
||||||
angle = aimingangle;
|
angle = aimingangle;
|
||||||
dimensionmultiply = ((float)textures[skytexture]->height/(128.0f*aspectratio));
|
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio));
|
||||||
|
|
||||||
if (splitscreen == 1)
|
if (splitscreen == 1)
|
||||||
{
|
{
|
||||||
|
@ -4637,6 +4668,7 @@ void HWR_DrawSkyBackground(void)
|
||||||
HWD.pfnSetShader(7); // sky shader
|
HWD.pfnSetShader(7); // sky shader
|
||||||
HWD.pfnDrawPolygon(NULL, v, 4, 0);
|
HWD.pfnDrawPolygon(NULL, v, 4, 0);
|
||||||
HWD.pfnSetShader(0);
|
HWD.pfnSetShader(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4776,7 +4808,7 @@ void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox)
|
||||||
ST_doPaletteStuff();
|
ST_doPaletteStuff();
|
||||||
|
|
||||||
// Draw the sky background.
|
// Draw the sky background.
|
||||||
HWR_DrawSkyBackground();
|
HWR_DrawSkyBackground(fpov);
|
||||||
if (skybox)
|
if (skybox)
|
||||||
drewsky = true;
|
drewsky = true;
|
||||||
|
|
||||||
|
@ -4817,7 +4849,8 @@ void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for new console commands.
|
// Check for new console commands.
|
||||||
NetUpdate();
|
// this was removed since it caused crashes on leaving record attack with models on since it was removing mobjs that were about to be rendered
|
||||||
|
//NetUpdate();
|
||||||
|
|
||||||
// Draw MD2 and sprites
|
// Draw MD2 and sprites
|
||||||
HWR_SortVisSprites();
|
HWR_SortVisSprites();
|
||||||
|
@ -4875,7 +4908,7 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here
|
R_SetupFrame(player, false); // This can stay false because it is only used to set viewsky in r_main.c, which isn't used here
|
||||||
HWR_RenderFrame(viewnumber, player, skybox);
|
HWR_RenderFrame(viewnumber, player, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -4909,6 +4942,7 @@ void HWR_AddCommands(void)
|
||||||
CV_RegisterVar(&cv_grsolvetjoin);
|
CV_RegisterVar(&cv_grsolvetjoin);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_grbatching);
|
CV_RegisterVar(&cv_grbatching);
|
||||||
|
CV_RegisterVar(&cv_grskydome);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
@ -4938,7 +4972,8 @@ void HWR_Startup(void)
|
||||||
|
|
||||||
// jimita
|
// jimita
|
||||||
HWD.pfnKillShaders();
|
HWD.pfnKillShaders();
|
||||||
HWD.pfnLoadShaders();
|
if (!HWD.pfnLoadShaders())
|
||||||
|
gr_shadersavailable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,8 +104,8 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
|
||||||
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
|
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
|
||||||
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
|
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
|
||||||
void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor);
|
void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor);
|
||||||
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top);
|
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
|
||||||
void HWR_DrawSkyBackground(void);
|
void HWR_DrawSkyBackground(float fpov);
|
||||||
|
|
||||||
#ifdef POLYOBJECTS
|
#ifdef POLYOBJECTS
|
||||||
void HWR_AddPolyObjectSegs(void);
|
void HWR_AddPolyObjectSegs(void);
|
||||||
|
|
|
@ -380,6 +380,10 @@ static PFNglMultiTexCoord2fv pglMultiTexCoord2fv;
|
||||||
typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum);
|
typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum);
|
||||||
static PFNglClientActiveTexture pglClientActiveTexture;
|
static PFNglClientActiveTexture pglClientActiveTexture;
|
||||||
|
|
||||||
|
// sky dome needs this
|
||||||
|
typedef void (APIENTRY *PFNglColorPointer) (GLint, GLenum, GLsizei, const GLvoid*);
|
||||||
|
static PFNglColorPointer pglColorPointer;
|
||||||
|
|
||||||
/* 1.2 Parms */
|
/* 1.2 Parms */
|
||||||
/* GL_CLAMP_TO_EDGE_EXT */
|
/* GL_CLAMP_TO_EDGE_EXT */
|
||||||
#ifndef GL_CLAMP_TO_EDGE
|
#ifndef GL_CLAMP_TO_EDGE
|
||||||
|
@ -544,7 +548,8 @@ static boolean gl_batching = false;// are we currently collecting batches?
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
// lighting
|
// lighting
|
||||||
gluniform_mix_color,
|
gluniform_poly_color,
|
||||||
|
gluniform_tint_color,
|
||||||
gluniform_fade_color,
|
gluniform_fade_color,
|
||||||
gluniform_lighting,
|
gluniform_lighting,
|
||||||
|
|
||||||
|
@ -574,37 +579,80 @@ static gl_shaderprogram_t gl_shaderprograms[MAXSHADERPROGRAMS];
|
||||||
// GLSL Software fragment shader
|
// GLSL Software fragment shader
|
||||||
//
|
//
|
||||||
|
|
||||||
#define GLSL_INTERNAL_FOG_FUNCTION \
|
// (new shader stuff taken from srb2 shader branch)
|
||||||
"float fog(const float dist, const float density, const float globaldensity) {\n" \
|
// this is missing support for fade_start and fade_end
|
||||||
"const float LOG2 = -1.442695;\n" \
|
|
||||||
"float d = density * dist;\n" \
|
#define GLSL_DOOM_COLORMAP \
|
||||||
"return 1.0 - clamp(exp2(d * sqrt(d) * globaldensity * LOG2), 0.0, 1.0);\n" \
|
"float R_DoomColormap(float light, float z)\n" \
|
||||||
|
"{\n" \
|
||||||
|
"float lightnum = clamp(light / 17.0, 0.0, 15.0);\n" \
|
||||||
|
"float lightz = clamp(z / 16.0, 0.0, 127.0);\n" \
|
||||||
|
"float startmap = (15.0 - lightnum) * 4.0;\n" \
|
||||||
|
"float scale = 160.0 / (lightz + 1.0);\n" \
|
||||||
|
"return startmap - scale * 0.5;\n" \
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
// https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_gpu_shader_fp64.txt
|
#define GLSL_DOOM_LIGHT_EQUATION \
|
||||||
#define GLSL_INTERNAL_FOG_MIX \
|
"float R_DoomLightingEquation(float light)\n" \
|
||||||
"float fog_distance = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
"{\n" \
|
||||||
"float fog_attenuation = floor(fog(fog_distance, 0.0001 * ((256.0-lighting)/24.0), fog_density)*10.0)/10.0;\n" \
|
"float z = gl_FragCoord.z / gl_FragCoord.w;\n" \
|
||||||
"vec4 fog_color = vec4(fade_color[0], fade_color[1], fade_color[2], 1.0);\n" \
|
"float colormap = floor(R_DoomColormap(light, z)) + 0.5;\n" \
|
||||||
"vec4 mixed_color = texel * mix_color;\n" \
|
"return clamp(colormap, 0.0, 31.0) / 32.0;\n" \
|
||||||
"vec4 fog_mix = mix(mixed_color, fog_color, fog_attenuation);\n" \
|
"}\n"
|
||||||
"vec4 final_color = mix(fog_mix, fog_color, ((256.0-lighting)/256.0));\n" \
|
|
||||||
"final_color[3] = mixed_color[3];\n"
|
#define GLSL_SOFTWARE_TINT_EQUATION \
|
||||||
|
"if (tint_color.a > 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" \
|
||||||
|
"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" \
|
||||||
|
"final_color = mix(final_color, fade_color, darkness);\n"
|
||||||
|
|
||||||
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
#define GLSL_SOFTWARE_FRAGMENT_SHADER \
|
||||||
"uniform sampler2D tex;\n" \
|
"uniform sampler2D tex;\n" \
|
||||||
"uniform vec4 mix_color;\n" \
|
"uniform vec4 poly_color;\n" \
|
||||||
|
"uniform vec4 tint_color;\n" \
|
||||||
"uniform vec4 fade_color;\n" \
|
"uniform vec4 fade_color;\n" \
|
||||||
"uniform float lighting;\n" \
|
"uniform float lighting;\n" \
|
||||||
"uniform int fog_mode;\n" \
|
GLSL_DOOM_COLORMAP \
|
||||||
"uniform float fog_density;\n" \
|
GLSL_DOOM_LIGHT_EQUATION \
|
||||||
GLSL_INTERNAL_FOG_FUNCTION \
|
|
||||||
"void main(void) {\n" \
|
"void main(void) {\n" \
|
||||||
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
"vec4 texel = texture2D(tex, gl_TexCoord[0].st);\n" \
|
||||||
GLSL_INTERNAL_FOG_MIX \
|
"vec4 base_color = texel * poly_color;\n" \
|
||||||
|
"vec4 final_color = base_color;\n" \
|
||||||
|
GLSL_SOFTWARE_TINT_EQUATION \
|
||||||
|
GLSL_SOFTWARE_FADE_EQUATION \
|
||||||
|
"final_color.a = texel.a * poly_color.a;\n" \
|
||||||
"gl_FragColor = final_color;\n" \
|
"gl_FragColor = final_color;\n" \
|
||||||
"}\0"
|
"}\0"
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Fog block shader (Taken from srb2 shader branch)
|
||||||
|
//
|
||||||
|
// Alpha of the planes themselves are still slightly off -- see HWR_FogBlockAlpha
|
||||||
|
//
|
||||||
|
|
||||||
|
#define GLSL_FOG_FRAGMENT_SHADER \
|
||||||
|
"uniform vec4 tint_color;\n" \
|
||||||
|
"uniform vec4 fade_color;\n" \
|
||||||
|
"uniform float lighting;\n" \
|
||||||
|
GLSL_DOOM_COLORMAP \
|
||||||
|
GLSL_DOOM_LIGHT_EQUATION \
|
||||||
|
"void main(void) {\n" \
|
||||||
|
"vec4 base_color = gl_Color;\n" \
|
||||||
|
"vec4 final_color = base_color;\n" \
|
||||||
|
GLSL_SOFTWARE_TINT_EQUATION \
|
||||||
|
GLSL_SOFTWARE_FADE_EQUATION \
|
||||||
|
"gl_FragColor = final_color;\n" \
|
||||||
|
"}\0"
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// GLSL generic fragment shader
|
// GLSL generic fragment shader
|
||||||
//
|
//
|
||||||
|
@ -636,9 +684,7 @@ static const char *fragment_shaders[] = {
|
||||||
GLSL_SOFTWARE_FRAGMENT_SHADER,
|
GLSL_SOFTWARE_FRAGMENT_SHADER,
|
||||||
|
|
||||||
// Fog fragment shader
|
// Fog fragment shader
|
||||||
"void main(void) {\n"
|
GLSL_FOG_FRAGMENT_SHADER,
|
||||||
"gl_FragColor = gl_Color;\n"
|
|
||||||
"}\0",
|
|
||||||
|
|
||||||
// Sky fragment shader
|
// Sky fragment shader
|
||||||
"uniform sampler2D tex;\n"
|
"uniform sampler2D tex;\n"
|
||||||
|
@ -706,6 +752,7 @@ void SetupGLFunc4(void)
|
||||||
pglBindBuffer = GetGLFunc("glBindBuffer");
|
pglBindBuffer = GetGLFunc("glBindBuffer");
|
||||||
pglBufferData = GetGLFunc("glBufferData");
|
pglBufferData = GetGLFunc("glBufferData");
|
||||||
pglDeleteBuffers = GetGLFunc("glDeleteBuffers");
|
pglDeleteBuffers = GetGLFunc("glDeleteBuffers");
|
||||||
|
pglColorPointer = GetGLFunc("glColorPointer");
|
||||||
|
|
||||||
#ifdef GL_SHADERS
|
#ifdef GL_SHADERS
|
||||||
pglCreateShader = GetGLFunc("glCreateShader");
|
pglCreateShader = GetGLFunc("glCreateShader");
|
||||||
|
@ -735,12 +782,14 @@ void SetupGLFunc4(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// jimita
|
// jimita
|
||||||
EXPORT void HWRAPI(LoadShaders) (void)
|
EXPORT boolean HWRAPI(LoadShaders) (void)
|
||||||
{
|
{
|
||||||
#ifdef GL_SHADERS
|
#ifdef GL_SHADERS
|
||||||
GLuint gl_vertShader, gl_fragShader;
|
GLuint gl_vertShader, gl_fragShader;
|
||||||
GLint i, result;
|
GLint i, result;
|
||||||
|
|
||||||
|
if (!pglUseProgram) return false;
|
||||||
|
|
||||||
gl_customvertexshaders[0] = NULL;
|
gl_customvertexshaders[0] = NULL;
|
||||||
gl_customfragmentshaders[0] = NULL;
|
gl_customfragmentshaders[0] = NULL;
|
||||||
|
|
||||||
|
@ -832,7 +881,8 @@ EXPORT void HWRAPI(LoadShaders) (void)
|
||||||
#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform);
|
#define GETUNI(uniform) pglGetUniformLocation(shader->program, uniform);
|
||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
shader->uniforms[gluniform_mix_color] = GETUNI("mix_color");
|
shader->uniforms[gluniform_poly_color] = GETUNI("poly_color");
|
||||||
|
shader->uniforms[gluniform_tint_color] = GETUNI("tint_color");
|
||||||
shader->uniforms[gluniform_fade_color] = GETUNI("fade_color");
|
shader->uniforms[gluniform_fade_color] = GETUNI("fade_color");
|
||||||
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
|
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
|
||||||
|
|
||||||
|
@ -846,11 +896,13 @@ EXPORT void HWRAPI(LoadShaders) (void)
|
||||||
#undef GETUNI
|
#undef GETUNI
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment)
|
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment)
|
||||||
{
|
{
|
||||||
#ifdef GL_SHADERS
|
#ifdef GL_SHADERS
|
||||||
|
if (!pglUseProgram) return;
|
||||||
if (number < 1 || number > MAXSHADERS)
|
if (number < 1 || number > MAXSHADERS)
|
||||||
I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS);
|
I_Error("LoadCustomShader(): cannot load shader %d (max %d)", number, MAXSHADERS);
|
||||||
|
|
||||||
|
@ -900,6 +952,7 @@ EXPORT void HWRAPI(UnSetShader) (void)
|
||||||
gl_shadersenabled = false;
|
gl_shadersenabled = false;
|
||||||
gl_currentshaderprogram = 0;
|
gl_currentshaderprogram = 0;
|
||||||
gl_shaderprogramchanged = true;// not sure if this is needed
|
gl_shaderprogramchanged = true;// not sure if this is needed
|
||||||
|
if (!pglUseProgram) return;
|
||||||
pglUseProgram(0);
|
pglUseProgram(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1621,10 +1674,10 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *mix, GLRGBAFloat *fade)
|
static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade)
|
||||||
{
|
{
|
||||||
#ifdef GL_SHADERS
|
#ifdef GL_SHADERS
|
||||||
if (gl_shadersenabled)
|
if (gl_shadersenabled && pglUseProgram)
|
||||||
{
|
{
|
||||||
gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram];
|
gl_shaderprogram_t *shader = &gl_shaderprograms[gl_currentshaderprogram];
|
||||||
if (shader->program)
|
if (shader->program)
|
||||||
|
@ -1680,7 +1733,9 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *mix, GLRGBAFloat *f
|
||||||
function (uniform, a, b, c, d);
|
function (uniform, a, b, c, d);
|
||||||
|
|
||||||
// polygon
|
// polygon
|
||||||
UNIFORM_4(shader->uniforms[gluniform_mix_color], mix->red, mix->green, mix->blue, mix->alpha, pglUniform4f);
|
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);
|
||||||
|
|
||||||
|
|
||||||
// 13062019
|
// 13062019
|
||||||
// Check for fog
|
// Check for fog
|
||||||
|
@ -1710,9 +1765,7 @@ static void load_shaders(FSurfaceInfo *Surface, GLRGBAFloat *mix, GLRGBAFloat *f
|
||||||
else
|
else
|
||||||
pglUseProgram(0);
|
pglUseProgram(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
pglUseProgram(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unfinished draw call batching
|
// unfinished draw call batching
|
||||||
|
@ -1789,6 +1842,8 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||||
|
|
||||||
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
diff64 = poly1->surf.PolyColor.rgba - poly2->surf.PolyColor.rgba;
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||||
|
diff64 = poly1->surf.TintColor.rgba - poly2->surf.TintColor.rgba;
|
||||||
|
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||||
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
|
diff64 = poly1->surf.FadeColor.rgba - poly2->surf.FadeColor.rgba;
|
||||||
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
if (diff64 < 0) return -1; else if (diff64 > 0) return 1;
|
||||||
|
|
||||||
|
@ -1835,6 +1890,7 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
FSurfaceInfo currentSurfaceInfo;
|
FSurfaceInfo currentSurfaceInfo;
|
||||||
|
|
||||||
GLRGBAFloat firstPoly = {0,0,0,0}; // may be misleading but this means first PolyColor
|
GLRGBAFloat firstPoly = {0,0,0,0}; // may be misleading but this means first PolyColor
|
||||||
|
GLRGBAFloat firstTint = {0,0,0,0};
|
||||||
GLRGBAFloat firstFade = {0,0,0,0};
|
GLRGBAFloat firstFade = {0,0,0,0};
|
||||||
|
|
||||||
boolean needRebind = false;
|
boolean needRebind = false;
|
||||||
|
@ -1896,6 +1952,11 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
firstPoly.alpha = byte2float[currentSurfaceInfo.PolyColor.s.alpha];
|
firstPoly.alpha = byte2float[currentSurfaceInfo.PolyColor.s.alpha];
|
||||||
pglColor4ubv((GLubyte*)¤tSurfaceInfo.PolyColor.s);
|
pglColor4ubv((GLubyte*)¤tSurfaceInfo.PolyColor.s);
|
||||||
}
|
}
|
||||||
|
// Tint color
|
||||||
|
firstTint.red = byte2float[currentSurfaceInfo.TintColor.s.red];
|
||||||
|
firstTint.green = byte2float[currentSurfaceInfo.TintColor.s.green];
|
||||||
|
firstTint.blue = byte2float[currentSurfaceInfo.TintColor.s.blue];
|
||||||
|
firstTint.alpha = byte2float[currentSurfaceInfo.TintColor.s.alpha];
|
||||||
// Fade color
|
// Fade color
|
||||||
firstFade.red = byte2float[currentSurfaceInfo.FadeColor.s.red];
|
firstFade.red = byte2float[currentSurfaceInfo.FadeColor.s.red];
|
||||||
firstFade.green = byte2float[currentSurfaceInfo.FadeColor.s.green];
|
firstFade.green = byte2float[currentSurfaceInfo.FadeColor.s.green];
|
||||||
|
@ -1903,7 +1964,7 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
firstFade.alpha = byte2float[currentSurfaceInfo.FadeColor.s.alpha];
|
firstFade.alpha = byte2float[currentSurfaceInfo.FadeColor.s.alpha];
|
||||||
|
|
||||||
if (gl_allowshaders)
|
if (gl_allowshaders)
|
||||||
load_shaders(¤tSurfaceInfo, &firstPoly, &firstFade);
|
load_shaders(¤tSurfaceInfo, &firstPoly, &firstTint, &firstFade);
|
||||||
|
|
||||||
if (currentPolyFlags & PF_NoTexture)
|
if (currentPolyFlags & PF_NoTexture)
|
||||||
currentTexture = 0;
|
currentTexture = 0;
|
||||||
|
@ -2017,6 +2078,7 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
if (gl_allowshaders)
|
if (gl_allowshaders)
|
||||||
{
|
{
|
||||||
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
if (currentSurfaceInfo.PolyColor.rgba != nextSurfaceInfo.PolyColor.rgba ||
|
||||||
|
currentSurfaceInfo.TintColor.rgba != nextSurfaceInfo.TintColor.rgba ||
|
||||||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level)
|
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level)
|
||||||
{
|
{
|
||||||
|
@ -2065,6 +2127,7 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
if (changeShader)
|
if (changeShader)
|
||||||
{
|
{
|
||||||
GLRGBAFloat poly = {0,0,0,0};
|
GLRGBAFloat poly = {0,0,0,0};
|
||||||
|
GLRGBAFloat tint = {0,0,0,0};
|
||||||
GLRGBAFloat fade = {0,0,0,0};
|
GLRGBAFloat fade = {0,0,0,0};
|
||||||
gl_currentshaderprogram = nextShader;
|
gl_currentshaderprogram = nextShader;
|
||||||
gl_shaderprogramchanged = true;
|
gl_shaderprogramchanged = true;
|
||||||
|
@ -2076,13 +2139,18 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue];
|
poly.blue = byte2float[nextSurfaceInfo.PolyColor.s.blue];
|
||||||
poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha];
|
poly.alpha = byte2float[nextSurfaceInfo.PolyColor.s.alpha];
|
||||||
}
|
}
|
||||||
|
// Tint color
|
||||||
|
tint.red = byte2float[nextSurfaceInfo.TintColor.s.red];
|
||||||
|
tint.green = byte2float[nextSurfaceInfo.TintColor.s.green];
|
||||||
|
tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue];
|
||||||
|
tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha];
|
||||||
// Fade color
|
// Fade color
|
||||||
fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red];
|
fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red];
|
||||||
fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green];
|
fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green];
|
||||||
fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue];
|
fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue];
|
||||||
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
|
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
|
||||||
|
|
||||||
load_shaders(&nextSurfaceInfo, &poly, &fade);
|
load_shaders(&nextSurfaceInfo, &poly, &tint, &fade);
|
||||||
currentShader = nextShader;
|
currentShader = nextShader;
|
||||||
changeShader = false;
|
changeShader = false;
|
||||||
|
|
||||||
|
@ -2109,6 +2177,7 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
if (changeSurfaceInfo)
|
if (changeSurfaceInfo)
|
||||||
{
|
{
|
||||||
GLRGBAFloat poly = {0,0,0,0};
|
GLRGBAFloat poly = {0,0,0,0};
|
||||||
|
GLRGBAFloat tint = {0,0,0,0};
|
||||||
GLRGBAFloat fade = {0,0,0,0};
|
GLRGBAFloat fade = {0,0,0,0};
|
||||||
gl_shaderprogramchanged = false;
|
gl_shaderprogramchanged = false;
|
||||||
if (nextPolyFlags & PF_Modulated)
|
if (nextPolyFlags & PF_Modulated)
|
||||||
|
@ -2122,13 +2191,18 @@ EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCall
|
||||||
}
|
}
|
||||||
if (gl_allowshaders)
|
if (gl_allowshaders)
|
||||||
{
|
{
|
||||||
|
// Tint color
|
||||||
|
tint.red = byte2float[nextSurfaceInfo.TintColor.s.red];
|
||||||
|
tint.green = byte2float[nextSurfaceInfo.TintColor.s.green];
|
||||||
|
tint.blue = byte2float[nextSurfaceInfo.TintColor.s.blue];
|
||||||
|
tint.alpha = byte2float[nextSurfaceInfo.TintColor.s.alpha];
|
||||||
// Fade color
|
// Fade color
|
||||||
fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red];
|
fade.red = byte2float[nextSurfaceInfo.FadeColor.s.red];
|
||||||
fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green];
|
fade.green = byte2float[nextSurfaceInfo.FadeColor.s.green];
|
||||||
fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue];
|
fade.blue = byte2float[nextSurfaceInfo.FadeColor.s.blue];
|
||||||
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
|
fade.alpha = byte2float[nextSurfaceInfo.FadeColor.s.alpha];
|
||||||
|
|
||||||
load_shaders(&nextSurfaceInfo, &poly, &fade);
|
load_shaders(&nextSurfaceInfo, &poly, &tint, &fade);
|
||||||
}
|
}
|
||||||
currentSurfaceInfo = nextSurfaceInfo;
|
currentSurfaceInfo = nextSurfaceInfo;
|
||||||
changeSurfaceInfo = false;
|
changeSurfaceInfo = false;
|
||||||
|
@ -2194,7 +2268,8 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static GLRGBAFloat mix = {0,0,0,0};
|
static GLRGBAFloat poly = {0,0,0,0};
|
||||||
|
static GLRGBAFloat tint = {0,0,0,0};
|
||||||
static GLRGBAFloat fade = {0,0,0,0};
|
static GLRGBAFloat fade = {0,0,0,0};
|
||||||
|
|
||||||
SetBlend(PolyFlags); //TODO: inline (#pragma..)
|
SetBlend(PolyFlags); //TODO: inline (#pragma..)
|
||||||
|
@ -2205,15 +2280,21 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||||
// If Modulated, mix the surface colour to the texture
|
// If Modulated, mix the surface colour to the texture
|
||||||
if (CurrentPolyFlags & PF_Modulated)
|
if (CurrentPolyFlags & PF_Modulated)
|
||||||
{
|
{
|
||||||
// Mix color
|
// Poly color
|
||||||
mix.red = byte2float[pSurf->PolyColor.s.red];
|
poly.red = byte2float[pSurf->PolyColor.s.red];
|
||||||
mix.green = byte2float[pSurf->PolyColor.s.green];
|
poly.green = byte2float[pSurf->PolyColor.s.green];
|
||||||
mix.blue = byte2float[pSurf->PolyColor.s.blue];
|
poly.blue = byte2float[pSurf->PolyColor.s.blue];
|
||||||
mix.alpha = byte2float[pSurf->PolyColor.s.alpha];
|
poly.alpha = byte2float[pSurf->PolyColor.s.alpha];
|
||||||
|
|
||||||
pglColor4ubv((GLubyte*)&pSurf->PolyColor.s);
|
pglColor4ubv((GLubyte*)&pSurf->PolyColor.s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tint color
|
||||||
|
tint.red = byte2float[pSurf->TintColor.s.red];
|
||||||
|
tint.green = byte2float[pSurf->TintColor.s.green];
|
||||||
|
tint.blue = byte2float[pSurf->TintColor.s.blue];
|
||||||
|
tint.alpha = byte2float[pSurf->TintColor.s.alpha];
|
||||||
|
|
||||||
// Fade color
|
// Fade color
|
||||||
fade.red = byte2float[pSurf->FadeColor.s.red];
|
fade.red = byte2float[pSurf->FadeColor.s.red];
|
||||||
fade.green = byte2float[pSurf->FadeColor.s.green];
|
fade.green = byte2float[pSurf->FadeColor.s.green];
|
||||||
|
@ -2221,7 +2302,7 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||||
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
fade.alpha = byte2float[pSurf->FadeColor.s.alpha];
|
||||||
}
|
}
|
||||||
|
|
||||||
load_shaders(pSurf, &mix, &fade);
|
load_shaders(pSurf, &poly, &tint, &fade);
|
||||||
|
|
||||||
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
pglVertexPointer(3, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].x);
|
||||||
pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s);
|
pglTexCoordPointer(2, GL_FLOAT, sizeof(FOutVector), &pOutVerts[0].s);
|
||||||
|
@ -2238,6 +2319,260 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sky dome code, taken/backported from SRB2
|
||||||
|
|
||||||
|
typedef struct vbo_vertex_s
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
float u, v;
|
||||||
|
unsigned char r, g, b, a;
|
||||||
|
} vbo_vertex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int mode;
|
||||||
|
int vertexcount;
|
||||||
|
int vertexindex;
|
||||||
|
int use_texture;
|
||||||
|
} GLSkyLoopDef;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
unsigned int id;
|
||||||
|
int rows, columns;
|
||||||
|
int loopcount;
|
||||||
|
GLSkyLoopDef *loops;
|
||||||
|
vbo_vertex_t *data;
|
||||||
|
} GLSkyVBO;
|
||||||
|
|
||||||
|
static const boolean gl_ext_arb_vertex_buffer_object = true;
|
||||||
|
|
||||||
|
#define NULL_VBO_VERTEX ((vbo_vertex_t*)NULL)
|
||||||
|
#define sky_vbo_x (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->x : &vbo->data[0].x)
|
||||||
|
#define sky_vbo_u (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->u : &vbo->data[0].u)
|
||||||
|
#define sky_vbo_r (gl_ext_arb_vertex_buffer_object ? &NULL_VBO_VERTEX->r : &vbo->data[0].r)
|
||||||
|
|
||||||
|
// The texture offset to be applied to the texture coordinates in SkyVertex().
|
||||||
|
static int rows, columns;
|
||||||
|
static signed char yflip;
|
||||||
|
static int texw, texh;
|
||||||
|
static boolean foglayer;
|
||||||
|
static float delta = 0.0f;
|
||||||
|
|
||||||
|
static int gl_sky_detail = 16;
|
||||||
|
|
||||||
|
static INT32 lasttex = -1;
|
||||||
|
|
||||||
|
#define MAP_COEFF 128.0f
|
||||||
|
|
||||||
|
static void SkyVertex(vbo_vertex_t *vbo, int r, int c)
|
||||||
|
{
|
||||||
|
const float radians = (float)(M_PIl / 180.0f);
|
||||||
|
const float scale = 10000.0f;
|
||||||
|
const float maxSideAngle = 60.0f;
|
||||||
|
|
||||||
|
float topAngle = (c / (float)columns * 360.0f);
|
||||||
|
float sideAngle = (maxSideAngle * (rows - r) / rows);
|
||||||
|
float height = (float)(sin(sideAngle * radians));
|
||||||
|
float realRadius = (float)(scale * cos(sideAngle * radians));
|
||||||
|
float x = (float)(realRadius * cos(topAngle * radians));
|
||||||
|
float y = (!yflip) ? scale * height : -scale * height;
|
||||||
|
float z = (float)(realRadius * sin(topAngle * radians));
|
||||||
|
float timesRepeat = (4 * (256.0f / texw));
|
||||||
|
if (fpclassify(timesRepeat) == FP_ZERO)
|
||||||
|
timesRepeat = 1.0f;
|
||||||
|
|
||||||
|
if (!foglayer)
|
||||||
|
{
|
||||||
|
vbo->r = 255;
|
||||||
|
vbo->g = 255;
|
||||||
|
vbo->b = 255;
|
||||||
|
vbo->a = (r == 0 ? 0 : 255);
|
||||||
|
|
||||||
|
// And the texture coordinates.
|
||||||
|
//vbo->u = (-timesRepeat * c / (float)columns);
|
||||||
|
vbo->u = (timesRepeat * c / (float)columns);// TEST
|
||||||
|
if (!yflip) // Flipped Y is for the lower hemisphere.
|
||||||
|
vbo->v = (r / (float)rows) + 0.5f;
|
||||||
|
else
|
||||||
|
vbo->v = 1.0f + ((rows - r) / (float)rows) + 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != 4)
|
||||||
|
{
|
||||||
|
y += 300.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// And finally the vertex.
|
||||||
|
vbo->x = x;
|
||||||
|
vbo->y = y + delta;
|
||||||
|
vbo->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLSkyVBO sky_vbo;
|
||||||
|
|
||||||
|
static void gld_BuildSky(int row_count, int col_count)
|
||||||
|
{
|
||||||
|
int c, r;
|
||||||
|
vbo_vertex_t *vertex_p;
|
||||||
|
int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2;
|
||||||
|
|
||||||
|
GLSkyVBO *vbo = &sky_vbo;
|
||||||
|
|
||||||
|
if ((vbo->columns != col_count) || (vbo->rows != row_count))
|
||||||
|
{
|
||||||
|
free(vbo->loops);
|
||||||
|
free(vbo->data);
|
||||||
|
memset(vbo, 0, sizeof(&vbo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vbo->data)
|
||||||
|
{
|
||||||
|
memset(vbo, 0, sizeof(&vbo));
|
||||||
|
vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0]));
|
||||||
|
// create vertex array
|
||||||
|
vbo->data = malloc(vertex_count * sizeof(vbo->data[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
vbo->columns = col_count;
|
||||||
|
vbo->rows = row_count;
|
||||||
|
|
||||||
|
vertex_p = &vbo->data[0];
|
||||||
|
vbo->loopcount = 0;
|
||||||
|
|
||||||
|
for (yflip = 0; yflip < 2; yflip++)
|
||||||
|
{
|
||||||
|
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN;
|
||||||
|
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||||
|
vbo->loops[vbo->loopcount].vertexcount = col_count;
|
||||||
|
vbo->loops[vbo->loopcount].use_texture = false;
|
||||||
|
vbo->loopcount++;
|
||||||
|
|
||||||
|
delta = 0.0f;
|
||||||
|
foglayer = true;
|
||||||
|
for (c = 0; c < col_count; c++)
|
||||||
|
{
|
||||||
|
SkyVertex(vertex_p, 1, c);
|
||||||
|
vertex_p->r = 255;
|
||||||
|
vertex_p->g = 255;
|
||||||
|
vertex_p->b = 255;
|
||||||
|
vertex_p->a = 255;
|
||||||
|
vertex_p++;
|
||||||
|
}
|
||||||
|
foglayer = false;
|
||||||
|
|
||||||
|
delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF;
|
||||||
|
|
||||||
|
for (r = 0; r < row_count; r++)
|
||||||
|
{
|
||||||
|
vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP;
|
||||||
|
vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0];
|
||||||
|
vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2;
|
||||||
|
vbo->loops[vbo->loopcount].use_texture = true;
|
||||||
|
vbo->loopcount++;
|
||||||
|
|
||||||
|
for (c = 0; c <= col_count; c++)
|
||||||
|
{
|
||||||
|
SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0));
|
||||||
|
SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
static void RenderDome(INT32 skytexture)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int vbosize;
|
||||||
|
GLSkyVBO *vbo = &sky_vbo;
|
||||||
|
|
||||||
|
rows = 4;
|
||||||
|
columns = 4 * gl_sky_detail;
|
||||||
|
|
||||||
|
vbosize = 2 * rows * (columns * 2 + 2) + columns * 2;
|
||||||
|
|
||||||
|
// Build the sky dome! Yes!
|
||||||
|
if (lasttex != skytexture)
|
||||||
|
{
|
||||||
|
// delete VBO when already exists
|
||||||
|
if (gl_ext_arb_vertex_buffer_object)
|
||||||
|
{
|
||||||
|
if (vbo->id)
|
||||||
|
pglDeleteBuffers(1, &vbo->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
lasttex = skytexture;
|
||||||
|
gld_BuildSky(rows, columns);
|
||||||
|
|
||||||
|
if (gl_ext_arb_vertex_buffer_object)
|
||||||
|
{
|
||||||
|
// generate a new VBO and get the associated ID
|
||||||
|
pglGenBuffers(1, &vbo->id);
|
||||||
|
|
||||||
|
// bind VBO in order to use
|
||||||
|
pglBindBuffer(GL_ARRAY_BUFFER, vbo->id);
|
||||||
|
|
||||||
|
// upload data to VBO
|
||||||
|
pglBufferData(GL_ARRAY_BUFFER, vbosize * sizeof(vbo->data[0]), vbo->data, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind VBO in order to use
|
||||||
|
if (gl_ext_arb_vertex_buffer_object)
|
||||||
|
pglBindBuffer(GL_ARRAY_BUFFER, vbo->id);
|
||||||
|
|
||||||
|
// activate and specify pointers to arrays
|
||||||
|
pglVertexPointer(3, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_x);
|
||||||
|
pglTexCoordPointer(2, GL_FLOAT, sizeof(vbo->data[0]), sky_vbo_u);
|
||||||
|
pglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(vbo->data[0]), sky_vbo_r);
|
||||||
|
|
||||||
|
// activate color arrays
|
||||||
|
pglEnableClientState(GL_COLOR_ARRAY);
|
||||||
|
|
||||||
|
// set transforms
|
||||||
|
pglScalef(1.0f, (float)texh / 230.0f, 1.0f);
|
||||||
|
pglRotatef(270.0f, 0.0f, 1.0f, 0.0f);
|
||||||
|
|
||||||
|
for (j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
for (i = 0; i < vbo->loopcount; i++)
|
||||||
|
{
|
||||||
|
GLSkyLoopDef *loop = &vbo->loops[i];
|
||||||
|
|
||||||
|
if (j == 0 ? loop->use_texture : !loop->use_texture)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
pglDrawArrays(loop->mode, loop->vertexindex, loop->vertexcount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pglScalef(1.0f, 1.0f, 1.0f);
|
||||||
|
pglColor4ubv(white);
|
||||||
|
|
||||||
|
// bind with 0, so, switch back to normal pointer operation
|
||||||
|
if (gl_ext_arb_vertex_buffer_object)
|
||||||
|
pglBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
// deactivate color array
|
||||||
|
pglDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform)
|
||||||
|
{
|
||||||
|
SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||||
|
SetTransform(&transform);
|
||||||
|
texw = texture_width;
|
||||||
|
texh = texture_height;
|
||||||
|
RenderDome(tex);
|
||||||
|
SetBlend(0);
|
||||||
|
}
|
||||||
|
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
//
|
//
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
@ -2521,7 +2856,8 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model)
|
||||||
|
|
||||||
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface)
|
||||||
{
|
{
|
||||||
static GLRGBAFloat mix = {0,0,0,0};
|
static GLRGBAFloat poly = {0,0,0,0};
|
||||||
|
static GLRGBAFloat tint = {0,0,0,0};
|
||||||
static GLRGBAFloat fade = {0,0,0,0};
|
static GLRGBAFloat fade = {0,0,0,0};
|
||||||
|
|
||||||
float pol = 0.0f;
|
float pol = 0.0f;
|
||||||
|
@ -2550,24 +2886,29 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32
|
||||||
pol = 0.0f;
|
pol = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
mix.red = byte2float[Surface->PolyColor.s.red];
|
poly.red = byte2float[Surface->PolyColor.s.red];
|
||||||
mix.green = byte2float[Surface->PolyColor.s.green];
|
poly.green = byte2float[Surface->PolyColor.s.green];
|
||||||
mix.blue = byte2float[Surface->PolyColor.s.blue];
|
poly.blue = byte2float[Surface->PolyColor.s.blue];
|
||||||
mix.alpha = byte2float[Surface->PolyColor.s.alpha];
|
poly.alpha = byte2float[Surface->PolyColor.s.alpha];
|
||||||
|
|
||||||
if (mix.alpha < 1)
|
if (poly.alpha < 1)
|
||||||
SetBlend(PF_Translucent|PF_Modulated);
|
SetBlend(PF_Translucent|PF_Modulated);
|
||||||
else
|
else
|
||||||
SetBlend(PF_Masked|PF_Modulated|PF_Occlude);
|
SetBlend(PF_Masked|PF_Modulated|PF_Occlude);
|
||||||
|
|
||||||
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
|
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
|
||||||
|
|
||||||
|
tint.red = byte2float[Surface->TintColor.s.red];
|
||||||
|
tint.green = byte2float[Surface->TintColor.s.green];
|
||||||
|
tint.blue = byte2float[Surface->TintColor.s.blue];
|
||||||
|
tint.alpha = byte2float[Surface->TintColor.s.alpha];
|
||||||
|
|
||||||
fade.red = byte2float[Surface->FadeColor.s.red];
|
fade.red = byte2float[Surface->FadeColor.s.red];
|
||||||
fade.green = byte2float[Surface->FadeColor.s.green];
|
fade.green = byte2float[Surface->FadeColor.s.green];
|
||||||
fade.blue = byte2float[Surface->FadeColor.s.blue];
|
fade.blue = byte2float[Surface->FadeColor.s.blue];
|
||||||
fade.alpha = byte2float[Surface->FadeColor.s.alpha];
|
fade.alpha = byte2float[Surface->FadeColor.s.alpha];
|
||||||
|
|
||||||
load_shaders(Surface, &mix, &fade);
|
load_shaders(Surface, &poly, &tint, &fade);
|
||||||
|
|
||||||
pglEnable(GL_CULL_FACE);
|
pglEnable(GL_CULL_FACE);
|
||||||
pglEnable(GL_NORMALIZE);
|
pglEnable(GL_NORMALIZE);
|
||||||
|
|
|
@ -101,6 +101,8 @@ void *hwSym(const char *funcName,void *handle)
|
||||||
GETFUNC(MakeScreenFinalTexture);
|
GETFUNC(MakeScreenFinalTexture);
|
||||||
GETFUNC(DrawScreenFinalTexture);
|
GETFUNC(DrawScreenFinalTexture);
|
||||||
|
|
||||||
|
GETFUNC(RenderSkyDome);
|
||||||
|
|
||||||
GETFUNC(LoadShaders);
|
GETFUNC(LoadShaders);
|
||||||
GETFUNC(KillShaders);
|
GETFUNC(KillShaders);
|
||||||
GETFUNC(SetShader);
|
GETFUNC(SetShader);
|
||||||
|
|
|
@ -1871,6 +1871,8 @@ void I_StartupGraphics(void)
|
||||||
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
|
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
|
||||||
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
|
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
|
||||||
|
|
||||||
|
HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL);
|
||||||
|
|
||||||
HWD.pfnLoadShaders = hwSym("LoadShaders",NULL);
|
HWD.pfnLoadShaders = hwSym("LoadShaders",NULL);
|
||||||
HWD.pfnKillShaders = hwSym("KillShaders",NULL);
|
HWD.pfnKillShaders = hwSym("KillShaders",NULL);
|
||||||
HWD.pfnSetShader = hwSym("SetShader",NULL);
|
HWD.pfnSetShader = hwSym("SetShader",NULL);
|
||||||
|
|
Loading…
Reference in a new issue