Nux

Merge lp:~unity-team/nux/linear-sample-blur into lp:nux

Proposed by Nicolas d'Offay
Status: Merged
Approved by: Nicolas d'Offay
Approved revision: 725
Merged at revision: 751
Proposed branch: lp:~unity-team/nux/linear-sample-blur
Merge into: lp:nux
Diff against target: 551 lines (+465/-5)
3 files modified
NuxGraphics/GraphicsEngine.cpp (+42/-0)
NuxGraphics/GraphicsEngine.h (+26/-0)
NuxGraphics/RenderingPipeGLSL.cpp (+397/-5)
To merge this branch: bzr merge lp:~unity-team/nux/linear-sample-blur
Reviewer Review Type Date Requested Status
Nicolas d'Offay (community) Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+144099@code.launchpad.net

Commit message

Added linear sample gaussian blur shader which halves the loop count of our vertical and horizontal blur drastically improving performance.

To post a comment you must log in.
Revision history for this message
Nicolas d'Offay (nicolas-doffay) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NuxGraphics/GraphicsEngine.cpp'
2--- NuxGraphics/GraphicsEngine.cpp 2012-11-28 15:16:41 +0000
3+++ NuxGraphics/GraphicsEngine.cpp 2013-01-21 12:52:20 +0000
4@@ -1335,6 +1335,48 @@
5 SetViewport(0, 0, width, height);
6 Push2DWindow(width, height);
7 }
8+
9+ /*! Description - This function calculates position offsets for our gaussian weight values to utilise the GPU bilinear sampling
10+ * which gets neighbouring pixel's data in just one sample. This serves to halve the loop for both vertical and
11+ * horizontal blur shaders.
12+ * Params - First two parameters are the weight and weight offsets which are passed as uniforms to our shader.
13+ * our sigma dictates how strong our blur will be.
14+ * Return - We return our loop count which is a #define in our vertical and horizontal shaders.
15+ */
16+ int GraphicsEngine::LinearSampleGaussianWeights(std::vector<float>& weights, std::vector<float>& offsets,
17+ float sigma)
18+ {
19+ //Calculate our support which is used as our loop count.
20+ int support = int(sigma * 3.0f);
21+
22+ weights.push_back(exp(-(0*0)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma));
23+
24+ float total = weights.back();
25+
26+ //Our first weight has an offset of 0.
27+ offsets.push_back(0);
28+
29+ for (int i = 1; i <= support; i++)
30+ {
31+ float w1 = exp(-(i*i)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);
32+ float w2 = exp(-((i+1)*(i+1))/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma);
33+
34+ weights.push_back(w1 + w2);
35+ total += 2.0f * weights[i];
36+
37+ //Calculate our offset to utilise our GPU's bilinear sampling capability. By sampling in between texel we get the data of
38+ //neighbouring pixels with only one sample.
39+ offsets.push_back((i * w1 + (i + 1) * w2) / weights[i]);
40+ }
41+
42+ //Normalise our weights.
43+ for (int i = 0; i < support; i++)
44+ {
45+ weights[i] /= total;
46+ }
47+
48+ return support;
49+ }
50
51 void GraphicsEngine::GaussianWeights(float **weights, float sigma, unsigned int num_tap)
52 {
53
54=== modified file 'NuxGraphics/GraphicsEngine.h'
55--- NuxGraphics/GraphicsEngine.h 2012-11-12 20:59:56 +0000
56+++ NuxGraphics/GraphicsEngine.h 2013-01-21 12:52:20 +0000
57@@ -434,6 +434,8 @@
58 void QRP_GLSL_VerticalGauss (int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f);
59 void QRP_GLSL_HorizontalHQGauss(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f);
60 void QRP_GLSL_VerticalHQGauss (int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f);
61+ void QRP_GLSL_HorizontalLSGauss(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f);
62+ void QRP_GLSL_VerticalLSGauss (int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, float sigma = 1.0f);
63 void QRP_GLSL_ColorMatrix (int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, const Color& c0, Matrix4 color_matrix, Vector4 offset);
64
65 /*!
66@@ -450,6 +452,13 @@
67 ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform,
68 const Color& c0,
69 float sigma = 1.0f, int num_pass = 1);
70+
71+ ObjectPtr<IOpenGLBaseTexture> QRP_GLSL_GetLSBlurTexture(
72+ int x, int y,
73+ int buffer_width, int buffer_height,
74+ ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform,
75+ const Color& c0,
76+ float sigma = 1.0f, int num_pass = 1);
77
78 ObjectPtr<IOpenGLBaseTexture> QRP_GLSL_GetAlphaTexture(
79 ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform,
80@@ -480,6 +489,12 @@
81 int buffer_width, int buffer_height,
82 FxStructure* fx_structure, TexCoordXForm& texxform,
83 const Color& c0, float sigma = 1.0f, int num_pass = 1);
84+
85+ void QRP_GLSL_GetLSBlurFx(
86+ int x, int y,
87+ int buffer_width, int buffer_height,
88+ FxStructure *fx_structure, TexCoordXForm &texxform,
89+ const Color& c0, float sigma = 1.0f, int num_pass = 1);
90
91 void QRP_GLSL_DisturbedTexture(
92 int x, int y, int width, int height,
93@@ -842,6 +857,9 @@
94
95 //! Helper function to compute a Gaussian filter weights
96 void GaussianWeights(float **weights, float sigma, unsigned int num_tap);
97+
98+ int LinearSampleGaussianWeights(std::vector<float>& weights, std::vector<float>& offsets,
99+ float sigma);
100
101 //! Helper function to set an fbo
102 void SetFrameBufferHelper(
103@@ -1009,6 +1027,14 @@
104 void InitSLVerticalHQGaussFilter(int sigma);
105 //! Gauss vertical filter.
106 ObjectPtr<IOpenGLShaderProgram> _vertical_hq_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA];
107+
108+ void InitSLHorizontalLSGaussFilter(int k);
109+ //! Gauss horizontal filter.
110+ ObjectPtr<IOpenGLShaderProgram> _horizontal_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA];
111+
112+ void InitSLVerticalLSGaussFilter(int k);
113+ //! Gauss vertical filter.
114+ ObjectPtr<IOpenGLShaderProgram> _vertical_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA];
115
116 void InitSLColorMatrixFilter();
117 //! Color matrix filter.
118
119=== modified file 'NuxGraphics/RenderingPipeGLSL.cpp'
120--- NuxGraphics/RenderingPipeGLSL.cpp 2012-11-12 20:59:56 +0000
121+++ NuxGraphics/RenderingPipeGLSL.cpp 2013-01-21 12:52:20 +0000
122@@ -629,6 +629,118 @@
123 CHECKGL(glBindAttribLocation(_vertical_hq_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "AVertex"));
124 _vertical_hq_gauss_filter_prog[k-1]->Link();
125 }
126+
127+ void GraphicsEngine::InitSLHorizontalLSGaussFilter(int k)
128+ {
129+ if (_horizontal_ls_gauss_filter_prog[k-1].IsValid())
130+ {
131+ // Shader program already compiled
132+ return;
133+ }
134+
135+ ObjectPtr<IOpenGLVertexShader> vs = _graphics_display.m_DeviceFactory->CreateVertexShader();
136+ ObjectPtr<IOpenGLPixelShader> ps = _graphics_display.m_DeviceFactory->CreatePixelShader();
137+
138+ std::string vs_string = NUX_VERTEX_SHADER_HEADER
139+ "uniform mat4 view_projection_matrix; \n\
140+ attribute vec4 vertex; \n\
141+ attribute vec4 tex_coord; \n\
142+ varying vec4 v_tex_coord; \n\
143+ void main() \n\
144+ { \n\
145+ v_tex_coord = tex_coord; \n\
146+ gl_Position = view_projection_matrix * vertex; \n\
147+ }";
148+
149+ std::string ps_string = NUX_FRAGMENT_SHADER_HEADER
150+ "varying vec4 v_tex_coord; \n\
151+ uniform sampler2D tex_object; \n\
152+ uniform vec2 tex_size; \n\
153+ #define NUM_SAMPLES %d \n\
154+ uniform float weights[NUM_SAMPLES]; \n\
155+ uniform float offsets[NUM_SAMPLES]; \n\
156+ void main() \n\
157+ { \n\
158+ vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0];\n\
159+ for (int i = 1; i < NUM_SAMPLES; i++) \n\
160+ { \n\
161+ acc += texture2D(tex_object, (v_tex_coord.st+(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i]; \n\
162+ acc += texture2D(tex_object, (v_tex_coord.st-(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i]; \n\
163+ } \n\
164+ gl_FragColor = vec4(acc, 1.0); \n\
165+ }";
166+
167+ int l = ps_string.length();
168+ char* shader_prog = new char[l+10];
169+ sprintf(shader_prog, ps_string.c_str(), k);
170+
171+ _horizontal_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram();
172+ vs->SetShaderCode(vs_string.c_str());
173+ ps->SetShaderCode(shader_prog);
174+ delete[] shader_prog;
175+
176+ _horizontal_ls_gauss_filter_prog[k-1]->ClearShaderObjects();
177+ _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(vs);
178+ _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(ps);
179+ CHECKGL(glBindAttribLocation(_horizontal_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex"));
180+ _horizontal_ls_gauss_filter_prog[k-1]->Link();
181+ }
182+
183+ void GraphicsEngine::InitSLVerticalLSGaussFilter(int k)
184+ {
185+ if (_vertical_ls_gauss_filter_prog[k-1].IsValid())
186+ {
187+ // Shader program already compiled
188+ return;
189+ }
190+
191+ ObjectPtr<IOpenGLVertexShader> vs = _graphics_display.m_DeviceFactory->CreateVertexShader();
192+ ObjectPtr<IOpenGLPixelShader> ps = _graphics_display.m_DeviceFactory->CreatePixelShader();
193+
194+ std::string vs_string = NUX_VERTEX_SHADER_HEADER
195+ "uniform mat4 view_projection_matrix; \n\
196+ attribute vec4 vertex; \n\
197+ attribute vec4 tex_coord; \n\
198+ varying vec4 v_tex_coord; \n\
199+ void main() \n\
200+ { \n\
201+ v_tex_coord = tex_coord; \n\
202+ gl_Position = view_projection_matrix * vertex; \n\
203+ }";
204+
205+ std::string ps_string = NUX_FRAGMENT_SHADER_HEADER
206+ "varying vec4 v_tex_coord; \n\
207+ uniform sampler2D tex_object; \n\
208+ uniform vec2 tex_size; \n\
209+ #define NUM_SAMPLES %d \n\
210+ uniform float weights[NUM_SAMPLES]; \n\
211+ uniform float offsets[NUM_SAMPLES]; \n\
212+ void main() \n\
213+ { \n\
214+ vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0]; \n\
215+ for (int i = 1; i < NUM_SAMPLES; i++) \n\
216+ { \n\
217+ acc += texture2D(tex_object, (v_tex_coord.st+(vec2(0.0, offsets[i])/tex_size))).rgb*weights[i]; \n\
218+ acc += texture2D(tex_object, (v_tex_coord.st-(vec2(0.0, offsets[i])/tex_size))).rgb*weights[i]; \n\
219+ } \n\
220+ gl_FragColor = vec4(acc, 1.0); \n\
221+ }";
222+
223+ int l = ps_string.length();
224+ char* shader_prog = new char[l+10];
225+ sprintf(shader_prog, ps_string.c_str(), k);
226+
227+ _vertical_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram();
228+ vs->SetShaderCode(vs_string.c_str());
229+ ps->SetShaderCode(shader_prog);
230+ delete[] shader_prog;
231+
232+ _vertical_ls_gauss_filter_prog[k-1]->ClearShaderObjects();
233+ _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(vs);
234+ _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(ps);
235+ CHECKGL(glBindAttribLocation(_vertical_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex"));
236+ _vertical_ls_gauss_filter_prog[k-1]->Link();
237+ }
238
239 void GraphicsEngine::InitSLColorMatrixFilter()
240 {
241@@ -1982,6 +2094,155 @@
242
243 ShaderProg->End();
244 }
245+
246+ void GraphicsEngine::QRP_GLSL_HorizontalLSGauss(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma)
247+ {
248+ std::vector<float> weights(0);
249+ std::vector<float> offsets(0);
250+
251+ int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma);
252+
253+ if (_horizontal_ls_gauss_filter_prog[num_samples-1].IsValid() == false)
254+ {
255+ InitSLHorizontalLSGaussFilter(num_samples);
256+ }
257+
258+ m_quad_tex_stats++;
259+ QRP_Compute_Texture_Coord(width, height, device_texture, texxform0);
260+ float fx = x, fy = y;
261+ float vtx_buffer[] =
262+ {
263+ fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0,
264+ fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0,
265+ fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0,
266+ fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0,
267+ };
268+
269+ ObjectPtr<IOpenGLShaderProgram> shader_prog;
270+
271+ if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType))
272+ {
273+ return;
274+ }
275+
276+ shader_prog = _horizontal_ls_gauss_filter_prog[num_samples-1];
277+
278+ CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
279+ CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
280+ shader_prog->Begin();
281+
282+ int tex_object_location = shader_prog->GetUniformLocationARB("tex_object");
283+ int weights_location = shader_prog->GetUniformLocationARB("weights");
284+ int offsets_location = shader_prog->GetUniformLocationARB("offsets");
285+ int tex_size_location = shader_prog->GetUniformLocationARB("tex_size");
286+ int vertex_location = shader_prog->GetAttributeLocation("vertex");
287+ int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord");
288+
289+ SetTexture(GL_TEXTURE0, device_texture);
290+ CHECKGL(glUniform1iARB(tex_object_location, 0));
291+
292+ CHECKGL(glUniform1fv(weights_location, weights.size(), &weights[0]));
293+ CHECKGL(glUniform1fv(offsets_location, offsets.size(), &offsets[0]));
294+
295+ CHECKGL(glUniform2fARB(tex_size_location, width, height));
296+
297+ int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix");
298+ Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix();
299+ shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m));
300+
301+ CHECKGL(glEnableVertexAttribArrayARB(vertex_location));
302+ CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer));
303+
304+ if (tex_coord_location != -1)
305+ {
306+ CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location));
307+ CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4));
308+ }
309+
310+ CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
311+
312+ CHECKGL(glDisableVertexAttribArrayARB(vertex_location));
313+
314+ if (tex_coord_location != -1)
315+ CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location));
316+
317+ shader_prog->End();
318+ }
319+
320+ void GraphicsEngine::QRP_GLSL_VerticalLSGauss(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform0, const Color & /* c0 */, float sigma)
321+ {
322+ std::vector<float> weights(0);
323+ std::vector<float> offsets(0);
324+
325+ int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma);
326+
327+ if (_vertical_ls_gauss_filter_prog[num_samples-1].IsValid() == false)
328+ {
329+ InitSLVerticalLSGaussFilter(num_samples);
330+ }
331+
332+ m_quad_tex_stats++;
333+ QRP_Compute_Texture_Coord(width, height, device_texture, texxform0);
334+ float fx = x, fy = y;
335+ float vtx_buffer[] =
336+ {
337+ fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0,
338+ fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0,
339+ fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0,
340+ fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0,
341+ };
342+
343+ ObjectPtr<IOpenGLShaderProgram> shader_prog;
344+
345+ if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType))
346+ {
347+ return;
348+ }
349+
350+ shader_prog = _vertical_ls_gauss_filter_prog[num_samples-1];
351+
352+ CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0));
353+ CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0));
354+ shader_prog->Begin();
355+
356+ int tex_object_location = shader_prog->GetUniformLocationARB("tex_object");
357+ int weights_location = shader_prog->GetUniformLocationARB("weights");
358+ int offsets_location = shader_prog->GetUniformLocationARB("offsets");
359+ int tex_size_location = shader_prog->GetUniformLocationARB("tex_size");
360+ int vertex_location = shader_prog->GetAttributeLocation("vertex");
361+ int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord");
362+
363+ SetTexture(GL_TEXTURE0, device_texture);
364+
365+ CHECKGL(glUniform1iARB(tex_object_location, 0));
366+
367+ CHECKGL(glUniform1fv(weights_location, weights.size(), &weights[0]));
368+ CHECKGL(glUniform1fv(offsets_location, offsets.size(), &offsets[0]));
369+
370+ CHECKGL(glUniform2fARB(tex_size_location, width, height));
371+
372+ int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix");
373+ Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix();
374+ shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m));
375+
376+ CHECKGL(glEnableVertexAttribArrayARB(vertex_location));
377+ CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer));
378+
379+ if (tex_coord_location != -1)
380+ {
381+ CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location));
382+ CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4));
383+ }
384+
385+ CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4));
386+
387+ CHECKGL(glDisableVertexAttribArrayARB(vertex_location));
388+
389+ if (tex_coord_location != -1)
390+ CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location));
391+
392+ shader_prog->End();
393+ }
394
395 void GraphicsEngine::QRP_GLSL_ColorMatrix(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform0,
396 const Color &c0,
397@@ -2133,6 +2394,72 @@
398
399 return _offscreen_color_rt0;
400 }
401+
402+ ObjectPtr<IOpenGLBaseTexture> GraphicsEngine::QRP_GLSL_GetLSBlurTexture(
403+ int x, int y,
404+ int buffer_width, int buffer_height,
405+ ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform,
406+ const Color& c0,
407+ float sigma, int num_pass)
408+ {
409+ int quad_width = device_texture->GetWidth();
410+ int quad_height = device_texture->GetHeight();
411+
412+ num_pass = Clamp<int> (num_pass, 1, 50);
413+
414+ ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject();
415+ int previous_width = 0;
416+ int previous_height = 0;
417+ if (prevFBO.IsValid())
418+ {
419+ previous_width = prevFBO->GetWidth();
420+ previous_height = prevFBO->GetHeight();
421+ }
422+ else
423+ {
424+ previous_width = _graphics_display.GetWindowWidth();
425+ previous_height = _graphics_display.GetWindowHeight();
426+ }
427+
428+ CHECKGL(glClearColor(0, 0, 0, 0));
429+ _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP);
430+ _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST);
431+ _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP);
432+ _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST);
433+
434+ SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height);
435+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
436+
437+ QRP_GLSL_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White);
438+
439+ TexCoordXForm texxform1;
440+ for (int i = 0; i < num_pass; i++)
441+ {
442+ SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height);
443+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
444+ QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0, sigma);
445+
446+ SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height);
447+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
448+ QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0, sigma);
449+ }
450+
451+ _offscreen_fbo->Deactivate();
452+
453+ if (prevFBO.IsValid())
454+ {
455+ prevFBO->Activate(true);
456+ SetViewport(0, 0, previous_width, previous_height);
457+ SetOrthographicProjectionMatrix(previous_width, previous_height);
458+ }
459+ else
460+ {
461+ SetViewport(0, 0, previous_width, previous_height);
462+ SetOrthographicProjectionMatrix(previous_width, previous_height);
463+ }
464+
465+ return _offscreen_color_rt0;
466+ }
467
468 ObjectPtr<IOpenGLBaseTexture> GraphicsEngine::QRP_GLSL_GetPower(
469 ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform, const Color &c0, const Vector4 &exponent)
470@@ -2469,11 +2796,76 @@
471 {
472 SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height);
473 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
474- QRP_GLSL_HorizontalHQGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma);
475-
476- SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height);
477- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
478- QRP_GLSL_VerticalHQGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma);
479+ QRP_GLSL_HorizontalGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma);
480+
481+ SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height);
482+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
483+ QRP_GLSL_VerticalGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma);
484+ }
485+
486+ _offscreen_fbo->Deactivate();
487+
488+ if (prevFBO.IsValid())
489+ {
490+ prevFBO->Activate(true);
491+ SetViewport(0, 0, previous_width, previous_height);
492+ SetOrthographicProjectionMatrix(previous_width, previous_height);
493+ }
494+ else
495+ {
496+ SetViewport(0, 0, previous_width, previous_height);
497+ SetOrthographicProjectionMatrix(previous_width, previous_height);
498+ }
499+ }
500+
501+ void GraphicsEngine::QRP_GLSL_GetLSBlurFx(
502+ int x, int y,
503+ int buffer_width, int buffer_height,
504+ FxStructure *fx_structure, TexCoordXForm &texxform,
505+ const Color& c0, float sigma, int num_pass)
506+ {
507+ int quad_width = fx_structure->src_texture->GetWidth();
508+ int quad_height = fx_structure->src_texture->GetHeight();
509+
510+ num_pass = Clamp<int> (num_pass, 1, 50);
511+
512+ ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject();
513+ int previous_width = 0;
514+ int previous_height = 0;
515+ if (prevFBO.IsValid())
516+ {
517+ previous_width = prevFBO->GetWidth();
518+ previous_height = prevFBO->GetHeight();
519+ }
520+ else
521+ {
522+ previous_width = _graphics_display.GetWindowWidth();
523+ previous_height = _graphics_display.GetWindowHeight();
524+ }
525+
526+ CHECKGL(glClearColor(0, 0, 0, 0));
527+ fx_structure->src_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP);
528+ fx_structure->src_texture->SetFiltering(GL_NEAREST, GL_NEAREST);
529+ fx_structure->dst_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP);
530+ fx_structure->dst_texture->SetFiltering(GL_NEAREST, GL_NEAREST);
531+ fx_structure->temp_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP);
532+ fx_structure->temp_texture->SetFiltering(GL_NEAREST, GL_NEAREST);
533+
534+ SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height);
535+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
536+
537+ QRP_GLSL_1Tex(x, y, quad_width, quad_height, fx_structure->src_texture, texxform, color::White);
538+
539+ TexCoordXForm texxform1;
540+ for (int i = 0; i < num_pass; i++)
541+ {
542+ SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height);
543+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
544+ QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma);
545+
546+ SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height);
547+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
548+ QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma);
549 }
550
551 _offscreen_fbo->Deactivate();

Subscribers

People subscribed via source and target branches