[Bug or Feature] Override of D3D9 render states
Posted: Sat Aug 02, 2014 22:51
Hi,
Not restoring states caused a lot of artifacts.
I fixed Direct3D9Renderer to restore the state and now it is better.
Maybe someone will find it useful.
Not restoring states caused a lot of artifacts.
I fixed Direct3D9Renderer to restore the state and now it is better.
Maybe someone will find it useful.
Code: Select all
03/08/2014 00:12:54 (Std) ********************************************************************************
03/08/2014 00:12:54 (Std) ---- Version: 0.8.4 (Build: Aug 3 2014 Microsoft Windows MSVC++ Great Scott! 32 bit) ----
03/08/2014 00:12:54 (Std) ---- Renderer module is: CEGUI::Direct3D9Renderer - Official Direct3D 9 based 2nd generation renderer module. ----
03/08/2014 00:12:54 (Std) ---- XML Parser module is: CEGUI::ExpatParser - Official expat based parser module for CEGUI ----
03/08/2014 00:12:54 (Std) ---- Image Codec module is: SILLYImageCodec - Official SILLY based image codec ----
03/08/2014 00:12:54 (Std) ---- Scripting module is: None ----
03/08/2014 00:12:54 (Std) ********************************************************************************
Code: Select all
#define SAVE_D3D_STATE(Flag, What)do{DWORD val = 0; if(SUCCEEDED(dev->Get##What##State(Flag, &val))) What##States[Flag] = val;}while(0)
#define SAVE_D3D_STATE1(Flag, Count, What)do{DWORD val = 0; if(SUCCEEDED(dev->Get##What##State(0, Flag, &val))) What##Count##States[Flag] = val;}while(0)
#define SAVE_D3D_RENDER(Flag) SAVE_D3D_STATE(Flag, Render)
#define SAVE_D3D_SAMPLER1(Flag) SAVE_D3D_STATE1(Flag,0, Sampler)
#define SAVE_D3D_TEXTURESTAGE0(Flag) SAVE_D3D_STATE1(Flag, 0, TextureStage)
#define SAVE_D3D_TEXTURESTAGE1(Flag) SAVE_D3D_STATE1(Flag, 1, TextureStage)
#define RESTORE_STATE(flag, what) do { dev->Set##what##State(flag, what##States[flag]);}while(0)
#define RESTORE_RENDER(flag) RESTORE_STATE(flag, Render)
#define RESTORE_STATE1(flag, count, what) do{dev->Set##what##State(count, flag, what##count##States[flag]);}while(0)
#define RESTORE_SAMPLER0(flag) RESTORE_STATE1(flag, 0, Sampler)
#define RESTORE_TEXTURE0(flag) RESTORE_STATE1(flag, 0, TextureStage)
#define RESTORE_TEXTURE1(flag) RESTORE_STATE1(flag, 1, TextureStage)
struct D3d9DevState
{
typedef std::unordered_map<int, DWORD> option_map;
DWORD FVF;
IDirect3DVertexShader9* vertexShader;
IDirect3DPixelShader9* pixelShader;
option_map RenderStates;
option_map Sampler0States;
option_map TextureStage0States;
option_map TextureStage1States;
D3DMATRIX transform;
LPDIRECT3DDEVICE9 dev;
D3d9DevState(LPDIRECT3DDEVICE9 _dev)
:dev(_dev)
{
// d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
dev->GetFVF(&FVF);
//// no shaders initially
//d_device->SetVertexShader(0);
dev->GetVertexShader(&vertexShader);
//d_device->SetPixelShader(0);
dev->GetPixelShader(&pixelShader);
//// set device states
//d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
SAVE_D3D_RENDER(D3DRS_LIGHTING);
//d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
SAVE_D3D_RENDER(D3DRS_FOGENABLE);
//d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
SAVE_D3D_RENDER(D3DRS_ZENABLE);
//d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
SAVE_D3D_RENDER(D3DRS_ALPHATESTENABLE);
//d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
SAVE_D3D_RENDER(D3DRS_CULLMODE);
//d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
SAVE_D3D_RENDER(D3DRS_FILLMODE);
//d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
SAVE_D3D_RENDER(D3DRS_SCISSORTESTENABLE);
//d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
SAVE_D3D_RENDER(D3DRS_ZWRITEENABLE);
//// setup texture addressing settings
//d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
SAVE_D3D_SAMPLER1(D3DSAMP_ADDRESSU);
//d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
SAVE_D3D_SAMPLER1(D3DSAMP_ADDRESSV);
//// setup colour calculations
//d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLORARG1);
//d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLORARG2);
//d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_COLOROP);
//// setup alpha calculations
//d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAARG1);
//d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAARG2);
//d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
SAVE_D3D_TEXTURESTAGE0(D3DTSS_ALPHAOP);
//// setup filtering
//d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
SAVE_D3D_SAMPLER1(D3DSAMP_MINFILTER);
//d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
SAVE_D3D_SAMPLER1(D3DSAMP_MAGFILTER);
//// disable texture stages we do not need.
//d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
SAVE_D3D_TEXTURESTAGE1(D3DTSS_COLOROP);
//// setup scene alpha blending
//d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
SAVE_D3D_RENDER(D3DRS_ALPHABLENDENABLE);
//// put alpha blend operations into a known state
//setupRenderingBlendMode(BM_NORMAL, true);
//// set view matrix back to identity.
//d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
dev->GetTransform(D3DTS_VIEW, &transform);
}
~D3d9DevState()
{
//d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
dev->SetFVF(FVF);
//// no shaders initially
//d_device->SetVertexShader(0);
dev->SetVertexShader(vertexShader);
//d_device->SetPixelShader(0);
dev->SetPixelShader(pixelShader);
//// set device states
//d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
RESTORE_RENDER(D3DRS_LIGHTING);
//d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
RESTORE_RENDER(D3DRS_FOGENABLE);
//d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
RESTORE_RENDER(D3DRS_ZENABLE);
//d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
RESTORE_RENDER(D3DRS_ALPHATESTENABLE);
//d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
RESTORE_RENDER(D3DRS_CULLMODE);
//d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
RESTORE_RENDER(D3DRS_FILLMODE);
//d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
RESTORE_RENDER(D3DRS_SCISSORTESTENABLE);
//d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
RESTORE_RENDER(D3DRS_ZWRITEENABLE);
//// setup texture addressing settings
//d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
RESTORE_SAMPLER0(D3DSAMP_ADDRESSU);
//d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
RESTORE_SAMPLER0(D3DSAMP_ADDRESSV);
//// setup colour calculations
//d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
RESTORE_TEXTURE0(D3DTSS_COLORARG1);
//d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
RESTORE_TEXTURE0(D3DTSS_COLORARG2);
//d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
RESTORE_TEXTURE0(D3DTSS_COLOROP);
//// setup alpha calculations
//d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
RESTORE_TEXTURE0(D3DTSS_ALPHAARG1);
//d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
RESTORE_TEXTURE0(D3DTSS_ALPHAARG2);
//d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
RESTORE_TEXTURE0(D3DTSS_ALPHAOP);
//// setup filtering
//d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
RESTORE_SAMPLER0(D3DSAMP_MINFILTER);
//d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
RESTORE_SAMPLER0(D3DSAMP_MAGFILTER);
//// disable texture stages we do not need.
//d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
RESTORE_TEXTURE1(D3DTSS_COLOROP);
//// setup scene alpha blending
//d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
//// put alpha blend operations into a known state
//setupRenderingBlendMode(BM_NORMAL, true);
//// set view matrix back to identity.
//d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
dev->SetTransform(D3DTS_VIEW, &transform);
}
};
D3d9DevState* d3dstate = nullptr;
void Direct3D9Renderer::beginRendering()
{
if (!d3dstate)
d3dstate = new D3d9DevState(d_device);
d_device->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1);
// no shaders initially
d_device->SetVertexShader(0);
d_device->SetPixelShader(0);
// set device states
d_device->SetRenderState(D3DRS_LIGHTING, FALSE);
d_device->SetRenderState(D3DRS_FOGENABLE, FALSE);
d_device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
d_device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
d_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d_device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
d_device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
d_device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
// setup texture addressing settings
d_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
d_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
// setup colour calculations
d_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
d_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
d_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// setup alpha calculations
d_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
d_device->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
d_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
// setup filtering
d_device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
d_device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
// disable texture stages we do not need.
d_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
// setup scene alpha blending
d_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
// put alpha blend operations into a known state
setupRenderingBlendMode(BM_NORMAL, true);
// set view matrix back to identity.
d_device->SetTransform(D3DTS_VIEW, &s_identityMatrix);
}
//----------------------------------------------------------------------------//
void Direct3D9Renderer::endRendering()
{
if (d3dstate)
{
delete d3dstate;
d3dstate = nullptr;
}
}