#include "Common.h" #include "D3DBase.h" #include "D3DTexture.h" #include "D3DUtil.h" #include "Globals.h" using namespace D3D; namespace Postprocess { LPDIRECT3DSURFACE9 displayColorBuffer; LPDIRECT3DSURFACE9 displayZStencilBuffer; LPDIRECT3DTEXTURE9 mainColorBufferTexture; LPDIRECT3DSURFACE9 mainColorBuffer; LPDIRECT3DSURFACE9 mainZStencilBuffer; const int numScratch = 2; LPDIRECT3DTEXTURE9 scratch[numScratch]; LPDIRECT3DSURFACE9 scratchSurface[numScratch]; const int mainWidth = 640, mainHeight=480; const int scratchWidth = 256, scratchHeight=256; int displayWidth, displayHeight; bool initialized; int GetWidth() { return initialized ? mainWidth : displayWidth; } int GetHeight() { return initialized ? mainHeight : displayHeight; } void CreateStuff() { mainColorBufferTexture = D3D::CreateRenderTarget(mainWidth,mainHeight); mainColorBufferTexture->GetSurfaceLevel(0,&mainColorBuffer); mainZStencilBuffer = D3D::CreateDepthStencilSurface(mainWidth,mainHeight); for (int i=0; iGetSurfaceLevel(0,&(scratchSurface[i])); } initialized=true; } void DestroyStuff() { SAFE_RELEASE(mainColorBuffer); SAFE_RELEASE(mainColorBufferTexture); SAFE_RELEASE(mainZStencilBuffer); for (int i=0; iGetRenderTarget(0,&displayColorBuffer); dev->GetDepthStencilSurface(&displayZStencilBuffer); D3DSURFACE_DESC desc; displayColorBuffer->GetDesc(&desc); displayWidth = desc.Width; displayHeight = desc.Height; if (g_Config.iPostprocessEffect) CreateStuff(); } void Cleanup() { DestroyStuff(); SAFE_RELEASE(displayColorBuffer); SAFE_RELEASE(displayZStencilBuffer); } void BeginFrame() { if (g_Config.iPostprocessEffect) { if (!initialized) CreateStuff(); dev->SetRenderTarget(0,mainColorBuffer); dev->SetDepthStencilSurface(mainZStencilBuffer); dev->SetRenderState(D3DRS_ZENABLE,TRUE); dev->Clear(0,0,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,0,1,0); } else { if (initialized) { dev->SetRenderTarget(0,displayColorBuffer); dev->SetDepthStencilSurface(displayZStencilBuffer); DestroyStuff(); } dev->SetRenderState(D3DRS_ZENABLE,TRUE); } } int filterKernel[8] = {0x40,0x80,0xc0,0xFF,0xFF,0xc0,0x80,0x40}; //goodlooking almostgaussian //int filterKernel[8] = {0xFF,0xc0,0x80,0x40,0x40,0x80,0xc0,0xFF,}; //crazy filter void NightGlow(bool intense, bool original) { dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SUBTRACT); dev->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE); dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE); dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); dev->SetDepthStencilSurface(0); dev->SetTexture(0,mainColorBufferTexture); dev->SetRenderTarget(0,scratchSurface[0]); dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_CLAMP); dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_CLAMP); dev->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR); dev->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR); dev->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_LINEAR); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); POINT pt; GetCursorPos(&pt); //dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,1.0f); #define QOFF(xoff,yoff,col) quad2d(-0.0f,-0.0f,scratchWidth-0.0f,scratchHeight-0.0f,col,0+xoff,0+yoff,1+xoff,1+yoff); float f=0.008f; QOFF(0,0,0xa0a0a0a0); dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); dev->SetTexture(0,scratch[0]); dev->SetRenderTarget(0,scratchSurface[1]); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); float yMul = 1.33333333333f; for (int i=0; i<8; i++) { DWORD c=filterKernel[i]/2; c|=c<<8; c|=c<<16; QOFF(0,(i-3.5f) * f * yMul,c); } dev->SetTexture(0,scratch[1]); dev->SetRenderTarget(0,scratchSurface[0]); dev->Clear(0,0,D3DCLEAR_TARGET,0,0,0); for (int i=0; i<8; i++) { DWORD c=filterKernel[i]/(intense?3:2); c|=c<<8; c|=c<<16; QOFF((i-3.5f) * f,0,c); } dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); if (intense) { dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_ONE); dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_SRCALPHA); } else { dev->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_INVDESTCOLOR); dev->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE); } dev->SetTexture(0,scratch[0]); dev->SetRenderTarget(0,mainColorBuffer); quad2d(0,0,(float)mainWidth,(float)mainHeight,original?0xCFFFFFFF:0xFFFFFFFF,0,0,1,1); dev->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE); dev->SetSamplerState(0,D3DSAMP_ADDRESSU,D3DTADDRESS_WRAP); dev->SetSamplerState(0,D3DSAMP_ADDRESSV,D3DTADDRESS_WRAP); //dev->SetSamplerState(0,D3DSAMP_MIPMAPLODBIAS,0); } const char **GetPostprocessingNames() { static const char *names[] = { "None", "Night Glow 1", "Night Glow 2", "Night Glow 3", 0, }; return names; } void FinalizeFrame() { if (initialized) { dev->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE); dev->SetRenderState(D3DRS_ZENABLE,FALSE); dev->SetRenderState(D3DRS_FOGENABLE,FALSE); dev->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE); dev->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE); dev->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE); dev->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); dev->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE); dev->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2); switch(g_Config.iPostprocessEffect) { case 1: NightGlow(true,true); case 2: NightGlow(false,true); break; case 3: NightGlow(false,false); break; } dev->SetRenderTarget(0,displayColorBuffer); dev->SetDepthStencilSurface(displayZStencilBuffer); dev->SetTexture(0,mainColorBufferTexture); quad2d(0, 0, (float)displayWidth, (float)displayHeight, 0xFFFFFFFF); } } }