31
31
#ifdef GLES3_ENABLED
32
32
33
33
#include " copy_effects.h"
34
+ #include " ../storage/texture_storage.h"
34
35
35
36
using namespace GLES3 ;
36
37
@@ -133,6 +134,7 @@ void CopyEffects::copy_screen() {
133
134
draw_screen_triangle ();
134
135
}
135
136
137
+ // Intended for efficiently mipmapping textures.
136
138
void CopyEffects::bilinear_blur (GLuint p_source_texture, int p_mipmap_count, const Rect2i &p_region) {
137
139
GLuint framebuffers[2 ];
138
140
glGenFramebuffers (2 , framebuffers);
@@ -158,6 +160,80 @@ void CopyEffects::bilinear_blur(GLuint p_source_texture, int p_mipmap_count, con
158
160
glDeleteFramebuffers (2 , framebuffers);
159
161
}
160
162
163
+ // Intended for approximating a gaussian blur. Used for 2D backbuffer mipmaps. Slightly less efficient than bilinear_blur().
164
+ void CopyEffects::gaussian_blur (GLuint p_source_texture, int p_mipmap_count, const Rect2i &p_region, const Size2i &p_size) {
165
+ GLuint framebuffer;
166
+ glGenFramebuffers (1 , &framebuffer);
167
+ glBindFramebuffer (GL_FRAMEBUFFER, framebuffer);
168
+
169
+ glActiveTexture (GL_TEXTURE0);
170
+ glBindTexture (GL_TEXTURE_2D, p_source_texture);
171
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
172
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
173
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
174
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
175
+
176
+ Size2i base_size = p_size;
177
+
178
+ Rect2i source_region = p_region;
179
+ Rect2i dest_region = p_region;
180
+
181
+ Size2 float_size = Size2 (p_size);
182
+ Rect2 normalized_source_region = Rect2 (p_region);
183
+ normalized_source_region.position = normalized_source_region.position / float_size;
184
+ normalized_source_region.size = normalized_source_region.size / float_size;
185
+ Rect2 normalized_dest_region = Rect2 (p_region);
186
+ for (int i = 1 ; i < p_mipmap_count; i++) {
187
+ dest_region.position .x >>= 1 ;
188
+ dest_region.position .y >>= 1 ;
189
+ dest_region.size .x = MAX (1 , dest_region.size .x >> 1 );
190
+ dest_region.size .y = MAX (1 , dest_region.size .y >> 1 );
191
+ base_size.x >>= 1 ;
192
+ base_size.y >>= 1 ;
193
+
194
+ glBindTexture (GL_TEXTURE_2D, p_source_texture);
195
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, i - 1 );
196
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, i - 1 );
197
+ glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, p_source_texture, i);
198
+ #ifdef DEV_ENABLED
199
+ GLenum status = glCheckFramebufferStatus (GL_FRAMEBUFFER);
200
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
201
+ WARN_PRINT (" Could not bind Gaussian blur framebuffer, status: " + GLES3::TextureStorage::get_singleton ()->get_framebuffer_error (status));
202
+ }
203
+ #endif
204
+
205
+ glViewport (0 , 0 , base_size.x , base_size.y );
206
+
207
+ bool success = copy.shader .version_bind_shader (copy.shader_version , CopyShaderGLES3::MODE_GAUSSIAN_BLUR);
208
+ if (!success) {
209
+ return ;
210
+ }
211
+
212
+ float_size = Size2 (base_size);
213
+ normalized_dest_region.position = Size2 (dest_region.position ) / float_size;
214
+ normalized_dest_region.size = Size2 (dest_region.size ) / float_size;
215
+
216
+ copy.shader .version_set_uniform (CopyShaderGLES3::COPY_SECTION, normalized_dest_region.position .x , normalized_dest_region.position .y , normalized_dest_region.size .x , normalized_dest_region.size .y , copy.shader_version , CopyShaderGLES3::MODE_GAUSSIAN_BLUR);
217
+ copy.shader .version_set_uniform (CopyShaderGLES3::SOURCE_SECTION, normalized_source_region.position .x , normalized_source_region.position .y , normalized_source_region.size .x , normalized_source_region.size .y , copy.shader_version , CopyShaderGLES3::MODE_GAUSSIAN_BLUR);
218
+ copy.shader .version_set_uniform (CopyShaderGLES3::PIXEL_SIZE, 1.0 / float_size.x , 1.0 / float_size.y , copy.shader_version , CopyShaderGLES3::MODE_GAUSSIAN_BLUR);
219
+
220
+ draw_screen_quad ();
221
+
222
+ source_region = dest_region;
223
+ normalized_source_region = normalized_dest_region;
224
+ }
225
+ glBindFramebuffer (GL_FRAMEBUFFER, 0 );
226
+ glDeleteFramebuffers (1 , &framebuffer);
227
+
228
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
229
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
230
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0 );
231
+ glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, p_mipmap_count - 1 );
232
+ glBindTexture (GL_TEXTURE_2D, 0 );
233
+
234
+ glViewport (0 , 0 , p_size.x , p_size.y );
235
+ }
236
+
161
237
void CopyEffects::set_color (const Color &p_color, const Rect2i &p_region) {
162
238
bool success = copy.shader .version_bind_shader (copy.shader_version , CopyShaderGLES3::MODE_SIMPLE_COLOR);
163
239
if (!success) {
0 commit comments