| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							|  |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2006 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is: all of this file. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Antony Riakiotakis. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/gpu/intern/gpu_compositing.c
 | 
					
						
							|  |  |  |  *  \ingroup gpu | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * System that manages framebuffer compositing. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_sys_types.h"
 | 
					
						
							|  |  |  | #include "BLI_rect.h"
 | 
					
						
							|  |  |  | #include "BLI_math.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BLI_rand.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_vec_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							|  |  |  | #include "DNA_gpu_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "GPU_compositing.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | #include "GPU_draw.h"
 | 
					
						
							| 
									
										
										
										
											2015-12-06 21:20:19 +01:00
										 |  |  | #include "GPU_extensions.h"
 | 
					
						
							|  |  |  | #include "GPU_framebuffer.h"
 | 
					
						
							| 
									
										
										
										
											2015-03-20 16:35:26 +01:00
										 |  |  | #include "GPU_glew.h"
 | 
					
						
							| 
									
										
										
										
											2015-12-06 21:20:19 +01:00
										 |  |  | #include "GPU_shader.h"
 | 
					
						
							|  |  |  | #include "GPU_texture.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | #include "GPU_batch.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "MEM_guardedalloc.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const float fullscreencos[4][2] = {{-1.0f, -1.0f}, {1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}}; | 
					
						
							|  |  |  | static const float fullscreenuvs[4][2] = {{0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* shader interfaces (legacy GL 2 style, without uniform buffer objects) */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int ssao_uniform; | 
					
						
							|  |  |  | 	int ssao_color_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | 	int ssao_sample_params_uniform; | 
					
						
							|  |  |  | 	int ssao_concentric_tex; | 
					
						
							|  |  |  | 	int ssao_jitter_uniform; | 
					
						
							|  |  |  | } GPUSSAOShaderInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | } GPUDOFHQPassOneInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int rendertargetdim_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int coc_uniform; | 
					
						
							|  |  |  | 	int select_uniform; | 
					
						
							|  |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | } GPUDOFHQPassTwoInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int far_uniform; | 
					
						
							|  |  |  | 	int near_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | } GPUDOFHQPassThreeInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | } GPUDOFPassOneInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | 	int color_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | } GPUDOFPassTwoInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int near_coc_downsampled; | 
					
						
							|  |  |  | 	int near_coc_blurred; | 
					
						
							|  |  |  | } GPUDOFPassThreeInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int near_coc_downsampled; | 
					
						
							|  |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | } GPUDOFPassFourInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int medium_blurred_uniform; | 
					
						
							|  |  |  | 	int high_blurred_uniform; | 
					
						
							|  |  |  | 	int dof_uniform; | 
					
						
							|  |  |  | 	int invrendertargetdim_uniform; | 
					
						
							|  |  |  | 	int original_uniform; | 
					
						
							|  |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | 	int viewvecs_uniform; | 
					
						
							|  |  |  | } GPUDOFPassFiveInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | typedef struct { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 	int depth_uniform; | 
					
						
							|  |  |  | } GPUDepthResolveInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | struct GPUFX { | 
					
						
							|  |  |  | 	/* we borrow the term gbuffer from deferred rendering however this is just a regular
 | 
					
						
							|  |  |  | 	 * depth/color framebuffer. Could be extended later though */ | 
					
						
							|  |  |  | 	GPUFrameBuffer *gbuffer; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	/* dimensions of the gbuffer */ | 
					
						
							|  |  |  | 	int gbuffer_dim[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	/* texture bound to the first color attachment of the gbuffer */ | 
					
						
							|  |  |  | 	GPUTexture *color_buffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* second texture used for ping-pong compositing */ | 
					
						
							|  |  |  | 	GPUTexture *color_buffer_sec; | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	/* texture bound to the depth attachment of the gbuffer */ | 
					
						
							|  |  |  | 	GPUTexture *depth_buffer; | 
					
						
							|  |  |  | 	GPUTexture *depth_buffer_xray; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* texture used for jittering for various effects */ | 
					
						
							|  |  |  | 	GPUTexture *jitter_buffer; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 	/* all those buffers below have to coexist.
 | 
					
						
							|  |  |  | 	 * Fortunately they are all quarter sized (1/16th of memory) of original framebuffer */ | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	int dof_downsampled_w; | 
					
						
							|  |  |  | 	int dof_downsampled_h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* texture used for near coc and color blurring calculation */ | 
					
						
							|  |  |  | 	GPUTexture *dof_near_coc_buffer; | 
					
						
							|  |  |  | 	/* blurred near coc buffer. */ | 
					
						
							|  |  |  | 	GPUTexture *dof_near_coc_blurred_buffer; | 
					
						
							|  |  |  | 	/* final near coc buffer. */ | 
					
						
							|  |  |  | 	GPUTexture *dof_near_coc_final_buffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* half size blur buffer */ | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	GPUTexture *dof_half_downsampled_near; | 
					
						
							|  |  |  | 	GPUTexture *dof_half_downsampled_far; | 
					
						
							|  |  |  | 	/* high quality dof texture downsamplers. 6 levels means 64 pixels wide - should be enough */ | 
					
						
							|  |  |  | 	GPUTexture *dof_nearfar_coc; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	GPUTexture *dof_near_blur; | 
					
						
							|  |  |  | 	GPUTexture *dof_far_blur; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	/* for high quality we use again a spiral texture with radius adapted */ | 
					
						
							|  |  |  | 	bool dof_high_quality; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* texture used for ssao */ | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	int ssao_sample_count_cache; | 
					
						
							|  |  |  | 	GPUTexture *ssao_spiral_samples_tex; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPUFXSettings settings; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* or-ed flags of enabled effects */ | 
					
						
							|  |  |  | 	int effects; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* number of passes, needed to detect if ping pong buffer allocation is needed */ | 
					
						
							|  |  |  | 	int num_passes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we have a stencil, restore the previous state */ | 
					
						
							|  |  |  | 	bool restore_stencil; | 
					
						
							| 
									
										
										
										
											2015-03-20 15:26:13 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 	Batch *quad_batch; | 
					
						
							|  |  |  | 	Batch *point_batch; | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct GPUStateValues attribs; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | /* concentric mapping, see "A Low Distortion Map Between Disk and Square" and
 | 
					
						
							|  |  |  |  * http://psgraphics.blogspot.nl/2011/01/improved-code-for-concentric-map.html */
 | 
					
						
							|  |  |  | static GPUTexture * create_concentric_sample_texture(int side) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	GPUTexture *tex; | 
					
						
							|  |  |  | 	float midpoint = 0.5f * (side - 1); | 
					
						
							|  |  |  | 	float *texels = (float *)MEM_mallocN(sizeof(float) * 2 * side * side, "concentric_tex"); | 
					
						
							|  |  |  | 	int i, j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < side; i++) { | 
					
						
							|  |  |  | 		for (j = 0; j < side; j++) { | 
					
						
							|  |  |  | 			int index = (i * side + j) * 2; | 
					
						
							|  |  |  | 			float a = 1.0f - i / midpoint; | 
					
						
							|  |  |  | 			float b = 1.0f - j / midpoint; | 
					
						
							|  |  |  | 			float phi, r; | 
					
						
							|  |  |  | 			if (a * a > b * b) { | 
					
						
							|  |  |  | 				r = a; | 
					
						
							|  |  |  | 				phi = (M_PI_4) * (b / a); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			else { | 
					
						
							|  |  |  | 				r = b; | 
					
						
							|  |  |  | 				phi = M_PI_2 - (M_PI_4) * (a / b); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			texels[index] = r * cos(phi); | 
					
						
							|  |  |  | 			texels[index + 1] = r * sin(phi); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 	tex = GPU_texture_create_1D_custom(side * side, 2, GPU_RG16F, (float *)texels, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set parameters */ | 
					
						
							|  |  |  | 	GPU_texture_bind(tex, 0); | 
					
						
							|  |  |  | 	GPU_texture_filter_mode(tex, false); | 
					
						
							|  |  |  | 	GPU_texture_unbind(tex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	MEM_freeN(texels); | 
					
						
							|  |  |  | 	return tex; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | static GPUTexture *create_spiral_sample_texture(int numsaples) | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	GPUTexture *tex; | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | 	float (*texels)[2] = MEM_mallocN(sizeof(float[2]) * numsaples, "concentric_tex"); | 
					
						
							|  |  |  | 	const float numsaples_inv = 1.0f / numsaples; | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | 	/* arbitrary number to ensure we don't get conciding samples every circle */ | 
					
						
							| 
									
										
										
										
											2015-02-25 23:30:50 +01:00
										 |  |  | 	const float spirals = 7.357; | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < numsaples; i++) { | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | 		float r = (i + 0.5f) * numsaples_inv; | 
					
						
							|  |  |  | 		float phi = r * spirals * (float)(2.0 * M_PI); | 
					
						
							|  |  |  | 		texels[i][0] = r * cosf(phi); | 
					
						
							|  |  |  | 		texels[i][1] = r * sinf(phi); | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 	tex = GPU_texture_create_1D_custom(numsaples, 2, GPU_RG16F, (float *)texels, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set parameters */ | 
					
						
							|  |  |  | 	GPU_texture_bind(tex, 0); | 
					
						
							|  |  |  | 	GPU_texture_filter_mode(tex, false); | 
					
						
							|  |  |  | 	GPU_texture_unbind(tex); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-25 23:10:01 +01:00
										 |  |  | 	MEM_freeN(texels); | 
					
						
							|  |  |  | 	return tex; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* generate a new FX compositor */ | 
					
						
							|  |  |  | GPUFX *GPU_fx_compositor_create(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	GPUFX *fx = MEM_callocN(sizeof(GPUFX), "GPUFX compositor"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 	/* Quad buffer */ | 
					
						
							|  |  |  | 	static VertexFormat format = {0}; | 
					
						
							|  |  |  | 	static unsigned int pos, uvs; | 
					
						
							|  |  |  | 	if (format.attrib_ct == 0) { | 
					
						
							|  |  |  | 		pos = add_attrib(&format, "pos", GL_FLOAT, 2, KEEP_FLOAT); | 
					
						
							|  |  |  | 		uvs = add_attrib(&format, "uvs", GL_FLOAT, 2, KEEP_FLOAT); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	VertexBuffer *vbo = VertexBuffer_create_with_format(&format); | 
					
						
							|  |  |  | 	VertexBuffer_allocate_data(vbo, 4); | 
					
						
							|  |  |  | 	for (int i = 0; i < 4; ++i)	{ | 
					
						
							| 
									
										
										
										
											2017-04-04 20:45:23 -04:00
										 |  |  | 		VertexBuffer_set_attrib(vbo, pos, i, fullscreencos[i]); | 
					
						
							|  |  |  | 		VertexBuffer_set_attrib(vbo, uvs, i, fullscreenuvs[i]); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	fx->quad_batch = Batch_create(GL_TRIANGLE_STRIP, vbo, NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Point Buffer */ | 
					
						
							|  |  |  | 	static VertexFormat format_point = {0}; | 
					
						
							|  |  |  | 	static unsigned int dummy_attrib; | 
					
						
							|  |  |  | 	if (format_point.attrib_ct == 0) { | 
					
						
							|  |  |  | 		dummy_attrib = add_attrib(&format_point, "pos", GL_FLOAT, 2, KEEP_FLOAT); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	float dummy[2] = {0.0f, 0.0f}; | 
					
						
							|  |  |  | 	VertexBuffer *vbo_point = VertexBuffer_create_with_format(&format_point); | 
					
						
							|  |  |  | 	VertexBuffer_allocate_data(vbo_point, 1); | 
					
						
							| 
									
										
										
										
											2017-04-04 20:45:23 -04:00
										 |  |  | 	VertexBuffer_set_attrib(vbo_point, dummy_attrib, 0, &dummy); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 	fx->point_batch = Batch_create(GL_POINTS, vbo_point, NULL); | 
					
						
							| 
									
										
										
										
											2015-11-24 02:20:38 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	return fx; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cleanup_fx_dof_buffers(GPUFX *fx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (fx->dof_near_coc_blurred_buffer) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_near_coc_blurred_buffer); | 
					
						
							|  |  |  | 		fx->dof_near_coc_blurred_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (fx->dof_near_coc_buffer) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_near_coc_buffer); | 
					
						
							|  |  |  | 		fx->dof_near_coc_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (fx->dof_near_coc_final_buffer) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_near_coc_final_buffer); | 
					
						
							|  |  |  | 		fx->dof_near_coc_final_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	if (fx->dof_half_downsampled_near) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_half_downsampled_near); | 
					
						
							|  |  |  | 		fx->dof_half_downsampled_near = NULL; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	if (fx->dof_half_downsampled_far) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_half_downsampled_far); | 
					
						
							|  |  |  | 		fx->dof_half_downsampled_far = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (fx->dof_nearfar_coc) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_nearfar_coc); | 
					
						
							|  |  |  | 		fx->dof_nearfar_coc = NULL; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (fx->dof_near_blur) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_near_blur); | 
					
						
							|  |  |  | 		fx->dof_near_blur = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (fx->dof_far_blur) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->dof_far_blur); | 
					
						
							|  |  |  | 		fx->dof_far_blur = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (fx->color_buffer) { | 
					
						
							|  |  |  | 		GPU_framebuffer_texture_detach(fx->color_buffer); | 
					
						
							|  |  |  | 		GPU_texture_free(fx->color_buffer); | 
					
						
							|  |  |  | 		fx->color_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx->color_buffer_sec) { | 
					
						
							|  |  |  | 		GPU_framebuffer_texture_detach(fx->color_buffer_sec); | 
					
						
							|  |  |  | 		GPU_texture_free(fx->color_buffer_sec); | 
					
						
							|  |  |  | 		fx->color_buffer_sec = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx->depth_buffer) { | 
					
						
							|  |  |  | 		GPU_framebuffer_texture_detach(fx->depth_buffer); | 
					
						
							|  |  |  | 		GPU_texture_free(fx->depth_buffer); | 
					
						
							|  |  |  | 		fx->depth_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 	if (fx->depth_buffer_xray) { | 
					
						
							|  |  |  | 		GPU_framebuffer_texture_detach(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 		GPU_texture_free(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 		fx->depth_buffer_xray = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	cleanup_fx_dof_buffers(fx); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	if (fx->ssao_spiral_samples_tex) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->ssao_spiral_samples_tex); | 
					
						
							|  |  |  | 		fx->ssao_spiral_samples_tex = NULL; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx->jitter_buffer && do_fbo) { | 
					
						
							|  |  |  | 		GPU_texture_free(fx->jitter_buffer); | 
					
						
							|  |  |  | 		fx->jitter_buffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx->gbuffer && do_fbo) { | 
					
						
							|  |  |  | 		GPU_framebuffer_free(fx->gbuffer); | 
					
						
							|  |  |  | 		fx->gbuffer = NULL; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* destroy a text compositor */ | 
					
						
							|  |  |  | void GPU_fx_compositor_destroy(GPUFX *fx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cleanup_fx_gl_data(fx, true); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 	Batch_discard_all(fx->quad_batch); | 
					
						
							|  |  |  | 	Batch_discard_all(fx->point_batch); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	MEM_freeN(fx); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static GPUTexture * create_jitter_texture(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 	GPUTexture *tex; | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 	float jitter[64 * 64][2]; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (i = 0; i < 64 * 64; i++) { | 
					
						
							| 
									
										
										
										
											2015-02-27 14:26:34 +11:00
										 |  |  | 		jitter[i][0] = 2.0f * BLI_frand() - 1.0f; | 
					
						
							|  |  |  | 		jitter[i][1] = 2.0f * BLI_frand() - 1.0f; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		normalize_v2(jitter[i]); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 	tex = GPU_texture_create_2D_custom(64, 64, 2, GPU_RG16F, &jitter[0][0], NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Set parameters */ | 
					
						
							|  |  |  | 	GPU_texture_bind(tex, 0); | 
					
						
							|  |  |  | 	GPU_texture_filter_mode(tex, false); | 
					
						
							|  |  |  | 	GPU_texture_wrap_mode(tex, true); | 
					
						
							|  |  |  | 	GPU_texture_unbind(tex); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return tex; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool GPU_fx_compositor_initialize_passes( | 
					
						
							|  |  |  |         GPUFX *fx, const rcti *rect, const rcti *scissor_rect, | 
					
						
							|  |  |  |         const GPUFXSettings *fx_settings) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-16 14:42:36 +01:00
										 |  |  | 	int w = BLI_rcti_size_x(rect), h = BLI_rcti_size_y(rect); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	char err_out[256]; | 
					
						
							|  |  |  | 	int num_passes = 0; | 
					
						
							| 
									
										
										
										
											2015-02-20 17:17:36 +11:00
										 |  |  | 	char fx_flag; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fx->effects = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!fx_settings) { | 
					
						
							|  |  |  | 		cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 17:17:36 +11:00
										 |  |  | 	fx_flag = fx_settings->fx_flag; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	/* disable effects if no options passed for them */ | 
					
						
							|  |  |  | 	if (!fx_settings->dof) { | 
					
						
							|  |  |  | 		fx_flag &= ~GPU_FX_FLAG_DOF; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (!fx_settings->ssao || fx_settings->ssao->samples < 1) { | 
					
						
							|  |  |  | 		fx_flag &= ~GPU_FX_FLAG_SSAO; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!fx_flag) { | 
					
						
							|  |  |  | 		cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-16 14:42:36 +01:00
										 |  |  | 	/* scissor is missing when drawing offscreen, in that case, dimensions match exactly. In opposite case
 | 
					
						
							|  |  |  | 	 * add one to match viewport dimensions */ | 
					
						
							| 
									
										
										
										
											2015-02-18 22:16:04 +01:00
										 |  |  | 	if (scissor_rect) { | 
					
						
							| 
									
										
										
										
											2016-03-05 09:09:05 +11:00
										 |  |  | 		w++; | 
					
						
							|  |  |  | 		h++; | 
					
						
							| 
									
										
										
										
											2015-02-16 14:42:36 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	fx->num_passes = 0; | 
					
						
							|  |  |  | 	/* dof really needs a ping-pong buffer to work */ | 
					
						
							|  |  |  | 	if (fx_flag & GPU_FX_FLAG_DOF) | 
					
						
							|  |  |  | 		num_passes++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx_flag & GPU_FX_FLAG_SSAO) | 
					
						
							|  |  |  | 		num_passes++; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-16 17:04:12 +03:00
										 |  |  | 	if (!fx->gbuffer) { | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		fx->gbuffer = GPU_framebuffer_create(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-16 17:04:12 +03:00
										 |  |  | 		if (!fx->gbuffer) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	/* try creating the jitter texture */ | 
					
						
							|  |  |  | 	if (!fx->jitter_buffer) | 
					
						
							|  |  |  | 		fx->jitter_buffer = create_jitter_texture(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* check if color buffers need recreation */ | 
					
						
							|  |  |  | 	if (!fx->color_buffer || !fx->depth_buffer || w != fx->gbuffer_dim[0] || h != fx->gbuffer_dim[1]) { | 
					
						
							|  |  |  | 		cleanup_fx_gl_data(fx, false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 		if (!(fx->color_buffer = GPU_texture_create_2D(w, h, NULL, err_out))) { | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			printf(".256%s\n", err_out); | 
					
						
							|  |  |  | 			cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!(fx->depth_buffer = GPU_texture_create_depth(w, h, err_out))) { | 
					
						
							|  |  |  | 			printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 			cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx_flag & GPU_FX_FLAG_SSAO) { | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 		if (fx_settings->ssao->samples != fx->ssao_sample_count_cache || !fx->ssao_spiral_samples_tex) { | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			if (fx_settings->ssao->samples < 1) | 
					
						
							|  |  |  | 				fx_settings->ssao->samples = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			fx->ssao_sample_count_cache = fx_settings->ssao->samples; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			if (fx->ssao_spiral_samples_tex) { | 
					
						
							|  |  |  | 				GPU_texture_free(fx->ssao_spiral_samples_tex); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			fx->ssao_spiral_samples_tex = create_spiral_sample_texture(fx_settings->ssao->samples); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 		if (fx->ssao_spiral_samples_tex) { | 
					
						
							|  |  |  | 			GPU_texture_free(fx->ssao_spiral_samples_tex); | 
					
						
							|  |  |  | 			fx->ssao_spiral_samples_tex = NULL; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* create textures for dof effect */ | 
					
						
							|  |  |  | 	if (fx_flag & GPU_FX_FLAG_DOF) { | 
					
						
							| 
									
										
										
										
											2015-03-25 14:43:28 +01:00
										 |  |  | 		bool dof_high_quality = (fx_settings->dof->high_quality != 0) && | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 		                        GPU_geometry_shader_support() && GPU_instanced_drawing_support(); | 
					
						
							| 
									
										
										
										
											2015-03-25 14:43:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* cleanup buffers if quality setting has changed (no need to keep more buffers around than necessary ) */ | 
					
						
							|  |  |  | 		if (dof_high_quality != fx->dof_high_quality) | 
					
						
							|  |  |  | 			cleanup_fx_dof_buffers(fx); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (dof_high_quality) { | 
					
						
							|  |  |  | 			fx->dof_downsampled_w = w / 2; | 
					
						
							|  |  |  | 			fx->dof_downsampled_h = h / 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!fx->dof_half_downsampled_near || !fx->dof_nearfar_coc || !fx->dof_near_blur || | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 			    !fx->dof_far_blur || !fx->dof_half_downsampled_far) | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (!(fx->dof_half_downsampled_near = GPU_texture_create_2D( | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				      fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!(fx->dof_half_downsampled_far = GPU_texture_create_2D( | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				      fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				if (!(fx->dof_nearfar_coc = GPU_texture_create_2D_custom( | 
					
						
							|  |  |  | 				    fx->dof_downsampled_w, fx->dof_downsampled_h, 2, GPU_RG16F, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_nearfar_coc, 0); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->dof_nearfar_coc, false); | 
					
						
							|  |  |  | 				GPU_texture_wrap_mode(fx->dof_nearfar_coc, false); | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_nearfar_coc); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				if (!(fx->dof_near_blur = GPU_texture_create_2D_custom( | 
					
						
							|  |  |  | 				    fx->dof_downsampled_w, fx->dof_downsampled_h, 2, GPU_RGBA16F, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				if (!(fx->dof_far_blur = GPU_texture_create_2D_custom( | 
					
						
							|  |  |  | 				    fx->dof_downsampled_w, fx->dof_downsampled_h, 2, GPU_RGBA16F, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			fx->dof_downsampled_w = w / 4; | 
					
						
							|  |  |  | 			fx->dof_downsampled_h = h / 4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			if (!fx->dof_near_coc_buffer || !fx->dof_near_coc_blurred_buffer || !fx->dof_near_coc_final_buffer) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (!(fx->dof_near_coc_buffer = GPU_texture_create_2D( | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				          fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!(fx->dof_near_coc_blurred_buffer = GPU_texture_create_2D( | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				          fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (!(fx->dof_near_coc_final_buffer = GPU_texture_create_2D( | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				          fx->dof_downsampled_w, fx->dof_downsampled_h, NULL, err_out))) | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				{ | 
					
						
							|  |  |  | 					printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 					cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 					return false; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-25 14:43:28 +01:00
										 |  |  | 		fx->dof_high_quality = dof_high_quality; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* cleanup unnecessary buffers */ | 
					
						
							|  |  |  | 		cleanup_fx_dof_buffers(fx); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we need to pass data between shader stages, allocate an extra color buffer */ | 
					
						
							|  |  |  | 	if (num_passes > 1) { | 
					
						
							| 
									
										
										
										
											2015-03-23 15:29:42 -04:00
										 |  |  | 		if (!fx->color_buffer_sec) { | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 			if (!(fx->color_buffer_sec = GPU_texture_create_2D(w, h, NULL, err_out))) { | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 				printf(".256%s\n", err_out); | 
					
						
							|  |  |  | 				cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (fx->color_buffer_sec) { | 
					
						
							|  |  |  | 			GPU_framebuffer_texture_detach(fx->color_buffer_sec); | 
					
						
							|  |  |  | 			GPU_texture_free(fx->color_buffer_sec); | 
					
						
							|  |  |  | 			fx->color_buffer_sec = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* bind the buffers */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* first depth buffer, because system assumes read/write buffers */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 	GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0); | 
					
						
							|  |  |  | 	GPU_framebuffer_texture_attach(fx->gbuffer, fx->color_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 15:29:42 -04:00
										 |  |  | 	if (!GPU_framebuffer_check_valid(fx->gbuffer, err_out)) | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_texture_bind_as_framebuffer(fx->color_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* enable scissor test. It's needed to ensure sculpting works correctly */ | 
					
						
							|  |  |  | 	if (scissor_rect) { | 
					
						
							|  |  |  | 		int w_sc = BLI_rcti_size_x(scissor_rect) + 1; | 
					
						
							|  |  |  | 		int h_sc = BLI_rcti_size_y(scissor_rect) + 1; | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | 		gpuSaveState(&fx->attribs, GPU_SCISSOR_BIT); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		glEnable(GL_SCISSOR_TEST); | 
					
						
							|  |  |  | 		glScissor(scissor_rect->xmin - rect->xmin, scissor_rect->ymin - rect->ymin, | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 		          w_sc, h_sc); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		fx->restore_stencil = true; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		fx->restore_stencil = false; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fx->effects = fx_flag; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx_settings) | 
					
						
							|  |  |  | 		fx->settings = *fx_settings; | 
					
						
							|  |  |  | 	fx->gbuffer_dim[0] = w; | 
					
						
							|  |  |  | 	fx->gbuffer_dim[1] = h; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	fx->num_passes = num_passes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void gpu_fx_bind_render_target(int *passes_left, GPUFX *fx, struct GPUOffScreen *ofs, GPUTexture *target) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if ((*passes_left)-- == 1) { | 
					
						
							|  |  |  | 		GPU_framebuffer_texture_unbind(fx->gbuffer, NULL); | 
					
						
							|  |  |  | 		if (ofs) { | 
					
						
							|  |  |  | 			GPU_offscreen_bind(ofs, false); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			GPU_framebuffer_restore(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* bind the ping buffer to the color buffer */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 		GPU_framebuffer_texture_attach(fx->gbuffer, target, 0); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | void GPU_fx_compositor_setup_XRay_pass(GPUFX *fx, bool do_xray) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char err_out[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (do_xray) { | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 		if (!fx->depth_buffer_xray && | 
					
						
							|  |  |  | 		    !(fx->depth_buffer_xray = GPU_texture_create_depth(fx->gbuffer_dim[0], fx->gbuffer_dim[1], err_out))) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 			printf("%.256s\n", err_out); | 
					
						
							|  |  |  | 			cleanup_fx_gl_data(fx, true); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		if (fx->depth_buffer_xray) { | 
					
						
							|  |  |  | 			GPU_framebuffer_texture_detach(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 			GPU_texture_free(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 			fx->depth_buffer_xray = NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_framebuffer_texture_detach(fx->depth_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* first depth buffer, because system assumes read/write buffers */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 	GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer_xray, 0); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_fx_compositor_XRay_resolve(GPUFX *fx) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	GPUShader *depth_resolve_shader; | 
					
						
							|  |  |  | 	GPU_framebuffer_texture_detach(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* attach regular framebuffer */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 	GPU_framebuffer_texture_attach(fx->gbuffer, fx->depth_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	/* full screen quad where we will always write to depth buffer */ | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | 	gpuSaveState(&fx->attribs, GPU_DEPTH_BUFFER_BIT | GPU_SCISSOR_BIT); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 	glDepthFunc(GL_ALWAYS); | 
					
						
							|  |  |  | 	/* disable scissor from sculpt if any */ | 
					
						
							|  |  |  | 	glDisable(GL_SCISSOR_TEST); | 
					
						
							|  |  |  | 	/* disable writing to color buffer, it's depth only pass */ | 
					
						
							|  |  |  | 	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	depth_resolve_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_RESOLVE, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (depth_resolve_shader) { | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 		GPUDepthResolveInterface *interface = GPU_fx_shader_get_interface(depth_resolve_shader); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 		/* set up quad buffer */ | 
					
						
							|  |  |  | 		Batch_set_program(fx->quad_batch, GPU_shader_get_program(depth_resolve_shader)); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		GPU_texture_bind(fx->depth_buffer_xray, 0); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 		GPU_texture_compare_mode(fx->depth_buffer_xray, false); | 
					
						
							|  |  |  | 		GPU_texture_filter_mode(fx->depth_buffer_xray, true); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 		GPU_shader_uniform_texture(depth_resolve_shader, interface->depth_uniform, fx->depth_buffer_xray); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* draw */ | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 		Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* disable bindings */ | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 		GPU_texture_compare_mode(fx->depth_buffer_xray, true); | 
					
						
							|  |  |  | 		GPU_texture_filter_mode(fx->depth_buffer_xray, false); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | 		GPU_texture_unbind(fx->depth_buffer_xray); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		GPU_shader_unbind(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | 	gpuRestoreState(&fx->attribs); | 
					
						
							| 
									
										
										
										
											2015-02-17 18:08:28 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | bool GPU_fx_do_composite_pass( | 
					
						
							|  |  |  |         GPUFX *fx, float projmat[4][4], bool is_persp, | 
					
						
							|  |  |  |         struct Scene *scene, struct GPUOffScreen *ofs) | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	GPUTexture *src, *target; | 
					
						
							|  |  |  | 	int numslots = 0; | 
					
						
							|  |  |  | 	float invproj[4][4]; | 
					
						
							|  |  |  | 	int i; | 
					
						
							| 
									
										
										
										
											2015-03-30 14:14:32 +02:00
										 |  |  | 	float dfdyfac[2]; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	/* number of passes left. when there are no more passes, the result is passed to the frambuffer */ | 
					
						
							|  |  |  | 	int passes_left = fx->num_passes; | 
					
						
							|  |  |  | 	/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */ | 
					
						
							|  |  |  | 	float viewvecs[3][4] = { | 
					
						
							|  |  |  | 	    {-1.0f, -1.0f, -1.0f, 1.0f}, | 
					
						
							|  |  |  | 	    {1.0f, -1.0f, -1.0f, 1.0f}, | 
					
						
							|  |  |  | 	    {-1.0f, 1.0f, -1.0f, 1.0f} | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (fx->effects == 0) | 
					
						
							|  |  |  | 		return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-30 14:14:32 +02:00
										 |  |  | 	GPU_get_dfdy_factors(dfdyfac); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 	/* first, unbind the render-to-texture framebuffer */ | 
					
						
							|  |  |  | 	GPU_framebuffer_texture_detach(fx->color_buffer); | 
					
						
							|  |  |  | 	GPU_framebuffer_texture_detach(fx->depth_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-04 20:33:23 +02:00
										 |  |  | 	if (fx->restore_stencil) { | 
					
						
							|  |  |  | 		gpuRestoreState(&fx->attribs); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	src = fx->color_buffer; | 
					
						
							|  |  |  | 	target = fx->color_buffer_sec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* full screen FX pass */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* invert the view matrix */ | 
					
						
							|  |  |  | 	invert_m4_m4(invproj, projmat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* convert the view vectors to view space */ | 
					
						
							|  |  |  | 	for (i = 0; i < 3; i++) { | 
					
						
							|  |  |  | 		mul_m4_v4(invproj, viewvecs[i]); | 
					
						
							|  |  |  | 		/* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ | 
					
						
							|  |  |  | 		mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]); | 
					
						
							|  |  |  | 		if (is_persp) | 
					
						
							|  |  |  | 			mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); | 
					
						
							|  |  |  | 		viewvecs[i][3] = 1.0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* we need to store the differences */ | 
					
						
							|  |  |  | 	viewvecs[1][0] -= viewvecs[0][0]; | 
					
						
							|  |  |  | 	viewvecs[1][1] = viewvecs[2][1] - viewvecs[0][1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* calculate a depth offset as well */ | 
					
						
							|  |  |  | 	if (!is_persp) { | 
					
						
							|  |  |  | 		float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f}; | 
					
						
							|  |  |  | 		mul_m4_v4(invproj, vec_far); | 
					
						
							|  |  |  | 		mul_v3_fl(vec_far, 1.0f / vec_far[3]); | 
					
						
							|  |  |  | 		viewvecs[1][2] = vec_far[2] - viewvecs[0][2]; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	glDisable(GL_DEPTH_TEST); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* ssao pass */ | 
					
						
							|  |  |  | 	if (fx->effects & GPU_FX_FLAG_SSAO) { | 
					
						
							|  |  |  | 		GPUShader *ssao_shader; | 
					
						
							|  |  |  | 		ssao_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_SSAO, is_persp); | 
					
						
							|  |  |  | 		if (ssao_shader) { | 
					
						
							|  |  |  | 			const GPUSSAOSettings *fx_ssao = fx->settings.ssao; | 
					
						
							|  |  |  | 			float ssao_params[4] = {fx_ssao->distance_max, fx_ssao->factor, fx_ssao->attenuation, 0.0f}; | 
					
						
							| 
									
										
										
										
											2015-05-11 14:14:06 +02:00
										 |  |  | 			float sample_params[3]; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			sample_params[0] = fx->ssao_sample_count_cache; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			/* multiplier so we tile the random texture on screen */ | 
					
						
							| 
									
										
										
										
											2015-05-11 14:14:06 +02:00
										 |  |  | 			sample_params[1] = fx->gbuffer_dim[0] / 64.0; | 
					
						
							|  |  |  | 			sample_params[2] = fx->gbuffer_dim[1] / 64.0; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-05-18 22:05:38 +02:00
										 |  |  | 			ssao_params[3] = (passes_left == 1 && !ofs) ? dfdyfac[0] : dfdyfac[1]; | 
					
						
							| 
									
										
										
										
											2015-03-30 14:14:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPUSSAOShaderInterface *interface = GPU_fx_shader_get_interface(ssao_shader); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 			Batch_set_program(fx->quad_batch, GPU_shader_get_program(ssao_shader)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			GPU_shader_uniform_vector(ssao_shader, interface->ssao_uniform, 4, 1, ssao_params); | 
					
						
							|  |  |  | 			GPU_shader_uniform_vector(ssao_shader, interface->ssao_color_uniform, 4, 1, fx_ssao->color); | 
					
						
							|  |  |  | 			GPU_shader_uniform_vector(ssao_shader, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							|  |  |  | 			GPU_shader_uniform_vector(ssao_shader, interface->ssao_sample_params_uniform, 3, 1, sample_params); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			GPU_texture_bind(src, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			GPU_shader_uniform_texture(ssao_shader, interface->color_uniform, src); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 			GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 			GPU_texture_filter_mode(fx->depth_buffer, true); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			GPU_shader_uniform_texture(ssao_shader, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			GPU_texture_bind(fx->jitter_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			GPU_shader_uniform_texture(ssao_shader, interface->ssao_jitter_uniform, fx->jitter_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			GPU_texture_bind(fx->ssao_spiral_samples_tex, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			GPU_shader_uniform_texture(ssao_shader, interface->ssao_concentric_tex, fx->ssao_spiral_samples_tex); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* draw */ | 
					
						
							|  |  |  | 			gpu_fx_bind_render_target(&passes_left, fx, ofs, target); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 			Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* disable bindings */ | 
					
						
							|  |  |  | 			GPU_texture_unbind(src); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 			GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							|  |  |  | 			GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 			GPU_texture_unbind(fx->depth_buffer); | 
					
						
							|  |  |  | 			GPU_texture_unbind(fx->jitter_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			GPU_texture_unbind(fx->ssao_spiral_samples_tex); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			/* may not be attached, in that case this just returns */ | 
					
						
							|  |  |  | 			if (target) { | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(target); | 
					
						
							|  |  |  | 				if (ofs) { | 
					
						
							|  |  |  | 					GPU_offscreen_bind(ofs, false); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					GPU_framebuffer_restore(); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* swap here, after src/target have been unbound */ | 
					
						
							|  |  |  | 			SWAP(GPUTexture *, target, src); | 
					
						
							|  |  |  | 			numslots = 0; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* second pass, dof */ | 
					
						
							|  |  |  | 	if (fx->effects & GPU_FX_FLAG_DOF) { | 
					
						
							|  |  |  | 		const GPUDOFSettings *fx_dof = fx->settings.dof; | 
					
						
							|  |  |  | 		float dof_params[4]; | 
					
						
							|  |  |  | 		float scale = scene->unit.system ? scene->unit.scale_length : 1.0f; | 
					
						
							| 
									
										
										
										
											2015-02-27 14:05:12 +01:00
										 |  |  | 		/* this is factor that converts to the scene scale. focal length and sensor are expressed in mm
 | 
					
						
							|  |  |  | 		 * unit.scale_length is how many meters per blender unit we have. We want to convert to blender units though | 
					
						
							| 
									
										
										
										
											2016-04-15 16:17:21 +02:00
										 |  |  | 		 * because the shader reads coordinates in world space, which is in blender units. | 
					
						
							|  |  |  | 		 * Note however that focus_distance is already in blender units and shall not be scaled here (see T48157). */ | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		float scale_camera = 0.001f / scale; | 
					
						
							| 
									
										
										
										
											2015-02-27 14:05:12 +01:00
										 |  |  | 		/* we want radius here for the aperture number  */ | 
					
						
							|  |  |  | 		float aperture = 0.5f * scale_camera * fx_dof->focal_length / fx_dof->fstop; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 		dof_params[0] = aperture * fabsf(scale_camera * fx_dof->focal_length / | 
					
						
							| 
									
										
										
										
											2016-04-15 16:17:21 +02:00
										 |  |  | 		                                 (fx_dof->focus_distance - scale_camera * fx_dof->focal_length)); | 
					
						
							|  |  |  | 		dof_params[1] = fx_dof->focus_distance; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * fx_dof->sensor); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 		dof_params[3] = fx_dof->num_blades; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 		if (fx->dof_high_quality) { | 
					
						
							|  |  |  | 			GPUShader *dof_shader_pass1, *dof_shader_pass2, *dof_shader_pass3; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* custom shaders close to the effect described in CryEngine 3 Graphics Gems */ | 
					
						
							|  |  |  | 			dof_shader_pass1 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass2 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE, is_persp); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* error occured, restore framebuffers and return */ | 
					
						
							|  |  |  | 			if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3)) { | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_unbind(fx->gbuffer, NULL); | 
					
						
							|  |  |  | 				GPU_framebuffer_restore(); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_shader_unbind(); | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* pass first, downsample the color buffer to near/far targets and calculate coc texture */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFHQPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1)); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass1, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(src, numslots++); | 
					
						
							|  |  |  | 				/* disable filtering for the texture so custom downsample can do the right thing */ | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_filter_mode(src, false); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, src); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* target is the downsampled coc buffer */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_near, 0); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_half_downsampled_far, 1); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_nearfar_coc, 2); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* binding takes care of setting the viewport to the downsampled size */ | 
					
						
							|  |  |  | 				GPU_framebuffer_slots_bind(fx->gbuffer, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 15:04:11 -04:00
										 |  |  | 				GPU_framebuffer_check_valid(fx->gbuffer, NULL); | 
					
						
							| 
									
										
										
										
											2015-03-23 19:23:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* disable bindings */ | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_filter_mode(src, true); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(src); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->depth_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_half_downsampled_near); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_half_downsampled_far); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_nearfar_coc); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_half_downsampled_near); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* second pass, shoot quads for every pixel in the downsampled buffers, scaling according
 | 
					
						
							|  |  |  | 			 * to circle of confusion */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				int rendertargetdim[2] = {fx->dof_downsampled_w, fx->dof_downsampled_h}; | 
					
						
							|  |  |  | 				float selection[2] = {0.0f, 1.0f}; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFHQPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->point_batch, GPU_shader_get_program(dof_shader_pass2)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_nearfar_coc, numslots++); | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_half_downsampled_far, numslots++); | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_half_downsampled_near, numslots++); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector_int(dof_shader_pass2, interface->rendertargetdim_uniform, 2, 1, rendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection); | 
					
						
							|  |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->coc_uniform, fx->dof_nearfar_coc); | 
					
						
							|  |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_far); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_filter_mode(fx->dof_half_downsampled_far, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* target is the downsampled coc buffer */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_far_blur, 0); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind_as_framebuffer(fx->dof_far_blur); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-20 15:26:13 +01:00
										 |  |  | 				glDisable(GL_DEPTH_TEST); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				glEnable(GL_BLEND); | 
					
						
							|  |  |  | 				glBlendFunc(GL_ONE, GL_ONE); | 
					
						
							| 
									
										
										
										
											2016-01-15 22:59:42 -05:00
										 |  |  | 				glPointSize(1.0f); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* have to clear the buffer unfortunately */ | 
					
						
							|  |  |  | 				glClearColor(0.0, 0.0, 0.0, 0.0); | 
					
						
							|  |  |  | 				glClear(GL_COLOR_BUFFER_BIT); | 
					
						
							|  |  |  | 				/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_half_downsampled_far); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_far_blur); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				selection[0] = 1.0f; | 
					
						
							|  |  |  | 				selection[1] = 0.0f; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->select_uniform, 2, 1, selection); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_half_downsampled_near); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->dof_half_downsampled_near, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_blur, 0); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* have to clear the buffer unfortunately */ | 
					
						
							|  |  |  | 				glClear(GL_COLOR_BUFFER_BIT); | 
					
						
							|  |  |  | 				/* the draw call we all waited for, draw a point per pixel, scaled per circle of confusion */ | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw_stupid_instanced(fx->point_batch, 0, fx->dof_downsampled_w * fx->dof_downsampled_h, 0, 0, NULL, NULL); | 
					
						
							|  |  |  | 				Batch_done_using_program(fx->point_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
					
						
							|  |  |  | 				glDisable(GL_BLEND); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_blur); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_half_downsampled_near); | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_nearfar_coc); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_far_blur); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				numslots = 0; | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* third pass, accumulate the near/far blur fields */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float invrendertargetdim[2] = {1.0f / fx->dof_downsampled_w, 1.0f / fx->dof_downsampled_h}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFHQPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3)); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass3, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass3, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass3, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_near_blur, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->near_uniform, fx->dof_near_blur); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_filter_mode(fx->dof_near_blur, true); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_far_blur, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->far_uniform, fx->dof_far_blur); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_filter_mode(fx->dof_far_blur, true); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(src, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->color_uniform, src); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* if this is the last pass, prepare for rendering on the frambuffer */ | 
					
						
							|  |  |  | 				gpu_fx_bind_render_target(&passes_left, fx, ofs, target); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_blur); | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_far_blur); | 
					
						
							|  |  |  | 				GPU_texture_unbind(src); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->depth_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* may not be attached, in that case this just returns */ | 
					
						
							|  |  |  | 				if (target) { | 
					
						
							|  |  |  | 					GPU_framebuffer_texture_detach(target); | 
					
						
							|  |  |  | 					if (ofs) { | 
					
						
							|  |  |  | 						GPU_offscreen_bind(ofs, false); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						GPU_framebuffer_restore(); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 		else { | 
					
						
							|  |  |  | 			GPUShader *dof_shader_pass1, *dof_shader_pass2, *dof_shader_pass3, *dof_shader_pass4, *dof_shader_pass5; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-10 07:12:10 +11:00
										 |  |  | 			/* DOF effect has many passes but most of them are performed
 | 
					
						
							|  |  |  | 			 * on a texture whose dimensions are 4 times less than the original | 
					
						
							|  |  |  | 			 * (16 times lower than original screen resolution). | 
					
						
							|  |  |  | 			 * Technique used is not very exact but should be fast enough and is based | 
					
						
							|  |  |  | 			 * on "Practical Post-Process Depth of Field" | 
					
						
							|  |  |  | 			 * see http://http.developer.nvidia.com/GPUGems3/gpugems3_ch28.html */
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			dof_shader_pass1 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass2 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass3 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass4 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR, is_persp); | 
					
						
							|  |  |  | 			dof_shader_pass5 = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE, is_persp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* error occured, restore framebuffers and return */ | 
					
						
							|  |  |  | 			if (!(dof_shader_pass1 && dof_shader_pass2 && dof_shader_pass3 && dof_shader_pass4 && dof_shader_pass5)) { | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_unbind(fx->gbuffer, NULL); | 
					
						
							|  |  |  | 				GPU_framebuffer_restore(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				GPU_shader_unbind(); | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* pass first, first level of blur in low res buffer */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]}; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFPassOneInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass1); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass1)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass1, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(src, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass1, interface->color_uniform, src); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, true); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass1, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* target is the downsampled coc buffer */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* binding takes care of setting the viewport to the downsampled size */ | 
					
						
							|  |  |  | 				GPU_texture_bind_as_framebuffer(fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(src); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_coc_buffer); | 
					
						
							|  |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* second pass, gaussian blur the downsampled image */ | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2015-12-06 21:41:21 +01:00
										 |  |  | 				float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer), | 
					
						
							|  |  |  | 				                               1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)}; | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				float tmp = invrendertargetdim[0]; | 
					
						
							|  |  |  | 				invrendertargetdim[0] = 0.0f; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFPassTwoInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass2); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				dof_params[2] = GPU_texture_width(fx->dof_near_coc_blurred_buffer) / (scale_camera * fx_dof->sensor); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* Blurring vertically */ | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, true); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_near_coc_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* use final buffer as a temp here */ | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* Drawing quad */ | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* Rebind Shader */ | 
					
						
							|  |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass2)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* *unbind/detach */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* Blurring horizontally */ | 
					
						
							|  |  |  | 				invrendertargetdim[0] = tmp; | 
					
						
							|  |  |  | 				invrendertargetdim[1] = 0.0f; | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass2, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass2, interface->color_uniform, fx->dof_near_coc_final_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_blurred_buffer, 0); | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* *unbind/detach */ | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->dof_near_coc_final_buffer); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_coc_blurred_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				dof_params[2] = fx->gbuffer_dim[0] / (scale_camera * fx_dof->sensor); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* third pass, calculate near coc */ | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFPassThreeInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass3); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass3)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_near_coc_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_downsampled, fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass3, interface->near_coc_blurred, fx->dof_near_coc_blurred_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_final_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_buffer); | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_blurred_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* unbinding here restores the size to the original */ | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_coc_final_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* fourth pass blur final coc once to eliminate discontinuities */ | 
					
						
							|  |  |  | 			{ | 
					
						
							| 
									
										
										
										
											2015-12-06 21:41:21 +01:00
										 |  |  | 				float invrendertargetdim[2] = {1.0f / GPU_texture_width(fx->dof_near_coc_blurred_buffer), | 
					
						
							|  |  |  | 				                               1.0f / GPU_texture_height(fx->dof_near_coc_blurred_buffer)}; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFPassFourInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass4); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass4)); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_bind(fx->dof_near_coc_final_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass4, interface->near_coc_downsampled, fx->dof_near_coc_final_buffer); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass4, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 00:52:52 -04:00
										 |  |  | 				GPU_framebuffer_texture_attach(fx->gbuffer, fx->dof_near_coc_buffer, 0); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_final_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* unbinding here restores the size to the original */ | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_unbind(fx->gbuffer, fx->dof_near_coc_buffer); | 
					
						
							|  |  |  | 				GPU_framebuffer_texture_detach(fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 			/* final pass, merge blurred layers according to final calculated coc */ | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				float invrendertargetdim[2] = {1.0f / fx->gbuffer_dim[0], 1.0f / fx->gbuffer_dim[1]}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 				GPUDOFPassFiveInterface *interface = GPU_fx_shader_get_interface(dof_shader_pass5); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_set_program(fx->quad_batch, GPU_shader_get_program(dof_shader_pass5)); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_vector(dof_shader_pass5, interface->dof_uniform, 4, 1, dof_params); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass5, interface->invrendertargetdim_uniform, 2, 1, invrendertargetdim); | 
					
						
							|  |  |  | 				GPU_shader_uniform_vector(dof_shader_pass5, interface->viewvecs_uniform, 4, 3, viewvecs[0]); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(src, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass5, interface->original_uniform, src); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_near_coc_blurred_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass5, interface->high_blurred_uniform, fx->dof_near_coc_blurred_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->dof_near_coc_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass5, interface->medium_blurred_uniform, fx->dof_near_coc_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				GPU_texture_bind(fx->depth_buffer, numslots++); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, false); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, true); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 				GPU_shader_uniform_texture(dof_shader_pass5, interface->depth_uniform, fx->depth_buffer); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				/* if this is the last pass, prepare for rendering on the frambuffer */ | 
					
						
							|  |  |  | 				gpu_fx_bind_render_target(&passes_left, fx, ofs, target); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-15 13:17:08 +01:00
										 |  |  | 				Batch_draw(fx->quad_batch); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				/* disable bindings */ | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_buffer); | 
					
						
							|  |  |  | 				GPU_texture_unbind(fx->dof_near_coc_blurred_buffer); | 
					
						
							|  |  |  | 				GPU_texture_unbind(src); | 
					
						
							| 
									
										
										
										
											2017-02-03 16:01:32 +01:00
										 |  |  | 				GPU_texture_compare_mode(fx->depth_buffer, true); | 
					
						
							|  |  |  | 				GPU_texture_filter_mode(fx->depth_buffer, false); | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				GPU_texture_unbind(fx->depth_buffer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				/* may not be attached, in that case this just returns */ | 
					
						
							|  |  |  | 				if (target) { | 
					
						
							|  |  |  | 					GPU_framebuffer_texture_detach(target); | 
					
						
							|  |  |  | 					if (ofs) { | 
					
						
							|  |  |  | 						GPU_offscreen_bind(ofs, false); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					else { | 
					
						
							|  |  |  | 						GPU_framebuffer_restore(); | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 				SWAP(GPUTexture *, target, src); | 
					
						
							|  |  |  | 				numslots = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	GPU_shader_unbind(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return true; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_fx_compositor_init_dof_settings(GPUDOFSettings *fx_dof) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	fx_dof->fstop = 128.0f; | 
					
						
							|  |  |  | 	fx_dof->focal_length = 1.0f; | 
					
						
							|  |  |  | 	fx_dof->focus_distance = 1.0f; | 
					
						
							|  |  |  | 	fx_dof->sensor = 1.0f; | 
					
						
							| 
									
										
										
										
											2015-03-03 17:47:31 +01:00
										 |  |  | 	fx_dof->num_blades = 6; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void GPU_fx_compositor_init_ssao_settings(GPUSSAOSettings *fx_ssao) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	fx_ssao->factor = 1.0f; | 
					
						
							|  |  |  | 	fx_ssao->distance_max = 0.2f; | 
					
						
							|  |  |  | 	fx_ssao->attenuation = 1.0f; | 
					
						
							| 
									
										
										
										
											2015-02-25 23:30:50 +01:00
										 |  |  | 	fx_ssao->samples = 20; | 
					
						
							| 
									
										
										
										
											2015-02-12 18:54:41 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | void GPU_fx_shader_init_interface(struct GPUShader *shader, GPUFXShaderEffect effect) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!shader) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 04:47:16 +11:00
										 |  |  | 	switch (effect) { | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 		case GPU_SHADER_FX_SSAO: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUSSAOShaderInterface *interface = MEM_mallocN(sizeof(GPUSSAOShaderInterface), "GPUSSAOShaderInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->ssao_uniform = GPU_shader_get_uniform(shader, "ssao_params"); | 
					
						
							|  |  |  | 			interface->ssao_color_uniform = GPU_shader_get_uniform(shader, "ssao_color"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 			interface->ssao_sample_params_uniform = GPU_shader_get_uniform(shader, "ssao_sample_params"); | 
					
						
							|  |  |  | 			interface->ssao_concentric_tex = GPU_shader_get_uniform(shader, "ssao_concentric_tex"); | 
					
						
							|  |  |  | 			interface->ssao_jitter_uniform = GPU_shader_get_uniform(shader, "jitter_tex"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_ONE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFHQPassOneInterface *interface = MEM_mallocN(sizeof(GPUDOFHQPassOneInterface), "GPUDOFHQPassOneInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_TWO: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFHQPassTwoInterface *interface = MEM_mallocN(sizeof(GPUDOFHQPassTwoInterface), "GPUDOFHQPassTwoInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->rendertargetdim_uniform = GPU_shader_get_uniform(shader, "rendertargetdim"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->coc_uniform = GPU_shader_get_uniform(shader, "cocbuffer"); | 
					
						
							|  |  |  | 			interface->select_uniform = GPU_shader_get_uniform(shader, "layerselection"); | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_HQ_PASS_THREE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFHQPassThreeInterface *interface = MEM_mallocN(sizeof(GPUDOFHQPassThreeInterface), "GPUDOFHQPassThreeInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->far_uniform = GPU_shader_get_uniform(shader, "farbuffer"); | 
					
						
							|  |  |  | 			interface->near_uniform = GPU_shader_get_uniform(shader, "nearbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_ONE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFPassOneInterface *interface = MEM_mallocN(sizeof(GPUDOFPassOneInterface), "GPUDOFPassOneInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_TWO: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFPassTwoInterface *interface = MEM_mallocN(sizeof(GPUDOFPassTwoInterface), "GPUDOFPassTwoInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 			interface->color_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_THREE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFPassThreeInterface *interface = MEM_mallocN(sizeof(GPUDOFPassThreeInterface), "GPUDOFPassThreeInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->near_coc_blurred = GPU_shader_get_uniform(shader, "blurredcolorbuffer"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FOUR: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFPassFourInterface *interface = MEM_mallocN(sizeof(GPUDOFPassFourInterface), "GPUDOFPassFourInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->near_coc_downsampled = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_OF_FIELD_PASS_FIVE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDOFPassFiveInterface *interface = MEM_mallocN(sizeof(GPUDOFPassFiveInterface), "GPUDOFPassFiveInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->medium_blurred_uniform = GPU_shader_get_uniform(shader, "mblurredcolorbuffer"); | 
					
						
							|  |  |  | 			interface->high_blurred_uniform = GPU_shader_get_uniform(shader, "blurredcolorbuffer"); | 
					
						
							|  |  |  | 			interface->dof_uniform = GPU_shader_get_uniform(shader, "dof_params"); | 
					
						
							|  |  |  | 			interface->invrendertargetdim_uniform = GPU_shader_get_uniform(shader, "invrendertargetdim"); | 
					
						
							|  |  |  | 			interface->original_uniform = GPU_shader_get_uniform(shader, "colorbuffer"); | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 			interface->viewvecs_uniform = GPU_shader_get_uniform(shader, "viewvecs"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		case GPU_SHADER_FX_DEPTH_RESOLVE: | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			GPUDepthResolveInterface *interface = MEM_mallocN(sizeof(GPUDepthResolveInterface), "GPUDepthResolveInterface"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			interface->depth_uniform = GPU_shader_get_uniform(shader, "depthbuffer"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-02 21:46:54 -05:00
										 |  |  | 			GPU_fx_shader_set_interface(shader, interface); | 
					
						
							| 
									
										
										
										
											2016-03-21 00:53:48 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |