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