Compare commits

...
2 Commits
Author SHA1 Message Date
alufolie91 59a4627911 gl: use shaders for vhs effect
this is a fuckton faster lol
the old one did a gazillion draw calls now we do two, one for the fuzzy and the 2nd for the bars as both are handled within a single shader
thanks to RRs heat effect being super similar to the vhs bars lul
2026-11-12 21:02:07 +01:00
alufolie91 ecab383078 gl: use shaders for underwater / heatwave effect
basically ported over from RR
water was massively toned down and adjusted, it visually almost matches software at default res (note that the software effects are not properly scaled lol)
the heat effect is just the water effect adjusted to look like the fixed function version from before but slightly slower to accomidate the slower water effect here

this should speed things up a little since we now only need ONE draw call instead of 20 per effect
small note: this does not zoom into the image like the shaderless version, which was quite jarring tbh but there can be some very slight "stretch" marks at screen border, but theyre extremely unnoticable
2026-11-12 20:32:38 +01:00
8 changed files with 426 additions and 130 deletions

No files matched your search

+6
View File
@@ -196,6 +196,12 @@ enum
SHADER_PALETTE_POSTPROCESS,
SHADER_UI_COLORMAP_FADE,
SHADER_POSTPROCESS_WATER,
SHADER_POSTPROCESS_HEAT,
SHADER_VHS_FUZZ,
SHADER_VHS_BAR,
NUMSHADERTARGETS
};
+2 -1
View File
@@ -66,10 +66,11 @@ void GL_FlushScreenTextures(void);
void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags);
void GL_DoScreenWipe(int wipeStart, int wipeEnd);
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize, boolean rewind);
void GL_DrawScreenFinalTexture(int tex, INT32 width, INT32 height);
void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2]);
void GL_DoPostProcessor(INT32 type);
boolean GL_InitShaders(void);
void GL_LoadShader(int slot, char *code, hwdshaderstage_t stage);
+44 -29
View File
@@ -5992,8 +5992,7 @@ void HWR_RenderPlayerView(void)
if (HWR_UseShader())
{
if (cv_ripplewater.value)
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
if (cv_glmdls.value)
{
@@ -6002,7 +6001,7 @@ void HWR_RenderPlayerView(void)
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
}
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
@@ -6352,42 +6351,58 @@ static void HWR_DoPostProcessor(void)
GL_MakeScreenTexture(HWD_SCREENTEXTURE_GENERIC1);
// Drunken vision! WooOOooo~
// 10 by 10 grid. 2 coordinates (xy)
float v[SCREENVERTS][SCREENVERTS][2];
float disStart = (leveltime-1) + FixedToFloat(R_GetTimeFrac(RTF_LEVEL));
UINT8 x, y;
float WAVELENGTH;
float AMPLITUDE;
float FREQUENCY;
// Modifies the wave.
if (thiscam->postimg & POSTIMG_WATER)
// shader based, should be a bit faster!
if (HWR_UseShader())
{
WAVELENGTH = 5.0f;
AMPLITUDE = 40.0f;
FREQUENCY = 8.0f;
if (thiscam->postimg & POSTIMG_WATER)
{
GL_DoPostProcessor(POSTIMG_WATER);
}
else if (thiscam->postimg & POSTIMG_HEAT)
{
GL_DoPostProcessor(POSTIMG_HEAT);
}
}
else
{
WAVELENGTH = 10.0f;
AMPLITUDE = 60.0f;
FREQUENCY = 4.0f;
}
// 10 by 10 grid. 2 coordinates (xy)
float v[SCREENVERTS][SCREENVERTS][2];
float disStart = (leveltime-1) + FixedToFloat(R_GetTimeFrac(RTF_LEVEL));
//static constexpr float scale = ((float)SCREENVERTS - 1.0f) / 9.0f; // well this evals to just 1.0f and what is x / 1? kek
UINT8 x, y;
float WAVELENGTH;
float AMPLITUDE;
float FREQUENCY;
for (x = 0; x < SCREENVERTS; x++)
{
for (y = 0; y < SCREENVERTS; y++)
// Modifies the wave.
if (thiscam->postimg & POSTIMG_WATER)
{
// Change X position based on its Y position.
v[x][y][0] = x-4.5f + sinf(((disStart+(static_cast<float>(y) * WAVELENGTH)) / FREQUENCY)) / AMPLITUDE; // (x / scale)
v[x][y][1] = y-4.5f; // (y / scale)
WAVELENGTH = 5.0f;
AMPLITUDE = 40.0f;
FREQUENCY = 8.0f;
}
else
{
WAVELENGTH = 10.0f;
AMPLITUDE = 60.0f;
FREQUENCY = 4.0f;
}
}
GL_PostImgRedraw(v);
//static constexpr float scale = ((float)SCREENVERTS - 1.0f) / 9.0f; // well this evals to just 1.0f and what is x / 1? kek
for (x = 0; x < SCREENVERTS; x++)
{
for (y = 0; y < SCREENVERTS; y++)
{
// Change X position based on its Y position.
v[x][y][0] = x-4.5f + sinf(((disStart+(static_cast<float>(y) * WAVELENGTH)) / FREQUENCY)) / AMPLITUDE; // (x / scale)
v[x][y][1] = y-4.5f; // (y / scale)
}
}
GL_PostImgRedraw(v);
}
// Capture the screen again for screen waving on the intermission
if (gamestate != GS_INTERMISSION)
+2 -2
View File
@@ -145,9 +145,9 @@ FUNCINLINE static ATTRINLINE void HWR_DrawIntermissionBG(void)
GL_DrawScreenTexture(HWD_SCREENTEXTURE_GENERIC1, NULL, 0);
}
FUNCINLINE static ATTRINLINE void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
FUNCINLINE static ATTRINLINE void HWR_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize, boolean rewind)
{
GL_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
GL_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize, rewind);
}
FUNCINLINE static ATTRINLINE void HWR_MakeScreenTexture(void)
+16
View File
@@ -53,6 +53,18 @@ static struct {
// UI colormap fade shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_UI_COLORMAP_FADE_FRAGMENT_SHADER},
// water postprocess shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_POSTPROCESS_FRAGMENT_WATER},
// heat postprocess shader
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_POSTPROCESS_FRAGMENT_HEAT},
// vhs fuzz
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_VHS_FUZZ_SHADER},
// vhs bars
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_VHS_BAR_SHADER},
{NULL, NULL},
};
@@ -444,6 +456,10 @@ customshaderxlat_t shaderxlat[] =
{"Sky", SHADER_SKY},
{"PalettePostprocess", SHADER_PALETTE_POSTPROCESS},
{"UIColormapFade", SHADER_UI_COLORMAP_FADE},
{"PostProcessWater", SHADER_POSTPROCESS_WATER},
{"PostProcessHeat", SHADER_POSTPROCESS_HEAT},
{"VHSFuzz", SHADER_VHS_FUZZ},
{"VHSBar", SHADER_VHS_BAR},
{NULL, 0},
};
+119
View File
@@ -337,6 +337,125 @@
"gl_FragColor = texture2D(lighttable_tex, lighttable_coord);\n" \
"}\0" \
// these are RRs postprocess shaders
// for water and heat
/*
#define GLSL_POSTPROCESS_FRAGMENT_WATER \
"uniform sampler2D tex;\n" \
"uniform float leveltime;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"float y = 1.0 - uv.y;\n" \
"uv.x += sin(leveltime * 2.0 + y * 20.0) * 0.01;\n" \
"uv = clamp(uv, vec2(0.0), vec2(0.9999));\n" \
"gl_FragColor = texture2D(tex, uv);\n" \
"}\0"
#define GLSL_POSTPROCESS_FRAGMENT_HEAT \
"uniform sampler2D tex;\n" \
"uniform float leveltime;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"float y = 1.0 - uv.y;\n" \
"float time = leveltime * 35.0;\n" \
"uv.x += max(sin((time / 35.0) * 1.2 - y * 5.0) - 0.995, 0.0);\n" \
"uv.x -= max(sin(((time + 24.0) / 35.0) * 0.2 - y * 1.5) - 0.990, 0.0);\n" \
"uv = clamp(uv, vec2(0.0), vec2(0.9999));\n" \
"gl_FragColor = texture2D(tex, uv);\n" \
"}\0"
*/
// for reference
// sin(leveltime * X + (y) + Y) * Z
// X = Speed, Y = Vertical phase, Z = Amplitude
// this matches software at 720p wonderfully
#define GLSL_POSTPROCESS_FRAGMENT_WATER \
"#version 120\n" \
"uniform sampler2D tex;\n" \
"uniform vec2 scr_resolution;\n" \
"uniform vec2 scr_tex_size;\n" \
"uniform float leveltime;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"vec2 maxuv = scr_resolution / scr_tex_size;\n" \
"float y = 1.0 - uv.y;\n" \
"uv.x += sin(leveltime * 3.0 + y * 15.0) * 0.0025;\n" \
"uv = clamp(uv, vec2(0.0), maxuv - vec2(0.0001));\n" \
"gl_FragColor = texture2D(tex, uv);\n" \
"}\0"
// like the fixed function version, this is just the water wave again
// a bit readjusted since the shader wave is more lean
// makes it less neausiating anyways :p
#define GLSL_POSTPROCESS_FRAGMENT_HEAT \
"#version 120\n" \
"uniform sampler2D tex;\n" \
"uniform vec2 scr_resolution;\n" \
"uniform vec2 scr_tex_size;\n" \
"uniform float leveltime;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"vec2 maxuv = scr_resolution / scr_tex_size;\n" \
"float y = 1.0 - uv.y;\n" \
"uv.x += sin(leveltime * 6.0 + y * 22.5) * 0.00125;\n" \
"uv = clamp(uv, vec2(0.0), maxuv - vec2(0.0001));\n" \
"gl_FragColor = texture2D(tex, uv);\n" \
"}\0"
// screen fuzzyness
// basically just what we did before as a shader lul
// thanks https://stackoverflow.com/a/4275343 for the pseudo random stuff for glsl
#define GLSL_VHS_FUZZ_SHADER \
"#version 120\n" \
"uniform sampler2D tex;\n" \
"uniform vec2 scr_resolution;\n" \
"uniform vec2 scr_tex_size;\n" \
"uniform float vhs_time;\n" \
"uniform float scr_dup;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"vec2 maxuv = scr_resolution / scr_tex_size;\n" \
"float y = 1.0 - uv.y;\n" \
"float ystep = (2.0 / scr_resolution.y) * scr_dup / 4.0;\n" \
"float rand = fract(sin((floor(y / ystep) + vhs_time) * 12.9898 + 78.233) * 43758.5453);\n" \
"uv.x += floor(rand * 128.0) / -22000.0;\n" \
"uv = clamp(uv, vec2(0.0), maxuv - vec2(0.0001));\n" \
"gl_FragColor = texture2D(tex, uv);\n" \
"}\0"
// repurposed the RR heat shader
// since it kinda matched the vhs bars lul
#define GLSL_VHS_BAR_SHADER \
"#version 120\n" \
"uniform sampler2D tex;\n" \
"uniform vec2 scr_resolution;\n" \
"uniform vec2 scr_tex_size;\n" \
"uniform float vhs_time;\n" \
"uniform float vhs_rewind;\n" \
"void main(void) {\n" \
"vec2 uv = gl_TexCoord[0].st;\n" \
"vec2 maxuv = scr_resolution / scr_tex_size;\n" \
"float y = 1.0 - uv.y;\n" \
"float downspd = (vhs_rewind > 0.5) ? 2.0 : 1.0;\n" \
"float downbar = max(sin(vhs_time * downspd - y * 5.0) - 0.95, 0.0);\n" \
"float upspd = (vhs_rewind > 0.5) ? 3.0 : 1.8;\n" \
"float upbar = max(sin((vhs_time * -1.0) * upspd - y * 5.0) - 0.95, 0.0);\n" \
"uv.x += (downbar) * 0.25;\n" \
"float updistort = (vhs_rewind > 0.5) ? 0.4125: 0.25;\n" \
"uv.x -= (upbar) * updistort;\n" \
"uv = clamp(uv, vec2(0.0), maxuv - vec2(0.0001));\n" \
"vec4 color = texture2D(tex, uv);\n" \
"float downcol = step(0.00001, downbar);\n" \
"float upcol = step(0.00001, upbar);\n" \
"color.rgb = mix(color.rgb, color.rgb * (190.0 / 255.0), downcol);\n" \
"color.rgb = mix(color.rgb, color.rgb * (190.0 / 255.0), upcol);\n" \
"color.a = mix(color.a, color.a * (250.0 / 255.0), downcol);\n" \
"color.a = mix(color.a, color.a * (250.0 / 255.0), upcol);\n" \
"gl_FragColor = color;\n" \
"}\0"
// ================
// Fallback shaders
// ================
+233 -94
View File
@@ -761,6 +761,14 @@ typedef enum
gluniform_scr_resolution,
// postprocess stuff
gluniform_scr_dup,
gluniform_scr_tex_size,
// vhs
gluniform_vhs_rewind,
gluniform_vhs_time,
gluniform_max,
} gluniform_t;
@@ -793,6 +801,9 @@ static float shader_light_z = 0.0f;
static INT32 shader_light_contrast = 0;
static INT32 shader_light_backlight = 0;
static float shader_vhs_rewind = 1.0f;
static float shader_vhs_time = 0.0f;
// Lactozilla: Shader functions
static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i);
static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAFloat *tint, GLRGBAFloat *fade);
@@ -2329,6 +2340,13 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
UNIFORM_2(shader->uniforms[gluniform_scr_resolution], (GLfloat)screen_width, (GLfloat)screen_height, pglUniform2f);
// udup is before highres scale adjustments
UNIFORM_1(shader->uniforms[gluniform_scr_dup], (GLfloat)vid.udup, pglUniform1f);
// grrrrr stupid 2.0 support.. used similar to yfix, xfix
UNIFORM_2(shader->uniforms[gluniform_scr_tex_size], (GLfloat)screen_texsizew, (GLfloat)screen_texsizeh, pglUniform2f);
UNIFORM_1(shader->uniforms[gluniform_vhs_rewind], shader_vhs_rewind, pglUniform1f);
UNIFORM_1(shader->uniforms[gluniform_vhs_time], shader_vhs_time, pglUniform1f);
#undef UNIFORM_1
#undef UNIFORM_2
@@ -2461,6 +2479,15 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
// misc.
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
// postprocessor stuff (water/heat effect)
shader->uniforms[gluniform_scr_dup] = GETUNI("scr_dup");
shader->uniforms[gluniform_scr_tex_size] = GETUNI("scr_tex_size");
// vhs stuff
shader->uniforms[gluniform_vhs_rewind] = GETUNI("vhs_rewind");
shader->uniforms[gluniform_vhs_time] = GETUNI("vhs_time");
#undef GETUNI
// set permanent uniform values
@@ -3597,6 +3624,55 @@ INT32 GL_GetTextureUsed(void)
return res;
}
void GL_DoPostProcessor(INT32 type)
{
float fix[8];
float xfix, yfix;
if (gl_enable_screen_textures != 2)
return;
xfix = 1/((float)screen_texsizew/(float)screen_width);
yfix = 1/((float)screen_texsizeh/(float)screen_height);
fix[0] = fix[1] =
fix[2] = fix[7] = 0.0f;
fix[3] = fix[5] = yfix;
fix[4] = fix[6] = xfix;
// this shouldnt be necessary, since this comes after level draw
// but somehow it breaks without this??
pglMatrixMode(GL_PROJECTION);
pglPushMatrix();
pglLoadIdentity();
pglMatrixMode(GL_MODELVIEW);
pglPushMatrix();
pglLoadIdentity();
GL_SetBlend(PF_NoDepthTest);
pglActiveTexture(GL_TEXTURE0);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_GENERIC1]);
tex_downloaded = screenTextures[HWD_SCREENTEXTURE_GENERIC1];
int shader = (type == POSTIMG_WATER) ? SHADER_POSTPROCESS_WATER : SHADER_POSTPROCESS_HEAT;
GL_SetShader(HWR_GetShaderFromTarget(shader));
GL_Shader_SetUniforms(NULL, NULL, NULL, NULL);
pglColor4ubv(white);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, defaultscreenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
GL_UnSetShader();
pglMatrixMode(GL_PROJECTION);
pglPopMatrix();
pglMatrixMode(GL_MODELVIEW);
pglPopMatrix();
}
void GL_PostImgRedraw(float points[SCREENVERTS][SCREENVERTS][2])
{
INT32 x, y;
@@ -3716,7 +3792,6 @@ void GL_DrawScreenTexture(int tex, FSurfaceInfo *surf, FBITFIELD polyflags)
tex_downloaded = screenTextures[tex];
}
// Do screen fades!
void GL_DoScreenWipe(int wipeStart, int wipeEnd)
{
@@ -3791,120 +3866,184 @@ void GL_DoScreenWipe(int wipeStart, int wipeEnd)
tex_downloaded = screenTextures[wipeEnd];
}
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
void GL_RenderVhsEffect(fixed_t upbary, fixed_t downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize, boolean rewind)
{
float xfix, yfix;
float fix[8];
float i;
if (gl_enable_screen_textures != 2)
return;
GLubyte color[4] = {255, 255, 255, 255};
float screenVerts[12] =
{
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
const GLfloat scrwf = (float)screen_width;
const GLfloat scrwh = (float)screen_height;
const GLfloat scrhf = (float)screen_height;
xfix = 1/((float)screen_texsizew/scrwf);
yfix = 1/((float)screen_texsizeh/scrwh);
yfix = 1/((float)screen_texsizeh/scrhf);
GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
// Slight fuzziness
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
uint32_t r = rand();
const float ystep = 2.f/scrwh * (float)vid.udup/4.f;
for (i = 0; i < 1; i += ystep)
// uses shaders to replicate the effect
// thanks RR for their heat effect being basically the vhs bars, made this lots easier lul
if (HWR_UseShader())
{
// avoid calling rand thousands of times
r ^= r >> 13;
r ^= r >> 11;
r ^= r << 21;
// leveltime pauses with the game so we need to keep our own ticker here
static tic_t lleveltime = 0;
if (renderisnewtic) lleveltime++;
shader_vhs_time = (((float)(lleveltime-1)) + FIXED_TO_FLOAT(R_GetTimeFrac(RTF_CAMERA))) / TICRATE; // RTF_CAMERA interpolates during pause gladly...
fix[2] = (float)(r & 127) / -22000.f * xfix;
fix[0] = fix[2];
fix[6] = fix[0] + xfix;
fix[4] = fix[2] + xfix;
fix[1] = fix[7] = i*yfix;
fix[3] = fix[5] = (i+0.015f)*yfix;
// easier to account for within the shader
shader_vhs_rewind = rewind ? 1.0f : 0.0f;
screenVerts[1] = screenVerts[10] = 2*i - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03f;
fix[0] = fix[1] =
fix[2] = fix[7] = 0.0f;
fix[3] = fix[5] = yfix;
fix[4] = fix[6] = xfix;
GL_SetBlend(PF_NoDepthTest);
// Slight fuzziness
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglActiveTexture(GL_TEXTURE0);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
tex_downloaded = screenTextures[HWD_SCREENTEXTURE_VHS];
GL_SetShader(HWR_GetShaderFromTarget(SHADER_VHS_FUZZ));
GL_Shader_SetUniforms(NULL, NULL, NULL, NULL);
pglColor4ubv(white);
pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, defaultscreenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
GL_UnSetShader();
// Upward and Downward bars
// theyre combined since the original shader also did this
// also saves us another screen copy + draw anyways
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglActiveTexture(GL_TEXTURE0);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
tex_downloaded = screenTextures[HWD_SCREENTEXTURE_VHS];
GL_SetShader(HWR_GetShaderFromTarget(SHADER_VHS_BAR));
GL_Shader_SetUniforms(NULL, NULL, NULL, NULL);
pglColor4ubv(white);
pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, defaultscreenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
GL_UnSetShader();
}
else // fallback fixed function version, this is quite slow
{
float i;
GLubyte color[4] = {255, 255, 255, 255};
float screenVerts[12] =
{
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f
};
xfix = 1/((float)screen_texsizew/scrwf);
yfix = 1/((float)screen_texsizeh/scrhf);
GL_SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
// Slight fuzziness
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
uint32_t r = rand();
const float ystep = 2.f/scrhf * (float)vid.udup/4.f;
for (i = 0; i < 1; i += ystep)
{
// avoid calling rand thousands of times
r ^= r >> 13;
r ^= r >> 11;
r ^= r << 21;
fix[2] = (float)(r & 127) / -22000.f * xfix;
fix[0] = fix[2];
fix[6] = fix[0] + xfix;
fix[4] = fix[2] + xfix;
fix[1] = fix[7] = i*yfix;
fix[3] = fix[5] = (i+0.015f)*yfix;
screenVerts[1] = screenVerts[10] = 2*i - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03f;
pglColor4ubv(color);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
// Upward bar
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
color[0] = color[1] = color[2] = 190;
color[3] = 250;
pglColor4ubv(color);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)updistort / scrwf * xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*upbary/scrhf - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrhf;
fix[1] = fix[7] = (float)upbary/scrhf * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/scrhf * yfix;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// Downward bar
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)downdistort / scrwf * -xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*downbary/scrhf - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrhf;
fix[1] = fix[7] = (float)downbary/scrhf * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/scrhf * yfix;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
// Upward bar
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
color[0] = color[1] = color[2] = 190;
color[3] = 250;
pglColor4ubv(color);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)updistort / scrwf * xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*upbary/scrwh - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh;
fix[1] = fix[7] = (float)upbary/scrwh * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
// Downward bar
GL_MakeScreenTexture(HWD_SCREENTEXTURE_VHS);
pglBindTexture(GL_TEXTURE_2D, screenTextures[HWD_SCREENTEXTURE_VHS]);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)downdistort / scrwf * -xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*downbary/scrwh - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/scrwh;
fix[1] = fix[7] = (float)downbary/scrwh * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/scrwh * yfix;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
fix[1] = fix[7] += (fix[3] - fix[7])*2;
screenVerts[1] = screenVerts[10] += (screenVerts[4] - screenVerts[1])*2;
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
// Create a texture from the screen.
+4 -4
View File
@@ -1882,7 +1882,7 @@ void V_DrawVhsEffect(boolean rewind)
#ifdef HWRENDER
if (rendermode == render_opengl)
{
HWR_RenderVhsEffect(uby, dby, updistort, downdistort, barsize);
HWR_RenderVhsEffect(uby, dby, updistort, downdistort, barsize, rewind);
return;
}
#endif
@@ -3619,7 +3619,7 @@ void V_DoPostProcessor(INT32 view, INT32 param)
for (y = yoffset; y < yoffset+viewheight; y++)
{
sine = (FINESINE(disStart)*5)>>FRACBITS;
sine = (FINESINE(disStart) * 5) >> FRACBITS;
newpix = abs(sine);
if (sine < 0)
@@ -3659,8 +3659,8 @@ void V_DoPostProcessor(INT32 view, INT32 param)
tmpscr[y*vid.width + x] = srcscr[y*vid.width+newpix]; // *(transme + (srcscr[y*vid.width+x]<<8) + srcscr[y*vid.width+newpix]);
}*/
disStart += 22;//the offset into the displacement map, increment each game loop
disStart &= FINEMASK; //clip it to FINEMASK
disStart += 22; // the offset into the displacement map, increment each game loop
disStart &= FINEMASK; // clip it to FINEMASK
}
UINT8 *tmp = tmpscr;