forked from Areteic/dsfix
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SSAO.cpp
126 lines (123 loc) · 4.46 KB
/
SSAO.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "SSAO.h"
#include <string>
#include <sstream>
#include <vector>
using namespace std;
#include "Settings.h"
#include "RenderstateManager.h"
SSAO::SSAO(IDirect3DDevice9 *device, int width, int height, unsigned strength, Type type)
: Effect(device), width(width), height(height) {
//Setup the defines for compiling the effect
vector<D3DXMACRO> defines;
//Setup pixel size macro
stringstream sp;
sp << "float2(1.0 / " << width << ", 1.0 / " << height << ")";
string pixelSizeText = sp.str();
D3DXMACRO pixelSizeMacro = { "PIXEL_SIZE", pixelSizeText.c_str() };
defines.push_back(pixelSizeMacro);
//Setup scale macro
stringstream ss;
ss << Settings::get().getSsaoScale() << ".0";
string scaleText = ss.str();
D3DXMACRO scaleMacro = { "SCALE", scaleText.c_str() };
defines.push_back(scaleMacro);
D3DXMACRO strengthMacros[] = {
{ "SSAO_STRENGTH_LOW", "1" },
{ "SSAO_STRENGTH_MEDIUM", "1" },
{ "SSAO_STRENGTH_HIGH", "1" }
};
defines.push_back(strengthMacros[strength]);
D3DXMACRO null = { NULL, NULL };
defines.push_back(null);
DWORD flags = D3DXFX_NOT_CLONEABLE | D3DXSHADER_OPTIMIZATION_LEVEL3;
//Load effect from file
const char* shader;
switch(type) {
case VSSAO: shader = "dsfix\\VSSAO.fx"; break;
case HBAO: shader = "dsfix\\HBAO.fx"; break;
case SCAO: shader = "dsfix\\SCAO.fx"; break;
case VSSAO2: shader = "dsfix\\VSSAO2.fx"; break;
}
SDLOG(0, "%s load, scale %s, strength %s\n", shader, scaleText.c_str(), strengthMacros[strength].Name);
ID3DXBuffer* errors;
HRESULT hr = D3DXCreateEffectFromFile(device, shader, &defines.front(), NULL, flags, NULL, &effect, &errors);
if(hr != D3D_OK) SDLOG(0, "ERRORS:\n %s\n", errors->GetBufferPointer());
//Create buffers
device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &buffer1Tex, NULL);
buffer1Tex->GetSurfaceLevel(0, &buffer1Surf);
device->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &buffer2Tex, NULL);
buffer2Tex->GetSurfaceLevel(0, &buffer2Surf);
//get handles
depthTexHandle = effect->GetParameterByName(NULL, "depthTex2D");
frameTexHandle = effect->GetParameterByName(NULL, "frameTex2D");
prevPassTexHandle = effect->GetParameterByName(NULL, "prevPassTex2D");
}
SSAO::~SSAO() {
SAFERELEASE(effect);
SAFERELEASE(buffer1Surf);
SAFERELEASE(buffer1Tex);
SAFERELEASE(buffer2Surf);
SAFERELEASE(buffer2Tex);
}
void SSAO::go(IDirect3DTexture9 *frame, IDirect3DTexture9 *depth, IDirect3DSurface9 *dst) {
device->SetVertexDeclaration(vertexDeclaration);
mainSsaoPass(depth, buffer1Surf);
for(size_t i = 0; i<1; ++i) {
hBlurPass(depth, buffer1Tex, buffer2Surf);
vBlurPass(depth, buffer2Tex, buffer1Surf);
}
combinePass(frame, buffer1Tex, dst);
}
void SSAO::mainSsaoPass(IDirect3DTexture9* depth, IDirect3DSurface9* dst) {
device->SetRenderTarget(0, dst);
device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0);
//Setup variables.
effect->SetTexture(depthTexHandle, depth);
//Do it!
UINT passes;
effect->Begin(&passes, 0);
effect->BeginPass(0);
quad(width, height);
effect->EndPass();
effect->End();
}
void SSAO::hBlurPass(IDirect3DTexture9 *depth, IDirect3DTexture9* src, IDirect3DSurface9* dst) {
device->SetRenderTarget(0, dst);
//Setup variables.
effect->SetTexture(prevPassTexHandle, src);
effect->SetTexture(depthTexHandle, depth);
//Do it!
UINT passes;
effect->Begin(&passes, 0);
effect->BeginPass(1);
quad(width, height);
effect->EndPass();
effect->End();
}
void SSAO::vBlurPass(IDirect3DTexture9 *depth, IDirect3DTexture9* src, IDirect3DSurface9* dst) {
device->SetRenderTarget(0, dst);
//Setup variables.
effect->SetTexture(prevPassTexHandle, src);
effect->SetTexture(depthTexHandle, depth);
//Do it!
UINT passes;
effect->Begin(&passes, 0);
effect->BeginPass(2);
quad(width, height);
effect->EndPass();
effect->End();
}
void SSAO::combinePass(IDirect3DTexture9* frame, IDirect3DTexture9* ao, IDirect3DSurface9* dst) {
device->SetRenderTarget(0, dst);
/*device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 255, 0, 255), 1.0f, 0);
Setup variables.*/
effect->SetTexture(prevPassTexHandle, ao);
effect->SetTexture(frameTexHandle, frame);
//Do it!
UINT passes;
effect->Begin(&passes, 0);
effect->BeginPass(3);
quad(width, height);
effect->EndPass();
effect->End();
}