Fix empty-images not using selection color
[blender.git] / source / blender / draw / modes / object_mode.c
1 /*
2  * Copyright 2016, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Blender Institute
19  *
20  */
21
22 /** \file blender/draw/modes/object_mode.c
23  *  \ingroup draw
24  */
25
26 #include "DRW_engine.h"
27 #include "DRW_render.h"
28
29 #include "DNA_userdef_types.h"
30 #include "DNA_armature_types.h"
31 #include "DNA_camera_types.h"
32 #include "DNA_curve_types.h"
33 #include "DNA_mesh_types.h"
34 #include "DNA_meta_types.h"
35 #include "DNA_object_force_types.h"
36 #include "DNA_lightprobe_types.h"
37 #include "DNA_particle_types.h"
38 #include "DNA_rigidbody_types.h"
39 #include "DNA_view3d_types.h"
40 #include "DNA_world_types.h"
41
42 #include "BIF_gl.h"
43
44 #include "BLI_string_utils.h"
45
46 #include "BKE_anim.h"
47 #include "BKE_camera.h"
48 #include "BKE_curve.h"
49 #include "BKE_global.h"
50 #include "BKE_mball.h"
51 #include "BKE_mesh.h"
52 #include "BKE_object.h"
53 #include "BKE_particle.h"
54 #include "BKE_image.h"
55 #include "BKE_texture.h"
56
57 #include "ED_view3d.h"
58
59 #include "GPU_shader.h"
60 #include "GPU_texture.h"
61
62 #include "MEM_guardedalloc.h"
63
64 #include "UI_resources.h"
65
66 #include "draw_mode_engines.h"
67 #include "draw_manager_text.h"
68 #include "draw_common.h"
69
70 #include "DEG_depsgraph_query.h"
71
72 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
73 extern struct GPUTexture *globals_ramp; /* draw_common.c */
74 extern GlobalsUboStorage ts;
75
76 extern char datatoc_object_outline_prepass_vert_glsl[];
77 extern char datatoc_object_outline_prepass_geom_glsl[];
78 extern char datatoc_object_outline_prepass_frag_glsl[];
79 extern char datatoc_object_outline_resolve_frag_glsl[];
80 extern char datatoc_object_outline_detect_frag_glsl[];
81 extern char datatoc_object_outline_expand_frag_glsl[];
82 extern char datatoc_object_grid_frag_glsl[];
83 extern char datatoc_object_grid_vert_glsl[];
84 extern char datatoc_object_empty_image_frag_glsl[];
85 extern char datatoc_object_empty_image_vert_glsl[];
86 extern char datatoc_object_lightprobe_grid_vert_glsl[];
87 extern char datatoc_object_particle_prim_vert_glsl[];
88 extern char datatoc_object_particle_dot_vert_glsl[];
89 extern char datatoc_object_particle_dot_frag_glsl[];
90 extern char datatoc_common_globals_lib_glsl[];
91 extern char datatoc_common_fxaa_lib_glsl[];
92 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
93 extern char datatoc_gpu_shader_flat_id_frag_glsl[];
94 extern char datatoc_common_fullscreen_vert_glsl[];
95 extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
96
97 /* *********** LISTS *********** */
98 typedef struct OBJECT_PassList {
99         struct DRWPass *non_meshes;
100         struct DRWPass *ob_center;
101         struct DRWPass *outlines;
102         struct DRWPass *outlines_search;
103         struct DRWPass *outlines_expand;
104         struct DRWPass *outlines_bleed;
105         struct DRWPass *outlines_resolve;
106         struct DRWPass *grid;
107         struct DRWPass *bone_solid;
108         struct DRWPass *bone_outline;
109         struct DRWPass *bone_wire;
110         struct DRWPass *bone_envelope;
111         struct DRWPass *bone_axes;
112         struct DRWPass *particle;
113         struct DRWPass *lightprobes;
114         /* use for empty/background images */
115         struct DRWPass *reference_image;
116 } OBJECT_PassList;
117
118 typedef struct OBJECT_FramebufferList {
119         struct GPUFrameBuffer *outlines_fb;
120         struct GPUFrameBuffer *blur_fb;
121         struct GPUFrameBuffer *expand_fb;
122 } OBJECT_FramebufferList;
123
124 typedef struct OBJECT_StorageList {
125         struct OBJECT_PrivateData *g_data;
126 } OBJECT_StorageList;
127
128 typedef struct OBJECT_Data {
129         void *engine_type;
130         OBJECT_FramebufferList *fbl;
131         DRWViewportEmptyList *txl;
132         OBJECT_PassList *psl;
133         OBJECT_StorageList *stl;
134 } OBJECT_Data;
135
136 /* *********** STATIC *********** */
137
138 typedef struct OBJECT_PrivateData {
139         /* Empties */
140         DRWShadingGroup *plain_axes;
141         DRWShadingGroup *cube;
142         DRWShadingGroup *circle;
143         DRWShadingGroup *sphere;
144         DRWShadingGroup *cone;
145         DRWShadingGroup *single_arrow;
146         DRWShadingGroup *single_arrow_line;
147         DRWShadingGroup *arrows;
148         DRWShadingGroup *axis_names;
149         /* GPUTexture -> EmptyImageShadingGroupData */
150         GHash *image_plane_map;
151
152         /* Force Field */
153         DRWShadingGroup *field_wind;
154         DRWShadingGroup *field_force;
155         DRWShadingGroup *field_vortex;
156         DRWShadingGroup *field_curve_sta;
157         DRWShadingGroup *field_curve_end;
158         DRWShadingGroup *field_tube_limit;
159         DRWShadingGroup *field_cone_limit;
160
161         /* Speaker */
162         DRWShadingGroup *speaker;
163
164         /* Probe */
165         DRWShadingGroup *probe_cube;
166         DRWShadingGroup *probe_planar;
167         DRWShadingGroup *probe_grid;
168
169         /* MetaBalls */
170         DRWShadingGroup *mball_handle;
171
172         /* Lamps */
173         DRWShadingGroup *lamp_center;
174         DRWShadingGroup *lamp_groundpoint;
175         DRWShadingGroup *lamp_groundline;
176         DRWShadingGroup *lamp_circle;
177         DRWShadingGroup *lamp_circle_shadow;
178         DRWShadingGroup *lamp_sunrays;
179         DRWShadingGroup *lamp_distance;
180         DRWShadingGroup *lamp_buflimit;
181         DRWShadingGroup *lamp_buflimit_points;
182         DRWShadingGroup *lamp_area_sphere;
183         DRWShadingGroup *lamp_area_square;
184         DRWShadingGroup *lamp_area_disk;
185         DRWShadingGroup *lamp_hemi;
186         DRWShadingGroup *lamp_spot_cone;
187         DRWShadingGroup *lamp_spot_blend;
188         DRWShadingGroup *lamp_spot_pyramid;
189         DRWShadingGroup *lamp_spot_blend_rect;
190
191         /* Helpers */
192         DRWShadingGroup *relationship_lines;
193
194         /* Objects Centers */
195         DRWShadingGroup *center_active;
196         DRWShadingGroup *center_selected;
197         DRWShadingGroup *center_deselected;
198         DRWShadingGroup *center_selected_lib;
199         DRWShadingGroup *center_deselected_lib;
200
201         /* Camera */
202         DRWShadingGroup *camera;
203         DRWShadingGroup *camera_frame;
204         DRWShadingGroup *camera_tria;
205         DRWShadingGroup *camera_focus;
206         DRWShadingGroup *camera_clip;
207         DRWShadingGroup *camera_clip_points;
208         DRWShadingGroup *camera_mist;
209         DRWShadingGroup *camera_mist_points;
210
211         /* Outlines */
212         DRWShadingGroup *outlines_active;
213         DRWShadingGroup *outlines_select;
214         DRWShadingGroup *outlines_transform;
215
216         /* Lightprobes */
217         DRWShadingGroup *lightprobes_cube_select;
218         DRWShadingGroup *lightprobes_cube_active;
219         DRWShadingGroup *lightprobes_cube_transform;
220
221         DRWShadingGroup *lightprobes_planar_select;
222         DRWShadingGroup *lightprobes_planar_active;
223         DRWShadingGroup *lightprobes_planar_transform;
224
225         /* Wire */
226         DRWShadingGroup *wire;
227         DRWShadingGroup *wire_active;
228         DRWShadingGroup *wire_select;
229         DRWShadingGroup *wire_transform;
230
231         /* Points */
232         DRWShadingGroup *points;
233         DRWShadingGroup *points_active;
234         DRWShadingGroup *points_select;
235         DRWShadingGroup *points_transform;
236
237         /* Texture Space */
238         DRWShadingGroup *texspace;
239
240         /* Outlines id offset */
241         int id_ofs_active;
242         int id_ofs_select;
243         int id_ofs_transform;
244         int id_ofs_prb_active;
245         int id_ofs_prb_select;
246         int id_ofs_prb_transform;
247 } OBJECT_PrivateData; /* Transient data */
248
249 static struct {
250         /* Instance Data format */
251         struct Gwn_VertFormat *particle_format;
252         struct Gwn_VertFormat *empty_image_format;
253         struct Gwn_VertFormat *empty_image_wire_format;
254
255         /* fullscreen shaders */
256         GPUShader *outline_prepass_sh;
257         GPUShader *outline_prepass_wire_sh;
258         GPUShader *outline_resolve_sh;
259         GPUShader *outline_resolve_aa_sh;
260         GPUShader *outline_detect_sh;
261         GPUShader *outline_detect_wire_sh;
262         GPUShader *outline_fade_sh;
263
264         /* regular shaders */
265         GPUShader *object_empty_image_sh;
266         GPUShader *object_empty_image_wire_sh;
267         GPUShader *grid_sh;
268         GPUShader *part_dot_sh;
269         GPUShader *part_prim_sh;
270         GPUShader *part_axis_sh;
271         GPUShader *lightprobe_grid_sh;
272         float camera_pos[3];
273         float screenvecs[3][4];
274         float grid_settings[5];
275         int grid_flag;
276         float grid_normal[3];
277         float grid_axes[3];
278         int zpos_flag;
279         int zneg_flag;
280         float zplane_normal[3];
281         float zplane_axes[3];
282         float inv_viewport_size[2];
283         bool draw_grid;
284         /* Temp buffer textures */
285         struct GPUTexture *outlines_depth_tx;
286         struct GPUTexture *outlines_id_tx;
287         struct GPUTexture *outlines_color_tx;
288         struct GPUTexture *outlines_blur_tx;
289 } e_data = {NULL}; /* Engine data */
290
291
292 enum {
293         SHOW_AXIS_X  = (1 << 0),
294         SHOW_AXIS_Y  = (1 << 1),
295         SHOW_AXIS_Z  = (1 << 2),
296         SHOW_GRID    = (1 << 3),
297         PLANE_XY     = (1 << 4),
298         PLANE_XZ     = (1 << 5),
299         PLANE_YZ     = (1 << 6),
300         CLIP_ZPOS    = (1 << 7),
301         CLIP_ZNEG    = (1 << 8),
302         GRID_BACK    = (1 << 9),
303 };
304
305 /* *********** FUNCTIONS *********** */
306
307 static void OBJECT_engine_init(void *vedata)
308 {
309         OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
310
311         const float *viewport_size = DRW_viewport_size_get();
312         const int size[2] = {(int)viewport_size[0], (int)viewport_size[1]};
313
314         if (DRW_state_is_fbo()) {
315                 e_data.outlines_depth_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_DEPTH_COMPONENT24,
316                                                                      &draw_engine_object_type);
317                 /* XXX TODO GPU_R16UI can overflow, it would cause no harm
318                  * (only bad colored or missing outlines) but we should
319                  * use 32bits only if the scene have that many objects */
320                 e_data.outlines_id_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_R16UI,
321                                                                   &draw_engine_object_type);
322
323                 GPU_framebuffer_ensure_config(&fbl->outlines_fb, {
324                         GPU_ATTACHMENT_TEXTURE(e_data.outlines_depth_tx),
325                         GPU_ATTACHMENT_TEXTURE(e_data.outlines_id_tx)
326                 });
327
328                 e_data.outlines_color_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
329                                                                      &draw_engine_object_type);
330
331                 GPU_framebuffer_ensure_config(&fbl->expand_fb, {
332                         GPU_ATTACHMENT_NONE,
333                         GPU_ATTACHMENT_TEXTURE(e_data.outlines_color_tx)
334                 });
335
336                 e_data.outlines_blur_tx = DRW_texture_pool_query_2D(size[0], size[1], GPU_RGBA8,
337                                                                     &draw_engine_object_type);
338
339                 GPU_framebuffer_ensure_config(&fbl->blur_fb, {
340                         GPU_ATTACHMENT_NONE,
341                         GPU_ATTACHMENT_TEXTURE(e_data.outlines_blur_tx)
342                 });
343         }
344
345         /* Shaders */
346         if (!e_data.outline_resolve_sh) {
347                 /* Outline */
348                 e_data.outline_prepass_sh = DRW_shader_create_3D(datatoc_object_outline_prepass_frag_glsl, NULL);
349
350                 e_data.outline_prepass_wire_sh = DRW_shader_create(
351                             datatoc_object_outline_prepass_vert_glsl,
352                             datatoc_object_outline_prepass_geom_glsl,
353                             datatoc_object_outline_prepass_frag_glsl, NULL);
354
355                 e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL);
356
357                 e_data.outline_resolve_aa_sh = DRW_shader_create_with_lib(
358                             datatoc_common_fullscreen_vert_glsl, NULL,
359                             datatoc_object_outline_resolve_frag_glsl,
360                             datatoc_common_fxaa_lib_glsl,
361                             "#define FXAA_ALPHA\n"
362                             "#define USE_FXAA\n");
363
364                 e_data.outline_detect_sh = DRW_shader_create_with_lib(
365                             datatoc_common_fullscreen_vert_glsl, NULL,
366                             datatoc_object_outline_detect_frag_glsl,
367                             datatoc_common_globals_lib_glsl,
368                             "#extension GL_ARB_texture_gather : enable\n");
369
370                 e_data.outline_detect_wire_sh = DRW_shader_create_with_lib(
371                             datatoc_common_fullscreen_vert_glsl, NULL,
372                             datatoc_object_outline_detect_frag_glsl,
373                             datatoc_common_globals_lib_glsl,
374                             "#define WIRE\n"
375                             "#extension GL_ARB_texture_gather : enable\n");
376
377
378                 e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
379
380                 /* Empty images */
381                 e_data.object_empty_image_sh = DRW_shader_create_with_lib(
382                            datatoc_object_empty_image_vert_glsl, NULL,
383                            datatoc_object_empty_image_frag_glsl,
384                            datatoc_common_globals_lib_glsl, NULL);
385
386                 e_data.object_empty_image_wire_sh = DRW_shader_create_with_lib(
387                            datatoc_object_empty_image_vert_glsl, NULL,
388                            datatoc_object_empty_image_frag_glsl,
389                            datatoc_common_globals_lib_glsl,
390                            "#define USE_WIRE\n");
391
392                 /* Grid */
393                 e_data.grid_sh = DRW_shader_create_with_lib(
394                         datatoc_object_grid_vert_glsl, NULL,
395                         datatoc_object_grid_frag_glsl,
396                         datatoc_common_globals_lib_glsl, NULL);
397
398                 /* Particles */
399                 e_data.part_prim_sh = DRW_shader_create(
400                         datatoc_object_particle_prim_vert_glsl, NULL, datatoc_gpu_shader_flat_color_frag_glsl, NULL);
401
402                 e_data.part_axis_sh = DRW_shader_create(
403                         datatoc_object_particle_prim_vert_glsl, NULL, datatoc_gpu_shader_flat_color_frag_glsl,
404                         "#define USE_AXIS\n");
405
406                 e_data.part_dot_sh = DRW_shader_create(
407                         datatoc_object_particle_dot_vert_glsl, NULL, datatoc_object_particle_dot_frag_glsl, NULL);
408
409                 /* Lightprobes */
410                 e_data.lightprobe_grid_sh = DRW_shader_create(
411                         datatoc_object_lightprobe_grid_vert_glsl, NULL, datatoc_gpu_shader_flat_id_frag_glsl, NULL);
412         }
413
414         {
415                 /* Grid precompute */
416                 float invviewmat[4][4], invwinmat[4][4];
417                 float viewmat[4][4], winmat[4][4];
418                 const DRWContextState *draw_ctx = DRW_context_state_get();
419                 View3D *v3d = draw_ctx->v3d;
420                 Scene *scene = draw_ctx->scene;
421                 RegionView3D *rv3d = draw_ctx->rv3d;
422                 float grid_scale = ED_view3d_grid_scale(scene, v3d, NULL);
423                 float grid_res;
424
425                 const bool show_axis_x = (v3d->gridflag & V3D_SHOW_X) != 0;
426                 const bool show_axis_y = (v3d->gridflag & V3D_SHOW_Y) != 0;
427                 const bool show_axis_z = (v3d->gridflag & V3D_SHOW_Z) != 0;
428                 const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) != 0;
429                 e_data.draw_grid = show_axis_x || show_axis_y || show_axis_z || show_floor;
430
431                 DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
432                 DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
433                 DRW_viewport_matrix_get(invwinmat, DRW_MAT_WININV);
434                 DRW_viewport_matrix_get(invviewmat, DRW_MAT_VIEWINV);
435
436                 /* Setup camera pos */
437                 copy_v3_v3(e_data.camera_pos, invviewmat[3]);
438
439                 /* if perps */
440                 if (winmat[3][3] == 0.0f) {
441                         float fov;
442                         float viewvecs[2][4] = {
443                             {1.0f, -1.0f, -1.0f, 1.0f},
444                             {-1.0f, 1.0f, -1.0f, 1.0f}
445                         };
446
447                         /* convert the view vectors to view space */
448                         for (int i = 0; i < 2; i++) {
449                                 mul_m4_v4(invwinmat, viewvecs[i]);
450                                 mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); /* perspective divide */
451                         }
452
453                         fov = angle_v3v3(viewvecs[0], viewvecs[1]) / 2.0f;
454                         grid_res = fabsf(tanf(fov)) / grid_scale;
455
456                         e_data.grid_flag = (1 << 4); /* XY plane */
457                         if (show_axis_x)
458                                 e_data.grid_flag |= SHOW_AXIS_X;
459                         if (show_axis_y)
460                                 e_data.grid_flag |= SHOW_AXIS_Y;
461                         if (show_floor)
462                                 e_data.grid_flag |= SHOW_GRID;
463
464                 }
465                 else {
466                         float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
467                         grid_res = viewdist / grid_scale;
468
469                         if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
470                                 e_data.grid_flag = PLANE_YZ;
471                                 e_data.grid_flag |= SHOW_AXIS_Y;
472                                 e_data.grid_flag |= SHOW_AXIS_Z;
473                                 e_data.grid_flag |= SHOW_GRID;
474                                 e_data.grid_flag |= GRID_BACK;
475                         }
476                         else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
477                                 e_data.grid_flag = PLANE_XY;
478                                 e_data.grid_flag |= SHOW_AXIS_X;
479                                 e_data.grid_flag |= SHOW_AXIS_Y;
480                                 e_data.grid_flag |= SHOW_GRID;
481                                 e_data.grid_flag |= GRID_BACK;
482                         }
483                         else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
484                                 e_data.grid_flag = PLANE_XZ;
485                                 e_data.grid_flag |= SHOW_AXIS_X;
486                                 e_data.grid_flag |= SHOW_AXIS_Z;
487                                 e_data.grid_flag |= SHOW_GRID;
488                                 e_data.grid_flag |= GRID_BACK;
489                         }
490                         else { /* RV3D_VIEW_USER */
491                                 e_data.grid_flag = PLANE_XY;
492                                 if (show_axis_x)
493                                         e_data.grid_flag |= SHOW_AXIS_X;
494                                 if (show_axis_y)
495                                         e_data.grid_flag |= SHOW_AXIS_Y;
496                                 if (show_floor)
497                                         e_data.grid_flag |= SHOW_GRID;
498                         }
499                 }
500
501                 e_data.grid_normal[0] = (float)((e_data.grid_flag & PLANE_YZ) != 0);
502                 e_data.grid_normal[1] = (float)((e_data.grid_flag & PLANE_XZ) != 0);
503                 e_data.grid_normal[2] = (float)((e_data.grid_flag & PLANE_XY) != 0);
504
505                 e_data.grid_axes[0] = (float)((e_data.grid_flag & (PLANE_XZ | PLANE_XY)) != 0);
506                 e_data.grid_axes[1] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XY)) != 0);
507                 e_data.grid_axes[2] = (float)((e_data.grid_flag & (PLANE_YZ | PLANE_XZ)) != 0);
508
509                 /* Vectors to recover pixel world position. Fix grid precision issue. */
510                 /* Using pixel at z = 0.0f in ndc space : gives average precision between
511                  * near and far plane. Note that it might not be the best choice. */
512                 copy_v4_fl4(e_data.screenvecs[0],  1.0f, -1.0f, 0.0f, 1.0f);
513                 copy_v4_fl4(e_data.screenvecs[1], -1.0f,  1.0f, 0.0f, 1.0f);
514                 copy_v4_fl4(e_data.screenvecs[2], -1.0f, -1.0f, 0.0f, 1.0f);
515
516                 for (int i = 0; i < 3; i++) {
517                         /* Doing 2 steps to recover world position of the corners of the frustum.
518                          * Using the inverse perspective matrix is giving very low precision output. */
519                         mul_m4_v4(invwinmat, e_data.screenvecs[i]);
520                         e_data.screenvecs[i][0] /= e_data.screenvecs[i][3]; /* perspective divide */
521                         e_data.screenvecs[i][1] /= e_data.screenvecs[i][3]; /* perspective divide */
522                         e_data.screenvecs[i][2] /= e_data.screenvecs[i][3]; /* perspective divide */
523                         e_data.screenvecs[i][3] = 1.0f;
524                         /* main instability come from this one */
525                         /* TODO : to make things even more stable, don't use
526                          * invviewmat and derive vectors from camera properties */
527                         mul_m4_v4(invviewmat, e_data.screenvecs[i]);
528                 }
529
530                 sub_v3_v3(e_data.screenvecs[0], e_data.screenvecs[2]);
531                 sub_v3_v3(e_data.screenvecs[1], e_data.screenvecs[2]);
532
533                 /* Z axis if needed */
534                 if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
535                         e_data.zpos_flag = SHOW_AXIS_Z;
536
537                         float zvec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
538                         mul_m4_v4(invviewmat, zvec);
539
540                         /* z axis : chose the most facing plane */
541                         if (fabsf(zvec[0]) < fabsf(zvec[1])) {
542                                 e_data.zpos_flag |= PLANE_XZ;
543                         }
544                         else {
545                                 e_data.zpos_flag |= PLANE_YZ;
546                         }
547
548                         e_data.zneg_flag = e_data.zpos_flag;
549
550                         /* Persp : If camera is below floor plane, we switch clipping
551                          * Ortho : If eye vector is looking up, we switch clipping */
552                         if (((winmat[3][3] == 0.0f) && (e_data.camera_pos[2] > 0.0f)) ||
553                             ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f)))
554                         {
555                                 e_data.zpos_flag |= CLIP_ZPOS;
556                                 e_data.zneg_flag |= CLIP_ZNEG;
557                         }
558                         else {
559                                 e_data.zpos_flag |= CLIP_ZNEG;
560                                 e_data.zneg_flag |= CLIP_ZPOS;
561                         }
562
563                         e_data.zplane_normal[0] = (float)((e_data.zpos_flag & PLANE_YZ) != 0);
564                         e_data.zplane_normal[1] = (float)((e_data.zpos_flag & PLANE_XZ) != 0);
565                         e_data.zplane_normal[2] = (float)((e_data.zpos_flag & PLANE_XY) != 0);
566
567                         e_data.zplane_axes[0] = (float)((e_data.zpos_flag & (PLANE_XZ | PLANE_XY)) != 0);
568                         e_data.zplane_axes[1] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XY)) != 0);
569                         e_data.zplane_axes[2] = (float)((e_data.zpos_flag & (PLANE_YZ | PLANE_XZ)) != 0);
570
571                 }
572                 else {
573                         e_data.zneg_flag = e_data.zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
574                 }
575
576                 float dist;
577                 if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
578                         Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
579                         dist = ((Camera *)camera_object)->clipend;
580                 }
581                 else {
582                         dist = v3d->far;
583                 }
584
585                 e_data.grid_settings[0] = dist / 2.0f; /* gridDistance */
586                 e_data.grid_settings[1] = grid_res; /* gridResolution */
587                 e_data.grid_settings[2] = grid_scale; /* gridScale */
588                 e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */
589                 e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / logf(v3d->gridsubdiv) : 0.0f; /* 1/log(gridSubdiv) */
590         }
591
592         copy_v2_v2(e_data.inv_viewport_size, DRW_viewport_size_get());
593         invert_v2(e_data.inv_viewport_size);
594 }
595
596 static void OBJECT_engine_free(void)
597 {
598         MEM_SAFE_FREE(e_data.particle_format);
599         MEM_SAFE_FREE(e_data.empty_image_format);
600         MEM_SAFE_FREE(e_data.empty_image_wire_format);
601         DRW_SHADER_FREE_SAFE(e_data.outline_prepass_sh);
602         DRW_SHADER_FREE_SAFE(e_data.outline_prepass_wire_sh);
603         DRW_SHADER_FREE_SAFE(e_data.outline_resolve_sh);
604         DRW_SHADER_FREE_SAFE(e_data.outline_resolve_aa_sh);
605         DRW_SHADER_FREE_SAFE(e_data.outline_detect_sh);
606         DRW_SHADER_FREE_SAFE(e_data.outline_detect_wire_sh);
607         DRW_SHADER_FREE_SAFE(e_data.outline_fade_sh);
608         DRW_SHADER_FREE_SAFE(e_data.object_empty_image_sh);
609         DRW_SHADER_FREE_SAFE(e_data.object_empty_image_wire_sh);
610         DRW_SHADER_FREE_SAFE(e_data.grid_sh);
611         DRW_SHADER_FREE_SAFE(e_data.part_prim_sh);
612         DRW_SHADER_FREE_SAFE(e_data.part_axis_sh);
613         DRW_SHADER_FREE_SAFE(e_data.part_dot_sh);
614         DRW_SHADER_FREE_SAFE(e_data.lightprobe_grid_sh);
615 }
616
617 static DRWShadingGroup *shgroup_outline(DRWPass *pass, const int *ofs, GPUShader *sh)
618 {
619         DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
620         DRW_shgroup_uniform_int(grp, "baseId", ofs, 1);
621
622         return grp;
623 }
624
625 /* currently same as 'shgroup_outline', new function to avoid confustion */
626 static DRWShadingGroup *shgroup_wire(DRWPass *pass, const float col[4], GPUShader *sh)
627 {
628         DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
629         DRW_shgroup_uniform_vec4(grp, "color", col, 1);
630
631         return grp;
632 }
633
634 /* currently same as 'shgroup_outline', new function to avoid confustion */
635 static DRWShadingGroup *shgroup_points(DRWPass *pass, const float col[4], GPUShader *sh)
636 {
637         DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
638         DRW_shgroup_uniform_vec4(grp, "color", col, 1);
639
640         return grp;
641 }
642
643 static int *shgroup_theme_id_to_probe_outline_counter(
644         OBJECT_StorageList *stl, int theme_id)
645 {
646         switch (theme_id) {
647                 case TH_ACTIVE:
648                         return &stl->g_data->id_ofs_prb_active;
649                 case TH_SELECT:
650                         return &stl->g_data->id_ofs_prb_select;
651                 case TH_TRANSFORM:
652                 default:
653                         return &stl->g_data->id_ofs_prb_transform;
654         }
655 }
656
657 static int *shgroup_theme_id_to_outline_counter(
658         OBJECT_StorageList *stl, int theme_id)
659 {
660         switch (theme_id) {
661                 case TH_ACTIVE:
662                         return &stl->g_data->id_ofs_active;
663                 case TH_SELECT:
664                         return &stl->g_data->id_ofs_select;
665                 case TH_TRANSFORM:
666                 default:
667                         return &stl->g_data->id_ofs_transform;
668         }
669 }
670
671 static DRWShadingGroup *shgroup_theme_id_to_probe_planar_outline_shgrp(
672         OBJECT_StorageList *stl, int theme_id)
673 {
674         /* does not increment counter */
675         switch (theme_id) {
676                 case TH_ACTIVE:
677                         return stl->g_data->lightprobes_planar_active;
678                 case TH_SELECT:
679                         return stl->g_data->lightprobes_planar_select;
680                 case TH_TRANSFORM:
681                 default:
682                         return stl->g_data->lightprobes_planar_transform;
683         }
684 }
685
686 static DRWShadingGroup *shgroup_theme_id_to_probe_cube_outline_shgrp(
687         OBJECT_StorageList *stl, int theme_id)
688 {
689         /* does not increment counter */
690         switch (theme_id) {
691                 case TH_ACTIVE:
692                         return stl->g_data->lightprobes_cube_active;
693                 case TH_SELECT:
694                         return stl->g_data->lightprobes_cube_select;
695                 case TH_TRANSFORM:
696                 default:
697                         return stl->g_data->lightprobes_cube_transform;
698         }
699 }
700
701 static DRWShadingGroup *shgroup_theme_id_to_outline_or(
702         OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback)
703 {
704         int *counter = shgroup_theme_id_to_outline_counter(stl, theme_id);
705         *counter += 1;
706
707         switch (theme_id) {
708                 case TH_ACTIVE:
709                         return stl->g_data->outlines_active;
710                 case TH_SELECT:
711                         return stl->g_data->outlines_select;
712                 case TH_TRANSFORM:
713                         return stl->g_data->outlines_transform;
714                 default:
715                         return fallback;
716         }
717 }
718
719 static DRWShadingGroup *shgroup_theme_id_to_wire_or(
720         OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback)
721 {
722         switch (theme_id) {
723                 case TH_ACTIVE:
724                         return stl->g_data->wire_active;
725                 case TH_SELECT:
726                         return stl->g_data->wire_select;
727                 case TH_TRANSFORM:
728                         return stl->g_data->wire_transform;
729                 default:
730                         return fallback;
731         }
732 }
733
734 static DRWShadingGroup *shgroup_theme_id_to_point_or(
735         OBJECT_StorageList *stl, int theme_id, DRWShadingGroup *fallback)
736 {
737         switch (theme_id) {
738                 case TH_ACTIVE:
739                         return stl->g_data->points_active;
740                 case TH_SELECT:
741                         return stl->g_data->points_select;
742                 case TH_TRANSFORM:
743                         return stl->g_data->points_transform;
744                 default:
745                         return fallback;
746         }
747 }
748
749 static void image_calc_aspect(Image *ima, ImageUser *iuser, float r_image_aspect[2])
750 {
751         float ima_x, ima_y;
752         if (ima) {
753                 int w, h;
754                 BKE_image_get_size(ima, iuser, &w, &h);
755                 ima_x = w;
756                 ima_y = h;
757         }
758         else {
759                 /* if no image, make it a 1x1 empty square, honor scale & offset */
760                 ima_x = ima_y = 1.0f;
761         }
762         /* Get the image aspect even if the buffer is invalid */
763         float sca_x = 1.0f, sca_y = 1.0f;
764         if (ima) {
765                 if (ima->aspx > ima->aspy) {
766                         sca_y = ima->aspy / ima->aspx;
767                 }
768                 else if (ima->aspx < ima->aspy) {
769                         sca_x = ima->aspx / ima->aspy;
770                 }
771         }
772
773         const float scale_x_inv = ima_x * sca_x;
774         const float scale_y_inv = ima_y * sca_y;
775         if (scale_x_inv > scale_y_inv) {
776                 r_image_aspect[0] = 1.0f;
777                 r_image_aspect[1] = scale_y_inv / scale_x_inv;
778         }
779         else {
780                 r_image_aspect[0] = scale_x_inv / scale_y_inv;
781                 r_image_aspect[1] = 1.0f;
782         }
783 }
784
785 /* per-image shading groups for image-type empty objects */
786 struct EmptyImageShadingGroupData {
787         DRWShadingGroup *shgrp_image;
788         DRWShadingGroup *shgrp_wire;
789         float image_aspect[2];
790 };
791
792 static void DRW_shgroup_empty_image(
793         OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, const float color[3])
794 {
795         /* TODO: 'StereoViews', see draw_empty_image. */
796
797         if (stl->g_data->image_plane_map == NULL) {
798                 stl->g_data->image_plane_map = BLI_ghash_ptr_new(__func__);
799         }
800
801         struct EmptyImageShadingGroupData *empty_image_data;
802
803         GPUTexture *tex = ob->data ?
804                 GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, 0.0f) : NULL;
805         void **val_p;
806
807         /* Create on demand, 'tex' may be NULL. */
808         if (BLI_ghash_ensure_p(stl->g_data->image_plane_map, tex, &val_p)) {
809                 empty_image_data = *val_p;
810         }
811         else {
812                 empty_image_data = MEM_mallocN(sizeof(*empty_image_data), __func__);
813
814                 image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect);
815
816                 if (tex) {
817                         DRW_shgroup_instance_format(e_data.empty_image_format, {
818                                 {"objectColor",         DRW_ATTRIB_FLOAT, 4},
819                                 {"size",                DRW_ATTRIB_FLOAT, 1},
820                                 {"offset",              DRW_ATTRIB_FLOAT, 2},
821                                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
822                         });
823
824                         struct Gwn_Batch *geom = DRW_cache_image_plane_get();
825                         DRWShadingGroup *grp = DRW_shgroup_instance_create(
826                                 e_data.object_empty_image_sh, psl->non_meshes, geom, e_data.empty_image_format);
827                         DRW_shgroup_uniform_texture(grp, "image", tex);
828                         DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
829
830                         empty_image_data->shgrp_image = grp;
831                 }
832                 else {
833                         empty_image_data->shgrp_image = NULL;
834                 }
835
836                 {
837                         DRW_shgroup_instance_format(e_data.empty_image_wire_format, {
838                                 {"color",               DRW_ATTRIB_FLOAT, 4},
839                                 {"size",                DRW_ATTRIB_FLOAT, 1},
840                                 {"offset",              DRW_ATTRIB_FLOAT, 2},
841                                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
842                         });
843
844                         struct Gwn_Batch *geom = DRW_cache_image_plane_wire_get();
845                         DRWShadingGroup *grp = DRW_shgroup_instance_create(
846                                 e_data.object_empty_image_wire_sh, psl->non_meshes, geom, e_data.empty_image_wire_format);
847                         DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
848
849                         empty_image_data->shgrp_wire = grp;
850                 }
851
852                 *val_p = empty_image_data;
853         }
854
855         if (empty_image_data->shgrp_image != NULL) {
856                 DRW_shgroup_call_dynamic_add(
857                         empty_image_data->shgrp_image,
858                         ob->col,
859                         &ob->empty_drawsize,
860                         ob->ima_ofs,
861                         ob->obmat);
862         }
863
864         DRW_shgroup_call_dynamic_add(
865                 empty_image_data->shgrp_wire,
866                 color,
867                 &ob->empty_drawsize,
868                 ob->ima_ofs,
869                 ob->obmat);
870 }
871
872 static void OBJECT_cache_init(void *vedata)
873 {
874         OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
875         OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
876         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
877         OBJECT_PrivateData *g_data;
878         const DRWContextState *draw_ctx = DRW_context_state_get();
879         const bool xray_enabled = ((draw_ctx->v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
880                                    (draw_ctx->v3d->drawtype < OB_MATERIAL);
881         /* TODO : use dpi setting for enabling the second pass */
882         const bool do_outline_expand = false;
883
884         if (!stl->g_data) {
885                 /* Alloc transient pointers */
886                 stl->g_data = MEM_mallocN(sizeof(*stl->g_data), __func__);
887         }
888
889         g_data = stl->g_data;
890
891         {
892                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE;
893                 psl->outlines = DRW_pass_create("Outlines Depth Pass", state);
894
895                 GPUShader *sh = e_data.outline_prepass_sh;
896
897                 if (xray_enabled) {
898                         sh = e_data.outline_prepass_wire_sh;
899                 }
900
901                 g_data->outlines_select = shgroup_outline(psl->outlines, &g_data->id_ofs_select, sh);
902                 g_data->outlines_transform = shgroup_outline(psl->outlines, &g_data->id_ofs_transform, sh);
903                 g_data->outlines_active = shgroup_outline(psl->outlines, &g_data->id_ofs_active, sh);
904
905                 g_data->id_ofs_select = 0;
906                 g_data->id_ofs_active = 0;
907                 g_data->id_ofs_transform = 0;
908         }
909
910         {
911                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_POINT;
912                 DRWPass *pass = psl->lightprobes = DRW_pass_create("Object Probe Pass", state);
913                 struct Gwn_Batch *sphere = DRW_cache_sphere_get();
914                 struct Gwn_Batch *quad = DRW_cache_quad_get();
915
916                 /* Cubemap */
917                 g_data->lightprobes_cube_select       = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_select);
918                 g_data->lightprobes_cube_active       = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_active);
919                 g_data->lightprobes_cube_transform    = shgroup_instance_outline(pass, sphere, &g_data->id_ofs_prb_transform);
920
921                 /* Planar */
922                 g_data->lightprobes_planar_select       = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_select);
923                 g_data->lightprobes_planar_active       = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_active);
924                 g_data->lightprobes_planar_transform    = shgroup_instance_outline(pass, quad, &g_data->id_ofs_prb_transform);
925
926                 g_data->id_ofs_prb_select = 0;
927                 g_data->id_ofs_prb_active = 0;
928                 g_data->id_ofs_prb_transform = 0;
929         }
930
931         {
932                 DRWState state = DRW_STATE_WRITE_COLOR;
933                 struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
934                 /* Don't occlude the "outline" detection pass if in xray mode (too much flickering). */
935                 float alphaOcclu = (xray_enabled) ? 1.0f : 0.35f;
936                 /* Reminder : bool uniforms need to be 4 bytes. */
937                 static const int bTrue = true;
938                 static const int bFalse = false;
939
940                 psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state);
941
942                 GPUShader *sh = (xray_enabled) ? e_data.outline_detect_wire_sh : e_data.outline_detect_sh;
943                 DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->outlines_search);
944                 DRW_shgroup_uniform_texture_ref(grp, "outlineId", &e_data.outlines_id_tx);
945                 DRW_shgroup_uniform_texture_ref(grp, "outlineDepth", &e_data.outlines_depth_tx);
946                 DRW_shgroup_uniform_texture_ref(grp, "sceneDepth", &dtxl->depth);
947                 DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
948                 DRW_shgroup_uniform_float_copy(grp, "alphaOcclu", alphaOcclu);
949                 DRW_shgroup_uniform_int(grp, "idOffsets", &stl->g_data->id_ofs_active, 3);
950                 DRW_shgroup_call_add(grp, quad, NULL);
951
952                 psl->outlines_expand = DRW_pass_create("Outlines Expand Pass", state);
953
954                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_expand);
955                 DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_blur_tx);
956                 DRW_shgroup_uniform_bool(grp, "doExpand", (do_outline_expand) ? &bTrue : &bFalse, 1);
957                 DRW_shgroup_call_add(grp, quad, NULL);
958
959                 psl->outlines_bleed = DRW_pass_create("Outlines Bleed Pass", state);
960
961                 if (do_outline_expand) {
962                         grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_bleed);
963                         DRW_shgroup_uniform_texture_ref(grp, "outlineColor", &e_data.outlines_color_tx);
964                         DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
965                         DRW_shgroup_call_add(grp, quad, NULL);
966                 }
967         }
968
969         {
970                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
971                 psl->outlines_resolve = DRW_pass_create("Outlines Resolve Pass", state);
972
973                 struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
974                 GPUTexture **outline_tx = (do_outline_expand) ? &e_data.outlines_blur_tx : &e_data.outlines_color_tx;
975
976                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_aa_sh, psl->outlines_resolve);
977                 DRW_shgroup_uniform_texture_ref(grp, "outlineBluredColor", outline_tx);
978                 DRW_shgroup_uniform_vec2(grp, "rcpDimensions", e_data.inv_viewport_size, 1);
979                 DRW_shgroup_call_add(grp, quad, NULL);
980         }
981
982         {
983                 /* Grid pass */
984                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
985                 psl->grid = DRW_pass_create("Infinite Grid Pass", state);
986
987                 struct Gwn_Batch *quad = DRW_cache_fullscreen_quad_get();
988                 static float mat[4][4];
989                 unit_m4(mat);
990
991                 /* Create 3 quads to render ordered transparency Z axis */
992                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
993                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1);
994                 DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
995                 DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
996                 DRW_shgroup_uniform_vec3(grp, "cameraPos", e_data.camera_pos, 1);
997                 DRW_shgroup_uniform_vec4(grp, "screenvecs[0]", e_data.screenvecs[0], 3);
998                 DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1);
999                 DRW_shgroup_uniform_float(grp, "gridOneOverLogSubdiv", &e_data.grid_settings[4], 1);
1000                 DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
1001                 DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
1002                 DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
1003                 DRW_shgroup_call_add(grp, quad, mat);
1004
1005                 grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
1006                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
1007                 DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.grid_normal, 1);
1008                 DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.grid_axes, 1);
1009                 DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
1010                 DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
1011                 DRW_shgroup_call_add(grp, quad, mat);
1012
1013                 grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
1014                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
1015                 DRW_shgroup_uniform_vec3(grp, "planeNormal", e_data.zplane_normal, 1);
1016                 DRW_shgroup_uniform_vec3(grp, "planeAxes", e_data.zplane_axes, 1);
1017                 DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo);
1018                 DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth);
1019                 DRW_shgroup_call_add(grp, quad, mat);
1020         }
1021
1022         {
1023                 /* Solid bones */
1024                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
1025                 psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
1026                 psl->bone_outline = DRW_pass_create("Bone Outline Pass", state);
1027         }
1028
1029         {
1030                 /* Wire bones */
1031                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
1032                 psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
1033         }
1034
1035         {
1036                 /* distance outline around envelope bones */
1037                 DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT;
1038                 psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
1039         }
1040
1041         {
1042                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE;
1043                 psl->bone_axes = DRW_pass_create("Bone Axes Pass", state);
1044         }
1045
1046         {
1047                 /* Non Meshes Pass (Camera, empties, lamps ...) */
1048                 struct Gwn_Batch *geom;
1049
1050                 DRWState state =
1051                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH |
1052                         DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_POINT;
1053                 state |= DRW_STATE_WIRE;
1054                 psl->non_meshes = DRW_pass_create("Non Meshes Pass", state);
1055
1056                 /* Empties */
1057                 geom = DRW_cache_plain_axes_get();
1058                 stl->g_data->plain_axes = shgroup_instance(psl->non_meshes, geom);
1059
1060                 geom = DRW_cache_cube_get();
1061                 stl->g_data->cube = shgroup_instance(psl->non_meshes, geom);
1062
1063                 geom = DRW_cache_circle_get();
1064                 stl->g_data->circle = shgroup_instance(psl->non_meshes, geom);
1065
1066                 geom = DRW_cache_empty_sphere_get();
1067                 stl->g_data->sphere = shgroup_instance(psl->non_meshes, geom);
1068
1069                 geom = DRW_cache_empty_cone_get();
1070                 stl->g_data->cone = shgroup_instance(psl->non_meshes, geom);
1071
1072                 geom = DRW_cache_single_arrow_get();
1073                 stl->g_data->single_arrow = shgroup_instance(psl->non_meshes, geom);
1074
1075                 geom = DRW_cache_single_line_get();
1076                 stl->g_data->single_arrow_line = shgroup_instance(psl->non_meshes, geom);
1077
1078                 geom = DRW_cache_arrows_get();
1079                 stl->g_data->arrows = shgroup_instance(psl->non_meshes, geom);
1080
1081                 geom = DRW_cache_axis_names_get();
1082                 stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
1083
1084                 /* initialize on first use */
1085                 stl->g_data->image_plane_map = NULL;
1086
1087                 /* Force Field */
1088                 geom = DRW_cache_field_wind_get();
1089                 stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom);
1090
1091                 geom = DRW_cache_field_force_get();
1092                 stl->g_data->field_force = shgroup_instance_screen_aligned(psl->non_meshes, geom);
1093
1094                 geom = DRW_cache_field_vortex_get();
1095                 stl->g_data->field_vortex = shgroup_instance_scaled(psl->non_meshes, geom);
1096
1097                 geom = DRW_cache_screenspace_circle_get();
1098                 stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom);
1099
1100                 /* Speaker */
1101                 geom = DRW_cache_speaker_get();
1102                 stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom);
1103
1104                 /* Probe */
1105                 static float probeSize = 14.0f;
1106                 geom = DRW_cache_lightprobe_cube_get();
1107                 stl->g_data->probe_cube = shgroup_instance_screenspace(psl->non_meshes, geom, &probeSize);
1108
1109                 geom = DRW_cache_lightprobe_grid_get();
1110                 stl->g_data->probe_grid = shgroup_instance_screenspace(psl->non_meshes, geom, &probeSize);
1111
1112                 static float probePlanarSize = 20.0f;
1113                 geom = DRW_cache_lightprobe_planar_get();
1114                 stl->g_data->probe_planar = shgroup_instance_screenspace(psl->non_meshes, geom, &probePlanarSize);
1115
1116                 /* Camera */
1117                 geom = DRW_cache_camera_get();
1118                 stl->g_data->camera = shgroup_camera_instance(psl->non_meshes, geom);
1119
1120                 geom = DRW_cache_camera_frame_get();
1121                 stl->g_data->camera_frame = shgroup_camera_instance(psl->non_meshes, geom);
1122
1123                 geom = DRW_cache_camera_tria_get();
1124                 stl->g_data->camera_tria = shgroup_camera_instance(psl->non_meshes, geom);
1125
1126                 geom = DRW_cache_plain_axes_get();
1127                 stl->g_data->camera_focus = shgroup_instance(psl->non_meshes, geom);
1128
1129                 geom = DRW_cache_single_line_get();
1130                 stl->g_data->camera_clip = shgroup_distance_lines_instance(psl->non_meshes, geom);
1131                 stl->g_data->camera_mist = shgroup_distance_lines_instance(psl->non_meshes, geom);
1132
1133                 geom = DRW_cache_single_line_endpoints_get();
1134                 stl->g_data->camera_clip_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
1135                 stl->g_data->camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
1136
1137                 /* Texture Space */
1138                 geom = DRW_cache_cube_get();
1139                 stl->g_data->texspace = shgroup_instance(psl->non_meshes, geom);
1140         }
1141
1142         {
1143                 GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
1144
1145                 /* Unselected */
1146                 stl->g_data->wire = shgroup_wire(psl->non_meshes, ts.colorWire, sh);
1147
1148                 /* Select */
1149                 stl->g_data->wire_select = shgroup_wire(psl->non_meshes, ts.colorSelect, sh);
1150
1151                 /* Transform */
1152                 stl->g_data->wire_transform = shgroup_wire(psl->non_meshes, ts.colorTransform, sh);
1153
1154                 /* Active */
1155                 stl->g_data->wire_active = shgroup_wire(psl->non_meshes, ts.colorActive, sh);
1156         }
1157
1158
1159         {
1160                 GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_UNIFORM_COLOR);
1161
1162                 /* Unselected */
1163                 stl->g_data->points = shgroup_points(psl->non_meshes, ts.colorWire, sh);
1164
1165                 /* Select */
1166                 stl->g_data->points_select = shgroup_points(psl->non_meshes, ts.colorSelect, sh);
1167
1168                 /* Transform */
1169                 stl->g_data->points_transform = shgroup_points(psl->non_meshes, ts.colorTransform, sh);
1170
1171                 /* Active */
1172                 stl->g_data->points_active = shgroup_points(psl->non_meshes, ts.colorActive, sh);
1173         }
1174
1175         {
1176                 /* Metaballs Handles */
1177                 stl->g_data->mball_handle = shgroup_instance_mball_handles(psl->non_meshes);
1178         }
1179
1180         {
1181                 /* Lamps */
1182                 /* TODO
1183                  * for now we create multiple times the same VBO with only lamp center coordinates
1184                  * but ideally we would only create it once */
1185                 struct Gwn_Batch *geom;
1186
1187                 /* start with buflimit because we don't want stipples */
1188                 geom = DRW_cache_single_line_get();
1189                 stl->g_data->lamp_buflimit = shgroup_distance_lines_instance(psl->non_meshes, geom);
1190
1191                 stl->g_data->lamp_center = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorLampNoAlpha, &ts.sizeLampCenter);
1192
1193                 geom = DRW_cache_lamp_get();
1194                 stl->g_data->lamp_circle = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
1195                 geom = DRW_cache_lamp_shadows_get();
1196                 stl->g_data->lamp_circle_shadow = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircleShadow);
1197
1198                 geom = DRW_cache_lamp_sunrays_get();
1199                 stl->g_data->lamp_sunrays = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
1200
1201                 stl->g_data->lamp_groundline = shgroup_groundlines_uniform_color(psl->non_meshes, ts.colorLamp);
1202                 stl->g_data->lamp_groundpoint = shgroup_groundpoints_uniform_color(psl->non_meshes, ts.colorLamp);
1203
1204                 geom = DRW_cache_screenspace_circle_get();
1205                 stl->g_data->lamp_area_sphere = shgroup_instance_screen_aligned(psl->non_meshes, geom);
1206
1207                 geom = DRW_cache_lamp_area_square_get();
1208                 stl->g_data->lamp_area_square = shgroup_instance(psl->non_meshes, geom);
1209
1210                 geom = DRW_cache_lamp_area_disk_get();
1211                 stl->g_data->lamp_area_disk = shgroup_instance(psl->non_meshes, geom);
1212
1213                 geom = DRW_cache_lamp_hemi_get();
1214                 stl->g_data->lamp_hemi = shgroup_instance(psl->non_meshes, geom);
1215
1216                 geom = DRW_cache_single_line_get();
1217                 stl->g_data->lamp_distance = shgroup_distance_lines_instance(psl->non_meshes, geom);
1218
1219                 geom = DRW_cache_single_line_endpoints_get();
1220                 stl->g_data->lamp_buflimit_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
1221
1222                 geom = DRW_cache_lamp_spot_get();
1223                 stl->g_data->lamp_spot_cone = shgroup_spot_instance(psl->non_meshes, geom);
1224
1225                 geom = DRW_cache_circle_get();
1226                 stl->g_data->lamp_spot_blend = shgroup_instance(psl->non_meshes, geom);
1227
1228                 geom = DRW_cache_lamp_spot_square_get();
1229                 stl->g_data->lamp_spot_pyramid = shgroup_instance(psl->non_meshes, geom);
1230
1231                 geom = DRW_cache_square_get();
1232                 stl->g_data->lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom);
1233         }
1234
1235         {
1236                 /* -------- STIPPLES ------- */
1237                 struct Gwn_Batch *geom;
1238
1239                 /* Relationship Lines */
1240                 stl->g_data->relationship_lines = shgroup_dynlines_dashed_uniform_color(psl->non_meshes, ts.colorWire);
1241
1242                 /* Force Field Curve Guide End (here because of stipple) */
1243                 /* TODO port to shader stipple */
1244                 geom = DRW_cache_screenspace_circle_get();
1245                 stl->g_data->field_curve_end = shgroup_instance_screen_aligned(psl->non_meshes, geom);
1246
1247                 /* Force Field Limits */
1248                 /* TODO port to shader stipple */
1249                 geom = DRW_cache_field_tube_limit_get();
1250                 stl->g_data->field_tube_limit = shgroup_instance_scaled(psl->non_meshes, geom);
1251
1252                 /* TODO port to shader stipple */
1253                 geom = DRW_cache_field_cone_limit_get();
1254                 stl->g_data->field_cone_limit = shgroup_instance_scaled(psl->non_meshes, geom);
1255         }
1256
1257         {
1258                 /* Object Center pass grouped by State */
1259                 DRWShadingGroup *grp;
1260                 static float outlineWidth, size;
1261
1262                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
1263                 psl->ob_center = DRW_pass_create("Obj Center Pass", state);
1264
1265                 outlineWidth = 1.0f * U.pixelsize;
1266                 size = U.obcenter_dia * U.pixelsize + outlineWidth;
1267
1268                 GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
1269
1270                 /* Active */
1271                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
1272                 DRW_shgroup_uniform_float(grp, "size", &size, 1);
1273                 DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
1274                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorActive, 1);
1275                 DRW_shgroup_uniform_vec4(grp, "outlineColor", ts.colorOutline, 1);
1276                 stl->g_data->center_active = grp;
1277
1278                 /* Select */
1279                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
1280                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorSelect, 1);
1281                 stl->g_data->center_selected = grp;
1282
1283                 /* Deselect */
1284                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
1285                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorDeselect, 1);
1286                 stl->g_data->center_deselected = grp;
1287
1288                 /* Select (library) */
1289                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
1290                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorLibrarySelect, 1);
1291                 stl->g_data->center_selected_lib = grp;
1292
1293                 /* Deselect (library) */
1294                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
1295                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorLibrary, 1);
1296                 stl->g_data->center_deselected_lib = grp;
1297         }
1298
1299         {
1300                 /* Particle Pass */
1301                 psl->particle = DRW_pass_create(
1302                         "Particle Pass",
1303                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
1304                         DRW_STATE_POINT | DRW_STATE_BLEND);
1305         }
1306
1307         {
1308                 /* Empty/Background Image Pass */
1309                 psl->reference_image = DRW_pass_create(
1310                         "Refrence Image Pass",
1311                         DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND);
1312         }
1313 }
1314
1315 static void DRW_shgroup_mball_handles(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
1316 {
1317         MetaBall *mb = ob->data;
1318
1319         float *color;
1320         DRW_object_wire_theme_get(ob, view_layer, &color);
1321
1322         float draw_scale_xform[3][4]; /* Matrix of Scale and Translation */
1323         {
1324                 float scamat[3][3];
1325                 copy_m3_m4(scamat, ob->obmat);
1326                 /* Get the normalized inverse matrix to extract only
1327                 * the scale of Scamat */
1328                 float iscamat[3][3];
1329                 invert_m3_m3(iscamat, scamat);
1330                 normalize_m3(iscamat);
1331                 mul_m3_m3_post(scamat, iscamat);
1332
1333                 copy_v3_v3(draw_scale_xform[0], scamat[0]);
1334                 copy_v3_v3(draw_scale_xform[1], scamat[1]);
1335                 copy_v3_v3(draw_scale_xform[2], scamat[2]);
1336         }
1337
1338         for (MetaElem *ml = mb->elems.first; ml != NULL; ml = ml->next) {
1339                 /* draw radius */
1340                 float world_pos[3];
1341                 mul_v3_m4v3(world_pos, ob->obmat, &ml->x);
1342                 draw_scale_xform[0][3] = world_pos[0];
1343                 draw_scale_xform[1][3] = world_pos[1];
1344                 draw_scale_xform[2][3] = world_pos[2];
1345
1346                 DRW_shgroup_call_dynamic_add(stl->g_data->mball_handle, draw_scale_xform, &ml->rad, color);
1347         }
1348 }
1349
1350 static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
1351 {
1352         Lamp *la = ob->data;
1353         float *color;
1354         int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
1355         static float zero = 0.0f;
1356
1357         typedef struct LampEngineData {
1358                 DrawData dd;
1359                 float shape_mat[4][4];
1360                 float spot_blend_mat[4][4];
1361         } LampEngineData;
1362
1363         LampEngineData *lamp_engine_data =
1364                 (LampEngineData *)DRW_drawdata_ensure(
1365                         &ob->id,
1366                         &draw_engine_object_type,
1367                         sizeof(LampEngineData),
1368                         NULL,
1369                         NULL);
1370
1371         float (*shapemat)[4] = lamp_engine_data->shape_mat;
1372         float (*spotblendmat)[4] = lamp_engine_data->spot_blend_mat;
1373
1374         /* Don't draw the center if it's selected or active */
1375         if (theme_id == TH_LAMP)
1376                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_center, ob->obmat[3]);
1377
1378         /* First circle */
1379         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle, ob->obmat[3], color);
1380
1381         /* draw dashed outer circle for shadow */
1382         if (la->type != LA_HEMI) {
1383                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_circle_shadow, ob->obmat[3], color);
1384         }
1385
1386         /* Distance */
1387         if (ELEM(la->type, LA_HEMI, LA_SUN, LA_AREA)) {
1388                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_distance, color, &zero, &la->dist, ob->obmat);
1389         }
1390
1391         copy_m4_m4(shapemat, ob->obmat);
1392
1393         if (la->type == LA_SUN) {
1394                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_sunrays, ob->obmat[3], color);
1395         }
1396         else if (la->type == LA_SPOT) {
1397                 float size[3], sizemat[4][4];
1398                 static float one = 1.0f;
1399                 float blend = 1.0f - pow2f(la->spotblend);
1400
1401                 size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist;
1402                 size[2] = cosf(la->spotsize * 0.5f) * la->dist;
1403
1404                 size_to_mat4(sizemat, size);
1405                 mul_m4_m4m4(shapemat, ob->obmat, sizemat);
1406
1407                 size[0] = size[1] = blend; size[2] = 1.0f;
1408                 size_to_mat4(sizemat, size);
1409                 translate_m4(sizemat, 0.0f, 0.0f, -1.0f);
1410                 rotate_m4(sizemat, 'X', (float)(M_PI / 2));
1411                 mul_m4_m4m4(spotblendmat, shapemat, sizemat);
1412
1413                 if (la->mode & LA_SQUARE) {
1414                         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_pyramid, color, &one, shapemat);
1415
1416                         /* hide line if it is zero size or overlaps with outer border,
1417                          * previously it adjusted to always to show it but that seems
1418                          * confusing because it doesn't show the actual blend size */
1419                         if (blend != 0.0f && blend != 1.0f) {
1420                                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_blend_rect, color, &one, spotblendmat);
1421                         }
1422                 }
1423                 else {
1424                         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_cone, color, shapemat);
1425
1426                         /* hide line if it is zero size or overlaps with outer border,
1427                          * previously it adjusted to always to show it but that seems
1428                          * confusing because it doesn't show the actual blend size */
1429                         if (blend != 0.0f && blend != 1.0f) {
1430                                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_spot_blend, color, &one, spotblendmat);
1431                         }
1432                 }
1433
1434                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit, color, &la->clipsta, &la->clipend, ob->obmat);
1435                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
1436         }
1437         else if (la->type == LA_HEMI) {
1438                 static float hemisize = 2.0f;
1439                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_hemi, color, &hemisize, shapemat);
1440         }
1441         else if (la->type == LA_AREA) {
1442                 float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
1443
1444                 if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
1445                         size[1] = la->area_sizey / la->area_size;
1446                         size_to_mat4(sizemat, size);
1447                         mul_m4_m4m4(shapemat, shapemat, sizemat);
1448                 }
1449
1450                 if (ELEM(la->area_shape, LA_AREA_DISK, LA_AREA_ELLIPSE)) {
1451                         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area_disk, color, &la->area_size, shapemat);
1452                 }
1453                 else {
1454                         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area_square, color, &la->area_size, shapemat);
1455                 }
1456         }
1457
1458         if (ELEM(la->type, LA_LOCAL, LA_SPOT)) {
1459                 /* We only want position not scale. */
1460                 shapemat[0][0] = shapemat[1][1] = shapemat[2][2] = 1.0f;
1461                 shapemat[0][1] = shapemat[0][2] = 0.0f;
1462                 shapemat[1][0] = shapemat[1][2] = 0.0f;
1463                 shapemat[2][0] = shapemat[2][1] = 0.0f;
1464                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_area_sphere, color, &la->area_size, shapemat);
1465         }
1466
1467         /* Line and point going to the ground */
1468         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundline, ob->obmat[3]);
1469         DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundpoint, ob->obmat[3]);
1470 }
1471
1472 static void DRW_shgroup_camera(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
1473 {
1474         const DRWContextState *draw_ctx = DRW_context_state_get();
1475         View3D *v3d = draw_ctx->v3d;
1476         Scene *scene = draw_ctx->scene;
1477         RegionView3D *rv3d = draw_ctx->rv3d;
1478
1479         Camera *cam = ob->data;
1480         const  Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
1481         const bool is_active = (ob == camera_object);
1482         const bool look_through = (is_active && (rv3d->persp == RV3D_CAMOB));
1483         float *color;
1484         DRW_object_wire_theme_get(ob, view_layer, &color);
1485
1486         float vec[4][3], asp[2], shift[2], scale[3], drawsize;
1487
1488         scale[0] = 1.0f / len_v3(ob->obmat[0]);
1489         scale[1] = 1.0f / len_v3(ob->obmat[1]);
1490         scale[2] = 1.0f / len_v3(ob->obmat[2]);
1491
1492         BKE_camera_view_frame_ex(scene, cam, cam->drawsize, false, scale,
1493                                  asp, shift, &drawsize, vec);
1494
1495         /* Frame coords */
1496         copy_v2_v2(cam->drwcorners[0], vec[0]);
1497         copy_v2_v2(cam->drwcorners[1], vec[1]);
1498         copy_v2_v2(cam->drwcorners[2], vec[2]);
1499         copy_v2_v2(cam->drwcorners[3], vec[3]);
1500
1501         /* depth */
1502         cam->drwdepth = vec[0][2];
1503
1504         /* tria */
1505         cam->drwtria[0][0] = shift[0] + ((0.7f * drawsize) * scale[0]);
1506         cam->drwtria[0][1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
1507         cam->drwtria[1][0] = shift[0];
1508         cam->drwtria[1][1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
1509
1510         if (look_through) {
1511                 /* Only draw the frame. */
1512                 DRW_shgroup_call_dynamic_add(
1513                         stl->g_data->camera_frame, color, cam->drwcorners,
1514                         &cam->drwdepth, cam->drwtria, ob->obmat);
1515         }
1516         else {
1517                 DRW_shgroup_call_dynamic_add(
1518                         stl->g_data->camera, color, cam->drwcorners,
1519                         &cam->drwdepth, cam->drwtria, ob->obmat);
1520
1521                 /* Active cam */
1522                 if (is_active) {
1523                         DRW_shgroup_call_dynamic_add(
1524                                 stl->g_data->camera_tria, color,
1525                                 cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
1526                 }
1527         }
1528
1529         /* draw the rest in normalize object space */
1530         copy_m4_m4(cam->drwnormalmat, ob->obmat);
1531         normalize_m4(cam->drwnormalmat);
1532
1533         if (cam->flag & CAM_SHOWLIMITS) {
1534                 static float col[3] = {0.5f, 0.5f, 0.25f}, col_hi[3] = {1.0f, 1.0f, 0.5f};
1535                 float sizemat[4][4], size[3] = {1.0f, 1.0f, 0.0f};
1536                 float focusdist = BKE_camera_object_dof_distance(ob);
1537
1538                 copy_m4_m4(cam->drwfocusmat, cam->drwnormalmat);
1539                 translate_m4(cam->drwfocusmat, 0.0f, 0.0f, -focusdist);
1540                 size_to_mat4(sizemat, size);
1541                 mul_m4_m4m4(cam->drwfocusmat, cam->drwfocusmat, sizemat);
1542
1543                 DRW_shgroup_call_dynamic_add(
1544                         stl->g_data->camera_focus, (is_active ? col_hi : col),
1545                         &cam->drawsize, cam->drwfocusmat);
1546
1547                 DRW_shgroup_call_dynamic_add(
1548                         stl->g_data->camera_clip, color,
1549                         &cam->clipsta, &cam->clipend, cam->drwnormalmat);
1550                 DRW_shgroup_call_dynamic_add(
1551                         stl->g_data->camera_clip_points, (is_active ? col_hi : col),
1552                         &cam->clipsta, &cam->clipend, cam->drwnormalmat);
1553         }
1554
1555         if (cam->flag & CAM_SHOWMIST) {
1556                 World *world = scene->world;
1557
1558                 if (world) {
1559                         static float col[3] = {0.5f, 0.5f, 0.5f}, col_hi[3] = {1.0f, 1.0f, 1.0f};
1560                         world->mistend = world->miststa + world->mistdist;
1561                         DRW_shgroup_call_dynamic_add(
1562                                 stl->g_data->camera_mist, color,
1563                                 &world->miststa, &world->mistend, cam->drwnormalmat);
1564                         DRW_shgroup_call_dynamic_add(
1565                                 stl->g_data->camera_mist_points, (is_active ? col_hi : col),
1566                                 &world->miststa, &world->mistend, cam->drwnormalmat);
1567                 }
1568         }
1569 }
1570
1571 static void DRW_shgroup_empty(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, ViewLayer *view_layer)
1572 {
1573         float *color;
1574         DRW_object_wire_theme_get(ob, view_layer, &color);
1575
1576         switch (ob->empty_drawtype) {
1577                 case OB_PLAINAXES:
1578                         DRW_shgroup_call_dynamic_add(stl->g_data->plain_axes, color, &ob->empty_drawsize, ob->obmat);
1579                         break;
1580                 case OB_SINGLE_ARROW:
1581                         DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow, color, &ob->empty_drawsize, ob->obmat);
1582                         DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow_line, color, &ob->empty_drawsize, ob->obmat);
1583                         break;
1584                 case OB_CUBE:
1585                         DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &ob->empty_drawsize, ob->obmat);
1586                         break;
1587                 case OB_CIRCLE:
1588                         DRW_shgroup_call_dynamic_add(stl->g_data->circle, color, &ob->empty_drawsize, ob->obmat);
1589                         break;
1590                 case OB_EMPTY_SPHERE:
1591                         DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &ob->empty_drawsize, ob->obmat);
1592                         break;
1593                 case OB_EMPTY_CONE:
1594                         DRW_shgroup_call_dynamic_add(stl->g_data->cone, color, &ob->empty_drawsize, ob->obmat);
1595                         break;
1596                 case OB_ARROWS:
1597                         DRW_shgroup_call_dynamic_add(stl->g_data->arrows, color, &ob->empty_drawsize, ob->obmat);
1598                         DRW_shgroup_call_dynamic_add(stl->g_data->axis_names, color, &ob->empty_drawsize, ob->obmat);
1599                         break;
1600                 case OB_EMPTY_IMAGE:
1601                         DRW_shgroup_empty_image(stl, psl, ob, color);
1602                         break;
1603         }
1604 }
1605
1606 static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
1607 {
1608         int theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
1609         float *color = DRW_color_background_blend_get(theme_id);
1610         PartDeflect *pd = ob->pd;
1611         Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL;
1612
1613         /* TODO Move this to depsgraph */
1614         float tmp[3];
1615         copy_v3_fl(pd->drawvec1, ob->empty_drawsize);
1616
1617         switch (pd->forcefield) {
1618                 case PFIELD_WIND:
1619                         pd->drawvec1[2] = pd->f_strength;
1620                         break;
1621                 case PFIELD_VORTEX:
1622                         if (pd->f_strength < 0.0f) {
1623                                 pd->drawvec1[1] = -pd->drawvec1[1];
1624                         }
1625                         break;
1626                 case PFIELD_GUIDE:
1627                         if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
1628                                 where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL);
1629                                 where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL);
1630                         }
1631                         break;
1632         }
1633
1634         if (pd->falloff == PFIELD_FALL_TUBE) {
1635                 pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f;
1636                 pd->drawvec_falloff_max[2] = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
1637
1638                 pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
1639                 pd->drawvec_falloff_min[2] = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
1640         }
1641         else if (pd->falloff == PFIELD_FALL_CONE) {
1642                 float radius, distance;
1643
1644                 radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
1645                 distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
1646                 pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = distance * sinf(radius);
1647                 pd->drawvec_falloff_max[2] = distance * cosf(radius);
1648
1649                 radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
1650                 distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
1651
1652                 pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = distance * sinf(radius);
1653                 pd->drawvec_falloff_min[2] = distance * cosf(radius);
1654         }
1655         /* End of things that should go to depthgraph */
1656
1657         switch (pd->forcefield) {
1658                 case PFIELD_WIND:
1659                         DRW_shgroup_call_dynamic_add(stl->g_data->field_wind, color, &pd->drawvec1, ob->obmat);
1660                         break;
1661                 case PFIELD_FORCE:
1662                         DRW_shgroup_call_dynamic_add(stl->g_data->field_force, color, &pd->drawvec1, ob->obmat);
1663                         break;
1664                 case PFIELD_VORTEX:
1665                         DRW_shgroup_call_dynamic_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat);
1666                         break;
1667                 case PFIELD_GUIDE:
1668                         if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
1669                                 DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat);
1670                                 DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat);
1671                         }
1672                         break;
1673         }
1674
1675         if (pd->falloff == PFIELD_FALL_SPHERE) {
1676                 /* as last, guide curve alters it */
1677                 if ((pd->flag & PFIELD_USEMAX) != 0) {
1678                         DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->maxdist, ob->obmat);
1679                 }
1680
1681                 if ((pd->flag & PFIELD_USEMIN) != 0) {
1682                         DRW_shgroup_call_dynamic_add(stl->g_data->field_curve_end, color, &pd->mindist, ob->obmat);
1683                 }
1684         }
1685         else if (pd->falloff == PFIELD_FALL_TUBE) {
1686                 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
1687                         DRW_shgroup_call_dynamic_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
1688                 }
1689
1690                 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
1691                         DRW_shgroup_call_dynamic_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
1692                 }
1693         }
1694         else if (pd->falloff == PFIELD_FALL_CONE) {
1695                 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
1696                         DRW_shgroup_call_dynamic_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
1697                 }
1698
1699                 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
1700                         DRW_shgroup_call_dynamic_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
1701                 }
1702         }
1703 }
1704
1705 static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer)
1706 {
1707         float *color;
1708         static float one = 1.0f;
1709         DRW_object_wire_theme_get(ob, view_layer, &color);
1710
1711         DRW_shgroup_call_dynamic_add(stl->g_data->speaker, color, &one, ob->obmat);
1712 }
1713
1714 typedef struct OBJECT_LightProbeEngineData {
1715         DrawData dd;
1716
1717         float prb_mats[6][4][4];
1718         float probe_cube_mat[4][4];
1719         float draw_size;
1720         float increment_x[3];
1721         float increment_y[3];
1722         float increment_z[3];
1723         float corner[3];
1724         uint cell_count;
1725 } OBJECT_LightProbeEngineData;
1726
1727 static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl, Object *ob, ViewLayer *view_layer)
1728 {
1729         float *color;
1730         static float one = 1.0f;
1731         LightProbe *prb = (LightProbe *)ob->data;
1732         bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
1733         int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color);
1734
1735         OBJECT_LightProbeEngineData *prb_data =
1736                 (OBJECT_LightProbeEngineData *)DRW_drawdata_ensure(
1737                         &ob->id,
1738                         &draw_engine_object_type,
1739                         sizeof(OBJECT_LightProbeEngineData),
1740                         NULL,
1741                         NULL);
1742
1743         if ((DRW_state_is_select() || do_outlines) && ((prb->flag & LIGHTPROBE_FLAG_SHOW_DATA) != 0)) {
1744                 int *call_id = shgroup_theme_id_to_probe_outline_counter(stl, theme_id);
1745
1746                 if (prb->type == LIGHTPROBE_TYPE_GRID) {
1747                         /* Update transforms */
1748                         float cell_dim[3], half_cell_dim[3];
1749                         cell_dim[0] = 2.0f / (float)(prb->grid_resolution_x);
1750                         cell_dim[1] = 2.0f / (float)(prb->grid_resolution_y);
1751                         cell_dim[2] = 2.0f / (float)(prb->grid_resolution_z);
1752
1753                         mul_v3_v3fl(half_cell_dim, cell_dim, 0.5f);
1754
1755                         /* First cell. */
1756                         copy_v3_fl(prb_data->corner, -1.0f);
1757                         add_v3_v3(prb_data->corner, half_cell_dim);
1758                         mul_m4_v3(ob->obmat, prb_data->corner);
1759
1760                         /* Opposite neighbor cell. */
1761                         copy_v3_fl3(prb_data->increment_x, cell_dim[0], 0.0f, 0.0f);
1762                         add_v3_v3(prb_data->increment_x, half_cell_dim);
1763                         add_v3_fl(prb_data->increment_x, -1.0f);
1764                         mul_m4_v3(ob->obmat, prb_data->increment_x);
1765                         sub_v3_v3(prb_data->increment_x, prb_data->corner);
1766
1767                         copy_v3_fl3(prb_data->increment_y, 0.0f, cell_dim[1], 0.0f);
1768                         add_v3_v3(prb_data->increment_y, half_cell_dim);
1769                         add_v3_fl(prb_data->increment_y, -1.0f);
1770                         mul_m4_v3(ob->obmat, prb_data->increment_y);
1771                         sub_v3_v3(prb_data->increment_y, prb_data->corner);
1772
1773                         copy_v3_fl3(prb_data->increment_z, 0.0f, 0.0f, cell_dim[2]);
1774                         add_v3_v3(prb_data->increment_z, half_cell_dim);
1775                         add_v3_fl(prb_data->increment_z, -1.0f);
1776                         mul_m4_v3(ob->obmat, prb_data->increment_z);
1777                         sub_v3_v3(prb_data->increment_z, prb_data->corner);
1778
1779                         prb_data->cell_count = prb->grid_resolution_x * prb->grid_resolution_y * prb->grid_resolution_z;
1780                         DRWShadingGroup *grp = DRW_shgroup_create(e_data.lightprobe_grid_sh, psl->lightprobes);
1781                         DRW_shgroup_uniform_int_copy(grp, "call_id", *call_id);
1782                         DRW_shgroup_uniform_int(grp, "baseId", call_id, 1); /* that's correct */
1783                         DRW_shgroup_uniform_vec3(grp, "corner", prb_data->corner, 1);
1784                         DRW_shgroup_uniform_vec3(grp, "increment_x", prb_data->increment_x, 1);
1785                         DRW_shgroup_uniform_vec3(grp, "increment_y", prb_data->increment_y, 1);
1786                         DRW_shgroup_uniform_vec3(grp, "increment_z", prb_data->increment_z, 1);
1787                         DRW_shgroup_uniform_ivec3(grp, "grid_resolution", &prb->grid_resolution_x, 1);
1788                         DRW_shgroup_call_procedural_points_add(grp, prb_data->cell_count, NULL);
1789                 }
1790                 else if (prb->type == LIGHTPROBE_TYPE_CUBE) {
1791                         prb_data->draw_size = prb->data_draw_size * 0.1f;
1792                         unit_m4(prb_data->probe_cube_mat);
1793                         copy_v3_v3(prb_data->probe_cube_mat[3], ob->obmat[3]);
1794
1795                         DRWShadingGroup *grp = shgroup_theme_id_to_probe_cube_outline_shgrp(stl, theme_id);
1796                         /* TODO remove or change the drawing of the cube probes. Theses line draws nothing on purpose
1797                          * to keep the call ids correct. */
1798                         zero_m4(prb_data->probe_cube_mat);
1799                         DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, prb_data->probe_cube_mat);
1800                 }
1801                 else {
1802                         prb_data->draw_size = 1.0f;
1803
1804                         DRWShadingGroup *grp = shgroup_theme_id_to_probe_planar_outline_shgrp(stl, theme_id);
1805                         DRW_shgroup_call_dynamic_add(grp, call_id, &prb_data->draw_size, ob->obmat);
1806                 }
1807
1808                 *call_id += 1;
1809         }
1810
1811         switch (prb->type) {
1812                 case LIGHTPROBE_TYPE_PLANAR:
1813                         DRW_shgroup_call_dynamic_add(stl->g_data->probe_planar, ob->obmat[3], color);
1814                         break;
1815                 case LIGHTPROBE_TYPE_GRID:
1816                         DRW_shgroup_call_dynamic_add(stl->g_data->probe_grid, ob->obmat[3], color);
1817                         break;
1818                 case LIGHTPROBE_TYPE_CUBE:
1819                 default:
1820                         DRW_shgroup_call_dynamic_add(stl->g_data->probe_cube, ob->obmat[3], color);
1821                         break;
1822         }
1823
1824
1825
1826         if (prb->type == LIGHTPROBE_TYPE_PLANAR) {
1827                 float (*mat)[4];
1828                 mat = (float (*)[4])(prb_data->prb_mats[0]);
1829                 copy_m4_m4(mat, ob->obmat);
1830                 normalize_m4(mat);
1831
1832                 DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow, color, &ob->empty_drawsize, mat);
1833                 DRW_shgroup_call_dynamic_add(stl->g_data->single_arrow_line, color, &ob->empty_drawsize, mat);
1834
1835                 mat = (float (*)[4])(prb_data->prb_mats[1]);
1836                 copy_m4_m4(mat, ob->obmat);
1837                 zero_v3(mat[2]);
1838
1839                 DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, mat);
1840         }
1841
1842         if ((prb->flag & LIGHTPROBE_FLAG_SHOW_INFLUENCE) != 0) {
1843
1844                 prb->distfalloff = (1.0f - prb->falloff) * prb->distinf;
1845                 prb->distgridinf = prb->distinf;
1846
1847                 if (prb->type == LIGHTPROBE_TYPE_GRID) {
1848                         prb->distfalloff += 1.0f;
1849                         prb->distgridinf += 1.0f;
1850                 }
1851
1852                 if (prb->type == LIGHTPROBE_TYPE_GRID ||
1853                     prb->attenuation_type == LIGHTPROBE_SHAPE_BOX)
1854                 {
1855                         DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &prb->distgridinf, ob->obmat);
1856                         DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &prb->distfalloff, ob->obmat);
1857                 }
1858                 else if (prb->type == LIGHTPROBE_TYPE_PLANAR) {
1859                         float (*rangemat)[4];
1860                         rangemat = (float (*)[4])(prb_data->prb_mats[2]);
1861                         copy_m4_m4(rangemat, ob->obmat);
1862                         normalize_v3(rangemat[2]);
1863                         mul_v3_fl(rangemat[2], prb->distinf);
1864
1865                         DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, rangemat);
1866
1867                         rangemat = (float (*)[4])(prb_data->prb_mats[3]);
1868                         copy_m4_m4(rangemat, ob->obmat);
1869                         normalize_v3(rangemat[2]);
1870                         mul_v3_fl(rangemat[2], prb->distfalloff);
1871
1872                         DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, &one, rangemat);
1873                 }
1874                 else {
1875                         DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &prb->distgridinf, ob->obmat);
1876                         DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, &prb->distfalloff, ob->obmat);
1877                 }
1878         }
1879
1880         if ((prb->flag & LIGHTPROBE_FLAG_SHOW_PARALLAX) != 0) {
1881                 if (prb->type != LIGHTPROBE_TYPE_PLANAR) {
1882                         float (*obmat)[4], *dist;
1883
1884                         if ((prb->flag & LIGHTPROBE_FLAG_CUSTOM_PARALLAX) != 0) {
1885                                 dist = &prb->distpar;
1886                                 /* TODO object parallax */
1887                                 obmat = ob->obmat;
1888                         }
1889                         else {
1890                                 dist = &prb->distinf;
1891                                 obmat = ob->obmat;
1892                         }
1893
1894                         if (prb->parallax_type == LIGHTPROBE_SHAPE_BOX) {
1895                                 DRW_shgroup_call_dynamic_add(stl->g_data->cube, color, dist, obmat);
1896                         }
1897                         else {
1898                                 DRW_shgroup_call_dynamic_add(stl->g_data->sphere, color, dist, obmat);
1899                         }
1900                 }
1901         }
1902
1903         if ((prb->flag & LIGHTPROBE_FLAG_SHOW_CLIP_DIST) != 0) {
1904                 if (prb->type != LIGHTPROBE_TYPE_PLANAR) {
1905                         static const float cubefacemat[6][4][4] = {
1906                                 {{0.0, 0.0, -1.0, 0.0}, {0.0, -1.0, 0.0, 0.0}, {-1.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1907                                 {{0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, 0.0}, {1.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1908                                 {{1.0, 0.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0}, {0.0, 1.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1909                                 {{1.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1910                                 {{1.0, 0.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, -1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1911                                 {{-1.0, 0.0, 0.0, 0.0}, {0.0, -1.0, 0.0, 0.0}, {0.0, 0.0, 1.0, 0.0}, {0.0, 0.0, 0.0, 1.0}},
1912                         };
1913
1914                         for (int i = 0; i < 6; ++i) {
1915                                 float (*clipmat)[4];
1916                                 clipmat = (float (*)[4])(prb_data->prb_mats[i]);
1917
1918                                 normalize_m4_m4(clipmat, ob->obmat);
1919                                 mul_m4_m4m4(clipmat, clipmat, cubefacemat[i]);
1920
1921                                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit, color, &prb->clipsta, &prb->clipend, clipmat);
1922                                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_buflimit_points, color, &prb->clipsta, &prb->clipend, clipmat);
1923                         }
1924                 }
1925         }
1926
1927         /* Line and point going to the ground */
1928         if (prb->type == LIGHTPROBE_TYPE_CUBE) {
1929                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundline, ob->obmat[3]);
1930                 DRW_shgroup_call_dynamic_add(stl->g_data->lamp_groundpoint, ob->obmat[3]);
1931         }
1932 }
1933
1934 static void DRW_shgroup_relationship_lines(OBJECT_StorageList *stl, Object *ob)
1935 {
1936         if (ob->parent && DRW_check_object_visible_within_active_context(ob->parent)) {
1937                 DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->parent->obmat[3]);
1938                 DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]);
1939         }
1940
1941         if (ob->rigidbody_constraint) {
1942                 Object *rbc_ob1 = ob->rigidbody_constraint->ob1;
1943                 Object *rbc_ob2 = ob->rigidbody_constraint->ob2;
1944                 if (rbc_ob1 && DRW_check_object_visible_within_active_context(rbc_ob1)) {
1945                         DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, rbc_ob1->obmat[3]);
1946                         DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]);
1947                 }
1948                 if (rbc_ob2 && DRW_check_object_visible_within_active_context(rbc_ob2)) {
1949                         DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, rbc_ob2->obmat[3]);
1950                         DRW_shgroup_call_dynamic_add(stl->g_data->relationship_lines, ob->obmat[3]);
1951                 }
1952         }
1953 }
1954
1955 static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob, ViewLayer *view_layer, View3D *v3d)
1956 {
1957         const bool is_library = ob->id.us > 1 || ID_IS_LINKED(ob);
1958         DRWShadingGroup *shgroup;
1959
1960         if (ob == OBACT(view_layer)) {
1961                 shgroup = stl->g_data->center_active;
1962         }
1963         else if (ob->base_flag & BASE_SELECTED) {
1964                 if (is_library) {
1965                         shgroup = stl->g_data->center_selected_lib;
1966                 }
1967                 else {
1968                         shgroup = stl->g_data->center_selected;
1969                 }
1970         }
1971         else if (v3d->flag & V3D_DRAW_CENTERS) {
1972                 if (is_library) {
1973                         shgroup = stl->g_data->center_deselected_lib;
1974                 }
1975                 else {
1976                         shgroup = stl->g_data->center_deselected;
1977                 }
1978         }
1979         else {
1980                 return;
1981         }
1982
1983         DRW_shgroup_call_dynamic_add(shgroup, ob->obmat[3]);
1984 }
1985
1986 static void DRW_shgroup_texture_space(OBJECT_StorageList *stl, Object *ob, int theme_id)
1987 {
1988         if (ob->data == NULL) {
1989                 return;
1990         }
1991
1992         ID *ob_data = ob->data;
1993         float *texcoloc = NULL;
1994         float *texcosize = NULL;
1995         if (ob->data != NULL) {
1996                 switch (GS(ob_data->name)) {
1997                         case ID_ME:
1998                                 BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, NULL, &texcosize);
1999                                 break;
2000                         case ID_CU:
2001                         {
2002                                 Curve *cu = (Curve *)ob_data;
2003                                 if (cu->bb == NULL || (cu->bb->flag & BOUNDBOX_DIRTY)) {
2004                                         BKE_curve_texspace_calc(cu);
2005                                 }
2006                                 texcoloc = cu->loc;
2007                                 texcosize = cu->size;
2008                                 break;
2009                         }
2010                         case ID_MB:
2011                         {
2012                                 MetaBall *mb = (MetaBall *)ob_data;
2013                                 texcoloc = mb->loc;
2014                                 texcosize = mb->size;
2015                                 break;
2016                         }
2017                         default:
2018                                 BLI_assert(0);
2019                 }
2020         }
2021
2022         float tmp[4][4] = {{0.0f}}, one = 1.0f;
2023         tmp[0][0] = texcosize[0];
2024         tmp[1][1] = texcosize[1];
2025         tmp[2][2] = texcosize[2];
2026         tmp[3][0] = texcoloc[0];
2027         tmp[3][1] = texcoloc[1];
2028         tmp[3][2] = texcoloc[2];
2029         tmp[3][3] = 1.0f;
2030
2031         mul_m4_m4m4(tmp, ob->obmat, tmp);
2032
2033         float color[4];
2034         UI_GetThemeColor4fv(theme_id, color);
2035
2036         DRW_shgroup_call_dynamic_add(stl->g_data->texspace, color, &one, tmp);
2037 }
2038
2039 static void OBJECT_cache_populate_particles(Object *ob,
2040                                             OBJECT_PassList *psl)
2041 {
2042         for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
2043                 if (!psys_check_enabled(ob, psys, false)) {
2044                         continue;
2045                 }
2046                 if (!DRW_check_psys_visible_within_active_context(ob, psys)) {
2047                         continue;
2048                 }
2049
2050                 ParticleSettings *part = psys->part;
2051                 int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as;
2052
2053                 static float mat[4][4];
2054                 unit_m4(mat);
2055
2056                 if (draw_as != PART_DRAW_PATH) {
2057                         struct Gwn_Batch *geom = DRW_cache_particles_get_dots(ob, psys);
2058                         DRWShadingGroup *shgrp = NULL;
2059                         static int screen_space[2] = {0, 1};
2060                         static float def_prim_col[3] = {0.5f, 0.5f, 0.5f};
2061                         static float def_sec_col[3] = {1.0f, 1.0f, 1.0f};
2062
2063                         /* Dummy particle format for instancing to work. */
2064                         DRW_shgroup_instance_format(e_data.particle_format, {{"dummy", DRW_ATTRIB_FLOAT, 1}});
2065
2066                         Material *ma = give_current_material(ob, part->omat);
2067
2068                         switch (draw_as) {
2069                                 case PART_DRAW_DOT:
2070                                         shgrp = DRW_shgroup_create(e_data.part_dot_sh, psl->particle);
2071                                         DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
2072                                         DRW_shgroup_uniform_vec3(shgrp, "outlineColor", ma ? &ma->specr : def_sec_col, 1);
2073                                         DRW_shgroup_uniform_float(shgrp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
2074                                         DRW_shgroup_uniform_float(shgrp, "size", &part->draw_size, 1);
2075                                         DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
2076                                         DRW_shgroup_call_add(shgrp, geom, mat);
2077                                         break;
2078                                 case PART_DRAW_CROSS:
2079                                         shgrp = DRW_shgroup_instance_create(
2080                                                 e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CROSS),
2081                                                 e_data.particle_format);
2082                                         DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
2083                                         DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
2084                                         DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
2085                                         break;
2086                                 case PART_DRAW_CIRC:
2087                                         shgrp = DRW_shgroup_instance_create(
2088                                                 e_data.part_prim_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_CIRC),
2089                                                 e_data.particle_format);
2090                                         DRW_shgroup_uniform_texture(shgrp, "ramp", globals_ramp);
2091                                         DRW_shgroup_uniform_vec3(shgrp, "color", ma ? &ma->r : def_prim_col, 1);
2092                                         DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[1], 1);
2093                                         break;
2094                                 case PART_DRAW_AXIS:
2095                                         shgrp = DRW_shgroup_instance_create(
2096                                                 e_data.part_axis_sh, psl->particle, DRW_cache_particles_get_prim(PART_DRAW_AXIS),
2097                                                 e_data.particle_format);
2098                                         DRW_shgroup_uniform_int(shgrp, "screen_space", &screen_space[0], 1);
2099                                         break;
2100                                 default:
2101                                         break;
2102                         }
2103
2104                         if (shgrp) {
2105                                 if (draw_as != PART_DRAW_DOT) {
2106                                         DRW_shgroup_uniform_float(shgrp, "draw_size", &part->draw_size, 1);
2107                                         DRW_shgroup_instance_batch(shgrp, geom);
2108                                 }
2109                         }
2110                 }
2111         }
2112 }
2113
2114 static void OBJECT_cache_populate(void *vedata, Object *ob)
2115 {
2116         OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
2117         OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
2118         const DRWContextState *draw_ctx = DRW_context_state_get();
2119         ViewLayer *view_layer = draw_ctx->view_layer;
2120         View3D *v3d = draw_ctx->v3d;
2121         int theme_id = TH_UNDEFINED;
2122
2123         /* Handle particles first in case the emitter itself shouldn't be rendered. */
2124         if (ob->type == OB_MESH) {
2125                 OBJECT_cache_populate_particles(ob, psl);
2126         }
2127
2128         if (DRW_check_object_visible_within_active_context(ob) == false) {
2129                 return;
2130         }
2131
2132         bool do_outlines = (draw_ctx->v3d->flag & V3D_SELECT_OUTLINE) && ((ob->base_flag & BASE_SELECTED) != 0);
2133         bool show_relations = ((draw_ctx->v3d->flag & V3D_HIDE_HELPLINES) == 0);
2134         const bool hide_object_extra = (v3d->overlay.flag & V3D_OVERLAY_HIDE_OBJECT_XTRAS) != 0;
2135
2136         if (do_outlines) {
2137                 if ((ob != draw_ctx->object_edit) && !((ob == draw_ctx->obact) && (draw_ctx->object_mode & OB_MODE_ALL_PAINT))) {
2138                         struct Gwn_Batch *geom;
2139                         const bool xray_enabled = ((v3d->shading.flag & V3D_SHADING_XRAY) != 0) &&
2140                                                    (v3d->drawtype < OB_MATERIAL);
2141                         if (xray_enabled) {
2142                                 geom = DRW_cache_object_edge_detection_get(ob, NULL);
2143                         }
2144                         else {
2145                                 geom = DRW_cache_object_surface_get(ob);
2146                         }
2147                         if (geom) {
2148                                 theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2149                                 DRWShadingGroup *shgroup = shgroup_theme_id_to_outline_or(stl, theme_id, NULL);
2150                                 if (shgroup != NULL) {
2151                                         DRW_shgroup_call_object_add(shgroup, geom, ob);
2152                                 }
2153                         }
2154                 }
2155         }
2156
2157         switch (ob->type) {
2158                 case OB_MESH:
2159                 {
2160                         if (hide_object_extra) {
2161                                 break;
2162                         }
2163                         if (ob != draw_ctx->object_edit) {
2164                                 Mesh *me = ob->data;
2165                                 if (me->totedge == 0) {
2166                                         struct Gwn_Batch *geom = DRW_cache_mesh_verts_get(ob);
2167                                         if (geom) {
2168                                                 if (theme_id == TH_UNDEFINED) {
2169                                                         theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2170                                                 }
2171
2172                                                 DRWShadingGroup *shgroup = shgroup_theme_id_to_point_or(stl, theme_id, stl->g_data->points);
2173                                                 DRW_shgroup_call_object_add(shgroup, geom, ob);
2174                                         }
2175                                 }
2176                                 else {
2177                                         struct Gwn_Batch *geom = DRW_cache_mesh_loose_edges_get(ob);
2178                                         if (geom) {
2179                                                 if (theme_id == TH_UNDEFINED) {
2180                                                         theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2181                                                 }
2182
2183                                                 DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
2184                                                 DRW_shgroup_call_object_add(shgroup, geom, ob);
2185                                         }
2186                                 }
2187                         }
2188                         break;
2189                 }
2190                 case OB_SURF:
2191                         break;
2192                 case OB_LATTICE:
2193                 {
2194                         if (ob != draw_ctx->object_edit) {
2195                                 if (hide_object_extra) {
2196                                         break;
2197                                 }
2198                                 struct Gwn_Batch *geom = DRW_cache_lattice_wire_get(ob, false);
2199                                 if (theme_id == TH_UNDEFINED) {
2200                                         theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2201                                 }
2202
2203                                 DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
2204                                 DRW_shgroup_call_object_add(shgroup, geom, ob);
2205                         }
2206                         break;
2207                 }
2208                 case OB_CURVE:
2209                 {
2210                         if (ob != draw_ctx->object_edit) {
2211                                 if (hide_object_extra) {
2212                                         break;
2213                                 }
2214                                 struct Gwn_Batch *geom = DRW_cache_curve_edge_wire_get(ob);
2215                                 if (theme_id == TH_UNDEFINED) {
2216                                         theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2217                                 }
2218                                 DRWShadingGroup *shgroup = shgroup_theme_id_to_wire_or(stl, theme_id, stl->g_data->wire);
2219                                 DRW_shgroup_call_object_add(shgroup, geom, ob);
2220                         }
2221                         break;
2222                 }
2223                 case OB_MBALL:
2224                 {
2225                         if (ob != draw_ctx->object_edit) {
2226                                 DRW_shgroup_mball_handles(stl, ob, view_layer);
2227                         }
2228                         break;
2229                 }
2230                 case OB_LAMP:
2231                         if (hide_object_extra) {
2232                                 break;
2233                         }
2234                         DRW_shgroup_lamp(stl, ob, view_layer);
2235                         break;
2236                 case OB_CAMERA:
2237                         if (hide_object_extra) {
2238                                 break;
2239                         }
2240                          DRW_shgroup_camera(stl, ob, view_layer);
2241                         break;
2242                 case OB_EMPTY:
2243                         if (hide_object_extra) {
2244                                 break;
2245                         }
2246                         DRW_shgroup_empty(stl, psl, ob, view_layer);
2247                         break;
2248                 case OB_SPEAKER:
2249                         if (hide_object_extra) {
2250                                 break;
2251                         }
2252                         DRW_shgroup_speaker(stl, ob, view_layer);
2253                         break;
2254                 case OB_LIGHTPROBE:
2255                         if (hide_object_extra) {
2256                                 break;
2257                         }
2258                         DRW_shgroup_lightprobe(stl, psl, ob, view_layer);
2259                         break;
2260                 case OB_ARMATURE:
2261                 {
2262                         if (v3d->overlay.flag & V3D_OVERLAY_HIDE_BONES) {
2263                                 break;
2264                         }
2265                         bArmature *arm = ob->data;
2266                         if (arm->edbo == NULL) {
2267                                 if (DRW_state_is_select() || !DRW_pose_mode_armature(ob, draw_ctx->obact)) {
2268                                         DRWArmaturePasses passes = {
2269                                             .bone_solid = psl->bone_solid,
2270                                             .bone_outline = psl->bone_outline,
2271                                             .bone_wire = psl->bone_wire,
2272                                             .bone_envelope = psl->bone_envelope,
2273                                             .bone_axes = psl->bone_axes,
2274                                             .relationship_lines = NULL, /* Don't draw relationship lines */
2275                                         };
2276                                         DRW_shgroup_armature_object(ob, view_layer, passes);
2277                                 }
2278                         }
2279                         break;
2280                 }
2281                 default:
2282                         break;
2283         }
2284
2285         if (ob->pd && ob->pd->forcefield) {
2286                 DRW_shgroup_forcefield(stl, ob, view_layer);
2287         }
2288
2289         /* don't show object extras in set's */
2290         if ((ob->base_flag & (BASE_FROM_SET | BASE_FROMDUPLI)) == 0) {
2291
2292                 DRW_shgroup_object_center(stl, ob, view_layer, v3d);
2293
2294                 if (show_relations) {
2295                         DRW_shgroup_relationship_lines(stl, ob);
2296                 }
2297
2298                 if ((ob->dtx != 0) && theme_id == TH_UNDEFINED) {
2299                         theme_id = DRW_object_wire_theme_get(ob, view_layer, NULL);
2300                 }
2301
2302                 if ((ob->dtx & OB_DRAWNAME) && DRW_state_show_text()) {
2303                         struct DRWTextStore *dt = DRW_text_cache_ensure();
2304
2305                         uchar color[4];
2306                         UI_GetThemeColor4ubv(theme_id, color);
2307
2308                         DRW_text_cache_add(
2309                                 dt, ob->obmat[3],
2310                                 ob->id.name + 2, strlen(ob->id.name + 2),
2311                                 10, DRW_TEXT_CACHE_GLOBALSPACE | DRW_TEXT_CACHE_STRING_PTR, color);
2312                 }
2313
2314                 if ((ob->dtx & OB_TEXSPACE) && ELEM(ob->type, OB_MESH, OB_CURVE, OB_MBALL)) {
2315                         DRW_shgroup_texture_space(stl, ob, theme_id);
2316                 }
2317         }
2318 }
2319
2320 static void OBJECT_draw_scene(void *vedata)
2321 {
2322
2323         OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
2324         OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
2325         OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
2326         OBJECT_PrivateData *g_data = stl->g_data;
2327         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
2328         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
2329
2330         int id_ct_select =       g_data->id_ofs_select;
2331         int id_ct_active =       g_data->id_ofs_active;
2332         int id_ct_transform =    g_data->id_ofs_transform;
2333
2334         int id_ct_prb_select =       g_data->id_ofs_prb_select;
2335         int id_ct_prb_active =       g_data->id_ofs_prb_active;
2336         int id_ct_prb_transform =    g_data->id_ofs_prb_transform;
2337
2338         int outline_calls = id_ct_select + id_ct_active + id_ct_transform;
2339         outline_calls += id_ct_prb_select + id_ct_prb_active + id_ct_prb_transform;
2340
2341         float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
2342
2343 //      DRW_draw_pass(psl->bone_envelope);  /* Never drawn in Object mode currently. */
2344
2345         MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl)
2346
2347         /* This needs to be drawn after the oultine */
2348         DRW_draw_pass(psl->bone_solid);
2349         DRW_draw_pass(psl->bone_wire);
2350         DRW_draw_pass(psl->bone_outline);
2351         DRW_draw_pass(psl->non_meshes);
2352         DRW_draw_pass(psl->particle);
2353         DRW_draw_pass(psl->reference_image);
2354         DRW_draw_pass(psl->bone_axes);
2355
2356         MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
2357
2358         if (DRW_state_is_fbo() && outline_calls > 0) {
2359                 DRW_stats_group_start("Outlines");
2360
2361                 g_data->id_ofs_active = 1;
2362                 g_data->id_ofs_select =    g_data->id_ofs_active + id_ct_active + id_ct_prb_active + 1;
2363                 g_data->id_ofs_transform = g_data->id_ofs_select + id_ct_select + id_ct_prb_select + 1;
2364
2365                 g_data->id_ofs_prb_active =       g_data->id_ofs_active       + id_ct_active;
2366                 g_data->id_ofs_prb_select =       g_data->id_ofs_select       + id_ct_select;
2367                 g_data->id_ofs_prb_transform =    g_data->id_ofs_transform    + id_ct_transform;
2368
2369                 /* Render filled polygon on a separate framebuffer */
2370                 GPU_framebuffer_bind(fbl->outlines_fb);
2371                 GPU_framebuffer_clear_color_depth(fbl->outlines_fb, clearcol, 1.0f);
2372                 DRW_draw_pass(psl->outlines);
2373                 DRW_draw_pass(psl->lightprobes);
2374
2375                 /* Search outline pixels */
2376                 GPU_framebuffer_bind(fbl->blur_fb);
2377                 DRW_draw_pass(psl->outlines_search);
2378
2379                 /* Expand outline to form a 3px wide line */
2380                 GPU_framebuffer_bind(fbl->expand_fb);
2381                 DRW_draw_pass(psl->outlines_expand);
2382
2383                 /* Bleed color so the AA can do it's stuff */
2384                 GPU_framebuffer_bind(fbl->blur_fb);
2385                 DRW_draw_pass(psl->outlines_bleed);
2386
2387                 /* restore main framebuffer */
2388                 GPU_framebuffer_bind(dfbl->default_fb);
2389                 DRW_stats_group_end();
2390         }
2391         else if (DRW_state_is_select()) {
2392                 /* Render probes spheres/planes so we can select them. */
2393                 DRW_draw_pass(psl->lightprobes);
2394         }
2395
2396         DRW_draw_pass(psl->ob_center);
2397
2398         if (DRW_state_is_fbo()) {
2399                 if (e_data.draw_grid) {
2400                         GPU_framebuffer_bind(dfbl->color_only_fb);
2401                         DRW_draw_pass(psl->grid);
2402                 }
2403
2404                 /* Combine with scene buffer last */
2405                 if (outline_calls > 0) {
2406                         DRW_draw_pass(psl->outlines_resolve);
2407                 }
2408         }
2409
2410         /* This has to be freed only after drawing empties! */
2411         if (stl->g_data->image_plane_map) {
2412                 BLI_ghash_free(stl->g_data->image_plane_map, NULL, MEM_freeN);
2413                 stl->g_data->image_plane_map = NULL;
2414         }
2415 }
2416
2417 static const DrawEngineDataSize OBJECT_data_size = DRW_VIEWPORT_DATA_SIZE(OBJECT_Data);
2418
2419 DrawEngineType draw_engine_object_type = {
2420         NULL, NULL,
2421         N_("ObjectMode"),
2422         &OBJECT_data_size,
2423         &OBJECT_engine_init,
2424         &OBJECT_engine_free,
2425         &OBJECT_cache_init,
2426         &OBJECT_cache_populate,
2427         NULL,
2428         NULL,
2429         &OBJECT_draw_scene,
2430         NULL,
2431         NULL,
2432 };