Blender  V3.3
basic_engine.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2016 Blender Foundation. */
3 
11 #include "DRW_render.h"
12 
13 #include "BKE_object.h"
14 #include "BKE_paint.h"
15 #include "BKE_particle.h"
16 
17 #include "BLI_alloca.h"
18 
19 #include "DNA_particle_types.h"
20 
21 #include "GPU_shader.h"
22 
23 #include "basic_engine.h"
24 #include "basic_private.h"
25 
26 #define BASIC_ENGINE "BLENDER_BASIC"
27 
28 /* *********** LISTS *********** */
29 
30 /* GPUViewport.storage
31  * Is freed every time the viewport engine changes. */
32 typedef struct BASIC_StorageList {
35 
36 typedef struct BASIC_PassList {
37  struct DRWPass *depth_pass[2];
41 
42 typedef struct BASIC_Data {
43  void *engine_type;
49 
50 /* *********** STATIC *********** */
51 
52 typedef struct BASIC_PrivateData {
59 } BASIC_PrivateData; /* Transient data */
60 
61 static void basic_cache_init(void *vedata)
62 {
63  BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
64  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
65  DRWShadingGroup *grp;
66 
67  const DRWContextState *draw_ctx = DRW_context_state_get();
68 
69  if (!stl->g_data) {
70  /* Alloc transient pointers */
71  stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
72  }
73 
75 
76  /* Twice for normal and in front objects. */
77  for (int i = 0; i < 2; i++) {
78  DRWState clip_state = (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? DRW_STATE_CLIP_PLANES : 0;
79  DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
81 
85 
86  DRW_PASS_CREATE(psl->depth_pass[i], state | clip_state | infront_state);
87  stl->g_data->depth_shgrp[i] = grp = DRW_shgroup_create(sh, psl->depth_pass[i]);
88  DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
89  DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
90 
94  DRW_PASS_CREATE(psl->depth_pass_pointcloud[i], state | clip_state | infront_state);
96  sh, psl->depth_pass_pointcloud[i]);
97  DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
98  DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
99 
100  stl->g_data->depth_hair_shgrp[i] = grp = DRW_shgroup_create(
101  BASIC_shaders_depth_sh_get(draw_ctx->sh_cfg), psl->depth_pass[i]);
102 
105 
109  DRW_PASS_CREATE(psl->depth_pass_cull[i], state | clip_state | infront_state);
110  stl->g_data->depth_shgrp_cull[i] = grp = DRW_shgroup_create(sh, psl->depth_pass_cull[i]);
111  DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
112  DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
113  }
114 }
115 
116 /* TODO(fclem): DRW_cache_object_surface_material_get needs a refactor to allow passing NULL
117  * instead of gpumat_array. Avoiding all this boilerplate code. */
119 {
120  const int materials_len = DRW_cache_object_material_count_get(ob);
121  struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
122  memset(gpumat_array, 0, sizeof(*gpumat_array) * materials_len);
123 
124  return DRW_cache_object_surface_material_get(ob, gpumat_array, materials_len);
125 }
126 
127 static void basic_cache_populate_particles(void *vedata, Object *ob)
128 {
129  const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
130  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
131  for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
133  continue;
134  }
135  ParticleSettings *part = psys->part;
136  const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
137  if (draw_as == PART_DRAW_PATH) {
138  struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
140  const short material_slot = part->omat;
141  DRW_select_load_id(ob->runtime.select_id | (material_slot << 16));
142  }
143  DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
144  }
145  }
146 }
147 
148 static void basic_cache_populate(void *vedata, Object *ob)
149 {
150  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
151 
152  /* TODO(fclem): fix selection of smoke domains. */
153 
154  if (!DRW_object_is_renderable(ob) || (ob->dt < OB_SOLID)) {
155  return;
156  }
157 
158  const DRWContextState *draw_ctx = DRW_context_state_get();
159  if (ob != draw_ctx->object_edit) {
160  basic_cache_populate_particles(vedata, ob);
161  }
162 
163  const bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
164  if (ob->type == OB_CURVES) {
166  }
167 
168  /* Make flat object selectable in ortho view if wireframe is enabled. */
169  if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
170  (draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
171  int flat_axis = 0;
172  bool is_flat_object_viewed_from_side = ((draw_ctx->rv3d->persp == RV3D_ORTHO) &&
173  DRW_object_is_flat(ob, &flat_axis) &&
174  DRW_object_axis_orthogonal_to_view(ob, flat_axis));
175 
176  if (is_flat_object_viewed_from_side) {
177  /* Avoid losing flat objects when in ortho views (see T56549) */
178  struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
179  if (geom) {
180  DRW_shgroup_call(stl->g_data->depth_shgrp[do_in_front], geom, ob);
181  }
182  return;
183  }
184  }
185 
186  const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) &&
188  const bool do_cull = (draw_ctx->v3d &&
190 
191  DRWShadingGroup *shgrp = NULL;
192 
193  if (ob->type == OB_POINTCLOUD) {
194  shgrp = stl->g_data->depth_pointcloud_shgrp[do_in_front];
195  }
196  else {
197  shgrp = (do_cull) ? stl->g_data->depth_shgrp_cull[do_in_front] :
198  stl->g_data->depth_shgrp[do_in_front];
199  }
200 
201  if (use_sculpt_pbvh) {
202  DRW_shgroup_call_sculpt(shgrp, ob, false, false);
203  }
204  else {
206  struct GPUBatch **geoms = basic_object_surface_material_get(ob);
207  if (geoms) {
208  const int materials_len = DRW_cache_object_material_count_get(ob);
209  for (int i = 0; i < materials_len; i++) {
210  if (geoms[i] == NULL) {
211  continue;
212  }
213  const short material_slot_select_id = i + 1;
214  DRW_select_load_id(ob->runtime.select_id | (material_slot_select_id << 16));
215  DRW_shgroup_call(shgrp, geoms[i], ob);
216  }
217  }
218  }
219  else {
220  struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
221  if (geom) {
222  DRW_shgroup_call(shgrp, geom, ob);
223  }
224  }
225  }
226 }
227 
228 static void basic_cache_finish(void *vedata)
229 {
230  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
231 
232  UNUSED_VARS(stl);
233 }
234 
235 static void basic_draw_scene(void *vedata)
236 {
237  BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
238 
239  DRW_draw_pass(psl->depth_pass[0]);
242  DRW_draw_pass(psl->depth_pass[1]);
245 }
246 
247 static void basic_engine_free(void)
248 {
250 }
251 
253 
255  NULL,
256  NULL,
257  N_("Basic"),
259  NULL,
261  NULL, /* instance_free */
266  NULL,
267  NULL,
268  NULL,
269  NULL,
270 };
271 
272 #undef BASIC_ENGINE
General operations, lookup, etc. for blender objects.
bool BKE_object_supports_material_slots(struct Object *ob)
Definition: object.cc:5070
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct RegionView3D *rv3d)
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:22
#define UNUSED_VARS(...)
@ OB_WIRE
@ OB_SOLID
@ OB_POINTCLOUD
@ OB_CURVES
@ OB_DRAW_IN_FRONT
@ OB_DRAWWIRE
#define PART_DRAW_PATH
#define PART_DRAW_REND
@ V3D_OVERLAY_WIREFRAMES
@ V3D_SHADING_BACKFACE_CULLING
#define RV3D_ORTHO
char DRWViewportEmptyList
Definition: DRW_render.h:90
DRWState
Definition: DRW_render.h:298
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:342
@ DRW_STATE_IN_FRONT_SELECT
Definition: DRW_render.h:340
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:302
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:311
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:316
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:690
#define DRW_VIEWPORT_DATA_SIZE(ty)
Definition: DRW_render.h:96
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:414
GPUBatch
Definition: GPU_batch.h:78
struct GPUShader GPUShader
Definition: GPU_shader.h:20
@ GPU_SHADER_CFG_CLIPPED
Definition: GPU_shader.h:366
struct BASIC_Data BASIC_Data
static void basic_cache_populate(void *vedata, Object *ob)
Definition: basic_engine.c:148
struct BASIC_PrivateData BASIC_PrivateData
struct BASIC_StorageList BASIC_StorageList
static const DrawEngineDataSize basic_data_size
Definition: basic_engine.c:252
static void basic_cache_finish(void *vedata)
Definition: basic_engine.c:228
struct BASIC_PassList BASIC_PassList
static void basic_engine_free(void)
Definition: basic_engine.c:247
DrawEngineType draw_engine_basic_type
Definition: basic_engine.c:254
static void basic_cache_init(void *vedata)
Definition: basic_engine.c:61
static struct GPUBatch ** basic_object_surface_material_get(Object *ob)
Definition: basic_engine.c:118
static void basic_draw_scene(void *vedata)
Definition: basic_engine.c:235
static void basic_cache_populate_particles(void *vedata, Object *ob)
Definition: basic_engine.c:127
GPUShader * BASIC_shaders_depth_conservative_sh_get(eGPUShaderConfig config)
Definition: basic_shader.c:67
void BASIC_shaders_free(void)
Definition: basic_shader.c:89
GPUShader * BASIC_shaders_pointcloud_depth_conservative_sh_get(eGPUShaderConfig config)
Definition: basic_shader.c:78
GPUShader * BASIC_shaders_pointcloud_depth_sh_get(eGPUShaderConfig config)
Definition: basic_shader.c:46
GPUShader * BASIC_shaders_depth_sh_get(eGPUShaderConfig config)
Definition: basic_shader.c:36
GPUShader * BASIC_shaders_curves_depth_sh_get(eGPUShaderConfig config)
Definition: basic_shader.c:57
GPUBatch * DRW_cache_object_all_edges_get(Object *ob)
Definition: draw_cache.c:800
GPUBatch ** DRW_cache_object_surface_material_get(struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
Definition: draw_cache.c:971
int DRW_cache_object_material_count_get(struct Object *ob)
Definition: draw_cache.c:936
GPUBatch * DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
Definition: draw_cache.c:3093
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:887
bool DRW_object_is_flat(Object *ob, int *r_axis)
Definition: draw_common.c:411
bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis)
Definition: draw_common.c:444
struct DRWShadingGroup * DRW_shgroup_curves_create_sub(struct Object *object, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material)
Definition: draw_curves.cc:303
bool DRW_state_is_select(void)
bool DRW_state_is_material_select(void)
bool DRW_object_is_renderable(const Object *ob)
Definition: draw_manager.c:180
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:234
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:288
bool DRW_state_is_image_render(void)
const float * DRW_viewport_invert_size_get(void)
Definition: draw_manager.c:293
void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup, Object *ob, bool use_wire, bool use_mask)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup, const char *name, const float *value, int arraysize)
void DRW_draw_pass(DRWPass *pass)
void DRW_select_load_id(uint id)
const int state
ccl_gpu_kernel_postfix ccl_global float int int int int sh
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
BASIC_StorageList * stl
Definition: basic_engine.c:47
DRWViewportEmptyList * fbl
Definition: basic_engine.c:44
void * engine_type
Definition: basic_engine.c:43
BASIC_PassList * psl
Definition: basic_engine.c:46
DRWViewportEmptyList * txl
Definition: basic_engine.c:45
struct DRWPass * depth_pass_pointcloud[2]
Definition: basic_engine.c:38
struct DRWPass * depth_pass_cull[2]
Definition: basic_engine.c:39
struct DRWPass * depth_pass[2]
Definition: basic_engine.c:37
DRWShadingGroup * depth_shgrp[2]
Definition: basic_engine.c:53
DRWShadingGroup * depth_hair_shgrp[2]
Definition: basic_engine.c:55
DRWShadingGroup * depth_shgrp_cull[2]
Definition: basic_engine.c:54
DRWShadingGroup * depth_pointcloud_shgrp[2]
Definition: basic_engine.c:57
bool use_material_slot_selection
Definition: basic_engine.c:58
DRWShadingGroup * depth_curves_shgrp[2]
Definition: basic_engine.c:56
struct BASIC_PrivateData * g_data
Definition: basic_engine.c:33
eGPUShaderConfig sh_cfg
Definition: DRW_render.h:993
struct View3D * v3d
Definition: DRW_render.h:976
struct Object * object_edit
Definition: DRW_render.h:1003
struct RegionView3D * rv3d
Definition: DRW_render.h:975
void * first
Definition: DNA_listBase.h:31
ListBase particlesystem
Object_Runtime runtime
View3DOverlay overlay
View3DShading shading
#define N_(msgid)