| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright 2016, Blender Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Contributor(s): Blender Institute | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-10-07 15:57:14 +11:00
										 |  |  | /** \file basic_engine.c
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  |  *  \ingroup draw_engine | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Simple engine for drawing color and/or depth. | 
					
						
							|  |  |  |  * When we only need simple flat shaders. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | #include "DRW_render.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_icons.h"
 | 
					
						
							|  |  |  | #include "BKE_idprop.h"
 | 
					
						
							|  |  |  | #include "BKE_main.h"
 | 
					
						
							| 
									
										
										
										
											2018-04-17 17:34:00 +02:00
										 |  |  | #include "BKE_particle.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "DNA_particle_types.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "GPU_shader.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | #include "basic_engine.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | /* Shaders */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | #define BASIC_ENGINE "BLENDER_BASIC"
 | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* *********** LISTS *********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* GPUViewport.storage
 | 
					
						
							|  |  |  |  * Is freed everytime the viewport engine changes */ | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | typedef struct BASIC_StorageList { | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | 	struct BASIC_PrivateData *g_data; | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | } BASIC_StorageList; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | typedef struct BASIC_PassList { | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	struct DRWPass *depth_pass; | 
					
						
							| 
									
										
										
										
											2017-04-26 18:08:49 +10:00
										 |  |  | 	struct DRWPass *depth_pass_cull; | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | } BASIC_PassList; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | typedef struct BASIC_Data { | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	void *engine_type; | 
					
						
							| 
									
										
										
										
											2018-03-25 17:13:11 +02:00
										 |  |  | 	DRWViewportEmptyList *fbl; | 
					
						
							|  |  |  | 	DRWViewportEmptyList *txl; | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	BASIC_PassList *psl; | 
					
						
							|  |  |  | 	BASIC_StorageList *stl; | 
					
						
							|  |  |  | } BASIC_Data; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* *********** STATIC *********** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static struct { | 
					
						
							|  |  |  | 	/* Depth Pre Pass */ | 
					
						
							|  |  |  | 	struct GPUShader *depth_sh; | 
					
						
							|  |  |  | } e_data = {NULL}; /* Engine data */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | typedef struct BASIC_PrivateData { | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	DRWShadingGroup *depth_shgrp; | 
					
						
							|  |  |  | 	DRWShadingGroup *depth_shgrp_cull; | 
					
						
							| 
									
										
										
										
											2018-04-17 17:34:00 +02:00
										 |  |  | 	DRWShadingGroup *depth_shgrp_hair; | 
					
						
							| 
									
										
										
										
											2017-04-29 16:52:12 +10:00
										 |  |  | } BASIC_PrivateData; /* Transient data */ | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Functions */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-25 17:13:11 +02:00
										 |  |  | static void basic_engine_init(void *UNUSED(vedata)) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* Depth prepass */ | 
					
						
							|  |  |  | 	if (!e_data.depth_sh) { | 
					
						
							|  |  |  | 		e_data.depth_sh = DRW_shader_create_3D_depth_only(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static void basic_cache_init(void *vedata) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl; | 
					
						
							|  |  |  | 	BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10: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-04-26 17:20:11 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2018-05-26 10:41:25 +02:00
										 |  |  | 		psl->depth_pass = DRW_pass_create( | 
					
						
							|  |  |  | 		        "Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 		stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass); | 
					
						
							| 
									
										
										
										
											2017-04-26 18:08:49 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		psl->depth_pass_cull = DRW_pass_create( | 
					
						
							|  |  |  | 		        "Depth Pass Cull", | 
					
						
							| 
									
										
										
										
											2018-05-20 19:05:13 +02:00
										 |  |  | 		        DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK); | 
					
						
							| 
									
										
										
										
											2017-04-26 18:08:49 +10:00
										 |  |  | 		stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.depth_sh, psl->depth_pass_cull); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static void basic_cache_populate(void *vedata, Object *ob) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-09 12:09:13 +02:00
										 |  |  | 	/* TODO(fclem) fix selection of smoke domains. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!DRW_object_is_renderable(ob) || (ob->dt < OB_SOLID)) { | 
					
						
							| 
									
										
										
										
											2018-05-09 16:55:09 +02:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-17 17:34:00 +02:00
										 |  |  | 	const DRWContextState *draw_ctx = DRW_context_state_get(); | 
					
						
							| 
									
										
										
										
											2018-07-10 10:29:24 +02:00
										 |  |  | 	if (ob != draw_ctx->object_edit) { | 
					
						
							|  |  |  | 		for (ParticleSystem *psys = ob->particlesystem.first; | 
					
						
							|  |  |  | 		     psys != NULL; | 
					
						
							|  |  |  | 		     psys = psys->next) | 
					
						
							| 
									
										
										
										
											2018-07-12 11:16:22 +02:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2018-07-10 10:29:24 +02:00
										 |  |  | 			if (!psys_check_enabled(ob, psys, false)) { | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-10-08 10:43:34 +11:00
										 |  |  | 			if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) { | 
					
						
							| 
									
										
										
										
											2018-07-10 10:29:24 +02:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ParticleSettings *part = psys->part; | 
					
						
							| 
									
										
										
										
											2018-07-12 11:16:22 +02:00
										 |  |  | 			const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as; | 
					
						
							| 
									
										
										
										
											2018-07-10 10:29:24 +02:00
										 |  |  | 			if (draw_as == PART_DRAW_PATH) { | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | 				struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL); | 
					
						
							| 
									
										
										
										
											2018-07-10 10:29:24 +02:00
										 |  |  | 				DRW_shgroup_call_add(stl->g_data->depth_shgrp, hairs, NULL); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-04-17 17:34:00 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-14 18:31:27 +02:00
										 |  |  | 	/* Make flat object selectable in ortho view if wireframe is enabled. */ | 
					
						
							|  |  |  | 	if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) || | 
					
						
							|  |  |  | 	    (ob->dtx & OB_DRAWWIRE) || | 
					
						
							|  |  |  | 	    (ob->dt == OB_WIRE)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		int flat_axis = 0; | 
					
						
							|  |  |  | 		bool is_flat_object_viewed_from_side = (draw_ctx->rv3d->persp == RV3D_ORTHO) && | 
					
						
							|  |  |  | 		                                       DRW_object_is_flat(ob, &flat_axis) && | 
					
						
							|  |  |  | 		                                       DRW_object_axis_orthogonal_to_view(ob, flat_axis); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (is_flat_object_viewed_from_side) { | 
					
						
							| 
									
										
										
										
											2018-09-19 18:19:49 +02:00
										 |  |  | 			/* Avoid losing flat objects when in ortho views (see T56549) */ | 
					
						
							| 
									
										
										
										
											2018-09-14 18:31:27 +02:00
										 |  |  | 			struct GPUBatch *geom = DRW_cache_object_wire_outline_get(ob); | 
					
						
							|  |  |  | 			DRW_shgroup_call_object_add(stl->g_data->depth_shgrp, geom, ob); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-18 00:12:21 +02:00
										 |  |  | 	struct GPUBatch *geom = DRW_cache_object_surface_get(ob); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	if (geom) { | 
					
						
							| 
									
										
										
										
											2018-07-20 12:30:23 +02:00
										 |  |  | 		const bool do_cull = (draw_ctx->v3d && (draw_ctx->v3d->flag2 & V3D_BACKFACE_CULLING)); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 		/* Depth Prepass */ | 
					
						
							|  |  |  | 		DRW_shgroup_call_add((do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp, geom, ob->obmat); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static void basic_cache_finish(void *vedata) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl; | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	UNUSED_VARS(stl); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static void basic_draw_scene(void *vedata) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl; | 
					
						
							| 
									
										
										
										
											2017-07-26 02:34:14 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-20 12:30:23 +02:00
										 |  |  | 	DRW_draw_pass(psl->depth_pass); | 
					
						
							|  |  |  | 	DRW_draw_pass(psl->depth_pass_cull); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static void basic_engine_free(void) | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* all shaders are builtin */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | static const DrawEngineDataSize basic_data_size = DRW_VIEWPORT_DATA_SIZE(BASIC_Data); | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | DrawEngineType draw_engine_basic_type = { | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	NULL, NULL, | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	N_("Basic"), | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | 	&basic_data_size, | 
					
						
							|  |  |  | 	&basic_engine_init, | 
					
						
							|  |  |  | 	&basic_engine_free, | 
					
						
							|  |  |  | 	&basic_cache_init, | 
					
						
							|  |  |  | 	&basic_cache_populate, | 
					
						
							|  |  |  | 	&basic_cache_finish, | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2017-11-29 12:24:36 +01:00
										 |  |  | 	&basic_draw_scene, | 
					
						
							| 
									
										
										
										
											2017-09-25 20:07:02 +02:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2017-11-28 17:05:52 +01:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2018-01-29 14:56:16 +01:00
										 |  |  | 	NULL, | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | /* Note: currently unused, we may want to register so we can see this when debugging the view. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | RenderEngineType DRW_engine_viewport_basic_type = { | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	NULL, NULL, | 
					
						
							| 
									
										
										
										
											2017-05-01 14:55:59 +02:00
										 |  |  | 	BASIC_ENGINE, N_("Basic"), RE_INTERNAL, | 
					
						
							| 
									
										
										
										
											2018-05-16 21:40:05 +02:00
										 |  |  | 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | 	&draw_engine_basic_type, | 
					
						
							| 
									
										
										
										
											2017-04-26 17:20:11 +10:00
										 |  |  | 	{NULL, NULL, NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-27 02:49:13 +10:00
										 |  |  | #undef BASIC_ENGINE
 |