1d89455e3ee3b84a2a1d42d269910e14ebd77ff2
[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_object_force.h"
34 #include "DNA_view3d_types.h"
35 #include "DNA_world_types.h"
36
37 #include "BKE_anim.h"
38 #include "BKE_camera.h"
39 #include "BKE_curve.h"
40 #include "BKE_global.h"
41
42 #include "ED_view3d.h"
43 #include "ED_view3d.h"
44
45 #include "GPU_shader.h"
46
47 #include "UI_resources.h"
48
49 #include "draw_mode_engines.h"
50 #include "draw_common.h"
51
52 extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
53 extern GlobalsUboStorage ts;
54
55 extern char datatoc_object_outline_resolve_frag_glsl[];
56 extern char datatoc_object_outline_detect_frag_glsl[];
57 extern char datatoc_object_outline_expand_frag_glsl[];
58 extern char datatoc_object_grid_frag_glsl[];
59 extern char datatoc_object_grid_vert_glsl[];
60 extern char datatoc_common_globals_lib_glsl[];
61
62 /* *********** LISTS *********** */
63 /* keep it under MAX_PASSES */
64 typedef struct OBJECT_PassList {
65         struct DRWPass *non_meshes;
66         struct DRWPass *ob_center;
67         struct DRWPass *outlines;
68         struct DRWPass *outlines_search;
69         struct DRWPass *outlines_expand;
70         struct DRWPass *outlines_fade1;
71         struct DRWPass *outlines_fade2;
72         struct DRWPass *outlines_fade3;
73         struct DRWPass *outlines_fade4;
74         struct DRWPass *outlines_fade5;
75         struct DRWPass *outlines_resolve;
76         struct DRWPass *grid;
77         struct DRWPass *bone_solid;
78         struct DRWPass *bone_wire;
79 } OBJECT_PassList;
80
81 /* keep it under MAX_BUFFERS */
82 typedef struct OBJECT_FramebufferList {
83         struct GPUFrameBuffer *outlines;
84         struct GPUFrameBuffer *blur;
85 } OBJECT_FramebufferList;
86
87 /* keep it under MAX_TEXTURES */
88 typedef struct OBJECT_TextureList {
89         struct GPUTexture *outlines_depth_tx;
90         struct GPUTexture *outlines_color_tx;
91         struct GPUTexture *outlines_blur_tx;
92 } OBJECT_TextureList;
93
94 /* keep it under MAX_STORAGE */
95 typedef struct OBJECT_StorageList {
96         struct g_data *g_data;
97 } OBJECT_StorageList;
98
99 typedef struct OBJECT_Data {
100         void *engine_type;
101         void *fbl;
102         void *txl;
103         OBJECT_PassList *psl;
104         void *stl;
105 } OBJECT_Data;
106
107 /* *********** STATIC *********** */
108
109 typedef struct g_data{
110         /* Empties */
111         DRWShadingGroup *plain_axes;
112         DRWShadingGroup *cube;
113         DRWShadingGroup *circle;
114         DRWShadingGroup *sphere;
115         DRWShadingGroup *cone;
116         DRWShadingGroup *single_arrow;
117         DRWShadingGroup *single_arrow_line;
118         DRWShadingGroup *arrows;
119         DRWShadingGroup *axis_names;
120
121         /* Force Field */
122         DRWShadingGroup *field_wind;
123         DRWShadingGroup *field_force;
124         DRWShadingGroup *field_vortex;
125         DRWShadingGroup *field_curve_sta;
126         DRWShadingGroup *field_curve_end;
127         DRWShadingGroup *field_tube_limit;
128         DRWShadingGroup *field_cone_limit;
129
130         /* Speaker */
131         DRWShadingGroup *speaker;
132
133         /* Lamps */
134         DRWShadingGroup *lamp_center;
135         DRWShadingGroup *lamp_center_group;
136         DRWShadingGroup *lamp_groundpoint;
137         DRWShadingGroup *lamp_groundline;
138         DRWShadingGroup *lamp_circle;
139         DRWShadingGroup *lamp_circle_shadow;
140         DRWShadingGroup *lamp_sunrays;
141         DRWShadingGroup *lamp_distance;
142         DRWShadingGroup *lamp_buflimit;
143         DRWShadingGroup *lamp_buflimit_points;
144         DRWShadingGroup *lamp_area;
145         DRWShadingGroup *lamp_hemi;
146         DRWShadingGroup *lamp_spot_cone;
147         DRWShadingGroup *lamp_spot_blend;
148         DRWShadingGroup *lamp_spot_pyramid;
149         DRWShadingGroup *lamp_spot_blend_rect;
150
151         /* Helpers */
152         DRWShadingGroup *relationship_lines;
153
154         /* Objects Centers */
155         DRWShadingGroup *center_active;
156         DRWShadingGroup *center_selected;
157         DRWShadingGroup *center_deselected;
158
159         /* Camera */
160         DRWShadingGroup *camera;
161         DRWShadingGroup *camera_tria;
162         DRWShadingGroup *camera_focus;
163         DRWShadingGroup *camera_clip;
164         DRWShadingGroup *camera_clip_points;
165         DRWShadingGroup *camera_mist;
166         DRWShadingGroup *camera_mist_points;
167
168         /* Outlines */
169         DRWShadingGroup *outlines_active;
170         DRWShadingGroup *outlines_active_group;
171         DRWShadingGroup *outlines_select;
172         DRWShadingGroup *outlines_select_group;
173         DRWShadingGroup *outlines_transform;
174
175 } g_data; /* Transient data */
176
177 static struct {
178         struct GPUShader *outline_resolve_sh;
179         struct GPUShader *outline_detect_sh;
180         struct GPUShader *outline_fade_sh;
181         struct GPUShader *grid_sh;
182         float camera_pos[3];
183         float grid_settings[5];
184         float grid_mat[4][4];
185         int grid_flag;
186         int zpos_flag;
187         int zneg_flag;
188 } e_data = {NULL}; /* Engine data */
189
190
191 enum {
192         SHOW_AXIS_X  = (1 << 0),
193         SHOW_AXIS_Y  = (1 << 1),
194         SHOW_AXIS_Z  = (1 << 2),
195         SHOW_GRID    = (1 << 3),
196         PLANE_XY     = (1 << 4),
197         PLANE_XZ     = (1 << 5),
198         PLANE_YZ     = (1 << 6),
199         CLIP_ZPOS    = (1 << 7),
200         CLIP_ZNEG    = (1 << 8),
201 };
202
203 /* *********** FUNCTIONS *********** */
204
205 static void OBJECT_engine_init(void *vedata)
206 {
207         OBJECT_TextureList *txl = ((OBJECT_Data *)vedata)->txl;
208         OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
209
210         float *viewport_size = DRW_viewport_size_get();
211
212         DRWFboTexture tex[2] = {{&txl->outlines_depth_tx, DRW_BUF_DEPTH_24, 0},
213                                 {&txl->outlines_color_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER}};
214         DRW_framebuffer_init(&fbl->outlines,
215                              (int)viewport_size[0], (int)viewport_size[1],
216                              tex, 2);
217
218         DRWFboTexture blur_tex = {&txl->outlines_blur_tx, DRW_BUF_RGBA_8, DRW_TEX_FILTER};
219         DRW_framebuffer_init(&fbl->blur,
220                              (int)viewport_size[0], (int)viewport_size[1],
221                              &blur_tex, 1);
222
223         if (!e_data.outline_resolve_sh) {
224                 e_data.outline_resolve_sh = DRW_shader_create_fullscreen(datatoc_object_outline_resolve_frag_glsl, NULL);
225         }
226
227         if (!e_data.outline_detect_sh) {
228                 e_data.outline_detect_sh = DRW_shader_create_fullscreen(datatoc_object_outline_detect_frag_glsl, NULL);
229         }
230
231         if (!e_data.outline_fade_sh) {
232                 e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
233         }
234
235         if (!e_data.grid_sh) {
236                 e_data.grid_sh = DRW_shader_create_with_lib(datatoc_object_grid_vert_glsl, NULL,
237                                                             datatoc_object_grid_frag_glsl,
238                                                             datatoc_common_globals_lib_glsl, NULL);
239         }
240
241         {
242                 /* Grid precompute */
243                 float viewinvmat[4][4], winmat[4][4], invwinmat[4][4], viewmat[4][4];
244                 const bContext *C = DRW_get_context();
245                 View3D *v3d = CTX_wm_view3d(C);
246                 Scene *scene = CTX_data_scene(C);
247                 RegionView3D *rv3d = CTX_wm_region_view3d(C);
248                 float grid_scale = ED_view3d_grid_scale(scene, v3d, NULL);
249                 float grid_res, offs;
250
251                 const bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
252                 const bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
253                 const bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
254                 const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR);
255
256                 DRW_viewport_matrix_get(winmat, DRW_MAT_WIN);
257                 DRW_viewport_matrix_get(viewmat, DRW_MAT_VIEW);
258                 DRW_viewport_matrix_get(viewinvmat, DRW_MAT_VIEWINV);
259
260                 /* Setup camera pos */
261                 copy_v3_v3(e_data.camera_pos, viewinvmat[3]);
262
263                 /* if perps */
264                 if (winmat[3][3] == 0.0f) {
265                         float fov;
266                         float viewvecs[2][4] = {
267                             {1.0f, -1.0f, -1.0f, 1.0f},
268                             {-1.0f, 1.0f, -1.0f, 1.0f}
269                         };
270                         /* invert the proj matrix */
271                         invert_m4_m4(invwinmat, winmat);
272
273                         /* convert the view vectors to view space */
274                         for (int i = 0; i < 2; i++) {
275                                 mul_m4_v4(invwinmat, viewvecs[i]);
276                                 mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); /* normalize */
277                         }
278
279                         fov = angle_v3v3(viewvecs[0], viewvecs[1]) / 2.0f;
280                         grid_res = fabsf(tanf(fov)) / grid_scale;
281
282                         /* Grid matrix polygon offset (fix depth fighting) */
283                         /* see ED_view3d_polygon_offset */
284                         offs = winmat[3][2] * -0.0025f;
285
286                         e_data.grid_flag = (1 << 4); /* XY plane */
287                         if (show_axis_x)
288                                 e_data.grid_flag |= SHOW_AXIS_X;
289                         if (show_axis_y)
290                                 e_data.grid_flag |= SHOW_AXIS_Y;
291                         if (show_floor)
292                                 e_data.grid_flag |= SHOW_GRID;
293                 }
294                 else {
295                         float viewdist = 1.0f / max_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
296                         grid_res = viewdist / grid_scale;
297
298                         /* Grid matrix polygon offset (fix depth fighting) */
299                         /* see ED_view3d_polygon_offset */
300                         offs = 0.00001f * viewdist;
301                         if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) {
302                                 e_data.grid_flag = PLANE_YZ;
303                                 e_data.grid_flag |= SHOW_AXIS_Y;
304                                 e_data.grid_flag |= SHOW_AXIS_Z;
305                                 e_data.grid_flag |= SHOW_GRID;
306                         }
307                         else if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) {
308                                 e_data.grid_flag = PLANE_XY;
309                                 e_data.grid_flag |= SHOW_AXIS_X;
310                                 e_data.grid_flag |= SHOW_AXIS_Y;
311                                 e_data.grid_flag |= SHOW_GRID;
312                         }
313                         else if (ELEM(rv3d->view, RV3D_VIEW_FRONT, RV3D_VIEW_BACK)) {
314                                 e_data.grid_flag = PLANE_XZ;
315                                 e_data.grid_flag |= SHOW_AXIS_X;
316                                 e_data.grid_flag |= SHOW_AXIS_Z;
317                                 e_data.grid_flag |= SHOW_GRID;
318                         }
319                         else { /* RV3D_VIEW_USER */
320                                 e_data.grid_flag = PLANE_XY;
321                                 if (show_axis_x)
322                                         e_data.grid_flag |= SHOW_AXIS_X;
323                                 if (show_axis_y)
324                                         e_data.grid_flag |= SHOW_AXIS_Y;
325                                 if (show_floor)
326                                         e_data.grid_flag |= SHOW_GRID;
327                         }
328                 }
329
330                 /* Z axis if needed */
331                 if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
332                         e_data.zpos_flag = SHOW_AXIS_Z;
333
334                         float zvec[4] = {0.0f, 0.0f, -1.0f, 0.0f};
335                         mul_m4_v4(viewinvmat, zvec);
336
337                         /* z axis : chose the most facing plane */
338                         if (fabsf(zvec[0]) < fabsf(zvec[1])) {
339                                 e_data.zpos_flag |= PLANE_XZ;
340                         }
341                         else {
342                                 e_data.zpos_flag |= PLANE_YZ;
343                         }
344
345                         e_data.zneg_flag = e_data.zpos_flag;
346
347                         /* Persp : If camera is below floor plane, we switch clipping
348                          * Ortho : If eye vector is looking up, we switch clipping */
349                         if (((winmat[3][3] == 0.0f) && (e_data.camera_pos[2] > 0.0f)) ||
350                                 ((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
351                                 e_data.zpos_flag |= CLIP_ZPOS;
352                                 e_data.zneg_flag |= CLIP_ZNEG;
353                         }
354                         else {
355                                 e_data.zpos_flag |= CLIP_ZNEG;
356                                 e_data.zneg_flag |= CLIP_ZPOS;
357                         }
358                 }
359                 else {
360                         e_data.zneg_flag = e_data.zpos_flag = CLIP_ZNEG | CLIP_ZPOS;
361                 }
362
363                 winmat[3][2] -= offs;
364                 mul_m4_m4m4(e_data.grid_mat, winmat, viewmat);
365
366                 e_data.grid_settings[0] = v3d->far / 2.0f; /* gridDistance */
367                 e_data.grid_settings[1] = grid_res; /* gridResolution */
368                 e_data.grid_settings[2] = grid_scale; /* gridScale */
369                 e_data.grid_settings[3] = v3d->gridsubdiv; /* gridSubdiv */
370                 e_data.grid_settings[4] = (v3d->gridsubdiv > 1) ? 1.0f / log(v3d->gridsubdiv) : 0.0; /* 1/log(gridSubdiv) */
371         }
372 }
373
374 static void OBJECT_engine_free(void)
375 {
376         if (e_data.outline_resolve_sh)
377                 DRW_shader_free(e_data.outline_resolve_sh);
378         if (e_data.outline_detect_sh)
379                 DRW_shader_free(e_data.outline_detect_sh);
380         if (e_data.outline_fade_sh)
381                 DRW_shader_free(e_data.outline_fade_sh);
382         if (e_data.grid_sh)
383                 DRW_shader_free(e_data.grid_sh);
384 }
385
386 static DRWShadingGroup *shgroup_outline(DRWPass *pass, const float col[4], struct GPUShader *sh)
387 {
388         DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
389         DRW_shgroup_uniform_vec4(grp, "color", col, 1);
390
391         return grp;
392 }
393
394 static void OBJECT_cache_init(void *vedata)
395 {
396         OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
397         OBJECT_TextureList *txl = ((OBJECT_Data *)vedata)->txl;
398         OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
399         DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
400
401         if (!stl->g_data) {
402                 /* Alloc transient pointers */
403                 stl->g_data = MEM_mallocN(sizeof(g_data), "g_data");
404         }
405
406         {
407                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
408                 psl->outlines = DRW_pass_create("Outlines Pass", state);
409
410                 struct GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
411
412                 /* Select */
413                 stl->g_data->outlines_select = shgroup_outline(psl->outlines, ts.colorSelect, sh);
414                 stl->g_data->outlines_select_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
415
416                 /* Transform */
417                 stl->g_data->outlines_transform = shgroup_outline(psl->outlines, ts.colorTransform, sh);
418
419                 /* Active */
420                 stl->g_data->outlines_active = shgroup_outline(psl->outlines, ts.colorActive, sh);
421                 stl->g_data->outlines_active_group = shgroup_outline(psl->outlines, ts.colorGroupActive, sh);
422         }
423
424         {
425                 DRWState state = DRW_STATE_WRITE_COLOR;
426                 struct Batch *quad = DRW_cache_fullscreen_quad_get();
427                 static float alphaOcclu = 0.35f;
428                 static float one = 1.0f;
429                 static float alpha1 = 5.0f / 6.0f;
430                 static float alpha2 = 4.0f / 5.0f;
431                 static float alpha3 = 3.0f / 4.0f;
432                 static float alpha4 = 2.0f / 3.0f;
433                 static float alpha5 = 1.0f / 2.0f;
434                 static bool bTrue = true;
435                 static bool bFalse = false;
436
437                 psl->outlines_search = DRW_pass_create("Outlines Expand Pass", state);
438
439                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_detect_sh, psl->outlines_search);
440                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_color_tx, 0);
441                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
442                 DRW_shgroup_uniform_buffer(grp, "sceneDepth", &dtxl->depth, 2);
443                 DRW_shgroup_uniform_float(grp, "alphaOcclu", &alphaOcclu, 1);
444                 DRW_shgroup_call_add(grp, quad, NULL);
445
446                 psl->outlines_expand = DRW_pass_create("Outlines Expand Pass", state);
447
448                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_expand);
449                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_blur_tx, 0);
450                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
451                 DRW_shgroup_uniform_float(grp, "alpha", &one, 1);
452                 DRW_shgroup_uniform_bool(grp, "doExpand", &bTrue, 1);
453                 DRW_shgroup_call_add(grp, quad, NULL);
454
455                 psl->outlines_fade1 = DRW_pass_create("Outlines Fade 1 Pass", state);
456
457                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade1);
458                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_color_tx, 0);
459                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
460                 DRW_shgroup_uniform_float(grp, "alpha", &alpha1, 1);
461                 DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
462                 DRW_shgroup_call_add(grp, quad, NULL);
463
464                 psl->outlines_fade2 = DRW_pass_create("Outlines Fade 2 Pass", state);
465
466                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade2);
467                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_blur_tx, 0);
468                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
469                 DRW_shgroup_uniform_float(grp, "alpha", &alpha2, 1);
470                 DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
471                 DRW_shgroup_call_add(grp, quad, NULL);
472
473                 psl->outlines_fade3 = DRW_pass_create("Outlines Fade 3 Pass", state);
474
475                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade3);
476                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_color_tx, 0);
477                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
478                 DRW_shgroup_uniform_float(grp, "alpha", &alpha3, 1);
479                 DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
480                 DRW_shgroup_call_add(grp, quad, NULL);
481
482                 psl->outlines_fade4 = DRW_pass_create("Outlines Fade 4 Pass", state);
483
484                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade4);
485                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_blur_tx, 0);
486                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
487                 DRW_shgroup_uniform_float(grp, "alpha", &alpha4, 1);
488                 DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
489                 DRW_shgroup_call_add(grp, quad, NULL);
490
491                 psl->outlines_fade5 = DRW_pass_create("Outlines Fade 5 Pass", state);
492
493                 grp = DRW_shgroup_create(e_data.outline_fade_sh, psl->outlines_fade5);
494                 DRW_shgroup_uniform_buffer(grp, "outlineColor", &txl->outlines_color_tx, 0);
495                 DRW_shgroup_uniform_buffer(grp, "outlineDepth", &txl->outlines_depth_tx, 1);
496                 DRW_shgroup_uniform_float(grp, "alpha", &alpha5, 1);
497                 DRW_shgroup_uniform_bool(grp, "doExpand", &bFalse, 1);
498                 DRW_shgroup_call_add(grp, quad, NULL);
499         }
500
501         {
502                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND;
503                 psl->outlines_resolve = DRW_pass_create("Outlines Resolve Pass", state);
504
505                 struct Batch *quad = DRW_cache_fullscreen_quad_get();
506
507                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_resolve_sh, psl->outlines_resolve);
508                 DRW_shgroup_uniform_buffer(grp, "outlineBluredColor", &txl->outlines_blur_tx, 0);
509                 DRW_shgroup_call_add(grp, quad, NULL);
510         }
511
512         {
513                 /* Grid pass */
514                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
515                 psl->grid = DRW_pass_create("Infinite Grid Pass", state);
516
517                 struct Batch *quad = DRW_cache_fullscreen_quad_get();
518                 static float mat[4][4];
519                 unit_m4(mat);
520
521                 /* Create 3 quads to render ordered transparency Z axis */
522                 DRWShadingGroup *grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
523                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zneg_flag, 1);
524                 DRW_shgroup_uniform_mat4(grp, "ViewProjectionOffsetMatrix", (float *)e_data.grid_mat);
525                 DRW_shgroup_uniform_vec3(grp, "cameraPos", e_data.camera_pos, 1);
526                 DRW_shgroup_uniform_vec4(grp, "gridSettings", e_data.grid_settings, 1);
527                 DRW_shgroup_uniform_float(grp, "gridOneOverLogSubdiv", &e_data.grid_settings[4], 1);
528                 DRW_shgroup_uniform_block(grp, "globalsBlock", globals_ubo, 0);
529                 DRW_shgroup_call_add(grp, quad, mat);
530
531                 grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
532                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.grid_flag, 1);
533                 DRW_shgroup_call_add(grp, quad, mat);
534
535                 grp = DRW_shgroup_create(e_data.grid_sh, psl->grid);
536                 DRW_shgroup_uniform_int(grp, "gridFlag", &e_data.zpos_flag, 1);
537                 DRW_shgroup_call_add(grp, quad, mat);
538         }
539
540         {
541                 /* Solid bones */
542                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS;
543                 psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
544         }
545
546         {
547                 /* Wire bones */
548                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
549                 psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
550         }
551
552         {
553                 /* Non Meshes Pass (Camera, empties, lamps ...) */
554                 struct Batch *geom;
555
556                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_POINT;
557                 state |= DRW_STATE_WIRE;
558                 psl->non_meshes = DRW_pass_create("Non Meshes Pass", state);
559
560                 /* Empties */
561                 geom = DRW_cache_plain_axes_get();
562                 stl->g_data->plain_axes = shgroup_instance(psl->non_meshes, geom);
563
564                 geom = DRW_cache_cube_get();
565                 stl->g_data->cube = shgroup_instance(psl->non_meshes, geom);
566
567                 geom = DRW_cache_circle_get();
568                 stl->g_data->circle = shgroup_instance(psl->non_meshes, geom);
569
570                 geom = DRW_cache_empty_sphere_get();
571                 stl->g_data->sphere = shgroup_instance(psl->non_meshes, geom);
572
573                 geom = DRW_cache_empty_cone_get();
574                 stl->g_data->cone = shgroup_instance(psl->non_meshes, geom);
575
576                 geom = DRW_cache_single_arrow_get();
577                 stl->g_data->single_arrow = shgroup_instance(psl->non_meshes, geom);
578
579                 geom = DRW_cache_single_line_get();
580                 stl->g_data->single_arrow_line = shgroup_instance(psl->non_meshes, geom);
581
582                 geom = DRW_cache_arrows_get();
583                 stl->g_data->arrows = shgroup_instance(psl->non_meshes, geom);
584
585                 geom = DRW_cache_axis_names_get();
586                 stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom);
587
588                 /* Force Field */
589                 geom = DRW_cache_field_wind_get();
590                 stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom);
591
592                 geom = DRW_cache_field_force_get();
593                 stl->g_data->field_force = shgroup_instance_screen_aligned(psl->non_meshes, geom);
594
595                 geom = DRW_cache_field_vortex_get();
596                 stl->g_data->field_vortex = shgroup_instance_scaled(psl->non_meshes, geom);
597
598                 geom = DRW_cache_screenspace_circle_get();
599                 stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom);
600
601                 /* Speaker */
602                 geom = DRW_cache_speaker_get();
603                 stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom);
604
605                 /* Camera */
606                 geom = DRW_cache_camera_get();
607                 stl->g_data->camera = shgroup_camera_instance(psl->non_meshes, geom);
608
609                 geom = DRW_cache_camera_tria_get();
610                 stl->g_data->camera_tria = shgroup_camera_instance(psl->non_meshes, geom);
611
612                 geom = DRW_cache_plain_axes_get();
613                 stl->g_data->camera_focus = shgroup_instance(psl->non_meshes, geom);
614
615                 geom = DRW_cache_single_line_get();
616                 stl->g_data->camera_clip = shgroup_distance_lines_instance(psl->non_meshes, geom);
617                 stl->g_data->camera_mist = shgroup_distance_lines_instance(psl->non_meshes, geom);
618
619                 geom = DRW_cache_single_line_endpoints_get();
620                 stl->g_data->camera_clip_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
621                 stl->g_data->camera_mist_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
622
623                 /* Lamps */
624                 /* TODO
625                  * for now we create multiple times the same VBO with only lamp center coordinates
626                  * but ideally we would only create it once */
627
628                 /* start with buflimit because we don't want stipples */
629                 geom = DRW_cache_single_line_get();
630                 stl->g_data->lamp_buflimit = shgroup_distance_lines_instance(psl->non_meshes, geom);
631
632                 stl->g_data->lamp_center = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorLampNoAlpha, &ts.sizeLampCenter);
633                 stl->g_data->lamp_center_group = shgroup_dynpoints_uniform_color(psl->non_meshes, ts.colorGroup, &ts.sizeLampCenter);
634
635                 geom = DRW_cache_lamp_get();
636                 stl->g_data->lamp_circle = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
637                 stl->g_data->lamp_circle_shadow = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircleShadow);
638
639                 geom = DRW_cache_lamp_sunrays_get();
640                 stl->g_data->lamp_sunrays = shgroup_instance_screenspace(psl->non_meshes, geom, &ts.sizeLampCircle);
641
642                 stl->g_data->lamp_groundline = shgroup_groundlines_uniform_color(psl->non_meshes, ts.colorLamp);
643                 stl->g_data->lamp_groundpoint = shgroup_groundpoints_uniform_color(psl->non_meshes, ts.colorLamp);
644
645                 geom = DRW_cache_lamp_area_get();
646                 stl->g_data->lamp_area = shgroup_instance(psl->non_meshes, geom);
647
648                 geom = DRW_cache_lamp_hemi_get();
649                 stl->g_data->lamp_hemi = shgroup_instance(psl->non_meshes, geom);
650
651                 geom = DRW_cache_single_line_get();
652                 stl->g_data->lamp_distance = shgroup_distance_lines_instance(psl->non_meshes, geom);
653
654                 geom = DRW_cache_single_line_endpoints_get();
655                 stl->g_data->lamp_buflimit_points = shgroup_distance_lines_instance(psl->non_meshes, geom);
656
657                 geom = DRW_cache_lamp_spot_get();
658                 stl->g_data->lamp_spot_cone = shgroup_spot_instance(psl->non_meshes, geom);
659
660                 geom = DRW_cache_circle_get();
661                 stl->g_data->lamp_spot_blend = shgroup_instance(psl->non_meshes, geom);
662
663                 geom = DRW_cache_lamp_spot_square_get();
664                 stl->g_data->lamp_spot_pyramid = shgroup_instance(psl->non_meshes, geom);
665
666                 geom = DRW_cache_square_get();
667                 stl->g_data->lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom);
668
669                 /* -------- STIPPLES ------- */
670                 /* TODO port to shader stipple */
671
672                 /* Relationship Lines */
673                 stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->non_meshes, ts.colorWire);
674                 DRW_shgroup_state_set(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3);
675
676                 /* Force Field Curve Guide End (here because of stipple) */
677                 geom = DRW_cache_screenspace_circle_get();
678                 stl->g_data->field_curve_end = shgroup_instance_screen_aligned(psl->non_meshes, geom);
679
680                 /* Force Field Limits */
681                 geom = DRW_cache_field_tube_limit_get();
682                 stl->g_data->field_tube_limit = shgroup_instance_scaled(psl->non_meshes, geom);
683
684                 geom = DRW_cache_field_cone_limit_get();
685                 stl->g_data->field_cone_limit = shgroup_instance_scaled(psl->non_meshes, geom);
686         }
687
688         {
689                 /* Object Center pass grouped by State */
690                 DRWShadingGroup *grp;
691                 static float outlineWidth, size;
692
693                 DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
694                 psl->ob_center = DRW_pass_create("Obj Center Pass", state);
695
696                 outlineWidth = 1.0f * U.pixelsize;
697                 size = U.obcenter_dia * U.pixelsize + outlineWidth;
698
699                 struct GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
700
701                 /* Active */
702                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
703                 DRW_shgroup_uniform_float(grp, "size", &size, 1);
704                 DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
705                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorActive, 1);
706                 DRW_shgroup_uniform_vec4(grp, "outlineColor", ts.colorOutline, 1);
707                 stl->g_data->center_active = grp;
708
709                 /* Select */
710                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
711                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorSelect, 1);
712                 stl->g_data->center_selected = grp;
713
714                 /* Deselect */
715                 grp = DRW_shgroup_point_batch_create(sh, psl->ob_center);
716                 DRW_shgroup_uniform_vec4(grp, "color", ts.colorDeselect, 1);
717                 stl->g_data->center_deselected = grp;
718         }
719 }
720
721 static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
722 {
723         Lamp *la = ob->data;
724         float *color;
725         int theme_id = DRW_object_wire_theme_get(ob, sl, &color);
726         static float zero = 0.0f;
727
728         float **la_mats = (float **)DRW_object_engine_data_get(ob, &draw_engine_object_type);
729         if (*la_mats == NULL) {
730                 /* we need 2 matrices */
731                 *la_mats = MEM_mallocN(sizeof(float) * 16 * 2, "Lamp Object Mode Matrices");
732         }
733
734         float (*shapemat)[4], (*spotblendmat)[4];
735         shapemat = (float (*)[4])(*la_mats);
736         spotblendmat = (float (*)[4])(*la_mats + 16);
737
738         /* Don't draw the center if it's selected or active */
739         if (theme_id == TH_GROUP)
740                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_center_group, ob->obmat[3]);
741         else if (theme_id == TH_LAMP)
742                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_center, ob->obmat[3]);
743
744         /* First circle */
745         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_circle, ob->obmat[3], color);
746
747         /* draw dashed outer circle if shadow is on. remember some lamps can't have certain shadows! */
748         if (la->type != LA_HEMI) {
749                 if ((la->mode & LA_SHAD_RAY) || ((la->mode & LA_SHAD_BUF) && (la->type == LA_SPOT))) {
750                         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_circle_shadow, ob->obmat[3], color);
751                 }
752         }
753
754         /* Distance */
755         if (ELEM(la->type, LA_HEMI, LA_SUN, LA_AREA)) {
756                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_distance, color, &zero, &la->dist, ob->obmat);
757         }
758
759         copy_m4_m4(shapemat, ob->obmat);
760
761         if (la->type == LA_SUN) {
762                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_sunrays, ob->obmat[3], color);
763         }
764         else if (la->type == LA_SPOT) {
765                 float size[3], sizemat[4][4];
766                 static float one = 1.0f;
767                 float blend = 1.0f - pow2f(la->spotblend);
768
769                 size[0] = size[1] = sinf(la->spotsize * 0.5f) * la->dist;
770                 size[2] = cosf(la->spotsize * 0.5f) * la->dist;
771
772                 size_to_mat4(sizemat, size);
773                 mul_m4_m4m4(shapemat, ob->obmat, sizemat);
774
775                 size[0] = size[1] = blend; size[2] = 1.0f;
776                 size_to_mat4(sizemat, size);
777                 translate_m4(sizemat, 0.0f, 0.0f, -1.0f);
778                 rotate_m4(sizemat, 'X', M_PI / 2.0f);
779                 mul_m4_m4m4(spotblendmat, shapemat, sizemat);
780
781                 if (la->mode & LA_SQUARE) {
782                         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_pyramid,    color, &one, shapemat);
783
784                         /* hide line if it is zero size or overlaps with outer border,
785                          * previously it adjusted to always to show it but that seems
786                          * confusing because it doesn't show the actual blend size */
787                         if (blend != 0.0f && blend != 1.0f) {
788                                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend_rect, color, &one, spotblendmat);
789                         }
790                 }
791                 else {
792                         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_cone,  color, shapemat);
793
794                         /* hide line if it is zero size or overlaps with outer border,
795                          * previously it adjusted to always to show it but that seems
796                          * confusing because it doesn't show the actual blend size */
797                         if (blend != 0.0f && blend != 1.0f) {
798                                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_spot_blend, color, &one, spotblendmat);
799                         }
800                 }
801
802                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit,        color, &la->clipsta, &la->clipend, ob->obmat);
803                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_buflimit_points, color, &la->clipsta, &la->clipend, ob->obmat);
804         }
805         else if (la->type == LA_HEMI) {
806                 static float hemisize = 2.0f;
807                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_hemi, color, &hemisize, shapemat);
808         }
809         else if (la->type == LA_AREA) {
810                 float size[3] = {1.0f, 1.0f, 1.0f}, sizemat[4][4];
811
812                 if (la->area_shape == LA_AREA_RECT) {
813                         size[1] = la->area_sizey / la->area_size;
814                         size_to_mat4(sizemat, size);
815                         mul_m4_m4m4(shapemat, shapemat, sizemat);
816                 }
817
818                 DRW_shgroup_dynamic_call_add(stl->g_data->lamp_area, color, &la->area_size, shapemat);
819         }
820
821         /* Line and point going to the ground */
822         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_groundline, ob->obmat[3]);
823         DRW_shgroup_dynamic_call_add(stl->g_data->lamp_groundpoint, ob->obmat[3]);
824 }
825
826 static void DRW_shgroup_camera(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
827 {
828         const struct bContext *C = DRW_get_context();
829         View3D *v3d = CTX_wm_view3d(C);
830         Scene *scene = CTX_data_scene(C);
831
832         Camera *cam = ob->data;
833         const bool is_active = (ob == v3d->camera);
834         float *color;
835         DRW_object_wire_theme_get(ob, sl, &color);
836
837         float vec[4][3], asp[2], shift[2], scale[3], drawsize;
838
839         scale[0] = 1.0f / len_v3(ob->obmat[0]);
840         scale[1] = 1.0f / len_v3(ob->obmat[1]);
841         scale[2] = 1.0f / len_v3(ob->obmat[2]);
842
843         BKE_camera_view_frame_ex(scene, cam, cam->drawsize, false, scale,
844                                  asp, shift, &drawsize, vec);
845
846         // /* Frame coords */
847         copy_v2_v2(cam->drwcorners[0], vec[0]);
848         copy_v2_v2(cam->drwcorners[1], vec[1]);
849         copy_v2_v2(cam->drwcorners[2], vec[2]);
850         copy_v2_v2(cam->drwcorners[3], vec[3]);
851
852         /* depth */
853         cam->drwdepth = vec[0][2];
854
855         /* tria */
856         cam->drwtria[0][0] = shift[0] + ((0.7f * drawsize) * scale[0]);
857         cam->drwtria[0][1] = shift[1] + ((drawsize * (asp[1] + 0.1f)) * scale[1]);
858         cam->drwtria[1][0] = shift[0];
859         cam->drwtria[1][1] = shift[1] + ((1.1f * drawsize * (asp[1] + 0.7f)) * scale[1]);
860
861         DRW_shgroup_dynamic_call_add(stl->g_data->camera, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
862
863         /* Active cam */
864         if (is_active) {
865                 DRW_shgroup_dynamic_call_add(stl->g_data->camera_tria, color, cam->drwcorners, &cam->drwdepth, cam->drwtria, ob->obmat);
866         }
867
868         /* draw the rest in normalize object space */
869         copy_m4_m4(cam->drwnormalmat, ob->obmat);
870         normalize_m4(cam->drwnormalmat);
871
872         if (cam->flag & CAM_SHOWLIMITS) {
873                 static float col[3] = {0.5f, 0.5f, 0.25f}, col_hi[3] = {1.0f, 1.0f, 0.5f};
874                 float sizemat[4][4], size[3] = {1.0f, 1.0f, 0.0f};
875                 float focusdist = BKE_camera_object_dof_distance(ob);
876
877                 copy_m4_m4(cam->drwfocusmat, cam->drwnormalmat);
878                 translate_m4(cam->drwfocusmat, 0.0f, 0.0f, -focusdist);
879                 size_to_mat4(sizemat, size);
880                 mul_m4_m4m4(cam->drwfocusmat, cam->drwfocusmat, sizemat);
881
882                 DRW_shgroup_dynamic_call_add(stl->g_data->camera_focus, (is_active ? col_hi : col), &cam->drawsize, cam->drwfocusmat);
883
884                 DRW_shgroup_dynamic_call_add(stl->g_data->camera_clip, color, &cam->clipsta, &cam->clipend, cam->drwnormalmat);
885                 DRW_shgroup_dynamic_call_add(stl->g_data->camera_clip_points, (is_active ? col_hi : col), &cam->clipsta, &cam->clipend, cam->drwnormalmat);
886         }
887
888         if (cam->flag & CAM_SHOWMIST) {
889                 World *world = scene->world;
890
891                 if (world) {
892                         static float col[3] = {0.5f, 0.5f, 0.5f}, col_hi[3] = {1.0f, 1.0f, 1.0f};
893                         world->mistend = world->miststa + world->mistdist;
894                         DRW_shgroup_dynamic_call_add(stl->g_data->camera_mist,        color, &world->miststa, &world->mistend, cam->drwnormalmat);
895                         DRW_shgroup_dynamic_call_add(stl->g_data->camera_mist_points, (is_active ? col_hi : col), &world->miststa, &world->mistend, cam->drwnormalmat);
896                 }
897         }
898 }
899
900 static void DRW_shgroup_empty(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
901 {
902         float *color;
903         DRW_object_wire_theme_get(ob, sl, &color);
904
905         switch (ob->empty_drawtype) {
906                 case OB_PLAINAXES:
907                         DRW_shgroup_dynamic_call_add(stl->g_data->plain_axes, color, &ob->empty_drawsize, ob->obmat);
908                         break;
909                 case OB_SINGLE_ARROW:
910                         DRW_shgroup_dynamic_call_add(stl->g_data->single_arrow, color, &ob->empty_drawsize, ob->obmat);
911                         DRW_shgroup_dynamic_call_add(stl->g_data->single_arrow_line, color, &ob->empty_drawsize, ob->obmat);
912                         break;
913                 case OB_CUBE:
914                         DRW_shgroup_dynamic_call_add(stl->g_data->cube, color, &ob->empty_drawsize, ob->obmat);
915                         break;
916                 case OB_CIRCLE:
917                         DRW_shgroup_dynamic_call_add(stl->g_data->circle, color, &ob->empty_drawsize, ob->obmat);
918                         break;
919                 case OB_EMPTY_SPHERE:
920                         DRW_shgroup_dynamic_call_add(stl->g_data->sphere, color, &ob->empty_drawsize, ob->obmat);
921                         break;
922                 case OB_EMPTY_CONE:
923                         DRW_shgroup_dynamic_call_add(stl->g_data->cone, color, &ob->empty_drawsize, ob->obmat);
924                         break;
925                 case OB_ARROWS:
926                         DRW_shgroup_dynamic_call_add(stl->g_data->arrows, color, &ob->empty_drawsize, ob->obmat);
927                         DRW_shgroup_dynamic_call_add(stl->g_data->axis_names, color, &ob->empty_drawsize, ob->obmat);
928                         break;
929         }
930 }
931
932 static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
933 {
934         int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
935         float *color = DRW_color_background_blend_get(theme_id);
936         PartDeflect *pd = ob->pd;
937         Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL;
938
939         /* TODO Move this to depsgraph */
940         float tmp[3];
941         copy_v3_fl(pd->drawvec1, ob->empty_drawsize);
942
943         switch (pd->forcefield) {
944                 case PFIELD_WIND:
945                         pd->drawvec1[2] = pd->f_strength;
946                         break;
947                 case PFIELD_VORTEX:
948                         if (pd->f_strength < 0.0f) {
949                                 pd->drawvec1[1] = -pd->drawvec1[1];
950                         }
951                         break;
952                 case PFIELD_GUIDE:
953                         if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
954                                 where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL);
955                                 where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL);
956                         }
957                         break;
958         }
959
960         if (pd->falloff == PFIELD_FALL_TUBE) {
961                 pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f;
962                 pd->drawvec_falloff_max[2] = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
963
964                 pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f;
965                 pd->drawvec_falloff_min[2] = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
966         }
967         else if (pd->falloff == PFIELD_FALL_CONE) {
968                 float radius, distance;
969
970                 radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f);
971                 distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f;
972                 pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = distance * sinf(radius);
973                 pd->drawvec_falloff_max[2] = distance * cosf(radius);
974
975                 radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f);
976                 distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f;
977
978                 pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = distance * sinf(radius);
979                 pd->drawvec_falloff_min[2] = distance * cosf(radius);
980         }
981         /* End of things that should go to depthgraph */
982
983         switch (pd->forcefield) {
984                 case PFIELD_WIND:
985                         DRW_shgroup_dynamic_call_add(stl->g_data->field_wind, color, &pd->drawvec1, ob->obmat);
986                         break;
987                 case PFIELD_FORCE:
988                         DRW_shgroup_dynamic_call_add(stl->g_data->field_force, color, &pd->drawvec1, ob->obmat);
989                         break;
990                 case PFIELD_VORTEX:
991                         DRW_shgroup_dynamic_call_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat);
992                         break;
993                 case PFIELD_GUIDE:
994                         if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) {
995                                 DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat);
996                                 DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat);
997                         }
998                         break;
999         }
1000
1001         if (pd->falloff == PFIELD_FALL_SPHERE) {
1002                 /* as last, guide curve alters it */
1003                 if ((pd->flag & PFIELD_USEMAX) != 0) {
1004                         DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->maxdist, ob->obmat);
1005                 }
1006
1007                 if ((pd->flag & PFIELD_USEMIN) != 0) {
1008                         DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->mindist, ob->obmat);
1009                 }
1010         }
1011         else if (pd->falloff == PFIELD_FALL_TUBE) {
1012                 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
1013                         DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat);
1014                 }
1015
1016                 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
1017                         DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat);
1018                 }
1019         }
1020         else if (pd->falloff == PFIELD_FALL_CONE) {
1021                 if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) {
1022                         DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat);
1023                 }
1024
1025                 if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) {
1026                         DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat);
1027                 }
1028         }
1029 }
1030
1031 static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl)
1032 {
1033         float *color;
1034         static float one = 1.0f;
1035         DRW_object_wire_theme_get(ob, sl, &color);
1036
1037         DRW_shgroup_dynamic_call_add(stl->g_data->speaker, color, &one, ob->obmat);
1038 }
1039
1040 static void DRW_shgroup_relationship_lines(OBJECT_StorageList *stl, Object *ob)
1041 {
1042         if (ob->parent) {
1043                 DRW_shgroup_dynamic_call_add(stl->g_data->relationship_lines, ob->obmat[3]);
1044                 DRW_shgroup_dynamic_call_add(stl->g_data->relationship_lines, ob->parent->obmat[3]);
1045         }
1046 }
1047
1048 static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob)
1049 {
1050         if ((ob->base_flag & BASE_SELECTED) != 0) {
1051                 DRW_shgroup_dynamic_call_add(stl->g_data->center_selected, ob->obmat[3]);
1052         }
1053         else if (0) {
1054                 DRW_shgroup_dynamic_call_add(stl->g_data->center_deselected, ob->obmat[3]);
1055         }
1056 }
1057
1058 static void OBJECT_cache_populate(void *vedata, Object *ob)
1059 {
1060         OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
1061         const struct bContext *C = DRW_get_context();
1062         Scene *scene = CTX_data_scene(C);
1063         SceneLayer *sl = CTX_data_scene_layer(C);
1064
1065         //CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
1066
1067         //bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
1068         bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0);
1069
1070         switch (ob->type) {
1071                 case OB_MESH:
1072                         {
1073                                 Object *obedit = scene->obedit;
1074                                 int theme_id = DRW_object_wire_theme_get(ob, sl, NULL);
1075                                 if (ob != obedit) {
1076                                         if (do_outlines) {
1077                                                 struct Batch *geom = DRW_cache_surface_get(ob);
1078                                                 switch (theme_id) {
1079                                                         case TH_ACTIVE:
1080                                                                 DRW_shgroup_call_add(stl->g_data->outlines_active, geom, ob->obmat);
1081                                                                 break;
1082                                                         case TH_SELECT:
1083                                                                 DRW_shgroup_call_add(stl->g_data->outlines_select, geom, ob->obmat);
1084                                                                 break;
1085                                                         case TH_GROUP_ACTIVE:
1086                                                                 DRW_shgroup_call_add(stl->g_data->outlines_select_group, geom, ob->obmat);
1087                                                                 break;
1088                                                         case TH_TRANSFORM:
1089                                                                 DRW_shgroup_call_add(stl->g_data->outlines_transform, geom, ob->obmat);
1090                                                                 break;
1091                                                 }
1092                                         }
1093                                 }
1094                         }
1095                         break;
1096                 case OB_LAMP:
1097                         DRW_shgroup_lamp(stl, ob, sl);
1098                         break;
1099                 case OB_CAMERA:
1100                         DRW_shgroup_camera(stl, ob, sl);
1101                         break;
1102                 case OB_EMPTY:
1103                         DRW_shgroup_empty(stl, ob, sl);
1104                         break;
1105                 case OB_SPEAKER:
1106                         DRW_shgroup_speaker(stl, ob, sl);
1107                         break;
1108                 case OB_ARMATURE:
1109                         {
1110                                 bArmature *arm = ob->data;
1111                                 if (arm->edbo == NULL) {
1112                                         DRW_shgroup_armature_object(ob, sl, ((OBJECT_Data *)vedata)->psl->bone_solid,
1113                                                                             ((OBJECT_Data *)vedata)->psl->bone_wire,
1114                                                                             stl->g_data->relationship_lines);
1115                                 }
1116                         }
1117                         break;
1118                 default:
1119                         break;
1120         }
1121
1122         if (ob->pd && ob->pd->forcefield) {
1123                 DRW_shgroup_forcefield(stl, ob, sl);
1124         }
1125
1126         DRW_shgroup_object_center(stl, ob);
1127         DRW_shgroup_relationship_lines(stl, ob);
1128 }
1129
1130 static void OBJECT_draw_scene(void *vedata)
1131 {
1132
1133         OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
1134         OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
1135         OBJECT_TextureList *txl = ((OBJECT_Data *)vedata)->txl;
1136         DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
1137         float clearcol[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1138
1139         /* Render filled polygon on a separate framebuffer */
1140         DRW_framebuffer_bind(fbl->outlines);
1141         DRW_framebuffer_clear(true, true, false, clearcol, 1.0f);
1142         DRW_draw_pass(psl->outlines);
1143
1144         /* detach textures */
1145         DRW_framebuffer_texture_detach(txl->outlines_depth_tx);
1146
1147         /* Search outline pixels */
1148         DRW_framebuffer_bind(fbl->blur);
1149         DRW_draw_pass(psl->outlines_search);
1150
1151         /* Expand and fade gradually */
1152         DRW_framebuffer_bind(fbl->outlines);
1153         DRW_draw_pass(psl->outlines_expand);
1154
1155         DRW_framebuffer_bind(fbl->blur);
1156         DRW_draw_pass(psl->outlines_fade1);
1157
1158         DRW_framebuffer_bind(fbl->outlines);
1159         DRW_draw_pass(psl->outlines_fade2);
1160
1161         DRW_framebuffer_bind(fbl->blur);
1162         DRW_draw_pass(psl->outlines_fade3);
1163
1164         DRW_framebuffer_bind(fbl->outlines);
1165         DRW_draw_pass(psl->outlines_fade4);
1166
1167         DRW_framebuffer_bind(fbl->blur);
1168         DRW_draw_pass(psl->outlines_fade5);
1169
1170         /* reattach */
1171         DRW_framebuffer_texture_attach(fbl->outlines, txl->outlines_depth_tx, 0);
1172         DRW_framebuffer_bind(dfbl->default_fb);
1173
1174         /* This needs to be drawn after the oultine */
1175         DRW_draw_pass(psl->bone_wire);
1176         DRW_draw_pass(psl->bone_solid);
1177         DRW_draw_pass(psl->non_meshes);
1178         DRW_draw_pass(psl->ob_center);
1179         DRW_draw_pass(psl->grid);
1180
1181         /* Combine with scene buffer last */
1182         DRW_draw_pass(psl->outlines_resolve);
1183 }
1184
1185 void OBJECT_collection_settings_create(IDProperty *props)
1186 {
1187         BLI_assert(props &&
1188                    props->type == IDP_GROUP &&
1189                    props->subtype == IDP_GROUP_SUB_MODE_OBJECT);
1190         BKE_collection_engine_property_add_int(props, "show_wire", false);
1191         BKE_collection_engine_property_add_int(props, "show_backface_culling", false);
1192 }
1193
1194 DrawEngineType draw_engine_object_type = {
1195         NULL, NULL,
1196         N_("ObjectMode"),
1197         &OBJECT_engine_init,
1198         &OBJECT_engine_free,
1199         &OBJECT_cache_init,
1200         &OBJECT_cache_populate,
1201         NULL,
1202         NULL,
1203         &OBJECT_draw_scene
1204 };