Files
itgmania212121/stepmania/src/RageDisplay.cpp
T
2002-08-23 08:30:44 +00:00

787 lines
22 KiB
C++

#include "stdafx.h"
/*
-----------------------------------------------------------------------------
Class: RageDisplay
Desc: See header.
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
#include "RageDisplay.h"
#include "RageUtil.h"
#include "RageLog.h"
#include "RageTimer.h"
#include "RageException.h"
#include "RageTexture.h"
RageDisplay* DISPLAY = NULL;
RageDisplay::RageDisplay( HWND hWnd )
{
LOG->Trace( "RageDisplay::RageDisplay()" );
// Save the window handle
m_hWnd = hWnd;
m_pd3d = NULL;
m_pd3dDevice = NULL;
m_pVB = NULL;
m_fLastCheckTime = TIMER->GetTimeSinceStart();
m_iFramesRenderedSinceLastCheck = 0;
m_iTrianglesRenderedSinceLastCheck = 0;
m_iDrawsSinceLastCheck = 0;
m_iFPS = 0;
m_iTPF = 0;
m_iDPF = 0;
m_iNumVerts = 0;
try
{
// Construct a Direct3D object
m_pd3d = Direct3DCreate8( D3D_SDK_VERSION );
}
catch (...)
{
// Edwin Evans: Catch any exception. It won't be caught by main exception handler.
throw RageException( "Unknown exception in Direct3DCreate8." );
}
if( NULL == m_pd3d )
throw RageException( "Direct3DCreate8 failed." );
HRESULT hr;
if( FAILED( hr = m_pd3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_DeviceCaps) ) )
{
throw RageException(
"There was an error while initializing your video card.\n\n"
"Your system is reporting that Direct3D8 hardware acceleration\n"
"is not available. In most cases, you can download an updated\n"
"driver from your card's manufacturer."
);
}
LOG->Trace(
"Video card info:\n"
" - max texture width is %d\n"
" - max texture height is %d\n"
" - max texture blend stages is %d\n"
" - max simultaneous textures is %d\n",
m_DeviceCaps.MaxTextureWidth,
m_DeviceCaps.MaxTextureHeight,
m_DeviceCaps.MaxTextureBlendStages,
m_DeviceCaps.MaxSimultaneousTextures
);
// Enumerate possible display modes
LOG->Trace( "This display adaptor supports the following modes:" );
for( UINT u=0; u<m_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT); u++ )
{
D3DDISPLAYMODE mode;
if( SUCCEEDED( m_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, u, &mode ) ) )
{
//LOG->Trace( " %ux%u %uHz, format %d", mode.Width, mode.Height, mode.RefreshRate, mode.Format );
}
}
// Save the original desktop format.
m_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &m_DesktopMode );
}
int RageDisplay::MaxRefresh(int iWidth, int iHeight) const
{
UINT mx = D3DPRESENT_RATE_DEFAULT;
for( UINT u=0; u<m_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT); u++ )
{
D3DDISPLAYMODE mode;
if( !SUCCEEDED( m_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, u, &mode ) ) )
continue;
if(mode.Width != iWidth) continue;
if(mode.Height != iHeight) continue;
/* also test mode.Format? */
if(mx == D3DPRESENT_RATE_DEFAULT || mode.RefreshRate > mx)
mx = mode.RefreshRate;
}
return mx;
}
void RageDisplay::GetHzAtResolution(int width, int height, CArray<int,int> &add) const
{
for( UINT u=0; u<m_pd3d->GetAdapterModeCount(D3DADAPTER_DEFAULT); u++ )
{
D3DDISPLAYMODE mode;
if( !SUCCEEDED( m_pd3d->EnumAdapterModes( D3DADAPTER_DEFAULT, u, &mode ) ) )
continue;
if(mode.Width != width) continue;
if(mode.Height != height) continue;
/* also test mode.Format? */
add.Add(mode.RefreshRate);
}
}
RageDisplay::~RageDisplay()
{
ReleaseVertexBuffer();
// Release our D3D Device
SAFE_RELEASE( m_pd3dDevice );
m_pd3d->Release();
}
//-----------------------------------------------------------------------------
// Name: SwitchDisplayMode()
// Desc:
//-----------------------------------------------------------------------------
bool RageDisplay::SwitchDisplayMode(
const bool bWindowed, const int iWidth, const int iHeight, const int iBPP, const int iFullScreenHz )
{
LOG->Trace( "RageDisplay::SwitchDisplayModes( %d, %d, %d, %d, %d )", bWindowed, iWidth, iHeight, iBPP, iFullScreenHz );
if( !bWindowed )
SetCursor( NULL );
HRESULT hr;
// Find an pixel format for the back buffer.
// If windowed, then dwBPP is ignored. Use whatever works.
CArray<D3DFORMAT,D3DFORMAT> arrayBackBufferFormats; // throw all possibilities in here
if( bWindowed )
{
arrayBackBufferFormats.Add( D3DFMT_R5G6B5 );
arrayBackBufferFormats.Add( D3DFMT_X1R5G5B5 );
arrayBackBufferFormats.Add( D3DFMT_A1R5G5B5 );
arrayBackBufferFormats.Add( D3DFMT_R8G8B8 );
arrayBackBufferFormats.Add( D3DFMT_X8R8G8B8 );
arrayBackBufferFormats.Add( D3DFMT_A8R8G8B8 );
}
else // full screen
{
// add only the formats that match dwBPP
switch( iBPP )
{
case 16:
arrayBackBufferFormats.Add( D3DFMT_R5G6B5 );
arrayBackBufferFormats.Add( D3DFMT_X1R5G5B5 );
arrayBackBufferFormats.Add( D3DFMT_A1R5G5B5 );
break;
case 32:
arrayBackBufferFormats.Add( D3DFMT_R8G8B8 );
arrayBackBufferFormats.Add( D3DFMT_X8R8G8B8 );
arrayBackBufferFormats.Add( D3DFMT_A8R8G8B8 );
break;
default:
throw RageException( ssprintf("Invalid BPP '%u' specified", iBPP) );
return false;
}
}
// Test each back buffer format until we find something that works.
D3DFORMAT fmtDisplay; // fill these in below...
D3DFORMAT fmtBackBuffer;
for( int i=0; i < arrayBackBufferFormats.GetSize(); i++ )
{
if( bWindowed )
{
fmtDisplay = m_DesktopMode.Format;
fmtBackBuffer = arrayBackBufferFormats[i];
}
else // Fullscreen
{
fmtDisplay = fmtBackBuffer = arrayBackBufferFormats[i];
}
LOG->Trace( "Testing format: display %d, back buffer %d, windowed %d...", fmtDisplay, fmtBackBuffer, bWindowed );
hr = m_pd3d->CheckDeviceType(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
fmtDisplay,
fmtBackBuffer,
bWindowed
);
if( SUCCEEDED(hr) )
{
LOG->Trace( "This will work." );
break; // done searching
}
else
{
LOG->Trace( "This won't work. Keep searching." );
}
}
if( i == arrayBackBufferFormats.GetSize() ) // we didn't find an appropriate format
{
LOG->Trace( hr, "failed to find an appropriate format for %d, %u, %u, %u.", bWindowed, iWidth, iHeight, iBPP );
return false;
}
// Set up presentation parameters for the display
ZeroMemory( &m_d3dpp, sizeof(m_d3dpp) );
m_d3dpp.BackBufferWidth = iWidth;
m_d3dpp.BackBufferHeight = iHeight;
m_d3dpp.BackBufferFormat = fmtBackBuffer;
m_d3dpp.BackBufferCount = 1;
m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
m_d3dpp.hDeviceWindow = m_hWnd;
m_d3dpp.Windowed = bWindowed;
m_d3dpp.EnableAutoDepthStencil = TRUE;
m_d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
m_d3dpp.Flags = 0;
m_d3dpp.FullScreen_RefreshRateInHz = bWindowed? D3DPRESENT_RATE_DEFAULT :
iFullScreenHz == 0? MaxRefresh(iWidth, iHeight):
iFullScreenHz == 1? D3DPRESENT_RATE_DEFAULT:
iFullScreenHz;
m_d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
LOG->Trace( "Present Parameters: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",
m_d3dpp.BackBufferWidth,
m_d3dpp.BackBufferHeight,
m_d3dpp.BackBufferFormat,
m_d3dpp.BackBufferCount,
m_d3dpp.MultiSampleType,
m_d3dpp.SwapEffect,
m_d3dpp.hDeviceWindow,
m_d3dpp.Windowed,
m_d3dpp.EnableAutoDepthStencil,
m_d3dpp.AutoDepthStencilFormat,
m_d3dpp.Flags,
m_d3dpp.FullScreen_RefreshRateInHz,
m_d3dpp.FullScreen_PresentationInterval
);
if( m_pd3dDevice == NULL )
{
D3DADAPTER_IDENTIFIER8 identifier;
if( FAILED( hr = m_pd3d->GetAdapterIdentifier( D3DADAPTER_DEFAULT, 0, &identifier ) ) )
{
LOG->Trace( hr, "GetAdapterIdentifier failed" );
return false;
}
LOG->Trace( "Driver: %s. Description: %s.",
identifier.Driver,
identifier.Description
);
// device is not yet created. We need to create it
if( FAILED( hr = m_pd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
m_hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,
&m_d3dpp, &m_pd3dDevice) ) )
{
LOG->Trace( hr, "failed to create device: %d, %u, %u, %u.", bWindowed, iWidth, iHeight, iBPP );
return false;
}
LOG->Trace(
"Video card info:\n"
" - available texture mem is %u\n",
m_pd3dDevice->GetAvailableTextureMem()
);
if( m_pVB == NULL )
CreateVertexBuffer();
}
else
{
// device is already created. Just reset it.
if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) )
{
LOG->Trace( hr, "failed to reset device: %d, %u, %u, %u.", bWindowed, iWidth, iHeight, iBPP );
return false;
}
}
LOG->Trace( "Mode change was successful." );
// Clear the back buffer and present it so we don't show the gibberish that was
// in video memory from the last app.
BeginFrame();
EndFrame();
ShowFrame();
return true;
}
//-----------------------------------------------------------------------------
// Name: Reset()
// Desc:
//-----------------------------------------------------------------------------
HRESULT RageDisplay::Reset()
{
return m_pd3dDevice->Reset( &m_d3dpp );
}
//-----------------------------------------------------------------------------
// Name: BeginFrame()
// Desc:
//-----------------------------------------------------------------------------
HRESULT RageDisplay::BeginFrame()
{
//////////////////////////////////////////////////////////////
// Do some fancy testing to make sure the D3D deivce is ready.
// This is mainly used when the the app is reactivated
// after the user has Alt-tabed out of full screen mode.
//////////////////////////////////////////////////////////////
// Test cooperative level
HRESULT hr;
// Test the cooperative level to see if it's okay to render
if( FAILED( hr = m_pd3dDevice->TestCooperativeLevel() ) )
{
// If the device was lost, do not render until we get it back
if( D3DERR_DEVICELOST == hr )
return hr; // not ready to render
// Check if the device needs to be resized.
if( D3DERR_DEVICENOTRESET == hr )
return hr;
return hr;
}
m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 );
if ( FAILED( hr = m_pd3dDevice->BeginScene() ) )
return E_FAIL;
// disable culling so backward polys can be drawn
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
// Enable Alpha Blending and Testing
m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
//m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
//m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x08 );
//m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
// m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
// m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
// Don't tile texture coords. This creates ugly wrapping artifacts on textures that have to be rescaled.
//m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_BORDER );
//m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER );
m_pd3dDevice->SetVertexShader( D3DFVF_RAGEVERTEX );
m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(RAGEVERTEX) );
return S_OK;
}
HRESULT RageDisplay::EndFrame()
{
FlushQueue();
m_pd3dDevice->EndScene();
// update stats
m_iFramesRenderedSinceLastCheck++;
float fTimeNow = TIMER->GetTimeSinceStart();
if( fTimeNow - m_fLastCheckTime > 1.0f ) // update stats every 1 sec.
{
m_iFPS = m_iFramesRenderedSinceLastCheck;
m_iFramesRenderedSinceLastCheck = 0;
m_iTPF = m_iTrianglesRenderedSinceLastCheck / m_iFPS;
m_iTrianglesRenderedSinceLastCheck = 0;
m_iDPF = m_iDrawsSinceLastCheck / m_iFPS;
m_iDrawsSinceLastCheck = 0;
m_fLastCheckTime = fTimeNow;
LOG->Trace( "FPS: %d, TPF: %d, DPF: %d", m_iFPS, m_iTPF, m_iDPF );
}
return S_OK;
}
HRESULT RageDisplay::ShowFrame()
{
if( m_pd3dDevice )
m_pd3dDevice->Present( 0, 0, 0, 0 );
return S_OK;
}
HRESULT RageDisplay::Invalidate()
{
return S_OK;
}
HRESULT RageDisplay::Restore()
{
return S_OK;
}
void RageDisplay::CreateVertexBuffer()
{
HRESULT hr;
if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer(
MAX_NUM_VERTICIES * sizeof(RAGEVERTEX),
D3DUSAGE_WRITEONLY, D3DFVF_RAGEVERTEX,
D3DPOOL_MANAGED, &m_pVB ) ) )
throw RageException( hr, "Vertex Buffer Could Not Be Created" );
}
void RageDisplay::ReleaseVertexBuffer()
{
SAFE_RELEASE( m_pVB );
}
/*
void RageDisplay::AddTriangle( const RAGEVERTEX& v[3] )
{
COPY( &m_vertQueue[m_iNumVerts], v ); // do a big mem copy
for( int i=0; i<3; i++ )
D3DXVec3TransformCoord( &m_vertQueue[m_iNumVerts+i].p, v[i].p, &GetTopMatrix() );
m_iNumVerts+=3;
}
*/
void RageDisplay::AddQuad( const RAGEVERTEX v[4] ) // upper-left, upper-right, lower-left, lower-right
{
AddQuad(
v[0].p, v[0].color, v[0].t,
v[1].p, v[1].color, v[1].t,
v[2].p, v[2].color, v[2].t,
v[3].p, v[3].color, v[3].t );
}
void RageDisplay::AddFan( const RAGEVERTEX v[], int iNumPrimitives )
{
// HACK: This function does not take winding order into account. It will goof if you turn on culling.
for( int i=0; i<iNumPrimitives; i++ )
{
AddTriangle(
v[0+0].p, v[0+0].color, v[0+0].t,
v[i+1].p, v[i+1].color, v[i+1].t,
v[i+2].p, v[i+2].color, v[i+2].t
);
}
}
void RageDisplay::AddStrip( const RAGEVERTEX v[], int iNumPrimitives )
{
// HACK: This function does not take winding order into account. It will goof if you turn on culling.
for( int i=0; i<iNumPrimitives; i++ )
{
AddTriangle(
v[i+0].p, v[i+0].color, v[i+0].t,
v[i+1].p, v[i+1].color, v[i+1].t,
v[i+2].p, v[i+2].color, v[i+2].t
);
}
}
void RageDisplay::AddTriangle(
const D3DXVECTOR3& p0, const D3DCOLOR& c0, const D3DXVECTOR2& t0,
const D3DXVECTOR3& p1, const D3DCOLOR& c1, const D3DXVECTOR2& t1,
const D3DXVECTOR3& p2, const D3DCOLOR& c2, const D3DXVECTOR2& t2 )
{
ASSERT( m_iNumVerts < MAX_NUM_VERTICIES-3 );
// transform the verticies as we copy
D3DXVec3TransformCoord( &m_vertQueue[m_iNumVerts].p, &p0, &GetTopMatrix() );
m_vertQueue[m_iNumVerts].color = c0;
m_vertQueue[m_iNumVerts].t = t0;
m_iNumVerts++;
D3DXVec3TransformCoord( &m_vertQueue[m_iNumVerts].p, &p1, &GetTopMatrix() );
m_vertQueue[m_iNumVerts].color = c1;
m_vertQueue[m_iNumVerts].t = t1;
m_iNumVerts++;
D3DXVec3TransformCoord( &m_vertQueue[m_iNumVerts].p, &p2, &GetTopMatrix() );
m_vertQueue[m_iNumVerts].color = c2;
m_vertQueue[m_iNumVerts].t = t2;
m_iNumVerts++;
if( m_iNumVerts > MAX_NUM_VERTICIES-4 )
FlushQueue();
m_iTrianglesRenderedSinceLastCheck++;
}
void RageDisplay::AddQuad(
const D3DXVECTOR3 &p0, const D3DCOLOR& c0, const D3DXVECTOR2& t0, // upper-left
const D3DXVECTOR3 &p1, const D3DCOLOR& c1, const D3DXVECTOR2& t1, // upper-right
const D3DXVECTOR3 &p2, const D3DCOLOR& c2, const D3DXVECTOR2& t2, // lower-left
const D3DXVECTOR3 &p3, const D3DCOLOR& c3, const D3DXVECTOR2& t3 ) // lower-right
{
// trangles must be in clockwise order in case we ever turn on clipping
AddTriangle(
p0, c0, t0, // upper-left
p2, c2, t2, // lower-left
p3, c3, t3 ); // lower-right
AddTriangle(
p0, c0, t0, // upper-left
p3, c3, t3, // lower-right
p1, c1, t1 ); // upper-right
}
void RageDisplay::FlushQueue()
{
if( m_iNumVerts == 0 )
return;
ASSERT( (m_iNumVerts % 3) == 0 );
m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST, m_iNumVerts/3, m_vertQueue, sizeof(RAGEVERTEX) );
m_iNumVerts = 0;
/*
RAGEVERTEX* v;
m_pVB->Lock( 0, 0, (BYTE**)&v, 0 );
memcpy( v, m_vertQueue, sizeof(RAGEVERTEX)*m_iNumVerts );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, m_iNumVerts/3 );
m_pVB->Unlock();
m_iNumVerts = 0;
*/
m_iDrawsSinceLastCheck++;
}
void RageDisplay::SetViewTransform( const D3DXMATRIX* pMatrix )
{
FlushQueue();
m_pd3dDevice->SetTransform( D3DTS_VIEW, pMatrix );
}
void RageDisplay::SetProjectionTransform( const D3DXMATRIX* pMatrix )
{
FlushQueue();
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, pMatrix );
}
void RageDisplay::GetViewTransform( D3DXMATRIX* pMatrixOut )
{
m_pd3dDevice->GetTransform( D3DTS_VIEW, pMatrixOut );
}
void RageDisplay::GetProjectionTransform( D3DXMATRIX* pMatrixOut )
{
m_pd3dDevice->GetTransform( D3DTS_PROJECTION, pMatrixOut );
}
void RageDisplay::ResetMatrixStack()
{
m_MatrixStack.SetSize( 1, 20 );
D3DXMatrixIdentity( &GetTopMatrix() );
}
void RageDisplay::PushMatrix()
{
m_MatrixStack.Add( GetTopMatrix() );
ASSERT(m_MatrixStack.GetSize()<20); // check for infinite loop
}
void RageDisplay::PopMatrix()
{
m_MatrixStack.RemoveAt( m_MatrixStack.GetSize()-1 );
}
void RageDisplay::Translate( const float x, const float y, const float z )
{
D3DXMATRIX matTemp;
D3DXMatrixTranslation( &matTemp, x, y, z );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
void RageDisplay::TranslateLocal( const float x, const float y, const float z )
{
D3DXMATRIX matTemp;
D3DXMatrixTranslation( &matTemp, x, y, z );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTop * matTemp;
}
void RageDisplay::Scale( const float x, const float y, const float z )
{
D3DXMATRIX matTemp;
D3DXMatrixScaling( &matTemp, x, y, z );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
void RageDisplay::RotateX( const float r )
{
D3DXMATRIX matTemp;
D3DXMatrixRotationX( &matTemp, r );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
void RageDisplay::RotateY( const float r )
{
D3DXMATRIX matTemp;
D3DXMatrixRotationY( &matTemp, r );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
void RageDisplay::RotateZ( const float r )
{
D3DXMATRIX matTemp;
D3DXMatrixRotationZ( &matTemp, r );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
/*
void RageDisplay::RotateYawPitchRoll( const float x, const float y, const float z )
{
D3DXMATRIX matTemp;
D3DXMatrixRotationYawPitchRoll( &matTemp, x, y, z );
D3DXMATRIX& matTop = GetTopMatrix();
matTop = matTemp * matTop;
}
*/
void RageDisplay::SetTexture( RageTexture* pTexture )
{
LPDIRECT3DBASETEXTURE8 pNewD3DTexture = pTexture ? pTexture->GetD3DTexture() : NULL;
LPDIRECT3DBASETEXTURE8 pOldD3DTexture;
m_pd3dDevice->GetTexture( 0, &pOldD3DTexture );
if( pOldD3DTexture != pNewD3DTexture )
FlushQueue();
if(pOldD3DTexture)
pOldD3DTexture->Release();
m_pd3dDevice->SetTexture( 0, pNewD3DTexture );
}
void RageDisplay::SetColorTextureMultDiffuse()
{
DWORD dw0, dw1, dw2;
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLORARG1, &dw0 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLORARG2, &dw1 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLOROP, &dw2 );
if( dw0!=D3DTA_TEXTURE || dw1!=D3DTA_DIFFUSE || dw2!=D3DTOP_MODULATE )
FlushQueue();
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
}
void RageDisplay::SetColorDiffuse()
{
DWORD dw0, dw1, dw2;
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLORARG1, &dw0 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLORARG2, &dw1 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_COLOROP, &dw2 );
if( dw0!=D3DTA_TEXTURE || dw1!=D3DTA_DIFFUSE || dw2!=D3DTOP_SELECTARG2 )
FlushQueue();
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
}
void RageDisplay::SetAlphaTextureMultDiffuse()
{
DWORD dw0, dw1, dw2;
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_ALPHAARG1, &dw0 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_ALPHAARG2, &dw1 );
m_pd3dDevice->GetTextureStageState( 0, D3DTSS_ALPHAOP, &dw2 );
if( dw0!=D3DTA_TEXTURE || dw1!=D3DTA_DIFFUSE || dw2!=D3DTOP_MODULATE )
FlushQueue();
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
}
void RageDisplay::SetBlendModeNormal()
{
DWORD dw0, dw1;
m_pd3dDevice->GetRenderState( D3DRS_SRCBLEND, &dw0 );
m_pd3dDevice->GetRenderState( D3DRS_DESTBLEND, &dw1 );
if( dw0!=D3DBLEND_SRCALPHA || dw1!=D3DBLEND_INVSRCALPHA )
FlushQueue();
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
}
void RageDisplay::SetBlendModeAdd()
{
DWORD dw0, dw1;
m_pd3dDevice->GetRenderState( D3DRS_SRCBLEND, &dw0 );
m_pd3dDevice->GetRenderState( D3DRS_DESTBLEND, &dw1 );
if( dw0!=D3DBLEND_ONE || dw1!=D3DBLEND_ONE )
FlushQueue();
m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
}
void RageDisplay::EnableZBuffer()
{
DWORD dw0, dw1;
m_pd3dDevice->GetRenderState( D3DRS_ZENABLE, &dw0 );
m_pd3dDevice->GetRenderState( D3DRS_ZWRITEENABLE, &dw1 );
if( dw0!=TRUE || dw1!=TRUE )
FlushQueue();
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
}
void RageDisplay::DisableZBuffer()
{
DWORD dw0, dw1;
m_pd3dDevice->GetRenderState( D3DRS_ZENABLE, &dw0 );
m_pd3dDevice->GetRenderState( D3DRS_ZWRITEENABLE, &dw1 );
if( dw0!=FALSE || dw1!=FALSE )
FlushQueue();
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
}