- Removed the screenshot parameter from D_Display(), since it was a relic of
a long-abandoned experiment to write directly to video memory instead of to a temporary buffer in system meroy. - Added Direct3D versions of the melt and burn screenwipes. - Fixed the strip sizes for the melt screenwipe to match what Doom would have produced on a 320x200 screen, rather than producing more, thinner strips for wider screens. SVN r659 (trunk)
This commit is contained in:
parent
db54c43175
commit
dc98279403
11 changed files with 1486 additions and 1022 deletions
|
|
@ -77,13 +77,6 @@
|
|||
|
||||
IMPLEMENT_CLASS(D3DFB)
|
||||
|
||||
struct FBVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw;
|
||||
FLOAT tu, tv;
|
||||
};
|
||||
#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX1)
|
||||
|
||||
class D3DTex : public FNativeTexture
|
||||
{
|
||||
public:
|
||||
|
|
@ -143,7 +136,6 @@ extern bool VidResizing;
|
|||
|
||||
EXTERN_CVAR (Bool, fullscreen)
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Int, vid_displaybits)
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
EXTERN_CVAR (Float, transsouls)
|
||||
|
||||
|
|
@ -183,6 +175,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
|
|||
PlainStencilShader = NULL;
|
||||
DimShader = NULL;
|
||||
GammaFixerShader = NULL;
|
||||
BurnShader = NULL;
|
||||
FBFormat = D3DFMT_UNKNOWN;
|
||||
PalFormat = D3DFMT_UNKNOWN;
|
||||
VSync = vid_vsync;
|
||||
|
|
@ -196,6 +189,7 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
|
|||
Textures = NULL;
|
||||
Accel2D = true;
|
||||
GatheringWipeScreen = false;
|
||||
ScreenWipe = NULL;
|
||||
|
||||
Gamma = 1.0;
|
||||
FlashConstants[0][3] = FlashConstants[0][2] = FlashConstants[0][1] = FlashConstants[0][0] = 0;
|
||||
|
|
@ -263,8 +257,6 @@ D3DFB::D3DFB (int width, int height, bool fullscreen)
|
|||
|
||||
D3DFB::~D3DFB ()
|
||||
{
|
||||
KillNativeTexs();
|
||||
KillNativePals();
|
||||
ReleaseResources ();
|
||||
if (D3DDevice != NULL)
|
||||
{
|
||||
|
|
@ -335,6 +327,11 @@ bool D3DFB::CreateResources ()
|
|||
Printf ("Windowed mode gamma will not work.\n");
|
||||
GammaFixerShader = NULL;
|
||||
}
|
||||
if (FAILED(D3DDevice->CreatePixelShader (BurnShaderDef, &BurnShader)))
|
||||
{
|
||||
Printf ("Burn screenwipe will not work in D3D mode.\n");
|
||||
BurnShader = NULL;
|
||||
}
|
||||
CurPixelShader = NULL;
|
||||
memset(Constant, 0, sizeof(Constant));
|
||||
if (!CreateFBTexture() ||
|
||||
|
|
@ -356,34 +353,9 @@ bool D3DFB::CreateResources ()
|
|||
void D3DFB::ReleaseResources ()
|
||||
{
|
||||
I_SaveWindowedPos ();
|
||||
if (FBTexture != NULL)
|
||||
{
|
||||
FBTexture->Release();
|
||||
FBTexture = NULL;
|
||||
}
|
||||
if (FinalWipeScreen != NULL)
|
||||
{
|
||||
if (FinalWipeScreen != TempRenderTexture)
|
||||
{
|
||||
FinalWipeScreen->Release();
|
||||
}
|
||||
FinalWipeScreen = NULL;
|
||||
}
|
||||
if (TempRenderTexture != NULL)
|
||||
{
|
||||
TempRenderTexture->Release();
|
||||
TempRenderTexture = NULL;
|
||||
}
|
||||
if (InitialWipeScreen != NULL)
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
}
|
||||
if (VertexBuffer != NULL)
|
||||
{
|
||||
VertexBuffer->Release();
|
||||
VertexBuffer = NULL;
|
||||
}
|
||||
KillNativeTexs();
|
||||
KillNativePals();
|
||||
ReleaseDefaultPoolItems();
|
||||
if (PaletteTexture != NULL)
|
||||
{
|
||||
PaletteTexture->Release();
|
||||
|
|
@ -424,28 +396,57 @@ void D3DFB::ReleaseResources ()
|
|||
GammaFixerShader->Release();
|
||||
GammaFixerShader = NULL;
|
||||
}
|
||||
if (BurnShader != NULL)
|
||||
{
|
||||
BurnShader->Release();
|
||||
BurnShader = NULL;
|
||||
}
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
ScreenWipe = NULL;
|
||||
}
|
||||
GatheringWipeScreen = false;
|
||||
}
|
||||
|
||||
bool D3DFB::Reset ()
|
||||
// Free resources created with D3DPOOL_DEFAULT.
|
||||
void D3DFB::ReleaseDefaultPoolItems()
|
||||
{
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
// Free resources created with D3DPOOL_DEFAULT.
|
||||
if (FBTexture != NULL)
|
||||
{
|
||||
FBTexture->Release();
|
||||
FBTexture = NULL;
|
||||
}
|
||||
if (FinalWipeScreen != NULL)
|
||||
{
|
||||
if (FinalWipeScreen != TempRenderTexture)
|
||||
{
|
||||
FinalWipeScreen->Release();
|
||||
}
|
||||
FinalWipeScreen = NULL;
|
||||
}
|
||||
if (TempRenderTexture != NULL)
|
||||
{
|
||||
TempRenderTexture->Release();
|
||||
TempRenderTexture = NULL;
|
||||
}
|
||||
if (InitialWipeScreen != NULL)
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
}
|
||||
if (VertexBuffer != NULL)
|
||||
{
|
||||
VertexBuffer->Release();
|
||||
VertexBuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool D3DFB::Reset ()
|
||||
{
|
||||
D3DPRESENT_PARAMETERS d3dpp;
|
||||
|
||||
ReleaseDefaultPoolItems();
|
||||
FillPresentParameters (&d3dpp, !Windowed, VSync);
|
||||
if (!SUCCEEDED(D3DDevice->Reset (&d3dpp)))
|
||||
{
|
||||
|
|
@ -1072,265 +1073,6 @@ void D3DFB::SetBlendingRect(int x1, int y1, int x2, int y2)
|
|||
/* 2D Stuff */
|
||||
/**************************************************************************/
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: 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.
|
||||
//
|
||||
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
|
||||
// is visible on screen right now.
|
||||
//
|
||||
// In windowed mode, we can't do that because we'll get the whole desktop.
|
||||
// Instead, we can conveniently use the TempRenderTexture, which is normally
|
||||
// used for gamma-correcting copying the image to the back buffer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::WipeStartScreen(int type)
|
||||
{
|
||||
IDirect3DSurface9 *surf, *tsurf;
|
||||
D3DSURFACE_DESC desc;
|
||||
|
||||
if (!test2d)
|
||||
{
|
||||
return Super::WipeStartScreen(type);
|
||||
}
|
||||
if (type != wipe_Fade)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Windowed)
|
||||
{
|
||||
// The InitialWipeScreen must have the same pixel format as
|
||||
// the TempRenderTexture.
|
||||
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) ||
|
||||
FAILED(tsurf->GetDesc(&desc)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// GetFrontBufferData works only with this format
|
||||
desc.Format = D3DFMT_A8R8G8B8;
|
||||
}
|
||||
|
||||
if (FAILED(D3DDevice->CreateTexture(Width, TrueHeight, 1, 0,
|
||||
desc.Format, D3DPOOL_SYSTEMMEM, &InitialWipeScreen, NULL)))
|
||||
{
|
||||
InitialWipeScreen = NULL;
|
||||
return false;
|
||||
}
|
||||
if (FAILED(InitialWipeScreen->GetSurfaceLevel(0, &surf)))
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
return false;
|
||||
}
|
||||
if (!Windowed)
|
||||
{
|
||||
if (FAILED(D3DDevice->GetFrontBufferData(0, surf)))
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
return false;
|
||||
}
|
||||
FinalWipeScreen = TempRenderTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)) ||
|
||||
FAILED(D3DDevice->GetRenderTargetData(tsurf, surf)))
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
return false;
|
||||
}
|
||||
// Create another texture to copy the final wipe screen to so
|
||||
// we can still gamma correct the wipe. Since this is just for
|
||||
// gamma correction, it's okay to fail (though not desirable.)
|
||||
if (GammaFixerShader != NULL && Gamma != 1)
|
||||
{
|
||||
if (FAILED(tsurf->GetDesc(&desc)) ||
|
||||
FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height,
|
||||
1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT,
|
||||
&FinalWipeScreen, NULL)))
|
||||
{
|
||||
FinalWipeScreen = TempRenderTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FinalWipeScreen = TempRenderTexture;
|
||||
}
|
||||
}
|
||||
// Even fullscreen will render to the TempRenderTexture, so we can have
|
||||
// a copy of the new screen readily available.
|
||||
GatheringWipeScreen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn. This function is
|
||||
// called in place of Update(), so it has not been Presented yet.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeEndScreen()
|
||||
{
|
||||
if (!test2d)
|
||||
{
|
||||
Super::WipeEndScreen();
|
||||
return;
|
||||
}
|
||||
WipeTime = 0;
|
||||
|
||||
// Don't do anything if there is no starting point.
|
||||
if (InitialWipeScreen == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the whole screen was drawn without 2D accel, get it in to
|
||||
// video memory now.
|
||||
if (!In2D)
|
||||
{
|
||||
Begin2D();
|
||||
}
|
||||
|
||||
// Don't do anything if there is no ending point.
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If these are different, reverse their roles so we don't need to
|
||||
// waste time copying from TempRenderTexture to FinalWipeScreen.
|
||||
swap(FinalWipeScreen, TempRenderTexture);
|
||||
|
||||
// At this point, InitialWipeScreen holds the screen we are wiping from.
|
||||
// FinalWipeScreen holds the screen we are wiping to, which may be the
|
||||
// same texture as TempRenderTexture.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: 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 D3DFB::WipeDo(int ticks)
|
||||
{
|
||||
if (!test2d)
|
||||
{
|
||||
return Super::WipeDo(ticks);
|
||||
}
|
||||
WipeTime += ticks;
|
||||
|
||||
// Sanity checks.
|
||||
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (GatheringWipeScreen)
|
||||
{ // This is the first time we've been called for this wipe.
|
||||
GatheringWipeScreen = false;
|
||||
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
||||
}
|
||||
else
|
||||
{ // This is the second or later time we've been called for this wipe.
|
||||
D3DDevice->BeginScene();
|
||||
}
|
||||
OldRenderTarget = NULL;
|
||||
if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen &&
|
||||
((Windowed && GammaFixerShader) || GatheringWipeScreen))
|
||||
{
|
||||
IDirect3DSurface9 *targetsurf;
|
||||
if (FAILED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)) ||
|
||||
FAILED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)) ||
|
||||
FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
|
||||
{
|
||||
// Setting the render target failed.
|
||||
OldRenderTarget = NULL;
|
||||
}
|
||||
}
|
||||
In2D = 2;
|
||||
D3DDevice->SetStreamSource(0, VertexBuffer, 0, sizeof(FBVERTEX));
|
||||
D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
|
||||
/* Crossfade only for testing purposes, because it's the simplest.
|
||||
* More to come later.
|
||||
*/
|
||||
|
||||
// Put the initial screen back to the buffer, presumably with DMA.
|
||||
IDirect3DSurface9 *source, *target;
|
||||
|
||||
if (SUCCEEDED(InitialWipeScreen->GetSurfaceLevel(0, &source)) &&
|
||||
SUCCEEDED(D3DDevice->GetRenderTarget(0, &target)))
|
||||
{
|
||||
D3DDevice->UpdateSurface(source, NULL, target, NULL);
|
||||
}
|
||||
|
||||
// Draw the new screen on top of it.
|
||||
SetTexture(0, FinalWipeScreen);
|
||||
SetAlphaBlend(TRUE, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
SetConstant(0, 0, 0, 0, clamp(WipeTime / 32.f, 0.f, 1.f));
|
||||
SetConstant(1, 1, 1, 1, 0);
|
||||
SetPixelShader(PlainShader);
|
||||
// FIXME: The FinalWipeScreen gets junk at the top in letterbox modes.
|
||||
D3DDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
|
||||
|
||||
DrawLetterbox();
|
||||
|
||||
return WipeTime >= 32;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeCleanup()
|
||||
{
|
||||
if (!test2d)
|
||||
{
|
||||
Super::WipeCleanup();
|
||||
return;
|
||||
}
|
||||
if (InitialWipeScreen != NULL)
|
||||
{
|
||||
InitialWipeScreen->Release();
|
||||
InitialWipeScreen = NULL;
|
||||
}
|
||||
if (FinalWipeScreen != NULL && FinalWipeScreen != TempRenderTexture)
|
||||
{
|
||||
FinalWipeScreen->Release();
|
||||
}
|
||||
FinalWipeScreen = NULL;
|
||||
GatheringWipeScreen = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DTex Constructor
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue