1 | #include "SsaoShader.h"
|
---|
2 | #include "FrameBufferObject.h"
|
---|
3 | #include "RenderState.h"
|
---|
4 | #include "SampleGenerator.h"
|
---|
5 |
|
---|
6 |
|
---|
7 | using namespace std;
|
---|
8 |
|
---|
9 | GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
|
---|
10 |
|
---|
11 | namespace CHCDemoEngine
|
---|
12 | {
|
---|
13 |
|
---|
14 | static CGprogram sCgSsaoProgram = NULL;
|
---|
15 |
|
---|
16 | static CGparameter sColorsTexParam;
|
---|
17 | static CGparameter sPositionsTexParam;
|
---|
18 | static CGparameter sNormalsTexParam;
|
---|
19 | static CGparameter sOldModelViewProjMatrixParam;
|
---|
20 | static CGparameter sMaxDepthParam;
|
---|
21 | static CGparameter sSamplesParam;
|
---|
22 | static CGparameter sOldTexParam;
|
---|
23 | static CGparameter sNoiseTexParam;
|
---|
24 | static CGparameter sNoiseMultiplierParam;
|
---|
25 | static CGparameter sExpFactorParam;
|
---|
26 |
|
---|
27 |
|
---|
28 | #define NUM_SAMPLES 16
|
---|
29 |
|
---|
30 | // ssao random spherical samples
|
---|
31 | static Sample2 samples[NUM_SAMPLES];
|
---|
32 |
|
---|
33 |
|
---|
34 | static void PrintGLerror(char *msg)
|
---|
35 | {
|
---|
36 | GLenum errCode;
|
---|
37 | const GLubyte *errStr;
|
---|
38 |
|
---|
39 | if ((errCode = glGetError()) != GL_NO_ERROR)
|
---|
40 | {
|
---|
41 | errStr = gluErrorString(errCode);
|
---|
42 | fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
|
---|
43 | }
|
---|
44 | }
|
---|
45 |
|
---|
46 |
|
---|
47 | /** Generate poisson disc distributed sample points on the unit disc
|
---|
48 | */
|
---|
49 | static void GenerateSamples()
|
---|
50 | {
|
---|
51 | static PoissonDiscSampleGenerator poisson(NUM_SAMPLES, 1.0f);
|
---|
52 | poisson.Generate((Sample2 *)samples);
|
---|
53 | }
|
---|
54 |
|
---|
55 |
|
---|
56 | SsaoShader::SsaoShader(int w, int h, float expFactor, float scaleFactor):
|
---|
57 | mWidth(w), mHeight(h), mExpFactor(expFactor), mScaleFactor(scaleFactor)
|
---|
58 | {}
|
---|
59 |
|
---|
60 |
|
---|
61 | void SsaoShader::Init(CGcontext context)
|
---|
62 | {
|
---|
63 |
|
---|
64 | ///////////////
|
---|
65 |
|
---|
66 | sCgSsaoProgram =
|
---|
67 | cgCreateProgramFromFile(context,
|
---|
68 | CG_SOURCE,
|
---|
69 | "src/shaders/deferred.cg",
|
---|
70 | RenderState::sCgFragmentProfile,
|
---|
71 | "main_ssao",
|
---|
72 | NULL);
|
---|
73 |
|
---|
74 | if (sCgSsaoProgram != NULL)
|
---|
75 | {
|
---|
76 | cgGLLoadProgram(sCgSsaoProgram);
|
---|
77 |
|
---|
78 | // we need size of texture for scaling
|
---|
79 | sPositionsTexParam = cgGetNamedParameter(sCgSsaoProgram, "positions");
|
---|
80 | sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors");
|
---|
81 | sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals");
|
---|
82 | sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
|
---|
83 | sNoiseMultiplierParam = cgGetNamedParameter(sCgSsaoProgram, "noiseMultiplier");
|
---|
84 | sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
|
---|
85 | sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
|
---|
86 | sExpFactorParam = cgGetNamedParameter(sCgSsaoProgram, "expFactor");
|
---|
87 |
|
---|
88 | sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
|
---|
89 | sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex");
|
---|
90 |
|
---|
91 | // generate samples for ssao kernel
|
---|
92 | GenerateSamples();
|
---|
93 | cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples);
|
---|
94 | }
|
---|
95 | else
|
---|
96 | cerr << "ssao program failed to load" << endl;
|
---|
97 |
|
---|
98 | PrintGLerror("init");
|
---|
99 | }
|
---|
100 |
|
---|
101 |
|
---|
102 | void SsaoShader::Render(FrameBufferObject *fbo, FrameBufferObject *fbo2)
|
---|
103 | {
|
---|
104 | FirstPass(fbo, fbo2);
|
---|
105 | SecondPass(fbo, fbo2);
|
---|
106 | }
|
---|
107 |
|
---|
108 |
|
---|
109 | void SsaoShader::FirstPass(FrameBufferObject *fbo, FrameBufferObject *fbo2)
|
---|
110 | {
|
---|
111 | GLuint positionsTex = fbo->GetColorBuffer(0)->GetTexture();
|
---|
112 | GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
|
---|
113 | GLuint normalsTex = fbo->GetColorBuffer(0)->GetTexture();
|
---|
114 |
|
---|
115 | glPushAttrib(GL_VIEWPORT_BIT);
|
---|
116 | glViewport(0, 0, mWidth, mHeight);
|
---|
117 |
|
---|
118 | glDrawBuffers(1, mrt);
|
---|
119 |
|
---|
120 | glDisable(GL_ALPHA_TEST);
|
---|
121 | glDisable(GL_TEXTURE_2D);
|
---|
122 | glDisable(GL_LIGHTING);
|
---|
123 |
|
---|
124 | glMatrixMode(GL_PROJECTION);
|
---|
125 | glPushMatrix();
|
---|
126 | glLoadIdentity();
|
---|
127 |
|
---|
128 | glMatrixMode(GL_MODELVIEW);
|
---|
129 | glPushMatrix();
|
---|
130 | glLoadIdentity();
|
---|
131 |
|
---|
132 | const float offs = 0.5f;
|
---|
133 |
|
---|
134 | glOrtho(-offs, offs, -offs, offs, 0, 1);
|
---|
135 |
|
---|
136 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
---|
137 |
|
---|
138 | cgGLEnableProfile(RenderState::sCgFragmentProfile);
|
---|
139 |
|
---|
140 | cgGLBindProgram(sCgSsaoProgram);
|
---|
141 |
|
---|
142 | cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
|
---|
143 | cgGLEnableTextureParameter(sPositionsTexParam);
|
---|
144 |
|
---|
145 | cgGLSetTextureParameter(sColorsTexParam, colorsTex);
|
---|
146 | cgGLEnableTextureParameter(sColorsTexParam);
|
---|
147 |
|
---|
148 | cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
|
---|
149 | cgGLEnableTextureParameter(sNormalsTexParam);
|
---|
150 |
|
---|
151 | cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
|
---|
152 | cgGLEnableTextureParameter(sNoiseTexParam);
|
---|
153 |
|
---|
154 | cgGLSetTextureParameter(sOldTexParam, oldTex);
|
---|
155 | cgGLEnableTextureParameter(sOldTexParam);
|
---|
156 |
|
---|
157 | cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
|
---|
158 |
|
---|
159 | cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
|
---|
160 | cgGLSetParameter1f(sExpFactorParam, mExpFactor);
|
---|
161 |
|
---|
162 |
|
---|
163 | GenerateSamples();
|
---|
164 | cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples);
|
---|
165 |
|
---|
166 | Vector3 tl, tr, bl, br;
|
---|
167 | ComputeViewVectors(tl, tr, bl, br);
|
---|
168 |
|
---|
169 | glColor3f(1.0f, 1.0f, 1.0f);
|
---|
170 |
|
---|
171 | glBegin(GL_QUADS);
|
---|
172 |
|
---|
173 | // note: slightly larger texture hides ambient occlusion error on border but costs resolution
|
---|
174 | //float offs2 = 0.55f;
|
---|
175 | float offs2 = 0.5f;
|
---|
176 |
|
---|
177 | glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
|
---|
178 | glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
|
---|
179 | glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( offs2, offs2, -0.5f);
|
---|
180 | glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-offs2, offs2, -0.5f);
|
---|
181 |
|
---|
182 | glEnd();
|
---|
183 |
|
---|
184 | cgGLDisableTextureParameter(sColorsTexParamSsao);
|
---|
185 | cgGLDisableTextureParameter(sPositionsTexParamSsao);
|
---|
186 | cgGLDisableTextureParameter(sNormalsTexParamSsao);
|
---|
187 | cgGLDisableTextureParameter(sNoiseTexParamSsao);
|
---|
188 | cgGLDisableTextureParameter(sOldTexParamSsao);
|
---|
189 |
|
---|
190 | cgGLDisableProfile(RenderState::sCgFragmentProfile);
|
---|
191 |
|
---|
192 | glEnable(GL_LIGHTING);
|
---|
193 | glDisable(GL_TEXTURE_2D);
|
---|
194 |
|
---|
195 | glMatrixMode(GL_PROJECTION);
|
---|
196 | glPopMatrix();
|
---|
197 |
|
---|
198 | glMatrixMode(GL_MODELVIEW);
|
---|
199 | glPopMatrix();
|
---|
200 |
|
---|
201 | glPopAttrib();
|
---|
202 |
|
---|
203 | PrintGLerror("displaytexture");
|
---|
204 |
|
---|
205 | glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
---|
206 |
|
---|
207 |
|
---|
208 | PrintGLerror("ssao first pass");
|
---|
209 | }
|
---|
210 |
|
---|
211 |
|
---|
212 | void SsaoShader::SecondPass(FrameBufferObject *fbo, FrameBufferObject *fbo2)
|
---|
213 | {
|
---|
214 | glEnable(GL_TEXTURE_2D);
|
---|
215 |
|
---|
216 | glBindTexture(GL_TEXTURE_2D, fbo2->GetColorBuffer(0)->GetTexture());
|
---|
217 |
|
---|
218 | glDisable(GL_LIGHTING);
|
---|
219 |
|
---|
220 | glMatrixMode(GL_PROJECTION);
|
---|
221 | glPushMatrix();
|
---|
222 | glLoadIdentity();
|
---|
223 |
|
---|
224 | glMatrixMode(GL_MODELVIEW);
|
---|
225 | glPushMatrix();
|
---|
226 | glLoadIdentity();
|
---|
227 |
|
---|
228 | const float offs = 0.5f;
|
---|
229 | glOrtho(-offs, offs, -offs, offs, 0, 1);
|
---|
230 |
|
---|
231 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
---|
232 |
|
---|
233 | glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
---|
234 | glBegin(GL_QUADS);
|
---|
235 |
|
---|
236 | glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
|
---|
237 | glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
|
---|
238 | glTexCoord2f(1, 1); glVertex3f( offs, offs, -0.5f);
|
---|
239 | glTexCoord2f(0, 1); glVertex3f(-offs, offs, -0.5f);
|
---|
240 |
|
---|
241 | glEnd();
|
---|
242 |
|
---|
243 | glEnable(GL_LIGHTING);
|
---|
244 | glDisable(GL_TEXTURE_2D);
|
---|
245 |
|
---|
246 | glMatrixMode(GL_PROJECTION);
|
---|
247 | glPopMatrix();
|
---|
248 |
|
---|
249 | glMatrixMode(GL_MODELVIEW);
|
---|
250 | glPopMatrix();
|
---|
251 |
|
---|
252 | PrintGLerror("ssao second pass");
|
---|
253 | }
|
---|
254 |
|
---|
255 |
|
---|
256 |
|
---|
257 | } // namespace
|
---|