| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2019-01-23 11:29:18 +11:00
										 |  |  |  * Copyright 2016, Blender Foundation. | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-02-18 08:08:12 +11:00
										 |  |  | /** \file
 | 
					
						
							|  |  |  |  * \ingroup draw | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DRW_render.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_particle_types.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_pointcache.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | #include "GPU_shader.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "draw_common.h"
 | 
					
						
							| 
									
										
										
										
											2019-02-23 18:31:45 +11:00
										 |  |  | #include "draw_mode_engines.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | #include "ED_particle.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DEG_depsgraph_query.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | extern char datatoc_particle_strand_vert_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | extern char datatoc_particle_strand_frag_glsl[]; | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | extern char datatoc_common_globals_lib_glsl[]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | /* *********** LISTS *********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct PARTICLE_PassList { | 
					
						
							| 
									
										
										
										
											2018-05-09 11:14:27 +02:00
										 |  |  | 	struct DRWPass *psys_edit_pass; | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } PARTICLE_PassList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct PARTICLE_FramebufferList { | 
					
						
							| 
									
										
										
										
											2017-03-13 11:39:41 +01:00
										 |  |  | 	struct GPUFrameBuffer *fb; | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } PARTICLE_FramebufferList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct PARTICLE_TextureList { | 
					
						
							| 
									
										
										
										
											2017-03-13 11:39:41 +01:00
										 |  |  | 	struct GPUTexture *texture; | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } PARTICLE_TextureList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct PARTICLE_StorageList { | 
					
						
							| 
									
										
										
										
											2017-03-13 11:39:41 +01:00
										 |  |  | 	struct CustomStruct *block; | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | 	struct PARTICLE_PrivateData *g_data; | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } PARTICLE_StorageList; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct PARTICLE_Data { | 
					
						
							| 
									
										
										
										
											2017-04-03 19:32:05 +02:00
										 |  |  | 	void *engine_type; /* Required */ | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 	PARTICLE_FramebufferList *fbl; | 
					
						
							|  |  |  | 	PARTICLE_TextureList *txl; | 
					
						
							|  |  |  | 	PARTICLE_PassList *psl; | 
					
						
							|  |  |  | 	PARTICLE_StorageList *stl; | 
					
						
							|  |  |  | } PARTICLE_Data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *********** STATIC *********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-18 22:14:53 +01:00
										 |  |  | static struct { | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	struct GPUShader *strands_shader; | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 	struct GPUShader *strands_weight_shader; | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	struct GPUShader *points_shader; | 
					
						
							| 
									
										
										
										
											2017-03-18 22:14:53 +01:00
										 |  |  | } e_data = {NULL}; /* Engine data */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | typedef struct PARTICLE_PrivateData { | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	DRWShadingGroup *strands_group; | 
					
						
							| 
									
										
										
										
											2018-05-09 14:59:29 +02:00
										 |  |  | 	DRWShadingGroup *inner_points_group; | 
					
						
							|  |  |  | 	DRWShadingGroup *tip_points_group; | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | } PARTICLE_PrivateData; /* Transient data */ | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* *********** FUNCTIONS *********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_engine_init(void *UNUSED(vedata)) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	if (!e_data.strands_shader) { | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | 		e_data.strands_shader = DRW_shader_create_with_lib( | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 		        datatoc_particle_strand_vert_glsl, | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | 		        NULL, | 
					
						
							|  |  |  | 		        datatoc_particle_strand_frag_glsl, | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | 		        datatoc_common_globals_lib_glsl, | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 		        ""); | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 		e_data.strands_weight_shader = DRW_shader_create_with_lib( | 
					
						
							|  |  |  | 		        datatoc_particle_strand_vert_glsl, | 
					
						
							|  |  |  | 		        NULL, | 
					
						
							|  |  |  | 		        datatoc_particle_strand_frag_glsl, | 
					
						
							|  |  |  | 		        datatoc_common_globals_lib_glsl, | 
					
						
							|  |  |  | 		        "#define USE_WEIGHT"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | 		e_data.points_shader = DRW_shader_create_with_lib( | 
					
						
							|  |  |  | 		        datatoc_particle_strand_vert_glsl, | 
					
						
							|  |  |  | 		        NULL, | 
					
						
							|  |  |  | 		        datatoc_particle_strand_frag_glsl, | 
					
						
							|  |  |  | 		        datatoc_common_globals_lib_glsl, | 
					
						
							|  |  |  | 		        "#define USE_POINTS"); | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_cache_init(void *vedata) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-26 19:10:53 +02:00
										 |  |  | 	PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl; | 
					
						
							|  |  |  | 	PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl; | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 	const DRWContextState *draw_ctx = DRW_context_state_get(); | 
					
						
							|  |  |  | 	ParticleEditSettings *pset = PE_settings(draw_ctx->scene); | 
					
						
							|  |  |  | 	const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT); | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-26 20:13:34 +02:00
										 |  |  | 	if (!stl->g_data) { | 
					
						
							|  |  |  | 		/* Alloc transient pointers */ | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | 		stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__); | 
					
						
							| 
									
										
										
										
											2017-03-26 20:13:34 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-14 18:40:23 +11:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | 	/* Create a pass */ | 
					
						
							| 
									
										
										
										
											2018-05-09 11:14:27 +02:00
										 |  |  | 	psl->psys_edit_pass = DRW_pass_create("PSys Edit Pass", | 
					
						
							|  |  |  | 	                                      (DRW_STATE_WRITE_COLOR | | 
					
						
							|  |  |  | 	                                       DRW_STATE_WRITE_DEPTH | | 
					
						
							| 
									
										
										
										
											2018-05-20 19:05:13 +02:00
										 |  |  | 	                                       DRW_STATE_DEPTH_LESS_EQUAL | | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	                                       DRW_STATE_WIRE | | 
					
						
							|  |  |  | 	                                       DRW_STATE_POINT)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 	GPUShader *strand_shader = (use_weight) ? e_data.strands_weight_shader : e_data.strands_shader; | 
					
						
							|  |  |  | 	stl->g_data->strands_group = DRW_shgroup_create(strand_shader, psl->psys_edit_pass); | 
					
						
							|  |  |  | 	stl->g_data->inner_points_group = DRW_shgroup_create(e_data.points_shader, psl->psys_edit_pass); | 
					
						
							|  |  |  | 	stl->g_data->tip_points_group = DRW_shgroup_create(e_data.points_shader, psl->psys_edit_pass); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-22 12:09:27 +11:00
										 |  |  | 	DRW_shgroup_uniform_block(stl->g_data->strands_group, "globalsBlock", G_draw.block_ubo); | 
					
						
							|  |  |  | 	DRW_shgroup_uniform_block(stl->g_data->inner_points_group, "globalsBlock", G_draw.block_ubo); | 
					
						
							|  |  |  | 	DRW_shgroup_uniform_block(stl->g_data->tip_points_group, "globalsBlock", G_draw.block_ubo); | 
					
						
							| 
									
										
										
										
											2018-05-09 11:14:27 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-11 12:18:37 +02:00
										 |  |  | static void particle_edit_cache_populate(void *vedata, | 
					
						
							|  |  |  |                                          Object *object, | 
					
						
							| 
									
										
										
										
											2018-05-11 14:54:50 +02:00
										 |  |  |                                          ParticleSystem *psys, | 
					
						
							| 
									
										
										
										
											2018-05-11 12:18:37 +02:00
										 |  |  |                                          PTCacheEdit *edit) | 
					
						
							| 
									
										
										
										
											2018-05-09 11:14:27 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	PARTICLE_StorageList *stl = ((PARTICLE_Data *)vedata)->stl; | 
					
						
							| 
									
										
										
										
											2018-05-09 14:59:29 +02:00
										 |  |  | 	const DRWContextState *draw_ctx = DRW_context_state_get(); | 
					
						
							| 
									
										
										
										
											2018-05-11 07:43:20 +02:00
										 |  |  | 	ParticleEditSettings *pset = PE_settings(draw_ctx->scene); | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 	const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | 		struct GPUBatch *strands = | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 		        DRW_cache_particles_get_edit_strands(object, psys, edit, use_weight); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 		DRW_shgroup_call_add(stl->g_data->strands_group, strands, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-09 14:59:29 +02:00
										 |  |  | 	if (pset->selectmode == SCE_SELECT_POINT) { | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | 		struct GPUBatch *points = | 
					
						
							| 
									
										
										
										
											2018-05-11 14:54:50 +02:00
										 |  |  | 		        DRW_cache_particles_get_edit_inner_points(object, psys, edit); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:59:29 +02:00
										 |  |  | 		DRW_shgroup_call_add(stl->g_data->inner_points_group, points, NULL); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (ELEM(pset->selectmode, SCE_SELECT_POINT, SCE_SELECT_END)) { | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | 		struct GPUBatch *points = | 
					
						
							| 
									
										
										
										
											2018-05-11 14:54:50 +02:00
										 |  |  | 		        DRW_cache_particles_get_edit_tip_points(object, psys, edit); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:59:29 +02:00
										 |  |  | 		DRW_shgroup_call_add(stl->g_data->tip_points_group, points, NULL); | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_cache_populate(void *vedata, Object *object) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-11 15:12:24 +02:00
										 |  |  | 	if (object->mode != OB_MODE_PARTICLE_EDIT) { | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-11 12:44:43 +02:00
										 |  |  | 	const DRWContextState *draw_ctx = DRW_context_state_get(); | 
					
						
							| 
									
										
										
										
											2018-05-14 15:37:54 +02:00
										 |  |  | 	Scene *scene_orig = (Scene *)DEG_get_original_id(&draw_ctx->scene->id); | 
					
						
							|  |  |  | 	/* Usually the edit structure is created by Particle Edit Mode Toggle
 | 
					
						
							|  |  |  | 	 * operator, but sometimes it's invoked after tagging hair as outdated | 
					
						
							|  |  |  | 	 * (for example, when toggling edit mode). That makes it impossible to | 
					
						
							|  |  |  | 	 * create edit structure for until after next dependency graph evaluation. | 
					
						
							|  |  |  | 	 * | 
					
						
							|  |  |  | 	 * Ideally, the edit structure will be created here already via some | 
					
						
							|  |  |  | 	 * dependency graph callback or so, but currently trying to make it nicer | 
					
						
							|  |  |  | 	 * only causes bad level calls and breaks design from the past. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-05-11 12:44:43 +02:00
										 |  |  | 	Object *object_orig = DEG_get_original_object(object); | 
					
						
							| 
									
										
										
										
											2018-05-14 15:37:54 +02:00
										 |  |  | 	PTCacheEdit *edit = PE_create_current( | 
					
						
							|  |  |  | 	        draw_ctx->depsgraph, scene_orig, object_orig); | 
					
						
							| 
									
										
										
										
											2018-06-06 13:51:57 +02:00
										 |  |  | 	if (edit == NULL) { | 
					
						
							|  |  |  | 		/* Happens when trying to edit particles in EMITTER mode without
 | 
					
						
							|  |  |  | 		 * having them cached. | 
					
						
							|  |  |  | 		 */ | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-15 13:08:06 +02:00
										 |  |  | 	/* NOTE: We need to pass evaluated particle system, which we need
 | 
					
						
							|  |  |  | 	 * to find first. | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2018-05-11 14:54:50 +02:00
										 |  |  | 	ParticleSystem *psys = object->particlesystem.first; | 
					
						
							|  |  |  | 	ParticleSystem *psys_orig = object_orig->particlesystem.first; | 
					
						
							|  |  |  | 	while (psys_orig != NULL) { | 
					
						
							|  |  |  | 		if (PE_get_current_from_psys(psys_orig) == edit) { | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		psys = psys->next; | 
					
						
							|  |  |  | 		psys_orig = psys_orig->next; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (psys == NULL) { | 
					
						
							|  |  |  | 		printf("Error getting evaluated particle system for edit.\n"); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	particle_edit_cache_populate(vedata, object, psys, edit); | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-14 18:40:23 +11:00
										 |  |  | /* Optional: Post-cache_populate callback */ | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_cache_finish(void *UNUSED(vedata)) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Draw time ! Control rendering pipeline from here */ | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_draw_scene(void *vedata) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-03-26 19:10:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	PARTICLE_PassList *psl = ((PARTICLE_Data *)vedata)->psl; | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 11:14:27 +02:00
										 |  |  | 	DRW_draw_pass(psl->psys_edit_pass); | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static void particle_engine_free(void) | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2018-05-09 14:08:44 +02:00
										 |  |  | 	DRW_SHADER_FREE_SAFE(e_data.strands_shader); | 
					
						
							| 
									
										
										
										
											2018-11-27 13:49:00 +01:00
										 |  |  | 	DRW_SHADER_FREE_SAFE(e_data.strands_weight_shader); | 
					
						
							| 
									
										
										
										
											2018-11-26 20:34:04 +01:00
										 |  |  | 	DRW_SHADER_FREE_SAFE(e_data.points_shader); | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | static const DrawEngineDataSize particle_data_size = | 
					
						
							|  |  |  |       DRW_VIEWPORT_DATA_SIZE(PARTICLE_Data); | 
					
						
							| 
									
										
										
										
											2017-04-12 19:49:19 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | DrawEngineType draw_engine_particle_type = { | 
					
						
							|  |  |  | 	NULL, NULL, | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | 	N_("Particle Mode"), | 
					
						
							|  |  |  | 	&particle_data_size, | 
					
						
							|  |  |  | 	&particle_engine_init, | 
					
						
							|  |  |  | 	&particle_engine_free, | 
					
						
							|  |  |  | 	&particle_cache_init, | 
					
						
							|  |  |  | 	&particle_cache_populate, | 
					
						
							|  |  |  | 	&particle_cache_finish, | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | 	NULL, /* draw_background but not needed by mode engines */ | 
					
						
							| 
									
										
										
										
											2018-05-08 17:11:42 +02:00
										 |  |  | 	&particle_draw_scene, | 
					
						
							| 
									
										
										
										
											2017-09-25 20:07:02 +02:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2018-01-29 14:56:16 +01:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2017-03-12 21:16:03 +01:00
										 |  |  | }; |