Direct3D: Added hardware motion blur

git-svn-id: https://svn.code.sf.net/p/vbam/code/trunk@254 a31d4220-a93d-0410-bf67-fe4944624d44
This commit is contained in:
spacy51 2008-01-01 02:31:07 +00:00
parent 22e4269c29
commit 35354a3556
8 changed files with 152 additions and 13 deletions

View File

@ -68,7 +68,8 @@ private:
D3DDISPLAYMODE mode; D3DDISPLAYMODE mode;
D3DPRESENT_PARAMETERS dpp; D3DPRESENT_PARAMETERS dpp;
D3DFORMAT screenFormat; D3DFORMAT screenFormat;
LPDIRECT3DTEXTURE9 emulatedImage; LPDIRECT3DTEXTURE9 emulatedImage[2];
unsigned char mbCurrentTexture; // current texture for motion blur
int width; int width;
int height; int height;
RECT destRect; RECT destRect;
@ -83,6 +84,12 @@ private:
// 1 3 // 1 3
// 0 2 // 0 2
struct TRANSP_VERTEX {
FLOAT x, y, z, rhw;
D3DCOLOR color;
FLOAT tx, ty;
} transpVertices[4];
void createFont(); void createFont();
void destroyFont(); void destroyFont();
void createTexture(); void createTexture();
@ -118,7 +125,9 @@ Direct3DDisplay::Direct3DDisplay()
height = 0; height = 0;
failed = false; failed = false;
pFont = NULL; pFont = NULL;
emulatedImage = NULL; emulatedImage[0] = NULL;
emulatedImage[1] = NULL;
mbCurrentTexture = 0;
} }
@ -297,6 +306,7 @@ bool Direct3DDisplay::initialize()
createFont(); createFont();
createTexture(); createTexture();
setOption( _T("d3dFilter"), theApp.d3dFilter ); setOption( _T("d3dFilter"), theApp.d3dFilter );
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
calculateDestRect(); calculateDestRect();
if(failed) return false; if(failed) return false;
@ -353,7 +363,7 @@ void Direct3DDisplay::render()
// copy pix to emulatedImage and apply pixel filter if selected // copy pix to emulatedImage and apply pixel filter if selected
D3DLOCKED_RECT lr; D3DLOCKED_RECT lr;
if( FAILED( hr = emulatedImage->LockRect( 0, &lr, NULL, D3DLOCK_DISCARD ) ) ) { if( FAILED( hr = emulatedImage[ mbCurrentTexture ]->LockRect( 0, &lr, NULL, D3DLOCK_DISCARD ) ) ) {
DXTRACE_ERR_MSGBOX( _T("Can not lock texture"), hr ); DXTRACE_ERR_MSGBOX( _T("Can not lock texture"), hr );
return; return;
} else { } else {
@ -395,16 +405,29 @@ void Direct3DDisplay::render()
break; break;
} }
} }
emulatedImage->UnlockRect( 0 ); emulatedImage[ mbCurrentTexture ]->UnlockRect( 0 );
} }
// set emulatedImage as active texture
pDevice->SetTexture( 0, emulatedImage ); // set current emulatedImage as active texture
pDevice->SetTexture( 0, emulatedImage[ mbCurrentTexture ] );
// render textured triangles // render textured triangles
pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 ); pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_TEX1 );
pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, Vertices, sizeof(VERTEX) ); pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, Vertices, sizeof(VERTEX) );
if( theApp.d3dMotionBlur ) {
// set old emulatedImage as active texture
mbCurrentTexture ^= 1; // XOR 1 = switch 0/1
pDevice->SetTexture( 0, emulatedImage[ mbCurrentTexture ] );
// render textured triangles
pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 );
pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, transpVertices, sizeof(TRANSP_VERTEX) );
}
// render speed and status messages // render speed and status messages
D3DCOLOR color; D3DCOLOR color;
RECT r; RECT r;
@ -511,16 +534,32 @@ void Direct3DDisplay::destroyFont()
void Direct3DDisplay::createTexture() void Direct3DDisplay::createTexture()
{ {
if( !emulatedImage ) { if( !emulatedImage[0] ) {
HRESULT hr = pDevice->CreateTexture( HRESULT hr = pDevice->CreateTexture(
width, height, 1, // 1 level, no mipmaps width, height, 1, // 1 level, no mipmaps
D3DUSAGE_DYNAMIC, dpp.BackBufferFormat, D3DUSAGE_DYNAMIC, dpp.BackBufferFormat,
D3DPOOL_DEFAULT, // anything else won't work D3DPOOL_DEFAULT, // anything else won't work
&emulatedImage, &emulatedImage[0],
NULL ); NULL );
if( FAILED( hr ) ) { if( FAILED( hr ) ) {
DXTRACE_ERR_MSGBOX( _T("createTexture failed"), hr ); DXTRACE_ERR_MSGBOX( _T("createTexture(0) failed"), hr );
return;
}
}
if( !emulatedImage[1] && theApp.d3dMotionBlur ) {
HRESULT hr = pDevice->CreateTexture(
width, height, 1, // 1 level, no mipmaps
D3DUSAGE_DYNAMIC, dpp.BackBufferFormat,
D3DPOOL_DEFAULT, // anything else won't work
&emulatedImage[1],
NULL );
if( FAILED( hr ) ) {
DXTRACE_ERR_MSGBOX( _T("createTexture(1) failed"), hr );
return;
} }
} }
} }
@ -528,9 +567,14 @@ void Direct3DDisplay::createTexture()
void Direct3DDisplay::destroyTexture() void Direct3DDisplay::destroyTexture()
{ {
if( emulatedImage ) { if( emulatedImage[0] ) {
emulatedImage->Release(); emulatedImage[0]->Release();
emulatedImage = NULL; emulatedImage[0] = NULL;
}
if( emulatedImage[1] ) {
emulatedImage[1]->Release();
emulatedImage[1] = NULL;
} }
} }
@ -593,6 +637,39 @@ void Direct3DDisplay::calculateDestRect()
Vertices[3].rhw = 1.0f; Vertices[3].rhw = 1.0f;
Vertices[3].tx = 1.0f; Vertices[3].tx = 1.0f;
Vertices[3].ty = 0.0f; Vertices[3].ty = 0.0f;
if( theApp.d3dMotionBlur ) {
// configure semi-transparent triangles
D3DCOLOR semiTrans = D3DCOLOR_ARGB( 0x7F, 0xFF, 0xFF, 0xFF );
transpVertices[0].x = Vertices[0].x;
transpVertices[0].y = Vertices[0].y;
transpVertices[0].z = Vertices[0].z;
transpVertices[0].rhw = Vertices[0].rhw;
transpVertices[0].color = semiTrans;
transpVertices[0].tx = Vertices[0].tx;
transpVertices[0].ty = Vertices[0].ty;
transpVertices[1].x = Vertices[1].x;
transpVertices[1].y = Vertices[1].y;
transpVertices[1].z = Vertices[1].z;
transpVertices[1].rhw = Vertices[1].rhw;
transpVertices[1].color = semiTrans;
transpVertices[1].tx = Vertices[1].tx;
transpVertices[1].ty = Vertices[1].ty;
transpVertices[2].x = Vertices[2].x;
transpVertices[2].y = Vertices[2].y;
transpVertices[2].z = Vertices[2].z;
transpVertices[2].rhw = Vertices[2].rhw;
transpVertices[2].color = semiTrans;
transpVertices[2].tx = Vertices[2].tx;
transpVertices[2].ty = Vertices[2].ty;
transpVertices[3].x = Vertices[3].x;
transpVertices[3].y = Vertices[3].y;
transpVertices[3].z = Vertices[3].z;
transpVertices[3].rhw = Vertices[3].rhw;
transpVertices[3].color = semiTrans;
transpVertices[3].tx = Vertices[3].tx;
transpVertices[3].ty = Vertices[3].ty;
}
} }
@ -631,6 +708,27 @@ void Direct3DDisplay::setOption( const char *option, int value )
if( !_tcscmp( option, _T("fullScreenStretch") ) ) { if( !_tcscmp( option, _T("fullScreenStretch") ) ) {
calculateDestRect(); calculateDestRect();
} }
if( !_tcscmp( option, _T("motionBlur") ) ) {
switch( value )
{
case 0:
mbCurrentTexture = 0;
pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
break;
case 1:
// enable vertex alpha blending
pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
pDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1 );
pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// apply vertex alpha values to texture
pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
calculateDestRect();
createTexture(); // create the second texture
break;
}
}
} }
@ -658,6 +756,7 @@ bool Direct3DDisplay::resetDevice()
} }
createTexture(); createTexture();
setOption( _T("d3dFilter"), theApp.d3dFilter ); setOption( _T("d3dFilter"), theApp.d3dFilter );
setOption( _T("motionBlur"), theApp.d3dMotionBlur );
failed = false; failed = false;
return true; return true;
} }

View File

@ -450,6 +450,8 @@ BEGIN_MESSAGE_MAP(MainWnd, CWnd)
ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_OPENAL, &MainWnd::OnUpdateOutputapiOpenal) ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_OPENAL, &MainWnd::OnUpdateOutputapiOpenal)
ON_COMMAND(ID_OUTPUTAPI_OALCONFIGURATION, &MainWnd::OnOutputapiOalconfiguration) ON_COMMAND(ID_OUTPUTAPI_OALCONFIGURATION, &MainWnd::OnOutputapiOalconfiguration)
ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_OALCONFIGURATION, &MainWnd::OnUpdateOutputapiOalconfiguration) ON_UPDATE_COMMAND_UI(ID_OUTPUTAPI_OALCONFIGURATION, &MainWnd::OnUpdateOutputapiOalconfiguration)
ON_COMMAND(ID_RENDERAPI_D3DMOTIONBLUR, &MainWnd::OnRenderapiD3dmotionblur)
ON_UPDATE_COMMAND_UI(ID_RENDERAPI_D3DMOTIONBLUR, &MainWnd::OnUpdateRenderapiD3dmotionblur)
END_MESSAGE_MAP() END_MESSAGE_MAP()

View File

@ -443,6 +443,8 @@ public:
afx_msg void OnUpdateOutputapiOalconfiguration(CCmdUI *pCmdUI); afx_msg void OnUpdateOutputapiOalconfiguration(CCmdUI *pCmdUI);
afx_msg void OnMoving(UINT fwSide, LPRECT pRect); afx_msg void OnMoving(UINT fwSide, LPRECT pRect);
afx_msg void OnSizing(UINT fwSide, LPRECT pRect); afx_msg void OnSizing(UINT fwSide, LPRECT pRect);
afx_msg void OnRenderapiD3dmotionblur();
afx_msg void OnUpdateRenderapiD3dmotionblur(CCmdUI *pCmdUI);
}; };
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -2028,3 +2028,22 @@ void MainWnd::OnUpdateOutputapiOalconfiguration(CCmdUI *pCmdUI)
pCmdUI->Enable( FALSE ); pCmdUI->Enable( FALSE );
#endif #endif
} }
void MainWnd::OnRenderapiD3dmotionblur()
{
#ifndef NO_D3D
theApp.d3dMotionBlur = !theApp.d3dMotionBlur;
if( theApp.display ) {
theApp.display->setOption( _T("motionBlur"), theApp.d3dMotionBlur ? 1 : 0 );
}
#endif
}
void MainWnd::OnUpdateRenderapiD3dmotionblur(CCmdUI *pCmdUI)
{
#ifndef NO_D3D
pCmdUI->SetCheck( theApp.d3dMotionBlur ? 1 : 0 );
#else
pCmdUI->Enable( FALSE );
#endif
}

View File

@ -287,7 +287,10 @@ VBA::VBA()
ddrawUsingEmulationOnly = false; ddrawUsingEmulationOnly = false;
ddrawDebug = false; ddrawDebug = false;
ddrawUseVideoMemory = false; ddrawUseVideoMemory = false;
#ifndef NO_D3D
d3dFilter = 0; d3dFilter = 0;
d3dMotionBlur = false;
#endif
glFilter = 0; glFilter = 0;
GLSLShaders = 0; GLSLShaders = 0;
skin = NULL; skin = NULL;
@ -1517,10 +1520,14 @@ void VBA::loadSettings()
ddrawUseVideoMemory = regQueryDwordValue("ddrawUseVideoMemory", true) ? true : false; ddrawUseVideoMemory = regQueryDwordValue("ddrawUseVideoMemory", true) ? true : false;
tripleBuffering = regQueryDwordValue("tripleBuffering", false) ? true : false; tripleBuffering = regQueryDwordValue("tripleBuffering", false) ? true : false;
#ifndef NO_D3D
d3dFilter = regQueryDwordValue("d3dFilter", 1); d3dFilter = regQueryDwordValue("d3dFilter", 1);
if(d3dFilter < 0 || d3dFilter > 1) if(d3dFilter < 0 || d3dFilter > 1)
d3dFilter = 1; d3dFilter = 1;
d3dMotionBlur = ( regQueryDwordValue("d3dMotionBlur", 0) == 1 ) ? true : false;
#endif
glFilter = regQueryDwordValue("glFilter", 1); glFilter = regQueryDwordValue("glFilter", 1);
if(glFilter < 0 || glFilter > 1) if(glFilter < 0 || glFilter > 1)
glFilter = 1; glFilter = 1;
@ -2583,7 +2590,11 @@ void VBA::saveSettings()
regSetDwordValue("ddrawUseVideoMemory", ddrawUseVideoMemory); regSetDwordValue("ddrawUseVideoMemory", ddrawUseVideoMemory);
regSetDwordValue("tripleBuffering", tripleBuffering); regSetDwordValue("tripleBuffering", tripleBuffering);
#ifndef NO_D3D
regSetDwordValue("d3dFilter", d3dFilter); regSetDwordValue("d3dFilter", d3dFilter);
regSetDwordValue("d3dMotionBlur", d3dMotionBlur ? 1 : 0);
#endif
regSetDwordValue("glFilter", glFilter); regSetDwordValue("glFilter", glFilter);
regSetDwordValue("GLSLShaders", GLSLShaders); regSetDwordValue("GLSLShaders", GLSLShaders);

View File

@ -161,7 +161,10 @@ class VBA : public CWinApp
bool ddrawUsingEmulationOnly; bool ddrawUsingEmulationOnly;
bool ddrawDebug; bool ddrawDebug;
bool ddrawUseVideoMemory; bool ddrawUseVideoMemory;
#ifndef NO_D3D
int d3dFilter; int d3dFilter;
bool d3dMotionBlur;
#endif
int glFilter; int glFilter;
int GLSLShaders; int GLSLShaders;
bool dinputKeyFocus; bool dinputKeyFocus;

View File

@ -1592,6 +1592,7 @@ BEGIN
MENUITEM "Direct&3D", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECT3D MENUITEM "Direct&3D", ID_OPTIONS_VIDEO_RENDERMETHOD_DIRECT3D
MENUITEM " Filter: Nearest", ID_OPTIONS_VIDEO_RENDEROPTIONS_D3DNOFILTER MENUITEM " Filter: Nearest", ID_OPTIONS_VIDEO_RENDEROPTIONS_D3DNOFILTER
MENUITEM " Filter: Bilinear", ID_OPTIONS_VIDEO_RENDEROPTIONS_D3DBILINEAR MENUITEM " Filter: Bilinear", ID_OPTIONS_VIDEO_RENDEROPTIONS_D3DBILINEAR
MENUITEM " Motion Blur", ID_RENDERAPI_D3DMOTIONBLUR
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "&OpenGL", ID_OPTIONS_VIDEO_RENDERMETHOD_OPENGL MENUITEM "&OpenGL", ID_OPTIONS_VIDEO_RENDERMETHOD_OPENGL
MENUITEM " Filter: Nearest", ID_OPTIONS_VIDEO_RENDEROPTIONS_GLNEAREST MENUITEM " Filter: Nearest", ID_OPTIONS_VIDEO_RENDEROPTIONS_GLNEAREST

View File

@ -822,13 +822,15 @@
#define ID_RENDERAPI_FILTER 40351 #define ID_RENDERAPI_FILTER 40351
#define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLSLSHADERS 40352 #define ID_OPTIONS_VIDEO_RENDEROPTIONS_GLSLSHADERS 40352
#define ID_OPTIONS_SPEED 40353 #define ID_OPTIONS_SPEED 40353
#define ID_RENDERAPI_MOTIONBLUR 40354
#define ID_RENDERAPI_D3DMOTIONBLUR 40355
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 161 #define _APS_NEXT_RESOURCE_VALUE 161
#define _APS_NEXT_COMMAND_VALUE 40354 #define _APS_NEXT_COMMAND_VALUE 40356
#define _APS_NEXT_CONTROL_VALUE 1272 #define _APS_NEXT_CONTROL_VALUE 1272
#define _APS_NEXT_SYMED_VALUE 103 #define _APS_NEXT_SYMED_VALUE 103
#endif #endif