mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-14 08:30:49 +00:00
- Untested wipe refactor
# Conflicts: # src/gl/renderer/gl_renderer.cpp # src/gl/system/gl_wipe.cpp # src/hwrenderer/scene/hw_attributebuffer.cpp
This commit is contained in:
parent
ecf6e3f620
commit
9af01c4667
11 changed files with 363 additions and 517 deletions
|
@ -638,7 +638,8 @@ CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||||
|
|
||||||
void D_Display ()
|
void D_Display ()
|
||||||
{
|
{
|
||||||
bool wipe;
|
FTexture *wipe;
|
||||||
|
int wipe_type;
|
||||||
sector_t *viewsec;
|
sector_t *viewsec;
|
||||||
|
|
||||||
if (nodrawers || screen == NULL)
|
if (nodrawers || screen == NULL)
|
||||||
|
@ -703,35 +704,36 @@ void D_Display ()
|
||||||
if (NoWipe)
|
if (NoWipe)
|
||||||
{
|
{
|
||||||
NoWipe--;
|
NoWipe--;
|
||||||
wipe = false;
|
wipe = nullptr;
|
||||||
wipegamestate = gamestate;
|
wipegamestate = gamestate;
|
||||||
}
|
}
|
||||||
// No wipes when in a stereo3D VR mode
|
// No wipes when in a stereo3D VR mode
|
||||||
else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL && (vr_mode == 0 || vid_rendermode != 4))
|
else if (gamestate != wipegamestate && gamestate != GS_FULLCONSOLE && gamestate != GS_TITLELEVEL && (vr_mode == 0 || vid_rendermode != 4))
|
||||||
{ // save the current screen if about to wipe
|
{ // save the current screen if about to wipe
|
||||||
|
wipe = screen->WipeStartScreen ();
|
||||||
switch (wipegamestate)
|
switch (wipegamestate)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
wipe = screen->WipeStartScreen (wipetype);
|
wipe_type = wipetype;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_FORCEWIPEFADE:
|
case GS_FORCEWIPEFADE:
|
||||||
wipe = screen->WipeStartScreen (wipe_Fade);
|
wipe_type = wipe_Fade;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_FORCEWIPEBURN:
|
case GS_FORCEWIPEBURN:
|
||||||
wipe = screen->WipeStartScreen (wipe_Burn);
|
wipe_type =wipe_Burn;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GS_FORCEWIPEMELT:
|
case GS_FORCEWIPEMELT:
|
||||||
wipe = screen->WipeStartScreen (wipe_Melt);
|
wipe_type = wipe_Melt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wipegamestate = gamestate;
|
wipegamestate = gamestate;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wipe = false;
|
wipe = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->FrameTime = I_msTimeFS();
|
screen->FrameTime = I_msTimeFS();
|
||||||
|
@ -885,7 +887,7 @@ void D_Display ()
|
||||||
GSnd->SetSfxPaused(true, 1);
|
GSnd->SetSfxPaused(true, 1);
|
||||||
I_FreezeTime(true);
|
I_FreezeTime(true);
|
||||||
screen->End2D();
|
screen->End2D();
|
||||||
screen->WipeEndScreen ();
|
auto wipend = screen->WipeEndScreen ();
|
||||||
|
|
||||||
wipestart = I_msTime();
|
wipestart = I_msTime();
|
||||||
NetUpdate(); // send out any new accumulation
|
NetUpdate(); // send out any new accumulation
|
||||||
|
|
284
src/f_wipe.cpp
284
src/f_wipe.cpp
|
@ -27,6 +27,36 @@
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "f_wipe.h"
|
#include "f_wipe.h"
|
||||||
#include "templates.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)
|
int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
|
||||||
{
|
{
|
||||||
|
@ -112,3 +142,257 @@ int wipe_CalcBurn (uint8_t *burnarray, int width, int height, int density)
|
||||||
return -1;
|
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();
|
||||||
|
~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, TAG_DONE);
|
||||||
|
screen->DrawTexture(endScreen, 0, 0, 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, 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 * h / WIDTH;
|
||||||
|
dpt.y = MAX(0, y[i] * h / HEIGHT);
|
||||||
|
rect.left = dpt.x;
|
||||||
|
rect.top = 0;
|
||||||
|
rect.right = (i + 1) * w / WIDTH;
|
||||||
|
rect.bottom = w - dpt.y;
|
||||||
|
if (rect.bottom > rect.top)
|
||||||
|
{
|
||||||
|
screen->DrawTexture(startScreen, 0, rect.top, DTA_ClipLeft, rect.left, DTA_ClipRight, rect.right, 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, TAG_DONE);
|
||||||
|
screen->DrawTexture(endScreen, 0, 0, DTA_Burn, true, 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__
|
#ifndef __F_WIPE_H__
|
||||||
#define __F_WIPE_H__
|
#define __F_WIPE_H__
|
||||||
|
|
||||||
//
|
#include "stdint.h"
|
||||||
// SCREEN WIPE PACKAGE
|
|
||||||
//
|
|
||||||
|
|
||||||
#if 0
|
class FTexture;
|
||||||
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
|
|
||||||
int wipe_CalcBurn(uint8_t *buffer, int width, int height, int density);
|
int wipe_CalcBurn(uint8_t *buffer, int width, int height, int density);
|
||||||
|
|
||||||
enum
|
enum
|
||||||
|
@ -50,4 +40,21 @@ enum
|
||||||
wipe_NUMWIPES
|
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
|
#endif
|
||||||
|
|
|
@ -428,12 +428,6 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
||||||
const auto &mScreenViewport = screen->mScreenViewport;
|
const auto &mScreenViewport = screen->mScreenViewport;
|
||||||
glViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
|
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);
|
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
// Korshun: ENABLE AUTOMAP ANTIALIASING!!!
|
// Korshun: ENABLE AUTOMAP ANTIALIASING!!!
|
||||||
|
@ -530,6 +524,10 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
||||||
gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f);
|
gl_RenderState.mTextureMatrix.translate(0.f, 1.f, 0.0f);
|
||||||
gl_RenderState.EnableTextureMatrix(true);
|
gl_RenderState.EnableTextureMatrix(true);
|
||||||
}
|
}
|
||||||
|
if (cmd.mFlags & F2DDrawer::DTF_Burn)
|
||||||
|
{
|
||||||
|
gl_RenderState.SetEffect(EFF_BURN);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -555,6 +553,8 @@ void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
||||||
gl_RenderState.SetObjectColor(0xffffffff);
|
gl_RenderState.SetObjectColor(0xffffffff);
|
||||||
gl_RenderState.SetObjectColor2(0);
|
gl_RenderState.SetObjectColor2(0);
|
||||||
gl_RenderState.EnableTextureMatrix(false);
|
gl_RenderState.EnableTextureMatrix(false);
|
||||||
|
gl_RenderState.SetEffect(EFF_NONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,6 @@ public:
|
||||||
// points to the last row in the buffer, which will be the first row output.
|
// 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;
|
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();
|
void Swap();
|
||||||
bool IsHWGammaActive() const { return HWGammaActive; }
|
bool IsHWGammaActive() const { return HWGammaActive; }
|
||||||
|
|
||||||
|
@ -63,33 +59,11 @@ public:
|
||||||
|
|
||||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||||
|
|
||||||
|
FTexture *WipeStartScreen() override;
|
||||||
|
FTexture *WipeEndScreen() override;
|
||||||
private:
|
private:
|
||||||
int camtexcount = 0;
|
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:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,49 +40,21 @@
|
||||||
#include "gl/data/gl_vertexbuffer.h"
|
#include "gl/data/gl_vertexbuffer.h"
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
class FGLWipeTexture : public FTexture
|
||||||
//
|
|
||||||
// Screen wipes
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
// TYPES -------------------------------------------------------------------
|
|
||||||
|
|
||||||
class OpenGLFrameBuffer::Wiper_Crossfade : public OpenGLFrameBuffer::Wiper
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Wiper_Crossfade();
|
|
||||||
bool Run(int ticks, OpenGLFrameBuffer *fb);
|
|
||||||
|
|
||||||
private:
|
FGLWipeTexture(int w, int h)
|
||||||
int Clock;
|
{
|
||||||
};
|
Width = w;
|
||||||
|
Height = h;
|
||||||
|
WidthBits = 4;
|
||||||
|
UseType = ETextureType::SWCanvas;
|
||||||
|
bNoCompress = true;
|
||||||
|
SystemTexture[0] = screen->CreateHardwareTexture(this);
|
||||||
|
}
|
||||||
|
|
||||||
class OpenGLFrameBuffer::Wiper_Melt : public OpenGLFrameBuffer::Wiper
|
// This is just a wrapper around the hardware texture being extracted below so that it can be passed to the 2D code.
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -95,46 +67,18 @@ private:
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
FTexture *OpenGLFrameBuffer::WipeStartScreen()
|
||||||
{
|
{
|
||||||
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;
|
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]()
|
FGLWipeTexture *tex = new FGLWipeTexture(viewport.width, viewport.height);
|
||||||
{
|
tex->SystemTexture[0]->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen");
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
glFinish();
|
||||||
};
|
static_cast<FHardwareTexture*>(tex->SystemTexture[0])->Bind(0, false, false);
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindCurrentFB();
|
GLRenderer->mBuffers->BindCurrentFB();
|
||||||
copyPixels();
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
||||||
|
return tex;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -145,392 +89,16 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void OpenGLFrameBuffer::WipeEndScreen()
|
FTexture *OpenGLFrameBuffer::WipeEndScreen()
|
||||||
{
|
{
|
||||||
GLRenderer->Flush();
|
GLRenderer->Flush();
|
||||||
const auto &viewport = screen->mScreenViewport;
|
const auto &viewport = screen->mScreenViewport;
|
||||||
wipeendscreen = new FHardwareTexture(true);
|
FGLWipeTexture *tex = new FGLWipeTexture(viewport.width, viewport.height);
|
||||||
wipeendscreen->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
|
tex->SystemTexture[0]->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen");
|
||||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER, -1);
|
|
||||||
glFinish();
|
glFinish();
|
||||||
wipeendscreen->Bind(0, false, false);
|
static_cast<FHardwareTexture*>(tex->SystemTexture[0])->Bind(0, false, false);
|
||||||
|
|
||||||
GLRenderer->mBuffers->BindCurrentFB();
|
GLRenderer->mBuffers->BindCurrentFB();
|
||||||
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height);
|
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);
|
return tex;
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
|
@ -242,6 +242,7 @@ bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor,
|
||||||
else if (quad.mDrawMode == DTM_Invert) quad.mDrawMode = DTM_InvertOpaque;
|
else if (quad.mDrawMode == DTM_Invert) quad.mDrawMode = DTM_InvertOpaque;
|
||||||
}
|
}
|
||||||
quad.mRenderStyle = parms.style; // this contains the blend mode and blend equation settings.
|
quad.mRenderStyle = parms.style; // this contains the blend mode and blend equation settings.
|
||||||
|
if (parms.burn) quad.mFlags |= DTF_Burn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ public:
|
||||||
{
|
{
|
||||||
DTF_Wrap = 1,
|
DTF_Wrap = 1,
|
||||||
DTF_Scissor = 2,
|
DTF_Scissor = 2,
|
||||||
|
DTF_Burn = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -511,6 +511,7 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
|
||||||
parms->srcy = 0.;
|
parms->srcy = 0.;
|
||||||
parms->srcwidth = 1.;
|
parms->srcwidth = 1.;
|
||||||
parms->srcheight = 1.;
|
parms->srcheight = 1.;
|
||||||
|
parms->burn = false;
|
||||||
|
|
||||||
// Parse the tag list for attributes. (For floating point attributes,
|
// Parse the tag list for attributes. (For floating point attributes,
|
||||||
// consider that the C ABI dictates that all floats be promoted to
|
// consider that the C ABI dictates that all floats be promoted to
|
||||||
|
@ -863,6 +864,10 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3
|
||||||
parms->celly = ListGetInt(tags);
|
parms->celly = ListGetInt(tags);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DTA_Burn:
|
||||||
|
parms->burn = true;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
tag = ListGetInt(tags);
|
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,8 +334,9 @@ bool DFrameBuffer::WipeStartScreen(int type)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void DFrameBuffer::WipeEndScreen()
|
FTexture *DFrameBuffer::WipeEndScreen()
|
||||||
{
|
{
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
|
|
||||||
struct sector_t;
|
struct sector_t;
|
||||||
class IShaderProgram;
|
class IShaderProgram;
|
||||||
|
class FTexture;
|
||||||
|
|
||||||
enum EHWCaps
|
enum EHWCaps
|
||||||
{
|
{
|
||||||
|
@ -205,6 +206,7 @@ enum
|
||||||
DTA_SrcWidth,
|
DTA_SrcWidth,
|
||||||
DTA_SrcHeight,
|
DTA_SrcHeight,
|
||||||
DTA_LegacyRenderStyle, // takes an old-style STYLE_* constant instead of an FRenderStyle
|
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;
|
bool virtBottom;
|
||||||
double srcx, srcy;
|
double srcx, srcy;
|
||||||
double srcwidth, srcheight;
|
double srcwidth, srcheight;
|
||||||
|
bool burn;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Va_List
|
struct Va_List
|
||||||
|
@ -467,8 +470,8 @@ public:
|
||||||
virtual sector_t *RenderView(player_t *player) { return nullptr; }
|
virtual sector_t *RenderView(player_t *player) { return nullptr; }
|
||||||
|
|
||||||
// Screen wiping
|
// Screen wiping
|
||||||
virtual bool WipeStartScreen(int type);
|
virtual FTexture *WipeStartScreen();
|
||||||
virtual void WipeEndScreen();
|
virtual FTexture *WipeEndScreen();
|
||||||
virtual bool WipeDo(int ticks);
|
virtual bool WipeDo(int ticks);
|
||||||
virtual void WipeCleanup();
|
virtual void WipeCleanup();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue