Blender  V2.93
basic_engine.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2016, Blender Foundation.
17  */
18 
26 #include "DRW_render.h"
27 
28 #include "BKE_paint.h"
29 #include "BKE_particle.h"
30 
31 #include "DNA_particle_types.h"
32 
33 #include "GPU_shader.h"
34 
35 #include "basic_engine.h"
36 /* Shaders */
37 
38 #define BASIC_ENGINE "BLENDER_BASIC"
39 
40 extern char datatoc_depth_frag_glsl[];
41 extern char datatoc_depth_vert_glsl[];
43 
44 extern char datatoc_common_view_lib_glsl[];
45 
46 /* *********** LISTS *********** */
47 
48 /* GPUViewport.storage
49  * Is freed every time the viewport engine changes. */
50 typedef struct BASIC_StorageList {
53 
54 typedef struct BASIC_PassList {
55  struct DRWPass *depth_pass[2];
58 
59 typedef struct BASIC_Data {
60  void *engine_type;
66 
67 typedef struct BASIC_Shaders {
68  /* Depth Pre Pass */
69  struct GPUShader *depth;
72 
73 /* *********** STATIC *********** */
74 
75 static struct {
77 } e_data = {{{NULL}}}; /* Engine data */
78 
79 typedef struct BASIC_PrivateData {
83 } BASIC_PrivateData; /* Transient data */
84 
85 /* Functions */
86 
87 static void basic_engine_init(void *UNUSED(vedata))
88 {
89  const DRWContextState *draw_ctx = DRW_context_state_get();
90  BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
91 
92  /* Depth prepass */
93  if (!sh_data->depth) {
94  const GPUShaderConfigData *sh_cfg = &GPU_shader_cfg_data[draw_ctx->sh_cfg];
95 
97  .vert = (const char *[]){sh_cfg->lib,
100  NULL},
101  .frag = (const char *[]){datatoc_depth_frag_glsl, NULL},
102  .defs = (const char *[]){sh_cfg->def, NULL},
103  });
104 
106  .vert = (const char *[]){sh_cfg->lib,
109  NULL},
110  .geom = (const char *[]){sh_cfg->lib,
113  NULL},
114  .frag = (const char *[]){datatoc_depth_frag_glsl, NULL},
115  .defs = (const char *[]){sh_cfg->def, "#define CONSERVATIVE_RASTER\n", NULL},
116  });
117  }
118 }
119 
120 static void basic_cache_init(void *vedata)
121 {
122  BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
123  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
124  DRWShadingGroup *grp;
125 
126  const DRWContextState *draw_ctx = DRW_context_state_get();
127  BASIC_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg];
128 
129  if (!stl->g_data) {
130  /* Alloc transient pointers */
131  stl->g_data = MEM_callocN(sizeof(*stl->g_data), __func__);
132  }
133 
134  /* Twice for normal and in front objects. */
135  for (int i = 0; i < 2; i++) {
136  DRWState clip_state = (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? DRW_STATE_CLIP_PLANES : 0;
137  DRWState infront_state = (DRW_state_is_select() && (i == 1)) ? DRW_STATE_IN_FRONT_SELECT : 0;
139 
141 
142  DRW_PASS_CREATE(psl->depth_pass[i], state | clip_state | infront_state);
143  stl->g_data->depth_shgrp[i] = grp = DRW_shgroup_create(sh, psl->depth_pass[i]);
144  DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
145  DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
146 
148  psl->depth_pass[i]);
149 
151  DRW_PASS_CREATE(psl->depth_pass_cull[i], state | clip_state | infront_state);
152  stl->g_data->depth_shgrp_cull[i] = grp = DRW_shgroup_create(sh, psl->depth_pass_cull[i]);
153  DRW_shgroup_uniform_vec2(grp, "sizeViewport", DRW_viewport_size_get(), 1);
154  DRW_shgroup_uniform_vec2(grp, "sizeViewportInv", DRW_viewport_invert_size_get(), 1);
155  }
156 }
157 
158 static void basic_cache_populate(void *vedata, Object *ob)
159 {
160  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
161 
162  /* TODO(fclem): fix selection of smoke domains. */
163 
164  if (!DRW_object_is_renderable(ob) || (ob->dt < OB_SOLID)) {
165  return;
166  }
167 
168  bool do_in_front = (ob->dtx & OB_DRAW_IN_FRONT) != 0;
169 
170  const DRWContextState *draw_ctx = DRW_context_state_get();
171  if (ob != draw_ctx->object_edit) {
172  for (ParticleSystem *psys = ob->particlesystem.first; psys != NULL; psys = psys->next) {
174  continue;
175  }
176  ParticleSettings *part = psys->part;
177  const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
178  if (draw_as == PART_DRAW_PATH) {
179  struct GPUBatch *hairs = DRW_cache_particles_get_hair(ob, psys, NULL);
180  DRW_shgroup_call(stl->g_data->depth_hair_shgrp[do_in_front], hairs, NULL);
181  }
182  }
183  }
184 
185  /* Make flat object selectable in ortho view if wireframe is enabled. */
186  if ((draw_ctx->v3d->overlay.flag & V3D_OVERLAY_WIREFRAMES) ||
187  (draw_ctx->v3d->shading.type == OB_WIRE) || (ob->dtx & OB_DRAWWIRE) || (ob->dt == OB_WIRE)) {
188  int flat_axis = 0;
189  bool is_flat_object_viewed_from_side = ((draw_ctx->rv3d->persp == RV3D_ORTHO) &&
190  DRW_object_is_flat(ob, &flat_axis) &&
191  DRW_object_axis_orthogonal_to_view(ob, flat_axis));
192 
193  if (is_flat_object_viewed_from_side) {
194  /* Avoid losing flat objects when in ortho views (see T56549) */
195  struct GPUBatch *geom = DRW_cache_object_all_edges_get(ob);
196  if (geom) {
197  DRW_shgroup_call(stl->g_data->depth_shgrp[do_in_front], geom, ob);
198  }
199  return;
200  }
201  }
202 
203  const bool use_sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->v3d) &&
205  const bool do_cull = (draw_ctx->v3d &&
207  DRWShadingGroup *shgrp = (do_cull) ? stl->g_data->depth_shgrp_cull[do_in_front] :
208  stl->g_data->depth_shgrp[do_in_front];
209 
210  if (use_sculpt_pbvh) {
211  DRW_shgroup_call_sculpt(shgrp, ob, false, false);
212  }
213  else {
214  struct GPUBatch *geom = DRW_cache_object_surface_get(ob);
215  if (geom) {
216  DRW_shgroup_call(shgrp, geom, ob);
217  }
218  }
219 }
220 
221 static void basic_cache_finish(void *vedata)
222 {
223  BASIC_StorageList *stl = ((BASIC_Data *)vedata)->stl;
224 
225  UNUSED_VARS(stl);
226 }
227 
228 static void basic_draw_scene(void *vedata)
229 {
230  BASIC_PassList *psl = ((BASIC_Data *)vedata)->psl;
231 
232  DRW_draw_pass(psl->depth_pass[0]);
234  DRW_draw_pass(psl->depth_pass[1]);
236 }
237 
238 static void basic_engine_free(void)
239 {
240  for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) {
241  BASIC_Shaders *sh_data = &e_data.sh_data[i];
244  }
245 }
246 
248 
250  NULL,
251  NULL,
252  N_("Basic"),
260  NULL,
261  NULL,
262  NULL,
263  NULL,
264 };
265 
266 #undef BASIC_ENGINE
bool BKE_sculptsession_use_pbvh_draw(const struct Object *ob, const struct View3D *v3d)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define N_(msgid)
@ OB_WIRE
@ OB_SOLID
@ 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:91
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_CLIP_PLANES
Definition: DRW_render.h:354
@ DRW_STATE_IN_FRONT_SELECT
Definition: DRW_render.h:352
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
@ DRW_STATE_CULL_BACK
Definition: DRW_render.h:328
#define DRW_SHADER_FREE_SAFE(shader)
Definition: DRW_render.h:279
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
#define DRW_VIEWPORT_DATA_SIZE(ty)
Definition: DRW_render.h:97
#define DRW_shgroup_call(shgroup, geom, ob)
Definition: DRW_render.h:420
GPUBatch
Definition: GPU_batch.h:93
struct GPUShader GPUShader
Definition: GPU_shader.h:33
@ GPU_SHADER_CFG_CLIPPED
Definition: GPU_shader.h:393
const GPUShaderConfigData GPU_shader_cfg_data[GPU_SHADER_CFG_LEN]
#define GPU_shader_create_from_arrays(...)
Definition: GPU_shader.h:69
#define GPU_SHADER_CFG_LEN
Definition: GPU_shader.h:395
char datatoc_conservative_depth_geom_glsl[]
struct BASIC_Data BASIC_Data
static void basic_cache_populate(void *vedata, Object *ob)
Definition: basic_engine.c:158
struct BASIC_PrivateData BASIC_PrivateData
struct BASIC_StorageList BASIC_StorageList
BASIC_Shaders sh_data[GPU_SHADER_CFG_LEN]
Definition: basic_engine.c:76
static const DrawEngineDataSize basic_data_size
Definition: basic_engine.c:247
static void basic_cache_finish(void *vedata)
Definition: basic_engine.c:221
char datatoc_common_view_lib_glsl[]
struct BASIC_PassList BASIC_PassList
static void basic_engine_init(void *UNUSED(vedata))
Definition: basic_engine.c:87
static void basic_engine_free(void)
Definition: basic_engine.c:238
char datatoc_depth_vert_glsl[]
DrawEngineType draw_engine_basic_type
Definition: basic_engine.c:249
static void basic_cache_init(void *vedata)
Definition: basic_engine.c:120
struct BASIC_Shaders BASIC_Shaders
static void basic_draw_scene(void *vedata)
Definition: basic_engine.c:228
static struct @191 e_data
char datatoc_depth_frag_glsl[]
GPUBatch * DRW_cache_object_all_edges_get(Object *ob)
Definition: draw_cache.c:799
GPUBatch * DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
Definition: draw_cache.c:3332
GPUBatch * DRW_cache_object_surface_get(Object *ob)
Definition: draw_cache.c:886
bool DRW_object_is_flat(Object *ob, int *r_axis)
Definition: draw_common.c:441
bool DRW_object_axis_orthogonal_to_view(Object *ob, int axis)
Definition: draw_common.c:474
bool DRW_state_is_select(void)
bool DRW_object_is_renderable(const Object *ob)
Definition: draw_manager.c:183
bool DRW_object_is_visible_psys_in_active_context(const Object *object, const ParticleSystem *psys)
Definition: draw_manager.c:271
const DRWContextState * DRW_context_state_get(void)
const float * DRW_viewport_size_get(void)
Definition: draw_manager.c:439
bool DRW_state_is_image_render(void)
const float * DRW_viewport_invert_size_get(void)
Definition: draw_manager.c:444
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 *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static ulong state[N]
BASIC_StorageList * stl
Definition: basic_engine.c:64
DRWViewportEmptyList * fbl
Definition: basic_engine.c:61
void * engine_type
Definition: basic_engine.c:60
BASIC_PassList * psl
Definition: basic_engine.c:63
DRWViewportEmptyList * txl
Definition: basic_engine.c:62
struct DRWPass * depth_pass_cull[2]
Definition: basic_engine.c:56
struct DRWPass * depth_pass[2]
Definition: basic_engine.c:55
DRWShadingGroup * depth_shgrp[2]
Definition: basic_engine.c:80
DRWShadingGroup * depth_hair_shgrp[2]
Definition: basic_engine.c:82
DRWShadingGroup * depth_shgrp_cull[2]
Definition: basic_engine.c:81
struct GPUShader * depth
Definition: basic_engine.c:69
struct GPUShader * depth_conservative
Definition: basic_engine.c:70
struct BASIC_PrivateData * g_data
Definition: basic_engine.c:51
eGPUShaderConfig sh_cfg
Definition: DRW_render.h:759
struct View3D * v3d
Definition: DRW_render.h:742
struct Object * object_edit
Definition: DRW_render.h:769
struct RegionView3D * rv3d
Definition: DRW_render.h:741
const char * lib
Definition: GPU_shader.h:398
const char * def
Definition: GPU_shader.h:399
void * first
Definition: DNA_listBase.h:47
ListBase particlesystem
View3DOverlay overlay
View3DShading shading