mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +00:00
Merge remote-tracking branch 'gzdoom/master' into asmjit
This commit is contained in:
commit
4e85134d8e
42 changed files with 875 additions and 974 deletions
|
@ -1044,6 +1044,7 @@ set (PCH_SOURCES
|
|||
g_statusbar/shared_sbar.cpp
|
||||
gl/data/gl_vertexbuffer.cpp
|
||||
gl/data/gl_uniformbuffer.cpp
|
||||
gl/data/gl_viewpointbuffer.cpp
|
||||
gl/dynlights/gl_lightbuffer.cpp
|
||||
gl/dynlights/gl_shadowmap.cpp
|
||||
gl/models/gl_models.cpp
|
||||
|
@ -1061,7 +1062,6 @@ set (PCH_SOURCES
|
|||
gl_load/gl_interface.cpp
|
||||
gl/system/gl_framebuffer.cpp
|
||||
gl/system/gl_debug.cpp
|
||||
gl/system/gl_wipe.cpp
|
||||
gl/textures/gl_hwtexture.cpp
|
||||
gl/textures/gl_samplers.cpp
|
||||
hwrenderer/data/flatvertices.cpp
|
||||
|
|
222
src/d_main.cpp
222
src/d_main.cpp
|
@ -638,7 +638,8 @@ CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
|
||||
void D_Display ()
|
||||
{
|
||||
bool wipe;
|
||||
FTexture *wipe = nullptr;
|
||||
int wipe_type;
|
||||
sector_t *viewsec;
|
||||
|
||||
if (nodrawers || screen == NULL)
|
||||
|
@ -703,142 +704,130 @@ void D_Display ()
|
|||
if (NoWipe)
|
||||
{
|
||||
NoWipe--;
|
||||
wipe = false;
|
||||
wipe = nullptr;
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
// No wipes when in a stereo3D VR mode
|
||||
else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL && (vr_mode == 0 || vid_rendermode != 4))
|
||||
{ // save the current screen if about to wipe
|
||||
wipe = screen->WipeStartScreen ();
|
||||
switch (wipegamestate)
|
||||
{
|
||||
default:
|
||||
wipe = screen->WipeStartScreen (wipetype);
|
||||
wipe_type = wipetype;
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEFADE:
|
||||
wipe = screen->WipeStartScreen (wipe_Fade);
|
||||
wipe_type = wipe_Fade;
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEBURN:
|
||||
wipe = screen->WipeStartScreen (wipe_Burn);
|
||||
wipe_type =wipe_Burn;
|
||||
break;
|
||||
|
||||
case GS_FORCEWIPEMELT:
|
||||
wipe = screen->WipeStartScreen (wipe_Melt);
|
||||
wipe_type = wipe_Melt;
|
||||
break;
|
||||
}
|
||||
wipegamestate = gamestate;
|
||||
}
|
||||
else
|
||||
{
|
||||
wipe = false;
|
||||
wipe = nullptr;
|
||||
}
|
||||
|
||||
|
||||
screen->FrameTime = I_msTimeFS();
|
||||
TexMan.UpdateAnimations(screen->FrameTime);
|
||||
R_UpdateSky(screen->FrameTime);
|
||||
screen->BeginFrame();
|
||||
screen->ClearClipRect();
|
||||
if ((gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL) && gametic != 0)
|
||||
{
|
||||
screen->FrameTime = I_msTimeFS();
|
||||
TexMan.UpdateAnimations(screen->FrameTime);
|
||||
R_UpdateSky(screen->FrameTime);
|
||||
screen->BeginFrame();
|
||||
screen->ClearClipRect();
|
||||
// [ZZ] execute event hook that we just started the frame
|
||||
//E_RenderFrame();
|
||||
//
|
||||
|
||||
// Check for the presence of dynamic lights at the start of the frame once.
|
||||
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
|
||||
{
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
level.HasDynamicLights = !!it.Next();
|
||||
}
|
||||
else level.HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
|
||||
viewsec = screen->RenderView(&players[consoleplayer]);
|
||||
screen->Begin2D();
|
||||
screen->DrawBlend(viewsec);
|
||||
if (automapactive)
|
||||
{
|
||||
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
}
|
||||
if (!automapactive || viewactive)
|
||||
{
|
||||
screen->RefreshViewBorder ();
|
||||
}
|
||||
|
||||
// for timing the statusbar code.
|
||||
//cycle_t stb;
|
||||
//stb.Reset();
|
||||
//stb.Clock();
|
||||
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_AltHud);
|
||||
if (DrawFSHUD || automapactive) DrawHUD();
|
||||
if (players[consoleplayer].camera && players[consoleplayer].camera->player && !automapactive)
|
||||
{
|
||||
StatusBar->DrawCrosshair();
|
||||
}
|
||||
StatusBar->CallDraw (HUD_AltHud, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (HUD_AltHud);
|
||||
}
|
||||
else if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10)
|
||||
{
|
||||
EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None;
|
||||
StatusBar->DrawBottomStuff (state);
|
||||
StatusBar->CallDraw (state, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (state);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_StatusBar);
|
||||
StatusBar->CallDraw (HUD_StatusBar, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (HUD_StatusBar);
|
||||
}
|
||||
//stb.Unclock();
|
||||
//Printf("Stbar = %f\n", stb.TimeMS());
|
||||
}
|
||||
else
|
||||
{
|
||||
screen->Begin2D();
|
||||
switch (gamestate)
|
||||
{
|
||||
case GS_FULLCONSOLE:
|
||||
screen->Begin2D(false);
|
||||
C_DrawConsole ();
|
||||
M_Drawer ();
|
||||
screen->End2D();
|
||||
screen->Update ();
|
||||
return;
|
||||
|
||||
case GS_LEVEL:
|
||||
case GS_TITLELEVEL:
|
||||
if (!gametic)
|
||||
{
|
||||
screen->Begin2D(false);
|
||||
case GS_FULLCONSOLE:
|
||||
screen->Begin2D();
|
||||
C_DrawConsole ();
|
||||
M_Drawer ();
|
||||
screen->End2DAndUpdate ();
|
||||
return;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
WI_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_FINALE:
|
||||
F_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_DEMOSCREEN:
|
||||
D_PageDrawer ();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// [ZZ] execute event hook that we just started the frame
|
||||
//E_RenderFrame();
|
||||
//
|
||||
|
||||
// Check for the presence of dynamic lights at the start of the frame once.
|
||||
if ((gl_lights && vid_rendermode == 4) || (r_dynlights && vid_rendermode != 4))
|
||||
{
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
level.HasDynamicLights = !!it.Next();
|
||||
}
|
||||
else level.HasDynamicLights = false; // lights are off so effectively we have none.
|
||||
|
||||
viewsec = screen->RenderView(&players[consoleplayer]);
|
||||
screen->Begin2D(false);
|
||||
screen->DrawBlend(viewsec);
|
||||
// returns with 2S mode set.
|
||||
if (automapactive)
|
||||
{
|
||||
AM_Drawer (hud_althud? viewheight : StatusBar->GetTopOfStatusbar());
|
||||
}
|
||||
if (!automapactive || viewactive)
|
||||
{
|
||||
screen->RefreshViewBorder ();
|
||||
}
|
||||
|
||||
// for timing the statusbar code.
|
||||
//cycle_t stb;
|
||||
//stb.Reset();
|
||||
//stb.Clock();
|
||||
if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_AltHud);
|
||||
if (DrawFSHUD || automapactive) DrawHUD();
|
||||
if (players[consoleplayer].camera && players[consoleplayer].camera->player && !automapactive)
|
||||
{
|
||||
StatusBar->DrawCrosshair();
|
||||
}
|
||||
StatusBar->CallDraw (HUD_AltHud, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (HUD_AltHud);
|
||||
}
|
||||
else
|
||||
if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10)
|
||||
{
|
||||
EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None;
|
||||
StatusBar->DrawBottomStuff (state);
|
||||
StatusBar->CallDraw (state, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (state);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar->DrawBottomStuff (HUD_StatusBar);
|
||||
StatusBar->CallDraw (HUD_StatusBar, vp.TicFrac);
|
||||
StatusBar->DrawTopStuff (HUD_StatusBar);
|
||||
}
|
||||
//stb.Unclock();
|
||||
//Printf("Stbar = %f\n", stb.TimeMS());
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_INTERMISSION:
|
||||
screen->Begin2D(false);
|
||||
WI_Drawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_FINALE:
|
||||
screen->Begin2D(false);
|
||||
F_Drawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_DEMOSCREEN:
|
||||
screen->Begin2D(false);
|
||||
D_PageDrawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
CT_Drawer ();
|
||||
|
||||
// draw pause pic
|
||||
if ((paused || pauseext) && menuactive == MENU_Off)
|
||||
{
|
||||
|
@ -879,15 +868,17 @@ void D_Display ()
|
|||
GSnd->DrawWaveDebug(snd_drawoutput);
|
||||
}
|
||||
|
||||
if (!wipe || NoWipe < 0)
|
||||
if (!wipe || NoWipe < 0 || wipe_type == wipe_None)
|
||||
{
|
||||
if (wipe != nullptr) delete wipe;
|
||||
wipe = nullptr;
|
||||
NetUpdate (); // send out any new accumulation
|
||||
// normal update
|
||||
// draw ZScript UI stuff
|
||||
C_DrawConsole (); // draw console
|
||||
M_Drawer (); // menu is drawn even on top of everything
|
||||
FStat::PrintStat ();
|
||||
screen->Update (); // page flip or blit buffer
|
||||
screen->End2DAndUpdate ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -897,7 +888,10 @@ void D_Display ()
|
|||
|
||||
GSnd->SetSfxPaused(true, 1);
|
||||
I_FreezeTime(true);
|
||||
screen->WipeEndScreen ();
|
||||
screen->End2D();
|
||||
auto wipend = screen->WipeEndScreen ();
|
||||
auto wiper = Wiper::Create(wipe_type);
|
||||
wiper->SetTextures(wipe, wipend);
|
||||
|
||||
wipestart = I_msTime();
|
||||
NetUpdate(); // send out any new accumulation
|
||||
|
@ -911,17 +905,17 @@ void D_Display ()
|
|||
diff = (nowtime - wipestart) * 40 / 1000; // Using 35 here feels too slow.
|
||||
} while (diff < 1);
|
||||
wipestart = nowtime;
|
||||
done = screen->WipeDo (1);
|
||||
screen->Begin2D();
|
||||
done = wiper->Run(1);
|
||||
C_DrawConsole (); // console and
|
||||
M_Drawer (); // menu are drawn even on top of wipes
|
||||
screen->Update (); // page flip or blit buffer
|
||||
screen->End2DAndUpdate ();
|
||||
NetUpdate (); // [RH] not sure this is needed anymore
|
||||
} while (!done);
|
||||
screen->WipeCleanup();
|
||||
delete wiper;
|
||||
I_FreezeTime(false);
|
||||
GSnd->SetSfxPaused(false, 1);
|
||||
}
|
||||
screen->End2D();
|
||||
cycles.Unclock();
|
||||
FrameCycles = cycles;
|
||||
}
|
||||
|
|
283
src/f_wipe.cpp
283
src/f_wipe.cpp
|
@ -27,6 +27,36 @@
|
|||
#include "m_random.h"
|
||||
#include "f_wipe.h"
|
||||
#include "templates.h"
|
||||
#include "textures/bitmap.h"
|
||||
#include "hwrenderer/textures/hw_material.h"
|
||||
|
||||
class FBurnTexture : public FTexture
|
||||
{
|
||||
uint32_t *WorkBuffer;
|
||||
public:
|
||||
FBurnTexture(int w, int h)
|
||||
{
|
||||
Width = w;
|
||||
Height = h;
|
||||
WorkBuffer = new uint32_t[w * h];
|
||||
}
|
||||
|
||||
~FBurnTexture()
|
||||
{
|
||||
delete [] WorkBuffer;
|
||||
}
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override
|
||||
{
|
||||
bmp->CopyPixelDataRGB(x, y, (uint8_t*)WorkBuffer, Width, Height, 4, Width*4, rotate, CF_RGBA, inf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t *GetBuffer()
|
||||
{
|
||||
return WorkBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
|
||||
{
|
||||
|
@ -112,3 +142,256 @@ int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class Wiper_Crossfade : public Wiper
|
||||
{
|
||||
public:
|
||||
bool Run(int ticks) override;
|
||||
|
||||
private:
|
||||
int Clock = 0;
|
||||
};
|
||||
|
||||
class Wiper_Melt : public Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Melt();
|
||||
bool Run(int ticks) override;
|
||||
|
||||
private:
|
||||
static const int WIDTH = 320, HEIGHT = 200;
|
||||
int y[WIDTH];
|
||||
};
|
||||
|
||||
class Wiper_Burn : public Wiper
|
||||
{
|
||||
public:
|
||||
~Wiper_Burn();
|
||||
bool Run(int ticks) override;
|
||||
void SetTextures(FTexture *startscreen, FTexture *endscreen) override;
|
||||
|
||||
private:
|
||||
static const int WIDTH = 64, HEIGHT = 64;
|
||||
uint8_t BurnArray[WIDTH * (HEIGHT + 5)] = {0};
|
||||
FBurnTexture *BurnTexture = nullptr;
|
||||
int Density = 4;
|
||||
int BurnTime = 8;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Screen wipes
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
Wiper *Wiper::Create(int type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case wipe_Burn:
|
||||
return new Wiper_Burn;
|
||||
|
||||
case wipe_Fade:
|
||||
return new Wiper_Crossfade;
|
||||
|
||||
case wipe_Melt:
|
||||
return new Wiper_Melt;
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
Wiper::~Wiper()
|
||||
{
|
||||
if (startScreen != nullptr) delete startScreen;
|
||||
if (endScreen != nullptr) delete endScreen;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Crossfade :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool Wiper_Crossfade::Run(int ticks)
|
||||
{
|
||||
Clock += ticks;
|
||||
screen->DrawTexture(startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
|
||||
screen->DrawTexture(endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, DTA_Alpha, clamp(Clock / 32.f, 0.f, 1.f), TAG_DONE);
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Melt Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
Wiper_Melt::Wiper_Melt()
|
||||
{
|
||||
int i, r;
|
||||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < WIDTH; ++i)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Melt :: Run
|
||||
//
|
||||
// Melts the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool Wiper_Melt::Run(int ticks)
|
||||
{
|
||||
bool done;
|
||||
screen->DrawTexture(endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
|
||||
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
done = true;
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < HEIGHT)
|
||||
{
|
||||
int dy = (y[i] < 16) ? y[i] + 1 : 8;
|
||||
y[i] = MIN(y[i] + dy, HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{
|
||||
struct {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} dpt;
|
||||
struct {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
} rect;
|
||||
|
||||
// Only draw for the final tick.
|
||||
// No need for optimization. Wipes won't ever be drawn with anything else.
|
||||
|
||||
int w = startScreen->GetWidth();
|
||||
int h = startScreen->GetHeight();
|
||||
dpt.x = i * w / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * h / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * w / WIDTH;
|
||||
rect.bottom = h - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
screen->DrawTexture(startScreen, 0, dpt.y, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_ClipLeft, rect.left, DTA_ClipRight, rect.right, DTA_Masked, false, TAG_DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Wiper_Burn::SetTextures(FTexture *startscreen, FTexture *endscreen)
|
||||
{
|
||||
startScreen = startscreen;
|
||||
endScreen = endscreen;
|
||||
BurnTexture = new FBurnTexture(WIDTH, HEIGHT);
|
||||
auto mat = FMaterial::ValidateTexture(startscreen, false);
|
||||
mat->AddTextureLayer(BurnTexture);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
Wiper_Burn::~Wiper_Burn()
|
||||
{
|
||||
if (BurnTexture != nullptr) delete BurnTexture;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn :: Run
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool Wiper_Burn::Run(int ticks)
|
||||
{
|
||||
bool done;
|
||||
|
||||
|
||||
BurnTime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
|
||||
done = (Density < 0);
|
||||
}
|
||||
|
||||
auto mat = FMaterial::ValidateTexture(BurnTexture, false);
|
||||
mat->Clean(true);
|
||||
const uint8_t *src = BurnArray;
|
||||
uint32_t *dest = (uint32_t *)BurnTexture->GetBuffer();
|
||||
for (int y = HEIGHT; y != 0; --y)
|
||||
{
|
||||
for (int x = WIDTH; x != 0; --x)
|
||||
{
|
||||
uint8_t s = clamp<int>((*src++)*2, 0, 255);
|
||||
*dest++ = MAKEARGB(s,255,255,255);
|
||||
}
|
||||
}
|
||||
|
||||
screen->DrawTexture(startScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Masked, false, TAG_DONE);
|
||||
screen->DrawTexture(endScreen, 0, 0, DTA_FlipY, screen->RenderTextureIsFlipped(), DTA_Burn, true, DTA_Masked, false, TAG_DONE);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
return done || (BurnTime > 40);
|
||||
}
|
||||
|
|
31
src/f_wipe.h
31
src/f_wipe.h
|
@ -26,19 +26,9 @@
|
|||
#ifndef __F_WIPE_H__
|
||||
#define __F_WIPE_H__
|
||||
|
||||
//
|
||||
// SCREEN WIPE PACKAGE
|
||||
//
|
||||
#include "stdint.h"
|
||||
|
||||
#if 0
|
||||
bool wipe_StartScreen (int type);
|
||||
void wipe_EndScreen (void);
|
||||
bool wipe_ScreenWipe (int ticks);
|
||||
void wipe_Cleanup ();
|
||||
|
||||
// The buffer must have an additional 5 rows not included in height
|
||||
// to use for a seeding area.
|
||||
#endif
|
||||
class FTexture;
|
||||
int wipe_CalcBurn(uint8_t *buffer, int width, int height, int density);
|
||||
|
||||
enum
|
||||
|
@ -50,4 +40,21 @@ enum
|
|||
wipe_NUMWIPES
|
||||
};
|
||||
|
||||
class Wiper
|
||||
{
|
||||
protected:
|
||||
FTexture *startScreen = nullptr, *endScreen = nullptr;
|
||||
public:
|
||||
virtual ~Wiper();
|
||||
virtual bool Run(int ticks) = 0;
|
||||
virtual void SetTextures(FTexture *startscreen, FTexture *endscreen)
|
||||
{
|
||||
startScreen = startscreen;
|
||||
endScreen = endscreen;
|
||||
}
|
||||
|
||||
static Wiper *Create(int type);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
176
src/gl/data/gl_viewpointbuffer.cpp
Normal file
176
src/gl/data/gl_viewpointbuffer.cpp
Normal file
|
@ -0,0 +1,176 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2018 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_viewpointbuffer.cpp
|
||||
** Buffer data maintenance for per viewpoint uniform data
|
||||
**
|
||||
**/
|
||||
|
||||
#include "gl_load/gl_system.h"
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "hwrenderer/data/shaderuniforms.h"
|
||||
#include "hwrenderer/scene/hw_viewpointuniforms.h"
|
||||
#include "gl_viewpointbuffer.h"
|
||||
|
||||
static const int INITIAL_BUFFER_SIZE = 100; // 100 viewpoints per frame should nearly always be enough
|
||||
|
||||
GLViewpointBuffer::GLViewpointBuffer()
|
||||
{
|
||||
mBufferSize = INITIAL_BUFFER_SIZE;
|
||||
mBlockAlign = ((sizeof(HWViewpointUniforms) / gl.uniformblockalignment) + 1) * gl.uniformblockalignment;
|
||||
mByteSize = mBufferSize * mBlockAlign;
|
||||
Allocate();
|
||||
Clear();
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
mClipPlaneInfo.Push(0);
|
||||
}
|
||||
|
||||
GLViewpointBuffer::~GLViewpointBuffer()
|
||||
{
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, 0);
|
||||
glDeleteBuffers(1, &mBufferId);
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Allocate()
|
||||
{
|
||||
glGenBuffers(1, &mBufferId);
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, VIEWPOINT_BINDINGPOINT, mBufferId);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, mBufferId); // Note: Some older AMD drivers don't do that in glBindBufferBase, as they should.
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
glBufferStorage(GL_UNIFORM_BUFFER, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
mBufferPointer = glMapBufferRange(GL_UNIFORM_BUFFER, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(GL_UNIFORM_BUFFER, mByteSize, NULL, GL_STATIC_DRAW);
|
||||
mBufferPointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::CheckSize()
|
||||
{
|
||||
if (mUploadIndex >= mBufferSize)
|
||||
{
|
||||
// reallocate the buffer with twice the size
|
||||
unsigned int oldbuffer = mBufferId;
|
||||
|
||||
mBufferSize *= 2;
|
||||
mByteSize *= 2;
|
||||
|
||||
// first unmap the old buffer
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, mBufferId);
|
||||
glUnmapBuffer(GL_UNIFORM_BUFFER);
|
||||
|
||||
Allocate();
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer);
|
||||
|
||||
// copy contents and delete the old buffer.
|
||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_UNIFORM_BUFFER, 0, 0, mByteSize / 2); // old size is half of the current one.
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||
glDeleteBuffers(1, &oldbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Map()
|
||||
{
|
||||
if (!(gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, mBufferId);
|
||||
mBufferPointer = (float*)glMapBufferRange(GL_UNIFORM_BUFFER, 0, mByteSize, GL_MAP_WRITE_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Unmap()
|
||||
{
|
||||
if (!(gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, mBufferId);
|
||||
glUnmapBuffer(GL_UNIFORM_BUFFER);
|
||||
mBufferPointer = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::Bind(unsigned int index)
|
||||
{
|
||||
if (index != mLastMappedIndex)
|
||||
{
|
||||
mLastMappedIndex = index;
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, VIEWPOINT_BINDINGPOINT, mBufferId, index * mBlockAlign, mBlockAlign);
|
||||
|
||||
// Update the viewpoint-related clip plane setting.
|
||||
if (!(gl.flags & RFL_NO_CLIP_PLANES))
|
||||
{
|
||||
if (mClipPlaneInfo[index])
|
||||
{
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Set2D(int width, int height)
|
||||
{
|
||||
if (width != m2DWidth || height != m2DHeight)
|
||||
{
|
||||
HWViewpointUniforms matrices;
|
||||
matrices.SetDefaults();
|
||||
matrices.mProjectionMatrix.ortho(0, width, height, 0, -1.0f, 1.0f);
|
||||
matrices.mFogEnabled = 3;
|
||||
matrices.CalcDependencies();
|
||||
Map();
|
||||
memcpy(mBufferPointer, &matrices, sizeof(matrices));
|
||||
Unmap();
|
||||
m2DWidth = width;
|
||||
m2DHeight = height;
|
||||
mLastMappedIndex = -1;
|
||||
}
|
||||
Bind(0);
|
||||
}
|
||||
|
||||
int GLViewpointBuffer::SetViewpoint(HWViewpointUniforms *vp)
|
||||
{
|
||||
CheckSize();
|
||||
Map();
|
||||
memcpy(((char*)mBufferPointer) + mUploadIndex * mBlockAlign, vp, sizeof(*vp));
|
||||
Unmap();
|
||||
|
||||
mClipPlaneInfo.Push(vp->mClipHeightDirection != 0.f || vp->mClipLine.X > -10000000.0f);
|
||||
return Bind(mUploadIndex++);
|
||||
}
|
||||
|
||||
void GLViewpointBuffer::Clear()
|
||||
{
|
||||
// Index 0 is reserved for the 2D projection.
|
||||
mUploadIndex = 1;
|
||||
mClipPlaneInfo.Resize(1);
|
||||
}
|
||||
|
36
src/gl/data/gl_viewpointbuffer.h
Normal file
36
src/gl/data/gl_viewpointbuffer.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "tarray.h"
|
||||
|
||||
struct HWViewpointUniforms;
|
||||
|
||||
class GLViewpointBuffer
|
||||
{
|
||||
unsigned int mBufferId;
|
||||
unsigned int mBufferSize;
|
||||
unsigned int mBlockAlign;
|
||||
unsigned int mUploadIndex;
|
||||
unsigned int mLastMappedIndex;
|
||||
unsigned int mByteSize;
|
||||
void * mBufferPointer;
|
||||
TArray<bool> mClipPlaneInfo;
|
||||
|
||||
unsigned int m2DWidth = ~0u, m2DHeight = ~0u;
|
||||
|
||||
unsigned int mBlockSize;
|
||||
|
||||
void CheckSize();
|
||||
void Allocate();
|
||||
|
||||
public:
|
||||
|
||||
GLViewpointBuffer();
|
||||
~GLViewpointBuffer();
|
||||
void Clear();
|
||||
void Map();
|
||||
void Unmap();
|
||||
int Bind(unsigned int index);
|
||||
void Set2D(int width, int height);
|
||||
int SetViewpoint(HWViewpointUniforms *vp);
|
||||
unsigned int GetBlockSize() const { return mBlockSize; }
|
||||
};
|
||||
|
|
@ -103,10 +103,10 @@ void gl_SetColor(int sectorlightlevel, int rellight, bool fullbright, const FCol
|
|||
}
|
||||
else
|
||||
{
|
||||
int hwlightlevel = hw_CalcLightLevel(sectorlightlevel, rellight, weapon);
|
||||
int hwlightlevel = hw_CalcLightLevel(sectorlightlevel, rellight, weapon, cm.BlendFactor);
|
||||
PalEntry pe = hw_CalcLightColor(hwlightlevel, cm.LightColor, cm.BlendFactor);
|
||||
gl_RenderState.SetColorAlpha(pe, alpha, cm.Desaturation);
|
||||
gl_RenderState.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight));
|
||||
gl_RenderState.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight), cm.BlendFactor);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
|||
else if (cmap != NULL && !fullbright)
|
||||
{
|
||||
fogcolor = cmap->FadeColor;
|
||||
fogdensity = hw_GetFogDensity(lightlevel, fogcolor, cmap->FogDensity);
|
||||
fogdensity = hw_GetFogDensity(lightlevel, fogcolor, cmap->FogDensity, cmap->BlendFactor);
|
||||
fogcolor.a=0;
|
||||
}
|
||||
else
|
||||
|
@ -184,9 +184,9 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
|||
}
|
||||
else
|
||||
{
|
||||
if (level.lightmode == 2 && fogcolor == 0)
|
||||
if ((level.lightmode == 2 || (level.lightmode == 8 && cmap->BlendFactor > 0)) && fogcolor == 0)
|
||||
{
|
||||
float light = hw_CalcLightLevel(lightlevel, rellight, false);
|
||||
float light = hw_CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor);
|
||||
gl_SetShaderLight(light, lightlevel);
|
||||
}
|
||||
else
|
||||
|
@ -205,7 +205,7 @@ void gl_SetFog(int lightlevel, int rellight, bool fullbright, const FColormap *c
|
|||
gl_RenderState.SetFog(fogcolor, fogdensity);
|
||||
|
||||
// Korshun: fullbright fog like in software renderer.
|
||||
if (level.lightmode == 8 && level.brightfog && fogdensity != 0 && fogcolor != 0)
|
||||
if (level.lightmode == 8 && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0)
|
||||
{
|
||||
gl_RenderState.SetSoftLightLevel(255);
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "gl/shaders/gl_postprocessshaderinstance.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/data/gl_viewpointbuffer.h"
|
||||
#include "r_videoscale.h"
|
||||
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
|
@ -79,21 +80,6 @@ extern bool NoInterpolateView;
|
|||
FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
framebuffer = fb;
|
||||
mMirrorCount = 0;
|
||||
mPlaneMirrorCount = 0;
|
||||
mVBO = nullptr;
|
||||
mSkyVBO = nullptr;
|
||||
mShaderManager = nullptr;
|
||||
mLights = nullptr;
|
||||
mBuffers = nullptr;
|
||||
mScreenBuffers = nullptr;
|
||||
mSaveBuffers = nullptr;
|
||||
mPresentShader = nullptr;
|
||||
mPresent3dCheckerShader = nullptr;
|
||||
mPresent3dColumnShader = nullptr;
|
||||
mPresent3dRowShader = nullptr;
|
||||
mShadowMapShader = nullptr;
|
||||
mCustomPostProcessShaders = nullptr;
|
||||
}
|
||||
|
||||
void FGLRenderer::Initialize(int width, int height)
|
||||
|
@ -118,6 +104,7 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
mVBO = new FFlatVertexBuffer(width, height);
|
||||
mSkyVBO = new FSkyVertexBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
mViewpoints = new GLViewpointBuffer;
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
mFBID = 0;
|
||||
mOldFBID = 0;
|
||||
|
@ -132,11 +119,12 @@ FGLRenderer::~FGLRenderer()
|
|||
FlushModels();
|
||||
AActor::DeleteAllAttachedLights();
|
||||
FMaterial::FlushAll();
|
||||
if (mShaderManager != NULL) delete mShaderManager;
|
||||
if (mSamplerManager != NULL) delete mSamplerManager;
|
||||
if (mVBO != NULL) delete mVBO;
|
||||
if (mSkyVBO != NULL) delete mSkyVBO;
|
||||
if (mLights != NULL) delete mLights;
|
||||
if (mShaderManager != nullptr) delete mShaderManager;
|
||||
if (mSamplerManager != nullptr) delete mSamplerManager;
|
||||
if (mVBO != nullptr) delete mVBO;
|
||||
if (mSkyVBO != nullptr) delete mSkyVBO;
|
||||
if (mLights != nullptr) delete mLights;
|
||||
if (mViewpoints != nullptr) delete mViewpoints;
|
||||
if (mFBID != 0) glDeleteFramebuffers(1, &mFBID);
|
||||
if (mVAOID != 0)
|
||||
{
|
||||
|
@ -147,6 +135,7 @@ FGLRenderer::~FGLRenderer()
|
|||
|
||||
if (swdrawer) delete swdrawer;
|
||||
if (mBuffers) delete mBuffers;
|
||||
if (mSaveBuffers) delete mSaveBuffers;
|
||||
if (mPresentShader) delete mPresentShader;
|
||||
if (mPresent3dCheckerShader) delete mPresent3dCheckerShader;
|
||||
if (mPresent3dColumnShader) delete mPresent3dColumnShader;
|
||||
|
@ -233,6 +222,7 @@ sector_t *FGLRenderer::RenderView(player_t* player)
|
|||
P_FindParticleSubsectors();
|
||||
|
||||
mLights->Clear();
|
||||
mViewpoints->Clear();
|
||||
|
||||
// NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below.
|
||||
bool saved_niv = NoInterpolateView;
|
||||
|
@ -334,7 +324,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, i
|
|||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
mVBO->Reset();
|
||||
mLights->Clear();
|
||||
|
||||
mViewpoints->Clear();
|
||||
|
||||
// This shouldn't overwrite the global viewpoint even for a short time.
|
||||
FRenderViewpoint savevp;
|
||||
sector_t *viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false);
|
||||
|
@ -427,12 +418,7 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
|||
mBuffers->BindCurrentFB();
|
||||
const auto &mScreenViewport = screen->mScreenViewport;
|
||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
||||
|
||||
HWViewpointUniforms matrices;
|
||||
matrices.SetDefaults();
|
||||
matrices.mProjectionMatrix.ortho(0, screen->GetWidth(), screen->GetHeight(), 0, -1.0f, 1.0f);
|
||||
matrices.CalcDependencies();
|
||||
GLRenderer->mShaderManager->ApplyMatrices(&matrices, NORMAL_PASS);
|
||||
GLRenderer->mViewpoints->Set2D(screen->GetWidth(), screen->GetHeight());
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
|
@ -530,6 +516,10 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
|||
gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f);
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
}
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Burn)
|
||||
{
|
||||
gl_RenderState.SetEffect(EFF_BURN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -555,6 +545,8 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
|||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.SetObjectColor2(0);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ class FHardwareTexture;
|
|||
class FShadowMapShader;
|
||||
class FCustomPostProcessShaders;
|
||||
class SWSceneDrawer;
|
||||
class GLViewpointBuffer;
|
||||
struct FRenderViewpoint;
|
||||
#define NOQUEUE nullptr // just some token to be used as a placeholder
|
||||
|
||||
|
@ -51,33 +52,34 @@ class FGLRenderer
|
|||
public:
|
||||
|
||||
OpenGLFrameBuffer *framebuffer;
|
||||
int mMirrorCount;
|
||||
int mPlaneMirrorCount;
|
||||
FShaderManager *mShaderManager;
|
||||
FSamplerManager *mSamplerManager;
|
||||
int mMirrorCount = 0;
|
||||
int mPlaneMirrorCount = 0;
|
||||
FShaderManager *mShaderManager = nullptr;
|
||||
FSamplerManager *mSamplerManager = nullptr;
|
||||
unsigned int mFBID;
|
||||
unsigned int mVAOID;
|
||||
unsigned int PortalQueryObject;
|
||||
|
||||
int mOldFBID;
|
||||
|
||||
FGLRenderBuffers *mBuffers;
|
||||
FGLRenderBuffers *mScreenBuffers;
|
||||
FGLRenderBuffers *mSaveBuffers;
|
||||
FPresentShader *mPresentShader;
|
||||
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
||||
FPresent3DColumnShader *mPresent3dColumnShader;
|
||||
FPresent3DRowShader *mPresent3dRowShader;
|
||||
FShadowMapShader *mShadowMapShader;
|
||||
FCustomPostProcessShaders *mCustomPostProcessShaders;
|
||||
FGLRenderBuffers *mBuffers = nullptr;
|
||||
FGLRenderBuffers *mScreenBuffers = nullptr;
|
||||
FGLRenderBuffers *mSaveBuffers = nullptr;
|
||||
FPresentShader *mPresentShader = nullptr;
|
||||
FPresent3DCheckerShader *mPresent3dCheckerShader = nullptr;
|
||||
FPresent3DColumnShader *mPresent3dColumnShader = nullptr;
|
||||
FPresent3DRowShader *mPresent3dRowShader = nullptr;
|
||||
FShadowMapShader *mShadowMapShader = nullptr;
|
||||
FCustomPostProcessShaders *mCustomPostProcessShaders = nullptr;
|
||||
|
||||
FShadowMap mShadowMap;
|
||||
|
||||
//FRotator mAngles;
|
||||
|
||||
FFlatVertexBuffer *mVBO;
|
||||
FSkyVertexBuffer *mSkyVBO;
|
||||
FLightBuffer *mLights;
|
||||
FFlatVertexBuffer *mVBO = nullptr;
|
||||
FSkyVertexBuffer *mSkyVBO = nullptr;
|
||||
FLightBuffer *mLights = nullptr;
|
||||
GLViewpointBuffer *mViewpoints = nullptr;
|
||||
SWSceneDrawer *swdrawer = nullptr;
|
||||
|
||||
FPortalSceneState mPortalState;
|
||||
|
|
|
@ -119,7 +119,7 @@ bool FRenderState::ApplyShader()
|
|||
static uint64_t firstFrame = 0;
|
||||
// if firstFrame is not yet initialized, initialize it to current time
|
||||
// if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision
|
||||
if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1<<24) || level.ShaderStartTime >= firstFrame)
|
||||
if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1 << 24) || level.ShaderStartTime >= firstFrame)
|
||||
firstFrame = screen->FrameTime;
|
||||
|
||||
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
|
@ -133,31 +133,15 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->Bind();
|
||||
}
|
||||
|
||||
int fogset = 0;
|
||||
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if (mFogEnabled == 2)
|
||||
{
|
||||
fogset = -3; // 2D rendering with 'foggy' overlay.
|
||||
}
|
||||
else if ((mFogColor & 0xffffff) == 0)
|
||||
{
|
||||
fogset = gl_fogmode;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogset = -gl_fogmode;
|
||||
}
|
||||
}
|
||||
|
||||
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
|
||||
glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec);
|
||||
|
||||
activeShader->muDesaturation.Set(mDesaturation / 255.f);
|
||||
activeShader->muFogEnabled.Set(fogset);
|
||||
activeShader->muTextureMode.Set(mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
|
||||
float fds = mLightParms[2];
|
||||
if (!mFogEnabled) mLightParms[2] = 0;
|
||||
activeShader->muLightParms.Set(mLightParms);
|
||||
mLightParms[2] = fds;
|
||||
activeShader->muFogColor.Set(mFogColor);
|
||||
activeShader->muObjectColor.Set(mObjectColor);
|
||||
activeShader->muObjectColor2.Set(mObjectColor2);
|
||||
|
|
|
@ -290,9 +290,9 @@ public:
|
|||
mGlowBottom.Set(b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
void SetSoftLightLevel(int llevel)
|
||||
void SetSoftLightLevel(int llevel, int blendfactor = 0)
|
||||
{
|
||||
if (level.lightmode == 8) mLightParms[3] = llevel / 255.f;
|
||||
if (level.lightmode == 8 && blendfactor == 0) mLightParms[3] = llevel / 255.f;
|
||||
else mLightParms[3] = -1.f;
|
||||
}
|
||||
|
||||
|
|
|
@ -213,6 +213,7 @@ void FDrawInfo::StartScene()
|
|||
decals[0].Clear();
|
||||
decals[1].Clear();
|
||||
hudsprites.Clear();
|
||||
vpIndex = 0;
|
||||
|
||||
// Fullbright information needs to be propagated from the main view.
|
||||
if (outer != nullptr) FullbrightFlags = outer->FullbrightFlags;
|
||||
|
|
|
@ -38,6 +38,7 @@ struct FDrawInfo : public HWDrawInfo
|
|||
HWDrawList drawlists[GLDL_TYPES];
|
||||
TArray<HUDSprite> hudsprites; // These may just be stored by value.
|
||||
TArray<GLDecal *> decals[2]; // the second slot is for mirrors which get rendered in a separate pass.
|
||||
int vpIndex;
|
||||
|
||||
void ApplyVPUniforms() override;
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "hwrenderer/scene/hw_clipper.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/data/gl_viewpointbuffer.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -66,9 +67,7 @@ void GLPortal::ClearScreen(HWDrawInfo *di)
|
|||
{
|
||||
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
||||
|
||||
di->VPUniforms.mViewMatrix.loadIdentity();
|
||||
di->VPUniforms.mProjectionMatrix.ortho(0, SCREENWIDTH, SCREENHEIGHT, 0, -1.0f, 1.0f);
|
||||
di->ApplyVPUniforms();
|
||||
GLRenderer->mViewpoints->Set2D(SCREENWIDTH, SCREENHEIGHT);
|
||||
gl_RenderState.SetColor(0, 0, 0);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
|
@ -236,7 +235,7 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil)
|
|||
Clocker c(PortalAll);
|
||||
|
||||
di = static_cast<FDrawInfo*>(di)->EndDrawInfo();
|
||||
di->ApplyVPUniforms();
|
||||
GLRenderer->mViewpoints->Bind(static_cast<FDrawInfo*>(di)->vpIndex);
|
||||
if (usestencil)
|
||||
{
|
||||
auto &vp = di->Viewpoint;
|
||||
|
@ -295,7 +294,6 @@ void GLPortal::End(HWDrawInfo *di, bool usestencil)
|
|||
|
||||
// Restore the old view
|
||||
if (vp.camera != nullptr) vp.camera->renderflags = (vp.camera->renderflags & ~RF_MAYBEINVISIBLE) | savedvisibility;
|
||||
di->SetupView(vp.Pos.X, vp.Pos.Y, vp.Pos.Z, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1));
|
||||
|
||||
// This draws a valid z-buffer into the stencil's contents to ensure it
|
||||
// doesn't get overwritten by the level's geometry.
|
||||
|
@ -345,10 +343,12 @@ GLHorizonPortal::GLHorizonPortal(FPortalSceneState *s, GLHorizonInfo * pt, FRend
|
|||
// Draw to some far away boundary
|
||||
// This is not drawn as larger strips because it causes visual glitches.
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (float x = -32768 + vx; x<32768 + vx; x += 4096)
|
||||
for (int xx = -32768; xx < 32768; xx += 4096)
|
||||
{
|
||||
for (float y = -32768 + vy; y<32768 + vy; y += 4096)
|
||||
float x = xx + vx;
|
||||
for (int yy = -32768; yy < 32768; yy += 4096)
|
||||
{
|
||||
float y = yy + vy;
|
||||
ptr->Set(x, z, y, x / 64, -y / 64);
|
||||
ptr++;
|
||||
ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64);
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/data/gl_viewpointbuffer.h"
|
||||
#include "hwrenderer/scene/hw_clipper.h"
|
||||
#include "hwrenderer/scene/hw_portal.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
@ -76,19 +77,7 @@ EXTERN_CVAR (Bool, r_drawvoxels)
|
|||
void FDrawInfo::ApplyVPUniforms()
|
||||
{
|
||||
VPUniforms.CalcDependencies();
|
||||
GLRenderer->mShaderManager->ApplyMatrices(&VPUniforms, gl_RenderState.GetPassType());
|
||||
|
||||
if (!(gl.flags & RFL_NO_CLIP_PLANES))
|
||||
{
|
||||
if (VPUniforms.mClipHeightDirection != 0.f || VPUniforms.mClipLine.X > -10000000.0f)
|
||||
{
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
}
|
||||
vpIndex = GLRenderer->mViewpoints->SetViewpoint(&VPUniforms);
|
||||
}
|
||||
|
||||
|
||||
|
@ -337,7 +326,7 @@ void FDrawInfo::DrawScene(int drawmode)
|
|||
GLRenderer->mBuffers->BindSceneFB(true);
|
||||
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
||||
gl_RenderState.Apply();
|
||||
ApplyVPUniforms();
|
||||
GLRenderer->mViewpoints->Bind(vpIndex);
|
||||
}
|
||||
|
||||
// Handle all portals after rendering the opaque objects but before
|
||||
|
@ -383,9 +372,11 @@ void FDrawInfo::DrawEndScene2D(sector_t * viewsector)
|
|||
const bool renderHUDModel = IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player);
|
||||
auto vrmode = VRMode::GetVRMode(true);
|
||||
|
||||
VPUniforms.mViewMatrix.loadIdentity();
|
||||
VPUniforms.mProjectionMatrix = vrmode->GetHUDSpriteProjection();
|
||||
ApplyVPUniforms();
|
||||
HWViewpointUniforms vp = VPUniforms;
|
||||
vp.mViewMatrix.loadIdentity();
|
||||
vp.mProjectionMatrix = vrmode->GetHUDSpriteProjection();
|
||||
vp.mFogEnabled = 0;
|
||||
GLRenderer->mViewpoints->SetViewpoint(&vp);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
|
||||
|
@ -493,6 +484,7 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
|
|||
|
||||
if (mainview)
|
||||
{
|
||||
PostProcess.Clock();
|
||||
if (toscreen) di->EndDrawScene(mainvp.sector); // do not call this for camera textures.
|
||||
|
||||
if (gl_RenderState.GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers
|
||||
|
@ -506,6 +498,7 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
|
|||
FGLDebug::PopGroup(); // MainView
|
||||
|
||||
PostProcessScene(cm, [&]() { di->DrawEndScene2D(mainvp.sector); });
|
||||
PostProcess.Unclock();
|
||||
}
|
||||
di->EndDrawInfo();
|
||||
if (vrmode->mEyeCount > 1)
|
||||
|
|
|
@ -269,7 +269,6 @@ void GLSkyPortal::DrawContents(HWDrawInfo *di)
|
|||
}
|
||||
}
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
di->ApplyVPUniforms();
|
||||
::level.lightmode = oldlightmode;
|
||||
gl_RenderState.SetDepthClamp(oldClamp);
|
||||
}
|
||||
|
|
|
@ -113,7 +113,7 @@ void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
|
|||
if (!sprite->Colormap.FadeColor.isBlack())
|
||||
{
|
||||
float dist=Dist2(vp.Pos.X, vp.Pos.Y, sprite->x, sprite->y);
|
||||
int fogd = hw_GetFogDensity(sprite->lightlevel, sprite->Colormap.FadeColor, sprite->Colormap.FogDensity);
|
||||
int fogd = hw_GetFogDensity(sprite->lightlevel, sprite->Colormap.FadeColor, sprite->Colormap.FogDensity, sprite->Colormap.BlendFactor);
|
||||
|
||||
// this value was determined by trial and error and is scale dependent!
|
||||
float factor = 0.05f + exp(-fogd*dist / 62500.f);
|
||||
|
|
|
@ -49,18 +49,32 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
static char buffer[10000];
|
||||
FString error;
|
||||
|
||||
FString i_data;
|
||||
|
||||
// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here.
|
||||
i_data += "precision highp int;\n";
|
||||
i_data += "precision highp float;\n";
|
||||
FString i_data = R"(
|
||||
// these settings are actually pointless but there seem to be some old ATI drivers that fail to compile the shader without setting the precision here.
|
||||
precision highp int;
|
||||
precision highp float;
|
||||
|
||||
i_data += "uniform vec4 uCameraPos;\n";
|
||||
// This must match the HWViewpointUniforms struct
|
||||
layout(std140) uniform ViewpointUBO {
|
||||
mat4 ProjectionMatrix;
|
||||
mat4 ViewMatrix;
|
||||
mat4 NormalViewMatrix;
|
||||
|
||||
vec4 uCameraPos;
|
||||
vec4 uClipLine;
|
||||
|
||||
float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
|
||||
int uPalLightLevels;
|
||||
int uViewHeight; // Software fuzz scaling
|
||||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uFogEnabled;
|
||||
|
||||
};
|
||||
)";
|
||||
|
||||
i_data += "uniform int uTextureMode;\n";
|
||||
i_data += "uniform float uClipHeight;\n";
|
||||
i_data += "uniform float uClipHeightDirection;\n";
|
||||
i_data += "uniform vec2 uClipSplit;\n";
|
||||
i_data += "uniform vec4 uClipLine;\n";
|
||||
i_data += "uniform float uAlphaThreshold;\n";
|
||||
|
||||
// colors
|
||||
|
@ -86,16 +100,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
i_data += "#define uFogDensity uLightAttr.b\n";
|
||||
i_data += "#define uLightFactor uLightAttr.g\n";
|
||||
i_data += "#define uLightDist uLightAttr.r\n";
|
||||
i_data += "uniform int uFogEnabled;\n";
|
||||
i_data += "uniform int uPalLightLevels;\n";
|
||||
i_data += "uniform float uGlobVis;\n"; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0
|
||||
|
||||
// dynamic lights
|
||||
i_data += "uniform int uLightIndex;\n";
|
||||
|
||||
// Software fuzz scaling
|
||||
i_data += "uniform int uViewHeight;\n";
|
||||
|
||||
// Blinn glossiness and specular level
|
||||
i_data += "uniform vec2 uSpecularMaterial;\n";
|
||||
|
||||
|
@ -107,10 +115,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
i_data += "#endif\n";
|
||||
|
||||
// matrices
|
||||
i_data += "uniform mat4 ProjectionMatrix;\n";
|
||||
i_data += "uniform mat4 ViewMatrix;\n";
|
||||
i_data += "uniform mat4 ModelMatrix;\n";
|
||||
i_data += "uniform mat4 NormalViewMatrix;\n";
|
||||
i_data += "uniform mat4 NormalModelMatrix;\n";
|
||||
i_data += "uniform mat4 TextureMatrix;\n";
|
||||
|
||||
|
@ -326,7 +331,6 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
|
||||
|
||||
muDesaturation.Init(hShader, "uDesaturationFactor");
|
||||
muFogEnabled.Init(hShader, "uFogEnabled");
|
||||
muTextureMode.Init(hShader, "uTextureMode");
|
||||
muLightParms.Init(hShader, "uLightAttr");
|
||||
muClipSplit.Init(hShader, "uClipSplit");
|
||||
|
@ -348,28 +352,20 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
|
||||
lights_index = glGetUniformLocation(hShader, "lights");
|
||||
fakevb_index = glGetUniformLocation(hShader, "fakeVB");
|
||||
projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix");
|
||||
viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix");
|
||||
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
|
||||
texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix");
|
||||
vertexmatrix_index = glGetUniformLocation(hShader, "uQuadVertices");
|
||||
texcoordmatrix_index = glGetUniformLocation(hShader, "uQuadTexCoords");
|
||||
normalviewmatrix_index = glGetUniformLocation(hShader, "NormalViewMatrix");
|
||||
normalmodelmatrix_index = glGetUniformLocation(hShader, "NormalModelMatrix");
|
||||
quadmode_index = glGetUniformLocation(hShader, "uQuadMode");
|
||||
viewheight_index = glGetUniformLocation(hShader, "uViewHeight");
|
||||
camerapos_index = glGetUniformLocation(hShader, "uCameraPos");
|
||||
pallightlevels_index = glGetUniformLocation(hShader, "uPalLightLevels");
|
||||
globvis_index = glGetUniformLocation(hShader, "uGlobVis");
|
||||
clipheight_index = glGetUniformLocation(hShader, "uClipHeight");
|
||||
clipheightdirection_index = glGetUniformLocation(hShader, "uClipHeightDirection");
|
||||
clipline_index = glGetUniformLocation(hShader, "uClipLine");
|
||||
|
||||
if (lightbuffertype == GL_UNIFORM_BUFFER)
|
||||
{
|
||||
int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO");
|
||||
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT);
|
||||
}
|
||||
int tempindex = glGetUniformBlockIndex(hShader, "ViewpointUBO");
|
||||
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, VIEWPOINT_BINDINGPOINT);
|
||||
|
||||
glUseProgram(hShader);
|
||||
if (quadmode_index > 0) glUniform1i(quadmode_index, 0);
|
||||
|
@ -448,27 +444,6 @@ FShader *FShaderCollection::Compile (const char *ShaderName, const char *ShaderP
|
|||
return shader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShader::ApplyMatrices(HWViewpointUniforms *u)
|
||||
{
|
||||
Bind();
|
||||
glUniformMatrix4fv(projectionmatrix_index, 1, false, u->mProjectionMatrix.get());
|
||||
glUniformMatrix4fv(viewmatrix_index, 1, false, u->mViewMatrix.get());
|
||||
glUniformMatrix4fv(normalviewmatrix_index, 1, false, u->mNormalViewMatrix.get());
|
||||
|
||||
glUniform4fv(camerapos_index, 1, &u->mCameraPos[0]);
|
||||
glUniform1i(viewheight_index, u->mViewHeight);
|
||||
glUniform1i(pallightlevels_index, u->mPalLightLevels);
|
||||
glUniform1f(globvis_index, u->mGlobVis);
|
||||
glUniform1f(clipheight_index, u->mClipHeight);
|
||||
glUniform1f(clipheightdirection_index, u->mClipHeightDirection);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -566,15 +541,6 @@ FShader *FShaderManager::Get(unsigned int eff, bool alphateston, EPassType passT
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void FShaderManager::ApplyMatrices(HWViewpointUniforms *u, EPassType passType)
|
||||
{
|
||||
if (passType < mPassShaders.Size())
|
||||
mPassShaders[passType]->ApplyMatrices(u);
|
||||
|
||||
if (mActiveShader)
|
||||
mActiveShader->Bind();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -706,35 +672,6 @@ FShader *FShaderCollection::BindEffect(int effect)
|
|||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
EXTERN_CVAR(Int, gl_fuzztype)
|
||||
|
||||
void FShaderCollection::ApplyMatrices(HWViewpointUniforms *u)
|
||||
{
|
||||
for (int i = 0; i < SHADER_NoTexture; i++)
|
||||
{
|
||||
mMaterialShaders[i]->ApplyMatrices(u);
|
||||
mMaterialShadersNAT[i]->ApplyMatrices(u);
|
||||
}
|
||||
mMaterialShaders[SHADER_NoTexture]->ApplyMatrices(u);
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
mMaterialShaders[SHADER_NoTexture + gl_fuzztype]->ApplyMatrices(u);
|
||||
}
|
||||
for (unsigned i = FIRST_USER_SHADER; i < mMaterialShaders.Size(); i++)
|
||||
{
|
||||
mMaterialShaders[i]->ApplyMatrices(u);
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i]->ApplyMatrices(u);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -242,7 +242,6 @@ class FShader
|
|||
FName mName;
|
||||
|
||||
FBufferedUniform1f muDesaturation;
|
||||
FBufferedUniform1i muFogEnabled;
|
||||
FBufferedUniform1i muTextureMode;
|
||||
FBufferedUniform4f muLightParms;
|
||||
FBufferedUniform2f muClipSplit;
|
||||
|
@ -267,16 +266,6 @@ class FShader
|
|||
int normalmodelmatrix_index;
|
||||
int texturematrix_index;
|
||||
|
||||
int projectionmatrix_index;
|
||||
int viewmatrix_index;
|
||||
int normalviewmatrix_index;
|
||||
int viewheight_index;
|
||||
int camerapos_index;
|
||||
int pallightlevels_index;
|
||||
int globvis_index;
|
||||
int clipheight_index;
|
||||
int clipheightdirection_index;
|
||||
int clipline_index;
|
||||
|
||||
public:
|
||||
int vertexmatrix_index;
|
||||
|
@ -308,9 +297,6 @@ public:
|
|||
|
||||
bool Bind();
|
||||
unsigned int GetHandle() const { return hShader; }
|
||||
|
||||
void ApplyMatrices(HWViewpointUniforms *u);
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
@ -329,7 +315,6 @@ public:
|
|||
|
||||
FShader *BindEffect(int effect, EPassType passType);
|
||||
FShader *Get(unsigned int eff, bool alphateston, EPassType passType);
|
||||
void ApplyMatrices(HWViewpointUniforms *u, EPassType passType);
|
||||
|
||||
private:
|
||||
FShader *mActiveShader = nullptr;
|
||||
|
@ -351,7 +336,6 @@ public:
|
|||
FShader *Compile(const char *ShaderName, const char *ShaderPath, const char *LightModePath, const char *shaderdefines, bool usediscard, EPassType passType);
|
||||
int Find(const char *mame);
|
||||
FShader *BindEffect(int effect);
|
||||
void ApplyMatrices(HWViewpointUniforms *u);
|
||||
|
||||
FShader *Get(unsigned int eff, bool alphateston)
|
||||
{
|
||||
|
|
|
@ -151,7 +151,6 @@ void OpenGLFrameBuffer::Update()
|
|||
twoD.Reset();
|
||||
Flush3D.Reset();
|
||||
|
||||
DrawRateStuff();
|
||||
Flush3D.Clock();
|
||||
GLRenderer->Flush();
|
||||
Flush3D.Unclock();
|
||||
|
@ -484,3 +483,71 @@ void OpenGLFrameBuffer::PostProcessScene(int fixedcm, const std::function<void()
|
|||
{
|
||||
GLRenderer->PostProcessScene(fixedcm, afterBloomDrawEndScene2D);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This is just a wrapper around the hardware texture being extracted below so that it can be passed to the 2D code.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FGLWipeTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
|
||||
FGLWipeTexture(int w, int h)
|
||||
{
|
||||
Width = w;
|
||||
Height = h;
|
||||
WidthBits = 4;
|
||||
UseType = ETextureType::SWCanvas;
|
||||
bNoCompress = true;
|
||||
SystemTexture[0] = screen->CreateHardwareTexture(this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
|
||||
FGLWipeTexture *tex = new FGLWipeTexture(viewport.width, viewport.height);
|
||||
tex->SystemTexture[0]->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->SystemTexture[0])->Bind(0, false, false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->Flush();
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
FGLWipeTexture *tex = new FGLWipeTexture(viewport.width, viewport.height);
|
||||
tex->SystemTexture[0]->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
|
||||
glFinish();
|
||||
static_cast<FHardwareTexture*>(tex->SystemTexture[0])->Bind(0, false, false);
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
~OpenGLFrameBuffer();
|
||||
|
||||
void InitializeState();
|
||||
void Update();
|
||||
void Update() override;
|
||||
|
||||
// Color correction
|
||||
void SetGamma();
|
||||
|
@ -49,10 +49,6 @@ public:
|
|||
// points to the last row in the buffer, which will be the first row output.
|
||||
virtual void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
|
||||
|
||||
bool WipeStartScreen(int type);
|
||||
void WipeEndScreen();
|
||||
bool WipeDo(int ticks);
|
||||
void WipeCleanup();
|
||||
void Swap();
|
||||
bool IsHWGammaActive() const { return HWGammaActive; }
|
||||
|
||||
|
@ -63,33 +59,11 @@ public:
|
|||
|
||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
|
||||
FTexture *WipeStartScreen() override;
|
||||
FTexture *WipeEndScreen() override;
|
||||
private:
|
||||
int camtexcount = 0;
|
||||
|
||||
class Wiper
|
||||
{
|
||||
|
||||
protected:
|
||||
FSimpleVertexBuffer *mVertexBuf;
|
||||
|
||||
void MakeVBO(OpenGLFrameBuffer *fb);
|
||||
|
||||
public:
|
||||
Wiper();
|
||||
virtual ~Wiper();
|
||||
virtual bool Run(int ticks, OpenGLFrameBuffer *fb) = 0;
|
||||
};
|
||||
|
||||
class Wiper_Melt; friend class Wiper_Melt;
|
||||
class Wiper_Burn; friend class Wiper_Burn;
|
||||
class Wiper_Crossfade; friend class Wiper_Crossfade;
|
||||
|
||||
Wiper *ScreenWipe;
|
||||
FHardwareTexture *wipestartscreen;
|
||||
FHardwareTexture *wipeendscreen;
|
||||
|
||||
|
||||
public:
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,536 +0,0 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2008-2016 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** Screen wipe stuff
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl_load/gl_system.h"
|
||||
#include "f_wipe.h"
|
||||
#include "m_random.h"
|
||||
#include "w_wad.h"
|
||||
#include "v_palette.h"
|
||||
#include "templates.h"
|
||||
|
||||
#include "gl_load/gl_interface.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Screen wipes
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class OpenGLFrameBuffer::Wiper_Crossfade : public OpenGLFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Crossfade();
|
||||
bool Run(int ticks, OpenGLFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
int Clock;
|
||||
};
|
||||
|
||||
class OpenGLFrameBuffer::Wiper_Melt : public OpenGLFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Melt();
|
||||
int MakeVBO(int ticks, OpenGLFrameBuffer *fb, bool &done);
|
||||
bool Run(int ticks, OpenGLFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
static const int WIDTH = 320, HEIGHT = 200;
|
||||
int y[WIDTH];
|
||||
};
|
||||
|
||||
class OpenGLFrameBuffer::Wiper_Burn : public OpenGLFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Burn();
|
||||
~Wiper_Burn();
|
||||
bool Run(int ticks, OpenGLFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
static const int WIDTH = 64, HEIGHT = 64;
|
||||
uint8_t BurnArray[WIDTH * (HEIGHT + 5)];
|
||||
FHardwareTexture *BurnTexture;
|
||||
int Density;
|
||||
int BurnTime;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case wipe_Burn:
|
||||
ScreenWipe = new Wiper_Burn;
|
||||
break;
|
||||
|
||||
case wipe_Fade:
|
||||
ScreenWipe = new Wiper_Crossfade;
|
||||
break;
|
||||
|
||||
case wipe_Melt:
|
||||
ScreenWipe = new Wiper_Melt;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
wipestartscreen = new FHardwareTexture(true);
|
||||
wipestartscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen");
|
||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
||||
GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE, -1);
|
||||
glFinish();
|
||||
wipestartscreen->Bind(0, false, false);
|
||||
|
||||
const auto copyPixels = [&viewport]()
|
||||
{
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
};
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
copyPixels();
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
GLRenderer->Flush();
|
||||
const auto &viewport = screen->mScreenViewport;
|
||||
wipeendscreen = new FHardwareTexture(true);
|
||||
wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
|
||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
||||
glFinish();
|
||||
wipeendscreen->Bind(0, false, false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeDo
|
||||
//
|
||||
// Perform the actual wipe animation. The number of tics since the last
|
||||
// time this function was called is passed in. Returns true when the wipe
|
||||
// is over. The first time this function has been called, the screen is
|
||||
// still locked from before and EndScene() still has not been called.
|
||||
// Successive times need to call BeginScene().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLFrameBuffer::WipeDo(int ticks)
|
||||
{
|
||||
bool done = true;
|
||||
// Sanity checks.
|
||||
if (wipestartscreen != nullptr && wipeendscreen != nullptr)
|
||||
{
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.EnableFog(false);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
|
||||
GLRenderer->mBuffers->BindCurrentFB();
|
||||
const auto &bounds = screen->mScreenViewport;
|
||||
glViewport(bounds.left, bounds.top, bounds.width, bounds.height);
|
||||
|
||||
done = ScreenWipe->Run(ticks, this);
|
||||
glDepthMask(true);
|
||||
}
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::WipeCleanup()
|
||||
{
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
ScreenWipe = NULL;
|
||||
}
|
||||
if (wipestartscreen != NULL)
|
||||
{
|
||||
delete wipestartscreen;
|
||||
wipestartscreen = NULL;
|
||||
}
|
||||
if (wipeendscreen != NULL)
|
||||
{
|
||||
delete wipeendscreen;
|
||||
wipeendscreen = NULL;
|
||||
}
|
||||
gl_RenderState.ClearLastMaterial();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
OpenGLFrameBuffer::Wiper::Wiper()
|
||||
{
|
||||
mVertexBuf = new FSimpleVertexBuffer;
|
||||
}
|
||||
|
||||
OpenGLFrameBuffer::Wiper::~Wiper()
|
||||
{
|
||||
delete mVertexBuf;
|
||||
}
|
||||
|
||||
void OpenGLFrameBuffer::Wiper::MakeVBO(OpenGLFrameBuffer *fb)
|
||||
{
|
||||
FSimpleVertex make[4];
|
||||
FSimpleVertex *ptr = make;
|
||||
|
||||
float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
|
||||
ptr->Set(0, 0, 0, 0, vb);
|
||||
ptr++;
|
||||
ptr->Set(0, fb->GetHeight(), 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(fb->GetWidth(), 0, 0, ur, vb);
|
||||
ptr++;
|
||||
ptr->Set(fb->GetWidth(), fb->GetHeight(), 0, ur, 0);
|
||||
mVertexBuf->set(make, 4);
|
||||
}
|
||||
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Crossfade Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLFrameBuffer::Wiper_Crossfade::Wiper_Crossfade()
|
||||
: Clock(0)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Crossfade :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
|
||||
{
|
||||
Clock += ticks;
|
||||
|
||||
MakeVBO(fb);
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
float a = clamp(Clock / 32.f, 0.f, 1.f);
|
||||
gl_RenderState.SetColorAlpha(0xffffff, a);
|
||||
gl_RenderState.Apply();
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
mVertexBuf->EnableColorArray(false);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Melt Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLFrameBuffer::Wiper_Melt::Wiper_Melt()
|
||||
{
|
||||
int i, r;
|
||||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < WIDTH; ++i)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Melt :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int OpenGLFrameBuffer::Wiper_Melt::MakeVBO(int ticks, OpenGLFrameBuffer *fb, bool &done)
|
||||
{
|
||||
FSimpleVertex *make = new FSimpleVertex[321*4];
|
||||
FSimpleVertex *ptr = make;
|
||||
int dy;
|
||||
|
||||
float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
|
||||
ptr->Set(0, 0, 0, 0, vb);
|
||||
ptr++;
|
||||
ptr->Set(0, fb->GetHeight(), 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(fb->GetWidth(), 0, 0, ur, vb);
|
||||
ptr++;
|
||||
ptr->Set(fb->GetWidth(), fb->GetHeight(), 0, ur, 0);
|
||||
ptr++;
|
||||
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
done = true;
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < HEIGHT)
|
||||
{
|
||||
dy = (y[i] < 16) ? y[i] + 1 : 8;
|
||||
y[i] = MIN(y[i] + dy, HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{
|
||||
struct {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} dpt;
|
||||
struct {
|
||||
int32_t left;
|
||||
int32_t top;
|
||||
int32_t right;
|
||||
int32_t bottom;
|
||||
} rect;
|
||||
|
||||
// Only draw for the final tick.
|
||||
// No need for optimization. Wipes won't ever be drawn with anything else.
|
||||
|
||||
dpt.x = i * fb->GetWidth() / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * fb->GetHeight() / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * fb->GetWidth() / WIDTH;
|
||||
rect.bottom = fb->GetHeight() - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
float tw = (float)FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
float th = (float)FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
rect.bottom = fb->GetHeight() - rect.bottom;
|
||||
rect.top = fb->GetHeight() - rect.top;
|
||||
|
||||
ptr->Set(rect.left, rect.bottom, 0, rect.left / tw, rect.top / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.left, rect.top, 0, rect.left / tw, rect.bottom / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.right, rect.bottom, 0, rect.right / tw, rect.top / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.right, rect.top, 0, rect.right / tw, rect.bottom / th);
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int numverts = int(ptr - make);
|
||||
mVertexBuf->set(make, numverts);
|
||||
delete[] make;
|
||||
return numverts;
|
||||
}
|
||||
|
||||
bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
|
||||
{
|
||||
bool done = false;
|
||||
int maxvert = MakeVBO(ticks, fb, done);
|
||||
|
||||
// Draw the new screen on the bottom.
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
for (int i = 4; i < maxvert; i += 4)
|
||||
{
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, i, 4);
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLFrameBuffer::Wiper_Burn::Wiper_Burn()
|
||||
{
|
||||
Density = 4;
|
||||
BurnTime = 0;
|
||||
memset(BurnArray, 0, sizeof(BurnArray));
|
||||
BurnTexture = NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLFrameBuffer::Wiper_Burn::~Wiper_Burn()
|
||||
{
|
||||
if (BurnTexture != NULL)
|
||||
{
|
||||
delete BurnTexture;
|
||||
BurnTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLFrameBuffer :: Wiper_Burn :: Run
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
|
||||
{
|
||||
bool done;
|
||||
|
||||
MakeVBO(fb);
|
||||
|
||||
BurnTime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
|
||||
done = (Density < 0);
|
||||
}
|
||||
|
||||
if (BurnTexture != NULL) delete BurnTexture;
|
||||
BurnTexture = new FHardwareTexture(true);
|
||||
|
||||
// Update the burn texture with the new burn data
|
||||
uint8_t rgb_buffer[WIDTH*HEIGHT*4];
|
||||
|
||||
const uint8_t *src = BurnArray;
|
||||
uint32_t *dest = (uint32_t *)rgb_buffer;
|
||||
for (int y = HEIGHT; y != 0; --y)
|
||||
{
|
||||
for (int x = WIDTH; x != 0; --x)
|
||||
{
|
||||
uint8_t s = clamp<int>((*src++)*2, 0, 255);
|
||||
*dest++ = MAKEARGB(s,255,255,255);
|
||||
}
|
||||
}
|
||||
|
||||
float ur = fb->GetWidth() / FHardwareTexture::GetTexDimension(fb->GetWidth());
|
||||
float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.SetEffect(EFF_BURN);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
|
||||
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0, "BurnTexture");
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
return done || (BurnTime > 40);
|
||||
}
|
|
@ -7,7 +7,8 @@
|
|||
enum
|
||||
{
|
||||
LIGHTBUF_BINDINGPOINT = 1,
|
||||
POSTPROCESS_BINDINGPOINT = 2
|
||||
POSTPROCESS_BINDINGPOINT = 2,
|
||||
VIEWPOINT_BINDINGPOINT = 3
|
||||
};
|
||||
|
||||
enum class UniformType
|
||||
|
|
|
@ -280,5 +280,6 @@ void HWViewpointUniforms::SetDefaults()
|
|||
mGlobVis = (float)R_GetGlobVis(r_viewwindow, r_visibility) / 32.f;
|
||||
mPalLightLevels = static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8);
|
||||
mClipLine.X = -10000000.0f;
|
||||
mFogEnabled = gl_fogmode;
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ struct HWViewpointUniforms
|
|||
int mViewHeight = 0;
|
||||
float mClipHeight = 0.f;
|
||||
float mClipHeightDirection = 0.f;
|
||||
int mFogEnabled = 0;
|
||||
|
||||
void CalcDependencies()
|
||||
{
|
||||
|
|
|
@ -190,7 +190,7 @@ static WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &po
|
|||
if (level.flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) l.cm.ClearColor();
|
||||
}
|
||||
|
||||
l.lightlevel = hw_CalcLightLevel(l.lightlevel, getExtraLight(), true);
|
||||
l.lightlevel = hw_CalcLightLevel(l.lightlevel, getExtraLight(), true, 0);
|
||||
|
||||
if (level.lightmode == 8 || l.lightlevel < 92)
|
||||
{
|
||||
|
|
|
@ -46,7 +46,7 @@ glcycle_t RenderWall,SetupWall,ClipWall;
|
|||
glcycle_t RenderFlat,SetupFlat;
|
||||
glcycle_t RenderSprite,SetupSprite;
|
||||
glcycle_t All, Finish, PortalAll, Bsp;
|
||||
glcycle_t ProcessAll;
|
||||
glcycle_t ProcessAll, PostProcess;
|
||||
glcycle_t RenderAll;
|
||||
glcycle_t Dirty;
|
||||
glcycle_t drawcalls;
|
||||
|
@ -64,6 +64,7 @@ void ResetProfilingData()
|
|||
PortalAll.Reset();
|
||||
RenderAll.Reset();
|
||||
ProcessAll.Reset();
|
||||
PostProcess.Reset();
|
||||
RenderWall.Reset();
|
||||
SetupWall.Reset();
|
||||
ClipWall.Reset();
|
||||
|
@ -94,13 +95,13 @@ static void AppendRenderTimes(FString &str)
|
|||
"F: Render=%2.3f, Setup=%2.3f\n"
|
||||
"S: Render=%2.3f, Setup=%2.3f\n"
|
||||
"2D: %2.3f Finish3D: %2.3f\n"
|
||||
"All=%2.3f, Render=%2.3f, Setup=%2.3f, Portal=%2.3f, Drawcalls=%2.3f, Finish=%2.3f\n",
|
||||
"All=%2.3f, Render=%2.3f, Setup=%2.3f, Portal=%2.3f, Drawcalls=%2.3f, Postprocess=%2.3f, Finish=%2.3f\n",
|
||||
bsp, clipwall,
|
||||
RenderWall.TimeMS(), setupwall,
|
||||
RenderFlat.TimeMS(), SetupFlat.TimeMS(),
|
||||
RenderSprite.TimeMS(), SetupSprite.TimeMS(),
|
||||
twoD.TimeMS(), Flush3D.TimeMS() - twoD.TimeMS(),
|
||||
All.TimeMS() + Finish.TimeMS(), RenderAll.TimeMS(), ProcessAll.TimeMS(), PortalAll.TimeMS(), drawcalls.TimeMS(), Finish.TimeMS());
|
||||
All.TimeMS() + Finish.TimeMS(), RenderAll.TimeMS(), ProcessAll.TimeMS(), PortalAll.TimeMS(), drawcalls.TimeMS(), PostProcess.TimeMS(), Finish.TimeMS());
|
||||
}
|
||||
|
||||
static void AppendRenderStats(FString &out)
|
||||
|
|
|
@ -9,7 +9,7 @@ extern glcycle_t RenderWall,SetupWall,ClipWall;
|
|||
extern glcycle_t RenderFlat,SetupFlat;
|
||||
extern glcycle_t RenderSprite,SetupSprite;
|
||||
extern glcycle_t All, Finish, PortalAll, Bsp;
|
||||
extern glcycle_t ProcessAll;
|
||||
extern glcycle_t ProcessAll, PostProcess;
|
||||
extern glcycle_t RenderAll;
|
||||
extern glcycle_t Dirty;
|
||||
extern glcycle_t drawcalls, twoD, Flush3D;
|
||||
|
|
|
@ -82,13 +82,15 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon)
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor)
|
||||
{
|
||||
int light;
|
||||
|
||||
if (lightlevel == 0) return 0;
|
||||
|
||||
if ((level.lightmode & 2) && lightlevel < 192 && !weapon)
|
||||
bool darklightmode = (level.lightmode & 2) || (level.lightmode == 8 && blendfactor > 0);
|
||||
|
||||
if (darklightmode && lightlevel < 192 && !weapon)
|
||||
{
|
||||
if (lightlevel > 100)
|
||||
{
|
||||
|
@ -126,12 +128,13 @@ PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor)
|
|||
{
|
||||
int r,g,b;
|
||||
|
||||
if (level.lightmode == 8)
|
||||
{
|
||||
return pe;
|
||||
}
|
||||
else if (blendfactor == 0)
|
||||
if (blendfactor == 0)
|
||||
{
|
||||
if (level.lightmode == 8)
|
||||
{
|
||||
return pe;
|
||||
}
|
||||
|
||||
r = pe.r * light / 255;
|
||||
g = pe.g * light / 255;
|
||||
b = pe.b * light / 255;
|
||||
|
@ -167,11 +170,14 @@ PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor)
|
||||
{
|
||||
float density;
|
||||
|
||||
if (level.lightmode & 4)
|
||||
int lightmode = level.lightmode;
|
||||
if (lightmode == 8 && blendfactor > 0) lightmode = 2; // The blendfactor feature does not work with software-style lighting.
|
||||
|
||||
if (lightmode & 4)
|
||||
{
|
||||
// uses approximations of Legacy's default settings.
|
||||
density = level.fogdensity ? (float)level.fogdensity : 18;
|
||||
|
@ -184,7 +190,7 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity)
|
|||
else if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
// case 2: black fog
|
||||
if (level.lightmode != 8 && !(level.flags3 & LEVEL3_NOLIGHTFADE))
|
||||
if ((lightmode != 8 || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE))
|
||||
{
|
||||
density = distfogtable[level.lightmode != 0][hw_ClampLight(lightlevel)];
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
struct Colormap;
|
||||
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon);
|
||||
int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor);
|
||||
PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor);
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity);
|
||||
float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
|
||||
bool hw_CheckFog(sector_t *frontsector, sector_t *backsector);
|
||||
|
||||
inline int hw_ClampLight(int lightlevel)
|
||||
|
|
|
@ -52,11 +52,7 @@ protected:
|
|||
|
||||
static const int MIN_WIDTH = 320;
|
||||
static const int MIN_HEIGHT = 200;
|
||||
|
||||
typedef DECLSPEC int SDLCALL (*SDL_GetWindowBordersSizePtr)(SDL_Window *, int *, int *, int *, int *);
|
||||
|
||||
SDL_GetWindowBordersSizePtr SDL_GetWindowBordersSize_;
|
||||
void *sdl_lib;
|
||||
};
|
||||
|
||||
#endif // __POSIX_SDL_GL_SYSFB_H__
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
|
||||
#include "i_module.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "m_argv.h"
|
||||
|
@ -172,6 +173,11 @@ IVideo *gl_CreateVideo()
|
|||
|
||||
// FrameBuffer implementation -----------------------------------------------
|
||||
|
||||
FModule sdl_lib("SDL2");
|
||||
|
||||
typedef int (*SDL_GetWindowBordersSizePtr)(SDL_Window *, int *, int *, int *, int *);
|
||||
static TOptProc<sdl_lib, SDL_GetWindowBordersSizePtr> SDL_GetWindowBordersSize_("SDL_GetWindowBordersSize");
|
||||
|
||||
SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen)
|
||||
: DFrameBuffer (vid_defwidth, vid_defheight)
|
||||
{
|
||||
|
@ -180,10 +186,9 @@ SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen)
|
|||
// SDL_GetWindowBorderSize() is only available since 2.0.5, but because
|
||||
// GZDoom supports platforms with older SDL2 versions, this function
|
||||
// has to be dynamically loaded
|
||||
sdl_lib = SDL_LoadObject("libSDL2.so");
|
||||
if (sdl_lib != nullptr)
|
||||
if (!sdl_lib.IsLoaded())
|
||||
{
|
||||
SDL_GetWindowBordersSize_ = (SDL_GetWindowBordersSizePtr)SDL_LoadFunction(sdl_lib,"SDL_GetWindowBordersSize");
|
||||
sdl_lib.Load({ "libSDL2.so", "libSDL2-2.0.so" });
|
||||
}
|
||||
|
||||
// NOTE: Core profiles were added with GL 3.2, so there's no sense trying
|
||||
|
@ -261,11 +266,6 @@ SystemGLFrameBuffer::SystemGLFrameBuffer (void *, bool fullscreen)
|
|||
|
||||
SystemGLFrameBuffer::~SystemGLFrameBuffer ()
|
||||
{
|
||||
if (sdl_lib != nullptr)
|
||||
{
|
||||
SDL_UnloadObject(sdl_lib);
|
||||
}
|
||||
|
||||
if (Screen)
|
||||
{
|
||||
ResetGammaTable();
|
||||
|
@ -391,7 +391,7 @@ void SystemGLFrameBuffer::SetWindowSize(int w, int h)
|
|||
|
||||
void SystemGLFrameBuffer::GetWindowBordersSize(int &top, int &left)
|
||||
{
|
||||
if (SDL_GetWindowBordersSize_ != nullptr)
|
||||
if (SDL_GetWindowBordersSize_)
|
||||
{
|
||||
SDL_GetWindowBordersSize_(Screen, &top, &left, nullptr, nullptr);
|
||||
}
|
||||
|
|
|
@ -1053,7 +1053,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
NEXTOP;
|
||||
OP(SRL_KR):
|
||||
ASSERTD(a); ASSERTKD(B); ASSERTD(C);
|
||||
reg.d[a] = (unsigned)konstd[B] >> C;
|
||||
reg.d[a] = (unsigned)konstd[B] >> reg.d[C];
|
||||
NEXTOP;
|
||||
|
||||
OP(SRA_RR):
|
||||
|
|
|
@ -242,6 +242,7 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
|
|||
else if (quad.mDrawMode == DTM_Invert) quad.mDrawMode = DTM_InvertOpaque;
|
||||
}
|
||||
quad.mRenderStyle = parms.style; // this contains the blend mode and blend equation settings.
|
||||
if (parms.burn) quad.mFlags |= DTF_Burn;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -427,6 +428,7 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
|||
// is necessary in order to best reproduce Doom's original lighting.
|
||||
double fadelevel;
|
||||
|
||||
// The hardware renderer's light modes 0, 1 and 4 use a linear light scale which must be used here as well. Otherwise the automap gets too dark.
|
||||
if (vid_rendermode != 4 || (level.lightmode >= 2 && level.lightmode != 4))
|
||||
{
|
||||
double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.));
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
{
|
||||
DTF_Wrap = 1,
|
||||
DTF_Scissor = 2,
|
||||
DTF_Burn = 4,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -511,6 +511,7 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
|
|||
parms->srcy = 0.;
|
||||
parms->srcwidth = 1.;
|
||||
parms->srcheight = 1.;
|
||||
parms->burn = false;
|
||||
|
||||
// Parse the tag list for attributes. (For floating point attributes,
|
||||
// consider that the C ABI dictates that all floats be promoted to
|
||||
|
@ -862,6 +863,10 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
|
|||
case DTA_CellY:
|
||||
parms->celly = ListGetInt(tags);
|
||||
break;
|
||||
|
||||
case DTA_Burn:
|
||||
parms->burn = true;
|
||||
break;
|
||||
|
||||
}
|
||||
tag = ListGetInt(tags);
|
||||
|
|
|
@ -320,9 +320,9 @@ void DFrameBuffer::SetVSync (bool vsync)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool DFrameBuffer::WipeStartScreen(int type)
|
||||
FTexture *DFrameBuffer::WipeStartScreen()
|
||||
{
|
||||
return false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -334,33 +334,9 @@ bool DFrameBuffer::WipeStartScreen(int type)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void DFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: WipeDo
|
||||
//
|
||||
// Draws one frame of a screenwipe. Should be called no more than 35
|
||||
// times per second. If called less than that, ticks indicates how many
|
||||
// ticks have passed since the last call.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool DFrameBuffer::WipeDo(int ticks)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: WipeCleanup
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DFrameBuffer::WipeCleanup()
|
||||
FTexture *DFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
struct sector_t;
|
||||
class IShaderProgram;
|
||||
class FTexture;
|
||||
|
||||
enum EHWCaps
|
||||
{
|
||||
|
@ -205,6 +206,7 @@ enum
|
|||
DTA_SrcWidth,
|
||||
DTA_SrcHeight,
|
||||
DTA_LegacyRenderStyle, // takes an old-style STYLE_* constant instead of an FRenderStyle
|
||||
DTA_Burn, // activates the burn shader for this element
|
||||
|
||||
};
|
||||
|
||||
|
@ -261,6 +263,7 @@ struct DrawParms
|
|||
bool virtBottom;
|
||||
double srcx, srcy;
|
||||
double srcwidth, srcheight;
|
||||
bool burn;
|
||||
};
|
||||
|
||||
struct Va_List
|
||||
|
@ -441,14 +444,26 @@ public:
|
|||
virtual IUniformBuffer *CreateUniformBuffer(size_t size, bool staticuse = false) { return nullptr; }
|
||||
virtual IShaderProgram *CreateShaderProgram() { return nullptr; }
|
||||
|
||||
// Begin 2D drawing operations.
|
||||
// Returns true if hardware-accelerated 2D has been entered, false if not.
|
||||
void Begin2D(bool copy3d) { isIn2D = true; }
|
||||
// Begin/End 2D drawing operations.
|
||||
void Begin2D() { isIn2D = true; }
|
||||
void End2D() { isIn2D = false; }
|
||||
|
||||
void End2DAndUpdate()
|
||||
{
|
||||
DrawRateStuff();
|
||||
End2D();
|
||||
Update();
|
||||
}
|
||||
|
||||
|
||||
// Returns true if Begin2D has been called and 2D drawing is now active
|
||||
bool HasBegun2D() { return isIn2D; }
|
||||
|
||||
// This is overridable in case Vulkan does it differently.
|
||||
virtual bool RenderTextureIsFlipped() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Report a game restart
|
||||
void InitPalette();
|
||||
|
@ -460,10 +475,8 @@ public:
|
|||
virtual sector_t *RenderView(player_t *player) { return nullptr; }
|
||||
|
||||
// Screen wiping
|
||||
virtual bool WipeStartScreen(int type);
|
||||
virtual void WipeEndScreen();
|
||||
virtual bool WipeDo(int ticks);
|
||||
virtual void WipeCleanup();
|
||||
virtual FTexture *WipeStartScreen();
|
||||
virtual FTexture *WipeEndScreen();
|
||||
|
||||
virtual void PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D) { if (afterBloomDrawEndScene2D) afterBloomDrawEndScene2D(); }
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ void main()
|
|||
//
|
||||
// calculate fog factor
|
||||
//
|
||||
if (uFogEnabled == -1)
|
||||
if (uFogEnabled == 1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
}
|
||||
|
|
|
@ -358,7 +358,7 @@ vec4 getLightColor(Material material, float fogdist, float fogfactor)
|
|||
float newlightlevel = 1.0 - R_DoomLightingEquation(uLightLevel);
|
||||
color.rgb *= newlightlevel;
|
||||
}
|
||||
else if (uFogEnabled > 0)
|
||||
else if (uFogColor.rgb == vec3(0.0))
|
||||
{
|
||||
// brightening around the player for light mode 2
|
||||
if (fogdist < uLightDist)
|
||||
|
@ -421,7 +421,7 @@ vec3 AmbientOcclusionColor()
|
|||
//
|
||||
// calculate fog factor
|
||||
//
|
||||
if (uFogEnabled == -1)
|
||||
if (uFogEnabled == 1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
}
|
||||
|
@ -449,17 +449,17 @@ void main()
|
|||
if (frag.a <= uAlphaThreshold) discard;
|
||||
#endif
|
||||
|
||||
if (uFogEnabled != -3) // check for special 2D 'fog' mode.
|
||||
if (uFogEnabled != 3) // check for special 2D 'fog' mode.
|
||||
{
|
||||
float fogdist = 0.0;
|
||||
float fogfactor = 0.0;
|
||||
float fogfactor = 1.0;
|
||||
|
||||
//
|
||||
// calculate fog factor
|
||||
//
|
||||
if (uFogEnabled != 0)
|
||||
if (uFogEnabled != 0 && uFogDensity != 0)
|
||||
{
|
||||
if (uFogEnabled == 1 || uFogEnabled == -1)
|
||||
if (uFogEnabled == 1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ void main()
|
|||
//
|
||||
// colored fog
|
||||
//
|
||||
if (uFogEnabled < 0)
|
||||
if (uFogColor.rgb != vec3(0.0))
|
||||
{
|
||||
frag = applyFog(frag, fogfactor);
|
||||
}
|
||||
|
@ -494,7 +494,7 @@ void main()
|
|||
vec4 cm = (uObjectColor + gray * (uObjectColor2 - uObjectColor)) * 2;
|
||||
frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a);
|
||||
}
|
||||
frag = frag * ProcessLight(material, vColor);
|
||||
frag = frag * ProcessLight(material, vColor);
|
||||
frag.rgb = frag.rgb + uFogColor.rgb;
|
||||
}
|
||||
FragColor = frag;
|
||||
|
|
|
@ -87,6 +87,10 @@ void main()
|
|||
{
|
||||
gl_ClipDistance[0] = -( (worldcoord.z - uClipLine.y) * uClipLine.z + (uClipLine.x - worldcoord.x) * uClipLine.w ) + 1.0/32768.0; // allow a tiny bit of imprecisions for colinear linedefs.
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_ClipDistance[0] = 1;
|
||||
}
|
||||
|
||||
// clip planes used for translucency splitting
|
||||
gl_ClipDistance[1] = worldcoord.y - uClipSplit.x;
|
||||
|
|
|
@ -73,7 +73,7 @@ class LevelCompatibility play
|
|||
AddSectorTag(35, 15);
|
||||
for(int i=605; i<609;i++)
|
||||
{
|
||||
SetLineActivation(i, SPAC_PCross);
|
||||
SetLineActivation(i, SPAC_Cross);
|
||||
SetLineSpecial(i, Door_Open, 15, 64);
|
||||
}
|
||||
break;
|
||||
|
@ -187,7 +187,7 @@ class LevelCompatibility play
|
|||
ClearSectorTags(197);
|
||||
AddSectorTag(197, 8);
|
||||
SetLineSpecial(1279, Floor_LowerToLowest, 8, 32);
|
||||
SetLineActivation(1240, SPAC_PCross);
|
||||
SetLineActivation(1240, SPAC_Cross);
|
||||
SetLineSpecial(1240, Floor_LowerToLowest, 38, 32);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue