Merge lp:~unity-team/nux/linear-sample-blur into lp:nux
- linear-sample-blur
- Merge into trunk
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 |
Related bugs: |
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.
Description of the change
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 | 1335 | SetViewport(0, 0, width, height); | 1335 | SetViewport(0, 0, width, height); |
6 | 1336 | Push2DWindow(width, height); | 1336 | Push2DWindow(width, height); |
7 | 1337 | } | 1337 | } |
8 | 1338 | |||
9 | 1339 | /*! Description - This function calculates position offsets for our gaussian weight values to utilise the GPU bilinear sampling | ||
10 | 1340 | * which gets neighbouring pixel's data in just one sample. This serves to halve the loop for both vertical and | ||
11 | 1341 | * horizontal blur shaders. | ||
12 | 1342 | * Params - First two parameters are the weight and weight offsets which are passed as uniforms to our shader. | ||
13 | 1343 | * our sigma dictates how strong our blur will be. | ||
14 | 1344 | * Return - We return our loop count which is a #define in our vertical and horizontal shaders. | ||
15 | 1345 | */ | ||
16 | 1346 | int GraphicsEngine::LinearSampleGaussianWeights(std::vector<float>& weights, std::vector<float>& offsets, | ||
17 | 1347 | float sigma) | ||
18 | 1348 | { | ||
19 | 1349 | //Calculate our support which is used as our loop count. | ||
20 | 1350 | int support = int(sigma * 3.0f); | ||
21 | 1351 | |||
22 | 1352 | weights.push_back(exp(-(0*0)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma)); | ||
23 | 1353 | |||
24 | 1354 | float total = weights.back(); | ||
25 | 1355 | |||
26 | 1356 | //Our first weight has an offset of 0. | ||
27 | 1357 | offsets.push_back(0); | ||
28 | 1358 | |||
29 | 1359 | for (int i = 1; i <= support; i++) | ||
30 | 1360 | { | ||
31 | 1361 | float w1 = exp(-(i*i)/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma); | ||
32 | 1362 | float w2 = exp(-((i+1)*(i+1))/(2*sigma*sigma))/(sqrt(2*constants::pi)*sigma); | ||
33 | 1363 | |||
34 | 1364 | weights.push_back(w1 + w2); | ||
35 | 1365 | total += 2.0f * weights[i]; | ||
36 | 1366 | |||
37 | 1367 | //Calculate our offset to utilise our GPU's bilinear sampling capability. By sampling in between texel we get the data of | ||
38 | 1368 | //neighbouring pixels with only one sample. | ||
39 | 1369 | offsets.push_back((i * w1 + (i + 1) * w2) / weights[i]); | ||
40 | 1370 | } | ||
41 | 1371 | |||
42 | 1372 | //Normalise our weights. | ||
43 | 1373 | for (int i = 0; i < support; i++) | ||
44 | 1374 | { | ||
45 | 1375 | weights[i] /= total; | ||
46 | 1376 | } | ||
47 | 1377 | |||
48 | 1378 | return support; | ||
49 | 1379 | } | ||
50 | 1338 | 1380 | ||
51 | 1339 | void GraphicsEngine::GaussianWeights(float **weights, float sigma, unsigned int num_tap) | 1381 | void GraphicsEngine::GaussianWeights(float **weights, float sigma, unsigned int num_tap) |
52 | 1340 | { | 1382 | { |
53 | 1341 | 1383 | ||
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 | 434 | 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); | 434 | 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 | 435 | 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); | 435 | 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 | 436 | 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); | 436 | 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 | 437 | 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 | 438 | 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 | 437 | 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); | 439 | 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 | 438 | 440 | ||
65 | 439 | /*! | 441 | /*! |
66 | @@ -450,6 +452,13 @@ | |||
67 | 450 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, | 452 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, |
68 | 451 | const Color& c0, | 453 | const Color& c0, |
69 | 452 | float sigma = 1.0f, int num_pass = 1); | 454 | float sigma = 1.0f, int num_pass = 1); |
70 | 455 | |||
71 | 456 | ObjectPtr<IOpenGLBaseTexture> QRP_GLSL_GetLSBlurTexture( | ||
72 | 457 | int x, int y, | ||
73 | 458 | int buffer_width, int buffer_height, | ||
74 | 459 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, | ||
75 | 460 | const Color& c0, | ||
76 | 461 | float sigma = 1.0f, int num_pass = 1); | ||
77 | 453 | 462 | ||
78 | 454 | ObjectPtr<IOpenGLBaseTexture> QRP_GLSL_GetAlphaTexture( | 463 | ObjectPtr<IOpenGLBaseTexture> QRP_GLSL_GetAlphaTexture( |
79 | 455 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, | 464 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm& texxform, |
80 | @@ -480,6 +489,12 @@ | |||
81 | 480 | int buffer_width, int buffer_height, | 489 | int buffer_width, int buffer_height, |
82 | 481 | FxStructure* fx_structure, TexCoordXForm& texxform, | 490 | FxStructure* fx_structure, TexCoordXForm& texxform, |
83 | 482 | const Color& c0, float sigma = 1.0f, int num_pass = 1); | 491 | const Color& c0, float sigma = 1.0f, int num_pass = 1); |
84 | 492 | |||
85 | 493 | void QRP_GLSL_GetLSBlurFx( | ||
86 | 494 | int x, int y, | ||
87 | 495 | int buffer_width, int buffer_height, | ||
88 | 496 | FxStructure *fx_structure, TexCoordXForm &texxform, | ||
89 | 497 | const Color& c0, float sigma = 1.0f, int num_pass = 1); | ||
90 | 483 | 498 | ||
91 | 484 | void QRP_GLSL_DisturbedTexture( | 499 | void QRP_GLSL_DisturbedTexture( |
92 | 485 | int x, int y, int width, int height, | 500 | int x, int y, int width, int height, |
93 | @@ -842,6 +857,9 @@ | |||
94 | 842 | 857 | ||
95 | 843 | //! Helper function to compute a Gaussian filter weights | 858 | //! Helper function to compute a Gaussian filter weights |
96 | 844 | void GaussianWeights(float **weights, float sigma, unsigned int num_tap); | 859 | void GaussianWeights(float **weights, float sigma, unsigned int num_tap); |
97 | 860 | |||
98 | 861 | int LinearSampleGaussianWeights(std::vector<float>& weights, std::vector<float>& offsets, | ||
99 | 862 | float sigma); | ||
100 | 845 | 863 | ||
101 | 846 | //! Helper function to set an fbo | 864 | //! Helper function to set an fbo |
102 | 847 | void SetFrameBufferHelper( | 865 | void SetFrameBufferHelper( |
103 | @@ -1009,6 +1027,14 @@ | |||
104 | 1009 | void InitSLVerticalHQGaussFilter(int sigma); | 1027 | void InitSLVerticalHQGaussFilter(int sigma); |
105 | 1010 | //! Gauss vertical filter. | 1028 | //! Gauss vertical filter. |
106 | 1011 | ObjectPtr<IOpenGLShaderProgram> _vertical_hq_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; | 1029 | ObjectPtr<IOpenGLShaderProgram> _vertical_hq_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; |
107 | 1030 | |||
108 | 1031 | void InitSLHorizontalLSGaussFilter(int k); | ||
109 | 1032 | //! Gauss horizontal filter. | ||
110 | 1033 | ObjectPtr<IOpenGLShaderProgram> _horizontal_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; | ||
111 | 1034 | |||
112 | 1035 | void InitSLVerticalLSGaussFilter(int k); | ||
113 | 1036 | //! Gauss vertical filter. | ||
114 | 1037 | ObjectPtr<IOpenGLShaderProgram> _vertical_ls_gauss_filter_prog[NUX_MAX_GAUSSIAN_SIGMA]; | ||
115 | 1012 | 1038 | ||
116 | 1013 | void InitSLColorMatrixFilter(); | 1039 | void InitSLColorMatrixFilter(); |
117 | 1014 | //! Color matrix filter. | 1040 | //! Color matrix filter. |
118 | 1015 | 1041 | ||
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 | 629 | CHECKGL(glBindAttribLocation(_vertical_hq_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "AVertex")); | 629 | CHECKGL(glBindAttribLocation(_vertical_hq_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "AVertex")); |
124 | 630 | _vertical_hq_gauss_filter_prog[k-1]->Link(); | 630 | _vertical_hq_gauss_filter_prog[k-1]->Link(); |
125 | 631 | } | 631 | } |
126 | 632 | |||
127 | 633 | void GraphicsEngine::InitSLHorizontalLSGaussFilter(int k) | ||
128 | 634 | { | ||
129 | 635 | if (_horizontal_ls_gauss_filter_prog[k-1].IsValid()) | ||
130 | 636 | { | ||
131 | 637 | // Shader program already compiled | ||
132 | 638 | return; | ||
133 | 639 | } | ||
134 | 640 | |||
135 | 641 | ObjectPtr<IOpenGLVertexShader> vs = _graphics_display.m_DeviceFactory->CreateVertexShader(); | ||
136 | 642 | ObjectPtr<IOpenGLPixelShader> ps = _graphics_display.m_DeviceFactory->CreatePixelShader(); | ||
137 | 643 | |||
138 | 644 | std::string vs_string = NUX_VERTEX_SHADER_HEADER | ||
139 | 645 | "uniform mat4 view_projection_matrix; \n\ | ||
140 | 646 | attribute vec4 vertex; \n\ | ||
141 | 647 | attribute vec4 tex_coord; \n\ | ||
142 | 648 | varying vec4 v_tex_coord; \n\ | ||
143 | 649 | void main() \n\ | ||
144 | 650 | { \n\ | ||
145 | 651 | v_tex_coord = tex_coord; \n\ | ||
146 | 652 | gl_Position = view_projection_matrix * vertex; \n\ | ||
147 | 653 | }"; | ||
148 | 654 | |||
149 | 655 | std::string ps_string = NUX_FRAGMENT_SHADER_HEADER | ||
150 | 656 | "varying vec4 v_tex_coord; \n\ | ||
151 | 657 | uniform sampler2D tex_object; \n\ | ||
152 | 658 | uniform vec2 tex_size; \n\ | ||
153 | 659 | #define NUM_SAMPLES %d \n\ | ||
154 | 660 | uniform float weights[NUM_SAMPLES]; \n\ | ||
155 | 661 | uniform float offsets[NUM_SAMPLES]; \n\ | ||
156 | 662 | void main() \n\ | ||
157 | 663 | { \n\ | ||
158 | 664 | vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0];\n\ | ||
159 | 665 | for (int i = 1; i < NUM_SAMPLES; i++) \n\ | ||
160 | 666 | { \n\ | ||
161 | 667 | acc += texture2D(tex_object, (v_tex_coord.st+(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i]; \n\ | ||
162 | 668 | acc += texture2D(tex_object, (v_tex_coord.st-(vec2(offsets[i], 0.0)/tex_size))).rgb*weights[i]; \n\ | ||
163 | 669 | } \n\ | ||
164 | 670 | gl_FragColor = vec4(acc, 1.0); \n\ | ||
165 | 671 | }"; | ||
166 | 672 | |||
167 | 673 | int l = ps_string.length(); | ||
168 | 674 | char* shader_prog = new char[l+10]; | ||
169 | 675 | sprintf(shader_prog, ps_string.c_str(), k); | ||
170 | 676 | |||
171 | 677 | _horizontal_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); | ||
172 | 678 | vs->SetShaderCode(vs_string.c_str()); | ||
173 | 679 | ps->SetShaderCode(shader_prog); | ||
174 | 680 | delete[] shader_prog; | ||
175 | 681 | |||
176 | 682 | _horizontal_ls_gauss_filter_prog[k-1]->ClearShaderObjects(); | ||
177 | 683 | _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(vs); | ||
178 | 684 | _horizontal_ls_gauss_filter_prog[k-1]->AddShaderObject(ps); | ||
179 | 685 | CHECKGL(glBindAttribLocation(_horizontal_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex")); | ||
180 | 686 | _horizontal_ls_gauss_filter_prog[k-1]->Link(); | ||
181 | 687 | } | ||
182 | 688 | |||
183 | 689 | void GraphicsEngine::InitSLVerticalLSGaussFilter(int k) | ||
184 | 690 | { | ||
185 | 691 | if (_vertical_ls_gauss_filter_prog[k-1].IsValid()) | ||
186 | 692 | { | ||
187 | 693 | // Shader program already compiled | ||
188 | 694 | return; | ||
189 | 695 | } | ||
190 | 696 | |||
191 | 697 | ObjectPtr<IOpenGLVertexShader> vs = _graphics_display.m_DeviceFactory->CreateVertexShader(); | ||
192 | 698 | ObjectPtr<IOpenGLPixelShader> ps = _graphics_display.m_DeviceFactory->CreatePixelShader(); | ||
193 | 699 | |||
194 | 700 | std::string vs_string = NUX_VERTEX_SHADER_HEADER | ||
195 | 701 | "uniform mat4 view_projection_matrix; \n\ | ||
196 | 702 | attribute vec4 vertex; \n\ | ||
197 | 703 | attribute vec4 tex_coord; \n\ | ||
198 | 704 | varying vec4 v_tex_coord; \n\ | ||
199 | 705 | void main() \n\ | ||
200 | 706 | { \n\ | ||
201 | 707 | v_tex_coord = tex_coord; \n\ | ||
202 | 708 | gl_Position = view_projection_matrix * vertex; \n\ | ||
203 | 709 | }"; | ||
204 | 710 | |||
205 | 711 | std::string ps_string = NUX_FRAGMENT_SHADER_HEADER | ||
206 | 712 | "varying vec4 v_tex_coord; \n\ | ||
207 | 713 | uniform sampler2D tex_object; \n\ | ||
208 | 714 | uniform vec2 tex_size; \n\ | ||
209 | 715 | #define NUM_SAMPLES %d \n\ | ||
210 | 716 | uniform float weights[NUM_SAMPLES]; \n\ | ||
211 | 717 | uniform float offsets[NUM_SAMPLES]; \n\ | ||
212 | 718 | void main() \n\ | ||
213 | 719 | { \n\ | ||
214 | 720 | vec3 acc = texture2D(tex_object, v_tex_coord.st).rgb*weights[0]; \n\ | ||
215 | 721 | for (int i = 1; i < NUM_SAMPLES; i++) \n\ | ||
216 | 722 | { \n\ | ||
217 | 723 | acc += texture2D(tex_object, (v_tex_coord.st+(vec2(0.0, offsets[i])/tex_size))).rgb*weights[i]; \n\ | ||
218 | 724 | acc += texture2D(tex_object, (v_tex_coord.st-(vec2(0.0, offsets[i])/tex_size))).rgb*weights[i]; \n\ | ||
219 | 725 | } \n\ | ||
220 | 726 | gl_FragColor = vec4(acc, 1.0); \n\ | ||
221 | 727 | }"; | ||
222 | 728 | |||
223 | 729 | int l = ps_string.length(); | ||
224 | 730 | char* shader_prog = new char[l+10]; | ||
225 | 731 | sprintf(shader_prog, ps_string.c_str(), k); | ||
226 | 732 | |||
227 | 733 | _vertical_ls_gauss_filter_prog[k-1] = _graphics_display.m_DeviceFactory->CreateShaderProgram(); | ||
228 | 734 | vs->SetShaderCode(vs_string.c_str()); | ||
229 | 735 | ps->SetShaderCode(shader_prog); | ||
230 | 736 | delete[] shader_prog; | ||
231 | 737 | |||
232 | 738 | _vertical_ls_gauss_filter_prog[k-1]->ClearShaderObjects(); | ||
233 | 739 | _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(vs); | ||
234 | 740 | _vertical_ls_gauss_filter_prog[k-1]->AddShaderObject(ps); | ||
235 | 741 | CHECKGL(glBindAttribLocation(_vertical_ls_gauss_filter_prog[k-1]->GetOpenGLID(), 0, "vertex")); | ||
236 | 742 | _vertical_ls_gauss_filter_prog[k-1]->Link(); | ||
237 | 743 | } | ||
238 | 632 | 744 | ||
239 | 633 | void GraphicsEngine::InitSLColorMatrixFilter() | 745 | void GraphicsEngine::InitSLColorMatrixFilter() |
240 | 634 | { | 746 | { |
241 | @@ -1982,6 +2094,155 @@ | |||
242 | 1982 | 2094 | ||
243 | 1983 | ShaderProg->End(); | 2095 | ShaderProg->End(); |
244 | 1984 | } | 2096 | } |
245 | 2097 | |||
246 | 2098 | 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 | 2099 | { | ||
248 | 2100 | std::vector<float> weights(0); | ||
249 | 2101 | std::vector<float> offsets(0); | ||
250 | 2102 | |||
251 | 2103 | int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma); | ||
252 | 2104 | |||
253 | 2105 | if (_horizontal_ls_gauss_filter_prog[num_samples-1].IsValid() == false) | ||
254 | 2106 | { | ||
255 | 2107 | InitSLHorizontalLSGaussFilter(num_samples); | ||
256 | 2108 | } | ||
257 | 2109 | |||
258 | 2110 | m_quad_tex_stats++; | ||
259 | 2111 | QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); | ||
260 | 2112 | float fx = x, fy = y; | ||
261 | 2113 | float vtx_buffer[] = | ||
262 | 2114 | { | ||
263 | 2115 | fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, | ||
264 | 2116 | fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, | ||
265 | 2117 | fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, | ||
266 | 2118 | fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, | ||
267 | 2119 | }; | ||
268 | 2120 | |||
269 | 2121 | ObjectPtr<IOpenGLShaderProgram> shader_prog; | ||
270 | 2122 | |||
271 | 2123 | if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) | ||
272 | 2124 | { | ||
273 | 2125 | return; | ||
274 | 2126 | } | ||
275 | 2127 | |||
276 | 2128 | shader_prog = _horizontal_ls_gauss_filter_prog[num_samples-1]; | ||
277 | 2129 | |||
278 | 2130 | CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); | ||
279 | 2131 | CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); | ||
280 | 2132 | shader_prog->Begin(); | ||
281 | 2133 | |||
282 | 2134 | int tex_object_location = shader_prog->GetUniformLocationARB("tex_object"); | ||
283 | 2135 | int weights_location = shader_prog->GetUniformLocationARB("weights"); | ||
284 | 2136 | int offsets_location = shader_prog->GetUniformLocationARB("offsets"); | ||
285 | 2137 | int tex_size_location = shader_prog->GetUniformLocationARB("tex_size"); | ||
286 | 2138 | int vertex_location = shader_prog->GetAttributeLocation("vertex"); | ||
287 | 2139 | int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord"); | ||
288 | 2140 | |||
289 | 2141 | SetTexture(GL_TEXTURE0, device_texture); | ||
290 | 2142 | CHECKGL(glUniform1iARB(tex_object_location, 0)); | ||
291 | 2143 | |||
292 | 2144 | CHECKGL(glUniform1fv(weights_location, weights.size(), &weights[0])); | ||
293 | 2145 | CHECKGL(glUniform1fv(offsets_location, offsets.size(), &offsets[0])); | ||
294 | 2146 | |||
295 | 2147 | CHECKGL(glUniform2fARB(tex_size_location, width, height)); | ||
296 | 2148 | |||
297 | 2149 | int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix"); | ||
298 | 2150 | Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); | ||
299 | 2151 | shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); | ||
300 | 2152 | |||
301 | 2153 | CHECKGL(glEnableVertexAttribArrayARB(vertex_location)); | ||
302 | 2154 | CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); | ||
303 | 2155 | |||
304 | 2156 | if (tex_coord_location != -1) | ||
305 | 2157 | { | ||
306 | 2158 | CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location)); | ||
307 | 2159 | CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); | ||
308 | 2160 | } | ||
309 | 2161 | |||
310 | 2162 | CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); | ||
311 | 2163 | |||
312 | 2164 | CHECKGL(glDisableVertexAttribArrayARB(vertex_location)); | ||
313 | 2165 | |||
314 | 2166 | if (tex_coord_location != -1) | ||
315 | 2167 | CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location)); | ||
316 | 2168 | |||
317 | 2169 | shader_prog->End(); | ||
318 | 2170 | } | ||
319 | 2171 | |||
320 | 2172 | 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 | 2173 | { | ||
322 | 2174 | std::vector<float> weights(0); | ||
323 | 2175 | std::vector<float> offsets(0); | ||
324 | 2176 | |||
325 | 2177 | int num_samples = LinearSampleGaussianWeights(weights, offsets, sigma); | ||
326 | 2178 | |||
327 | 2179 | if (_vertical_ls_gauss_filter_prog[num_samples-1].IsValid() == false) | ||
328 | 2180 | { | ||
329 | 2181 | InitSLVerticalLSGaussFilter(num_samples); | ||
330 | 2182 | } | ||
331 | 2183 | |||
332 | 2184 | m_quad_tex_stats++; | ||
333 | 2185 | QRP_Compute_Texture_Coord(width, height, device_texture, texxform0); | ||
334 | 2186 | float fx = x, fy = y; | ||
335 | 2187 | float vtx_buffer[] = | ||
336 | 2188 | { | ||
337 | 2189 | fx, fy, 0.0f, 1.0f, texxform0.u0, texxform0.v0, 0, 0, | ||
338 | 2190 | fx, fy + height, 0.0f, 1.0f, texxform0.u0, texxform0.v1, 0, 0, | ||
339 | 2191 | fx + width, fy + height, 0.0f, 1.0f, texxform0.u1, texxform0.v1, 0, 0, | ||
340 | 2192 | fx + width, fy, 0.0f, 1.0f, texxform0.u1, texxform0.v0, 0, 0, | ||
341 | 2193 | }; | ||
342 | 2194 | |||
343 | 2195 | ObjectPtr<IOpenGLShaderProgram> shader_prog; | ||
344 | 2196 | |||
345 | 2197 | if (!device_texture->Type().IsDerivedFromType(IOpenGLTexture2D::StaticObjectType)) | ||
346 | 2198 | { | ||
347 | 2199 | return; | ||
348 | 2200 | } | ||
349 | 2201 | |||
350 | 2202 | shader_prog = _vertical_ls_gauss_filter_prog[num_samples-1]; | ||
351 | 2203 | |||
352 | 2204 | CHECKGL(glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)); | ||
353 | 2205 | CHECKGL(glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)); | ||
354 | 2206 | shader_prog->Begin(); | ||
355 | 2207 | |||
356 | 2208 | int tex_object_location = shader_prog->GetUniformLocationARB("tex_object"); | ||
357 | 2209 | int weights_location = shader_prog->GetUniformLocationARB("weights"); | ||
358 | 2210 | int offsets_location = shader_prog->GetUniformLocationARB("offsets"); | ||
359 | 2211 | int tex_size_location = shader_prog->GetUniformLocationARB("tex_size"); | ||
360 | 2212 | int vertex_location = shader_prog->GetAttributeLocation("vertex"); | ||
361 | 2213 | int tex_coord_location = shader_prog->GetAttributeLocation("tex_coord"); | ||
362 | 2214 | |||
363 | 2215 | SetTexture(GL_TEXTURE0, device_texture); | ||
364 | 2216 | |||
365 | 2217 | CHECKGL(glUniform1iARB(tex_object_location, 0)); | ||
366 | 2218 | |||
367 | 2219 | CHECKGL(glUniform1fv(weights_location, weights.size(), &weights[0])); | ||
368 | 2220 | CHECKGL(glUniform1fv(offsets_location, offsets.size(), &offsets[0])); | ||
369 | 2221 | |||
370 | 2222 | CHECKGL(glUniform2fARB(tex_size_location, width, height)); | ||
371 | 2223 | |||
372 | 2224 | int VPMatrixLocation = shader_prog->GetUniformLocationARB("view_projection_matrix"); | ||
373 | 2225 | Matrix4 MVPMatrix = GetOpenGLModelViewProjectionMatrix(); | ||
374 | 2226 | shader_prog->SetUniformLocMatrix4fv((GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m)); | ||
375 | 2227 | |||
376 | 2228 | CHECKGL(glEnableVertexAttribArrayARB(vertex_location)); | ||
377 | 2229 | CHECKGL(glVertexAttribPointerARB((GLuint) vertex_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer)); | ||
378 | 2230 | |||
379 | 2231 | if (tex_coord_location != -1) | ||
380 | 2232 | { | ||
381 | 2233 | CHECKGL(glEnableVertexAttribArrayARB(tex_coord_location)); | ||
382 | 2234 | CHECKGL(glVertexAttribPointerARB((GLuint) tex_coord_location, 4, GL_FLOAT, GL_FALSE, 32, vtx_buffer + 4)); | ||
383 | 2235 | } | ||
384 | 2236 | |||
385 | 2237 | CHECKGL(glDrawArrays(GL_TRIANGLE_FAN, 0, 4)); | ||
386 | 2238 | |||
387 | 2239 | CHECKGL(glDisableVertexAttribArrayARB(vertex_location)); | ||
388 | 2240 | |||
389 | 2241 | if (tex_coord_location != -1) | ||
390 | 2242 | CHECKGL(glDisableVertexAttribArrayARB(tex_coord_location)); | ||
391 | 2243 | |||
392 | 2244 | shader_prog->End(); | ||
393 | 2245 | } | ||
394 | 1985 | 2246 | ||
395 | 1986 | void GraphicsEngine::QRP_GLSL_ColorMatrix(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform0, | 2247 | void GraphicsEngine::QRP_GLSL_ColorMatrix(int x, int y, int width, int height, ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform0, |
396 | 1987 | const Color &c0, | 2248 | const Color &c0, |
397 | @@ -2133,6 +2394,72 @@ | |||
398 | 2133 | 2394 | ||
399 | 2134 | return _offscreen_color_rt0; | 2395 | return _offscreen_color_rt0; |
400 | 2135 | } | 2396 | } |
401 | 2397 | |||
402 | 2398 | ObjectPtr<IOpenGLBaseTexture> GraphicsEngine::QRP_GLSL_GetLSBlurTexture( | ||
403 | 2399 | int x, int y, | ||
404 | 2400 | int buffer_width, int buffer_height, | ||
405 | 2401 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform, | ||
406 | 2402 | const Color& c0, | ||
407 | 2403 | float sigma, int num_pass) | ||
408 | 2404 | { | ||
409 | 2405 | int quad_width = device_texture->GetWidth(); | ||
410 | 2406 | int quad_height = device_texture->GetHeight(); | ||
411 | 2407 | |||
412 | 2408 | num_pass = Clamp<int> (num_pass, 1, 50); | ||
413 | 2409 | |||
414 | 2410 | ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); | ||
415 | 2411 | int previous_width = 0; | ||
416 | 2412 | int previous_height = 0; | ||
417 | 2413 | if (prevFBO.IsValid()) | ||
418 | 2414 | { | ||
419 | 2415 | previous_width = prevFBO->GetWidth(); | ||
420 | 2416 | previous_height = prevFBO->GetHeight(); | ||
421 | 2417 | } | ||
422 | 2418 | else | ||
423 | 2419 | { | ||
424 | 2420 | previous_width = _graphics_display.GetWindowWidth(); | ||
425 | 2421 | previous_height = _graphics_display.GetWindowHeight(); | ||
426 | 2422 | } | ||
427 | 2423 | |||
428 | 2424 | CHECKGL(glClearColor(0, 0, 0, 0)); | ||
429 | 2425 | _offscreen_color_rt0->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); | ||
430 | 2426 | _offscreen_color_rt0->SetFiltering(GL_NEAREST, GL_NEAREST); | ||
431 | 2427 | _offscreen_color_rt1->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); | ||
432 | 2428 | _offscreen_color_rt1->SetFiltering(GL_NEAREST, GL_NEAREST); | ||
433 | 2429 | |||
434 | 2430 | SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); | ||
435 | 2431 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
436 | 2432 | |||
437 | 2433 | QRP_GLSL_1Tex(x, y, quad_width, quad_height, device_texture, texxform, color::White); | ||
438 | 2434 | |||
439 | 2435 | TexCoordXForm texxform1; | ||
440 | 2436 | for (int i = 0; i < num_pass; i++) | ||
441 | 2437 | { | ||
442 | 2438 | SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt1, _offscreen_depth_rt1, buffer_width, buffer_height); | ||
443 | 2439 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
444 | 2440 | QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt0, texxform1, c0, sigma); | ||
445 | 2441 | |||
446 | 2442 | SetFrameBufferHelper(_offscreen_fbo, _offscreen_color_rt0, _offscreen_depth_rt0, buffer_width, buffer_height); | ||
447 | 2443 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
448 | 2444 | QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, _offscreen_color_rt1, texxform1, c0, sigma); | ||
449 | 2445 | } | ||
450 | 2446 | |||
451 | 2447 | _offscreen_fbo->Deactivate(); | ||
452 | 2448 | |||
453 | 2449 | if (prevFBO.IsValid()) | ||
454 | 2450 | { | ||
455 | 2451 | prevFBO->Activate(true); | ||
456 | 2452 | SetViewport(0, 0, previous_width, previous_height); | ||
457 | 2453 | SetOrthographicProjectionMatrix(previous_width, previous_height); | ||
458 | 2454 | } | ||
459 | 2455 | else | ||
460 | 2456 | { | ||
461 | 2457 | SetViewport(0, 0, previous_width, previous_height); | ||
462 | 2458 | SetOrthographicProjectionMatrix(previous_width, previous_height); | ||
463 | 2459 | } | ||
464 | 2460 | |||
465 | 2461 | return _offscreen_color_rt0; | ||
466 | 2462 | } | ||
467 | 2136 | 2463 | ||
468 | 2137 | ObjectPtr<IOpenGLBaseTexture> GraphicsEngine::QRP_GLSL_GetPower( | 2464 | ObjectPtr<IOpenGLBaseTexture> GraphicsEngine::QRP_GLSL_GetPower( |
469 | 2138 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform, const Color &c0, const Vector4 &exponent) | 2465 | ObjectPtr<IOpenGLBaseTexture> device_texture, TexCoordXForm &texxform, const Color &c0, const Vector4 &exponent) |
470 | @@ -2469,11 +2796,76 @@ | |||
471 | 2469 | { | 2796 | { |
472 | 2470 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); | 2797 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); |
473 | 2471 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 2798 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
479 | 2472 | QRP_GLSL_HorizontalHQGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma); | 2799 | QRP_GLSL_HorizontalGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma); |
480 | 2473 | 2800 | ||
481 | 2474 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); | 2801 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); |
482 | 2475 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | 2802 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
483 | 2476 | QRP_GLSL_VerticalHQGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma); | 2803 | QRP_GLSL_VerticalGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma); |
484 | 2804 | } | ||
485 | 2805 | |||
486 | 2806 | _offscreen_fbo->Deactivate(); | ||
487 | 2807 | |||
488 | 2808 | if (prevFBO.IsValid()) | ||
489 | 2809 | { | ||
490 | 2810 | prevFBO->Activate(true); | ||
491 | 2811 | SetViewport(0, 0, previous_width, previous_height); | ||
492 | 2812 | SetOrthographicProjectionMatrix(previous_width, previous_height); | ||
493 | 2813 | } | ||
494 | 2814 | else | ||
495 | 2815 | { | ||
496 | 2816 | SetViewport(0, 0, previous_width, previous_height); | ||
497 | 2817 | SetOrthographicProjectionMatrix(previous_width, previous_height); | ||
498 | 2818 | } | ||
499 | 2819 | } | ||
500 | 2820 | |||
501 | 2821 | void GraphicsEngine::QRP_GLSL_GetLSBlurFx( | ||
502 | 2822 | int x, int y, | ||
503 | 2823 | int buffer_width, int buffer_height, | ||
504 | 2824 | FxStructure *fx_structure, TexCoordXForm &texxform, | ||
505 | 2825 | const Color& c0, float sigma, int num_pass) | ||
506 | 2826 | { | ||
507 | 2827 | int quad_width = fx_structure->src_texture->GetWidth(); | ||
508 | 2828 | int quad_height = fx_structure->src_texture->GetHeight(); | ||
509 | 2829 | |||
510 | 2830 | num_pass = Clamp<int> (num_pass, 1, 50); | ||
511 | 2831 | |||
512 | 2832 | ObjectPtr<IOpenGLFrameBufferObject> prevFBO = GetGraphicsDisplay()->GetGpuDevice()->GetCurrentFrameBufferObject(); | ||
513 | 2833 | int previous_width = 0; | ||
514 | 2834 | int previous_height = 0; | ||
515 | 2835 | if (prevFBO.IsValid()) | ||
516 | 2836 | { | ||
517 | 2837 | previous_width = prevFBO->GetWidth(); | ||
518 | 2838 | previous_height = prevFBO->GetHeight(); | ||
519 | 2839 | } | ||
520 | 2840 | else | ||
521 | 2841 | { | ||
522 | 2842 | previous_width = _graphics_display.GetWindowWidth(); | ||
523 | 2843 | previous_height = _graphics_display.GetWindowHeight(); | ||
524 | 2844 | } | ||
525 | 2845 | |||
526 | 2846 | CHECKGL(glClearColor(0, 0, 0, 0)); | ||
527 | 2847 | fx_structure->src_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); | ||
528 | 2848 | fx_structure->src_texture->SetFiltering(GL_NEAREST, GL_NEAREST); | ||
529 | 2849 | fx_structure->dst_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); | ||
530 | 2850 | fx_structure->dst_texture->SetFiltering(GL_NEAREST, GL_NEAREST); | ||
531 | 2851 | fx_structure->temp_texture->SetWrap(GL_CLAMP, GL_CLAMP, GL_CLAMP); | ||
532 | 2852 | fx_structure->temp_texture->SetFiltering(GL_NEAREST, GL_NEAREST); | ||
533 | 2853 | |||
534 | 2854 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); | ||
535 | 2855 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
536 | 2856 | |||
537 | 2857 | QRP_GLSL_1Tex(x, y, quad_width, quad_height, fx_structure->src_texture, texxform, color::White); | ||
538 | 2858 | |||
539 | 2859 | TexCoordXForm texxform1; | ||
540 | 2860 | for (int i = 0; i < num_pass; i++) | ||
541 | 2861 | { | ||
542 | 2862 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->temp_texture, _offscreen_depth_rt1, buffer_width, buffer_height); | ||
543 | 2863 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
544 | 2864 | QRP_GLSL_HorizontalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->dst_texture, texxform1, c0, sigma); | ||
545 | 2865 | |||
546 | 2866 | SetFrameBufferHelper(_offscreen_fbo, fx_structure->dst_texture, _offscreen_depth_rt0, buffer_width, buffer_height); | ||
547 | 2867 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
548 | 2868 | QRP_GLSL_VerticalLSGauss(0, 0, buffer_width, buffer_height, fx_structure->temp_texture, texxform1, c0, sigma); | ||
549 | 2477 | } | 2869 | } |
550 | 2478 | 2870 | ||
551 | 2479 | _offscreen_fbo->Deactivate(); | 2871 | _offscreen_fbo->Deactivate(); |