Port opengl VHS effect from SRB2Kart-Saturn

Does not include uncap stuff currently
This commit is contained in:
NepDisk 2025-02-09 11:31:45 -05:00
parent 3ae6342306
commit bb566685e4
7 changed files with 113 additions and 2 deletions

View file

@ -66,6 +66,7 @@ EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (void);
EXPORT void HWRAPI(DrawIntermissionBG) (void);
EXPORT void HWRAPI(MakeScreenTexture) (void);
EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
@ -121,6 +122,7 @@ struct hwdriver_s
DoScreenWipe pfnDoScreenWipe;
DrawIntermissionBG pfnDrawIntermissionBG;
MakeScreenTexture pfnMakeScreenTexture;
RenderVhsEffect pfnRenderVhsEffect;
MakeScreenFinalTexture pfnMakeScreenFinalTexture;
DrawScreenFinalTexture pfnDrawScreenFinalTexture;

View file

@ -6672,6 +6672,11 @@ void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum)
HWR_DoWipe(wipenum, scrnnum);
}
void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
HWD.pfnRenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
}
void HWR_MakeScreenFinalTexture(void)
{
HWD.pfnMakeScreenFinalTexture();

View file

@ -67,6 +67,7 @@ void HWR_EndScreenWipe(void);
void HWR_DrawIntermissionBG(void);
void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_DoTintedWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_RenderVhsEffect(INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize);
void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height);

View file

@ -3512,6 +3512,86 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
tex_downloaded = screentexture;
}
EXPORT void HWRAPI(RenderVhsEffect) (INT16 upbary, INT16 downbary, UINT8 updistort, UINT8 downdistort, UINT8 barsize)
{
float xfix, yfix;
float fix[8];
GLubyte color[4] = {255, 255, 255, 255};
float i;
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
};
// look for power of two that is large enough for the screen
while (texsize < screen_width || texsize < screen_height)
texsize <<= 1;
xfix = 1/((float)(texsize)/((float)((screen_width))));
yfix = 1/((float)(texsize)/((float)((screen_height))));
// Slight fuzziness
MakeScreenTexture();
SetBlend(PF_Modulated|PF_Translucent|PF_NoDepthTest);
pglBindTexture(GL_TEXTURE_2D, screentexture);
for (i = 0; i < 1; i += 2.f/vid.height)
{
fix[2] = (float)(rand() % 128) / -22000 * 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.015)*yfix;
screenVerts[1] = screenVerts[10] = 2*i - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + 0.03;
pglColor4ubv(color);
pglTexCoordPointer(2, GL_FLOAT, 0, fix);
pglVertexPointer(3, GL_FLOAT, 0, screenVerts);
pglDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
// Upward bar
MakeScreenTexture();
pglBindTexture(GL_TEXTURE_2D, screentexture);
color[0] = color[1] = color[2] = 190;
color[3] = 250;
pglColor4ubv(color);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)updistort / screen_width * xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*upbary/screen_height - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height;
fix[1] = fix[7] = (float)upbary/screen_height * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * 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
MakeScreenTexture();
pglBindTexture(GL_TEXTURE_2D, screentexture);
fix[0] = 0.0f;
fix[6] = xfix;
fix[2] = (float)downdistort / screen_width * -xfix;
fix[4] = fix[2] + fix[6];
screenVerts[1] = screenVerts[10] = 2.0f*downbary/screen_height - 1.0f;
screenVerts[4] = screenVerts[7] = screenVerts[1] + (float)barsize/screen_height;
fix[1] = fix[7] = (float)downbary/screen_height * yfix;
fix[3] = fix[5] = fix[1] + (float)barsize/2/screen_height * 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);
}
EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
{
boolean firstTime = (finalScreenTexture == 0);

View file

@ -102,6 +102,7 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(DoScreenWipe);
GETFUNC(DrawIntermissionBG);
GETFUNC(MakeScreenTexture);
GETFUNC(RenderVhsEffect);
GETFUNC(MakeScreenFinalTexture);
GETFUNC(DrawScreenFinalTexture);

View file

@ -2080,6 +2080,7 @@ void VID_StartupOpenGL(void)
*(void**)&HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL);
*(void**)&HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL);
*(void**)&HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
*(void**)&HWD.pfnRenderVhsEffect = hwSym("RenderVhsEffect",NULL);
*(void**)&HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
*(void**)&HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);

View file

@ -30,6 +30,7 @@
#include "m_misc.h"
#include "m_random.h"
#include "doomstat.h"
#include "r_fps.h"
#ifdef HWRENDER
#include "hardware/hw_glob.h"
@ -1421,11 +1422,31 @@ void V_DrawVhsEffect(boolean rewind)
if (rewind)
V_DrawVhsEffect(false); // experimentation
upbary -= FixedMul(vid.dupy * (rewind ? 3 : 1.8f), renderdeltatics);
downbary += FixedMul(vid.dupy * (rewind ? 2 : 1), renderdeltatics);
if (R_UsingFrameInterpolation()) // omg i fucking hate interp so much, its a bit smoother but still not great whatever, atleast like this shit wont completely go nuts when youre on high framerates
{
if (renderisnewtic)
{
upbary -= FixedMul(vid.dupy * (rewind ? 3 : 1.8f), 22937*3);
downbary += FixedMul(vid.dupy * (rewind ? 2 : 1), 22937*3);
}
}
else
{
upbary -= vid.dupy * (rewind ? 3 : 1.8f);
downbary += vid.dupy * (rewind ? 2 : 1);
}
if (upbary < -barsize) upbary = vid.height;
if (downbary > vid.height) downbary = -barsize;
#ifdef HWRENDER
if ((rendermode == render_opengl))
{
HWR_RenderVhsEffect(upbary, downbary, updistort, downdistort, barsize);
return;
}
#endif
for (y = 0; y < vid.height; y+=2)
{
thismapstart = normalmapstart;