Fix T56692: The edges are not highlighted in Mark Freestyle Edge
[blender.git] / source / blender / draw / intern / draw_common.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/intern/draw_common.c
23  *  \ingroup draw
24  */
25
26 #include "DRW_render.h"
27
28 #include "GPU_shader.h"
29 #include "GPU_texture.h"
30
31 #include "UI_resources.h"
32
33 #include "BKE_global.h"
34 #include "BKE_colorband.h"
35
36 #include "draw_common.h"
37
38 #if 0
39 #define UI_COLOR_RGB_FROM_U8(r, g, b, v4) \
40         ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, 1.0)
41 #endif
42 #define UI_COLOR_RGBA_FROM_U8(r, g, b, a, v4) \
43         ARRAY_SET_ITEMS(v4, (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f)
44
45 /* Colors & Constant */
46 GlobalsUboStorage ts;
47 struct GPUUniformBuffer *globals_ubo = NULL;
48 struct GPUTexture *globals_ramp = NULL;
49
50 void DRW_globals_update(void)
51 {
52         UI_GetThemeColor4fv(TH_WIRE, ts.colorWire);
53         UI_GetThemeColor4fv(TH_WIRE_EDIT, ts.colorWireEdit);
54         UI_GetThemeColor4fv(TH_ACTIVE, ts.colorActive);
55         UI_GetThemeColor4fv(TH_SELECT, ts.colorSelect);
56         UI_GetThemeColor4fv(TH_TRANSFORM, ts.colorTransform);
57         UI_COLOR_RGBA_FROM_U8(0x88, 0xFF, 0xFF, 155, ts.colorLibrarySelect);
58         UI_COLOR_RGBA_FROM_U8(0x55, 0xCC, 0xCC, 155, ts.colorLibrary);
59         UI_GetThemeColor4fv(TH_LAMP, ts.colorLamp);
60         UI_GetThemeColor4fv(TH_SPEAKER, ts.colorSpeaker);
61         UI_GetThemeColor4fv(TH_CAMERA, ts.colorCamera);
62         UI_GetThemeColor4fv(TH_EMPTY, ts.colorEmpty);
63         UI_GetThemeColor4fv(TH_VERTEX, ts.colorVertex);
64         UI_GetThemeColor4fv(TH_VERTEX_SELECT, ts.colorVertexSelect);
65         UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, ts.colorEditMeshActive);
66         UI_GetThemeColor4fv(TH_EDGE_SELECT, ts.colorEdgeSelect);
67
68         UI_GetThemeColor4fv(TH_EDGE_SEAM, ts.colorEdgeSeam);
69         UI_GetThemeColor4fv(TH_EDGE_SHARP, ts.colorEdgeSharp);
70         UI_GetThemeColor4fv(TH_EDGE_CREASE, ts.colorEdgeCrease);
71         UI_GetThemeColor4fv(TH_EDGE_BEVEL, ts.colorEdgeBWeight);
72         UI_GetThemeColor4fv(TH_EDGE_FACESEL, ts.colorEdgeFaceSelect);
73         UI_GetThemeColor4fv(TH_FACE, ts.colorFace);
74         UI_GetThemeColor4fv(TH_FACE_SELECT, ts.colorFaceSelect);
75         UI_GetThemeColor4fv(TH_NORMAL, ts.colorNormal);
76         UI_GetThemeColor4fv(TH_VNORMAL, ts.colorVNormal);
77         UI_GetThemeColor4fv(TH_LNORMAL, ts.colorLNormal);
78         UI_GetThemeColor4fv(TH_FACE_DOT, ts.colorFaceDot);
79         UI_GetThemeColor4fv(TH_BACK, ts.colorBackground);
80
81 #ifdef WITH_FREESTYLE
82         UI_GetThemeColor4fv(TH_FREESTYLE_EDGE_MARK, ts.colorEdgeFreestyle);
83         UI_GetThemeColor4fv(TH_FREESTYLE_FACE_MARK, ts.colorFaceFreestyle);
84 #else
85         zero_v4(ts.colorEdgeFreestyle);
86         zero_v4(ts.colorFaceFreestyle);
87 #endif
88
89         /* Curve */
90         UI_GetThemeColor4fv(TH_HANDLE_FREE, ts.colorHandleFree);
91         UI_GetThemeColor4fv(TH_HANDLE_AUTO, ts.colorHandleAuto);
92         UI_GetThemeColor4fv(TH_HANDLE_VECT, ts.colorHandleVect);
93         UI_GetThemeColor4fv(TH_HANDLE_ALIGN, ts.colorHandleAlign);
94         UI_GetThemeColor4fv(TH_HANDLE_AUTOCLAMP, ts.colorHandleAutoclamp);
95         UI_GetThemeColor4fv(TH_HANDLE_SEL_FREE, ts.colorHandleSelFree);
96         UI_GetThemeColor4fv(TH_HANDLE_SEL_AUTO, ts.colorHandleSelAuto);
97         UI_GetThemeColor4fv(TH_HANDLE_SEL_VECT, ts.colorHandleSelVect);
98         UI_GetThemeColor4fv(TH_HANDLE_SEL_ALIGN, ts.colorHandleSelAlign);
99         UI_GetThemeColor4fv(TH_HANDLE_SEL_AUTOCLAMP, ts.colorHandleSelAutoclamp);
100         UI_GetThemeColor4fv(TH_NURB_ULINE, ts.colorNurbUline);
101         UI_GetThemeColor4fv(TH_NURB_SEL_ULINE, ts.colorNurbSelUline);
102         UI_GetThemeColor4fv(TH_ACTIVE_SPLINE, ts.colorActiveSpline);
103
104         UI_GetThemeColor4fv(TH_BONE_POSE, ts.colorBonePose);
105
106         UI_GetThemeColor4fv(TH_CFRAME, ts.colorCurrentFrame);
107
108         /* Grid */
109         UI_GetThemeColorShade4fv(TH_GRID, 10, ts.colorGrid);
110         /* emphasise division lines lighter instead of darker, if background is darker than grid */
111         UI_GetThemeColorShade4fv(
112                 TH_GRID,
113                 (ts.colorGrid[0] + ts.colorGrid[1] + ts.colorGrid[2] + 0.12f >
114                  ts.colorBackground[0] + ts.colorBackground[1] + ts.colorBackground[2]) ?
115                 20 : -10, ts.colorGridEmphasise);
116         /* Grid Axis */
117         UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_X, 0.5f, -10, ts.colorGridAxisX);
118         UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_Y, 0.5f, -10, ts.colorGridAxisY);
119         UI_GetThemeColorBlendShade4fv(TH_GRID, TH_AXIS_Z, 0.5f, -10, ts.colorGridAxisZ);
120
121         UI_GetThemeColorShadeAlpha4fv(TH_TRANSFORM, 0, -80, ts.colorDeselect);
122         UI_GetThemeColorShadeAlpha4fv(TH_WIRE, 0, -30, ts.colorOutline);
123         UI_GetThemeColorShadeAlpha4fv(TH_LAMP, 0, 255, ts.colorLampNoAlpha);
124
125         ts.sizeLampCenter = (U.obcenter_dia + 1.5f) * U.pixelsize;
126         ts.sizeLampCircle = U.pixelsize * 9.0f;
127         ts.sizeLampCircleShadow = ts.sizeLampCircle + U.pixelsize * 3.0f;
128
129         /* M_SQRT2 to be at least the same size of the old square */
130         ts.sizeVertex = U.pixelsize * (max_ff(1.0f, UI_GetThemeValuef(TH_VERTEX_SIZE) * (float)M_SQRT2 / 2.0f));
131         ts.sizeFaceDot = U.pixelsize * UI_GetThemeValuef(TH_FACEDOT_SIZE);
132         ts.sizeEdge = U.pixelsize * (1.0f / 2.0f); /* TODO Theme */
133         ts.sizeEdgeFix = U.pixelsize * (0.5f + 2.0f * (2.0f * (MAX2(ts.sizeVertex, ts.sizeEdge)) * (float)M_SQRT1_2));
134
135         if (globals_ubo == NULL) {
136                 globals_ubo = DRW_uniformbuffer_create(sizeof(GlobalsUboStorage), &ts);
137         }
138
139         DRW_uniformbuffer_update(globals_ubo, &ts);
140
141         ColorBand ramp = {0};
142         float *colors;
143         int col_size;
144
145         ramp.tot = 3;
146         ramp.data[0].a = 1.0f;
147         ramp.data[0].b = 1.0f;
148         ramp.data[0].pos = 0.0f;
149         ramp.data[1].a = 1.0f;
150         ramp.data[1].g = 1.0f;
151         ramp.data[1].pos = 0.5f;
152         ramp.data[2].a = 1.0f;
153         ramp.data[2].r = 1.0f;
154         ramp.data[2].pos = 1.0f;
155
156         BKE_colorband_evaluate_table_rgba(&ramp, &colors, &col_size);
157
158         if (globals_ramp) {
159                 GPU_texture_free(globals_ramp);
160         }
161         globals_ramp = GPU_texture_create_1D(col_size, GPU_RGBA8, colors, NULL);
162
163         MEM_freeN(colors);
164 }
165
166 /* ********************************* SHGROUP ************************************* */
167
168 extern char datatoc_animviz_mpath_lines_vert_glsl[];
169 extern char datatoc_animviz_mpath_lines_geom_glsl[];
170 extern char datatoc_animviz_mpath_points_vert_glsl[];
171
172 extern char datatoc_volume_velocity_vert_glsl[];
173
174 extern char datatoc_armature_axes_vert_glsl[];
175 extern char datatoc_armature_sphere_solid_vert_glsl[];
176 extern char datatoc_armature_sphere_solid_frag_glsl[];
177 extern char datatoc_armature_sphere_outline_vert_glsl[];
178 extern char datatoc_armature_envelope_solid_vert_glsl[];
179 extern char datatoc_armature_envelope_solid_frag_glsl[];
180 extern char datatoc_armature_envelope_outline_vert_glsl[];
181 extern char datatoc_armature_envelope_distance_frag_glsl[];
182 extern char datatoc_armature_shape_solid_vert_glsl[];
183 extern char datatoc_armature_shape_solid_frag_glsl[];
184 extern char datatoc_armature_shape_outline_vert_glsl[];
185 extern char datatoc_armature_shape_outline_geom_glsl[];
186 extern char datatoc_armature_stick_vert_glsl[];
187 extern char datatoc_armature_stick_frag_glsl[];
188
189 extern char datatoc_common_globals_lib_glsl[];
190
191 extern char datatoc_gpu_shader_flat_color_frag_glsl[];
192 extern char datatoc_gpu_shader_3D_smooth_color_frag_glsl[];
193 extern char datatoc_gpu_shader_point_varying_color_frag_glsl[];
194
195 extern char datatoc_object_mball_handles_vert_glsl[];
196 extern char datatoc_object_empty_axes_vert_glsl[];
197
198 static struct {
199         struct GPUShader *shape_outline;
200         struct GPUShader *shape_solid;
201         struct GPUShader *bone_axes;
202         struct GPUShader *bone_envelope;
203         struct GPUShader *bone_envelope_distance;
204         struct GPUShader *bone_envelope_outline;
205         struct GPUShader *bone_sphere;
206         struct GPUShader *bone_sphere_outline;
207         struct GPUShader *bone_stick;
208
209         struct GPUShader *mpath_line_sh;
210         struct GPUShader *mpath_points_sh;
211
212         struct GPUShader *volume_velocity_needle_sh;
213         struct GPUShader *volume_velocity_sh;
214         struct GPUShader *empty_axes_sh;
215
216         struct GPUShader *mball_handles;
217 } g_shaders = {NULL};
218
219 static struct {
220         struct GPUVertFormat *instance_screenspace;
221         struct GPUVertFormat *instance_color;
222         struct GPUVertFormat *instance_screen_aligned;
223         struct GPUVertFormat *instance_scaled;
224         struct GPUVertFormat *instance_sized;
225         struct GPUVertFormat *instance_outline;
226         struct GPUVertFormat *instance;
227         struct GPUVertFormat *instance_camera;
228         struct GPUVertFormat *instance_distance_lines;
229         struct GPUVertFormat *instance_spot;
230         struct GPUVertFormat *instance_bone;
231         struct GPUVertFormat *instance_bone_stick;
232         struct GPUVertFormat *instance_bone_outline;
233         struct GPUVertFormat *instance_bone_envelope;
234         struct GPUVertFormat *instance_bone_envelope_distance;
235         struct GPUVertFormat *instance_bone_envelope_outline;
236         struct GPUVertFormat *instance_mball_handles;
237         struct GPUVertFormat *dynlines_color;
238 } g_formats = {NULL};
239
240 void DRW_globals_free(void)
241 {
242         struct GPUVertFormat **format = &g_formats.instance_screenspace;
243         for (int i = 0; i < sizeof(g_formats) / sizeof(void *); ++i, ++format) {
244                 MEM_SAFE_FREE(*format);
245         }
246
247         struct GPUShader **shader = &g_shaders.shape_outline;
248         for (int i = 0; i < sizeof(g_shaders) / sizeof(void *); ++i, ++shader) {
249                 DRW_SHADER_FREE_SAFE(*shader);
250         }
251 }
252
253 DRWShadingGroup *shgroup_dynlines_flat_color(DRWPass *pass)
254 {
255         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
256
257         DRW_shgroup_instance_format(g_formats.dynlines_color, {
258                 {"pos",       DRW_ATTRIB_FLOAT, 3},
259                 {"color",     DRW_ATTRIB_FLOAT, 4}
260         });
261
262         DRWShadingGroup *grp = DRW_shgroup_line_batch_create_with_format(sh, pass, g_formats.dynlines_color);
263
264         return grp;
265 }
266
267 DRWShadingGroup *shgroup_dynlines_dashed_uniform_color(DRWPass *pass, float color[4])
268 {
269         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
270
271         static float dash_width = 6.0f;
272         static float dash_factor = 0.5f;
273         DRWShadingGroup *grp = DRW_shgroup_line_batch_create(sh, pass);
274         DRW_shgroup_uniform_vec4(grp, "color", color, 1);
275         DRW_shgroup_uniform_vec2(grp, "viewport_size", DRW_viewport_size_get(), 1);
276         DRW_shgroup_uniform_float(grp, "dash_width", &dash_width, 1);
277         DRW_shgroup_uniform_float(grp, "dash_factor", &dash_factor, 1);
278         DRW_shgroup_uniform_int_copy(grp, "colors_len", 0); /* "simple" mode */
279
280         return grp;
281 }
282
283 DRWShadingGroup *shgroup_dynpoints_uniform_color(DRWPass *pass, float color[4], float *size)
284 {
285         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
286
287         DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
288         DRW_shgroup_uniform_vec4(grp, "color", color, 1);
289         DRW_shgroup_uniform_float(grp, "size", size, 1);
290         DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
291
292         return grp;
293 }
294
295 DRWShadingGroup *shgroup_groundlines_uniform_color(DRWPass *pass, float color[4])
296 {
297         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDLINE);
298
299         DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
300         DRW_shgroup_uniform_vec4(grp, "color", color, 1);
301
302         return grp;
303 }
304
305 DRWShadingGroup *shgroup_groundpoints_uniform_color(DRWPass *pass, float color[4])
306 {
307         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_GROUNDPOINT);
308
309         DRWShadingGroup *grp = DRW_shgroup_point_batch_create(sh, pass);
310         DRW_shgroup_uniform_vec4(grp, "color", color, 1);
311         DRW_shgroup_state_enable(grp, DRW_STATE_POINT);
312
313         return grp;
314 }
315
316 DRWShadingGroup *shgroup_instance_screenspace(DRWPass *pass, struct GPUBatch *geom, float *size)
317 {
318         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR);
319
320         DRW_shgroup_instance_format(g_formats.instance_screenspace, {
321                 {"world_pos", DRW_ATTRIB_FLOAT, 3},
322                 {"color",     DRW_ATTRIB_FLOAT, 3}
323         });
324
325         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screenspace);
326         DRW_shgroup_uniform_float(grp, "size", size, 1);
327         DRW_shgroup_uniform_float(grp, "pixel_size", DRW_viewport_pixelsize_get(), 1);
328         DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
329         DRW_shgroup_state_enable(grp, DRW_STATE_STIPPLE_3);
330
331         return grp;
332 }
333
334 DRWShadingGroup *shgroup_instance_solid(DRWPass *pass, struct GPUBatch *geom)
335 {
336         static float light[3] = {0.0f, 0.0f, 1.0f};
337         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR);
338
339         DRW_shgroup_instance_format(g_formats.instance_color, {
340                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
341                 {"color",               DRW_ATTRIB_FLOAT, 4}
342         });
343
344         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
345         DRW_shgroup_uniform_vec3(grp, "light", light, 1);
346
347         return grp;
348 }
349
350 DRWShadingGroup *shgroup_instance_wire(DRWPass *pass, struct GPUBatch *geom)
351 {
352         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_OBJECTSPACE_VARIYING_COLOR);
353
354         DRW_shgroup_instance_format(g_formats.instance_color, {
355                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
356                 {"color",               DRW_ATTRIB_FLOAT, 4}
357         });
358
359         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_color);
360
361         return grp;
362 }
363
364 DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct GPUBatch *geom)
365 {
366         GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED);
367
368         DRW_shgroup_instance_format(g_formats.instance_screen_aligned, {
369                 {"color",               DRW_ATTRIB_FLOAT, 3},
370                 {"size",                DRW_ATTRIB_FLOAT, 1},
371                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
372         });
373
374         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom, g_formats.instance_screen_aligned);
375         DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
376
377         return grp;
378 }
379
380 DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct GPUBatch *geom)
381 {
382         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE);
383
384         DRW_shgroup_instance_format(g_formats.instance_scaled, {
385                 {"color",               DRW_ATTRIB_FLOAT, 3},
386                 {"size",                DRW_ATTRIB_FLOAT, 3},
387                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
388         });
389
390         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_scaled);
391
392         return grp;
393 }
394
395 DRWShadingGroup *shgroup_instance(DRWPass *pass, struct GPUBatch *geom)
396 {
397         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
398
399         DRW_shgroup_instance_format(g_formats.instance_sized, {
400                 {"color",               DRW_ATTRIB_FLOAT, 3},
401                 {"size",                DRW_ATTRIB_FLOAT, 1},
402                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
403         });
404
405         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized);
406         DRW_shgroup_uniform_float_copy(grp, "alpha", 1.0f);
407
408         return grp;
409 }
410
411 DRWShadingGroup *shgroup_instance_alpha(DRWPass *pass, struct GPUBatch *geom, float alpha)
412 {
413         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE);
414
415         DRW_shgroup_instance_format(g_formats.instance_sized, {
416                 {"color",               DRW_ATTRIB_FLOAT, 4},
417                 {"size",                DRW_ATTRIB_FLOAT, 1},
418                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
419         });
420
421         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_sized);
422         DRW_shgroup_uniform_float_copy(grp, "alpha", alpha);
423
424         return grp;
425 }
426
427 DRWShadingGroup *shgroup_instance_empty_axes(DRWPass *pass, struct GPUBatch *geom)
428 {
429         if (g_shaders.empty_axes_sh == NULL) {
430                 g_shaders.empty_axes_sh = DRW_shader_create(
431                         datatoc_object_empty_axes_vert_glsl, NULL,
432                         datatoc_gpu_shader_flat_color_frag_glsl, NULL);
433         }
434
435         DRW_shgroup_instance_format(g_formats.instance_sized, {
436                 {"color",               DRW_ATTRIB_FLOAT, 3},
437                 {"size",                DRW_ATTRIB_FLOAT, 1},
438                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
439         });
440
441         DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.empty_axes_sh, pass, geom, g_formats.instance_sized);
442         DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
443
444         return grp;
445 }
446
447 DRWShadingGroup *shgroup_instance_outline(DRWPass *pass, struct GPUBatch *geom, int *baseid)
448 {
449         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_ID_VARIYING_SIZE);
450
451         DRW_shgroup_instance_format(g_formats.instance_outline, {
452                 {"callId",              DRW_ATTRIB_INT,   1},
453                 {"size",                DRW_ATTRIB_FLOAT, 1},
454                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
455         });
456
457         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_outline);
458         DRW_shgroup_uniform_int(grp, "baseId", baseid, 1);
459
460         return grp;
461 }
462
463 DRWShadingGroup *shgroup_camera_instance(DRWPass *pass, struct GPUBatch *geom)
464 {
465         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_CAMERA);
466
467         DRW_shgroup_instance_format(g_formats.instance_camera, {
468                 {"color",               DRW_ATTRIB_FLOAT, 3},
469                 {"corners",             DRW_ATTRIB_FLOAT, 8},
470                 {"depth",               DRW_ATTRIB_FLOAT, 1},
471                 {"tria",                DRW_ATTRIB_FLOAT, 4},
472                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
473         });
474
475         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_camera);
476
477         return grp;
478 }
479
480 DRWShadingGroup *shgroup_distance_lines_instance(DRWPass *pass, struct GPUBatch *geom)
481 {
482         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_DISTANCE_LINES);
483         static float point_size = 4.0f;
484
485         DRW_shgroup_instance_format(g_formats.instance_distance_lines, {
486                 {"color",               DRW_ATTRIB_FLOAT, 3},
487                 {"start",               DRW_ATTRIB_FLOAT, 1},
488                 {"end",                 DRW_ATTRIB_FLOAT, 1},
489                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
490         });
491
492         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_distance_lines);
493         DRW_shgroup_uniform_float(grp, "size", &point_size, 1);
494
495         return grp;
496 }
497
498 DRWShadingGroup *shgroup_spot_instance(DRWPass *pass, struct GPUBatch *geom)
499 {
500         GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR);
501         static const int True = true;
502         static const int False = false;
503
504         DRW_shgroup_instance_format(g_formats.instance_spot, {
505                 {"color",               DRW_ATTRIB_FLOAT, 3},
506                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
507         });
508
509         DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom, g_formats.instance_spot);
510         DRW_shgroup_uniform_bool(grp, "drawFront", &False, 1);
511         DRW_shgroup_uniform_bool(grp, "drawBack", &False, 1);
512         DRW_shgroup_uniform_bool(grp, "drawSilhouette", &True, 1);
513
514         return grp;
515 }
516
517 DRWShadingGroup *shgroup_instance_bone_axes(DRWPass *pass)
518 {
519         if (g_shaders.bone_axes == NULL) {
520                 g_shaders.bone_axes = DRW_shader_create(
521                             datatoc_armature_axes_vert_glsl, NULL,
522                             datatoc_gpu_shader_flat_color_frag_glsl, NULL);
523         }
524
525         DRW_shgroup_instance_format(g_formats.instance_color, {
526                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
527                 {"color",               DRW_ATTRIB_FLOAT, 4}
528         });
529
530         DRWShadingGroup *grp = DRW_shgroup_instance_create(
531                 g_shaders.bone_axes,
532                 pass, DRW_cache_bone_arrows_get(),
533                 g_formats.instance_color);
534         DRW_shgroup_uniform_vec3(grp, "screenVecs[0]", DRW_viewport_screenvecs_get(), 2);
535
536         return grp;
537 }
538
539 DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass)
540 {
541         if (g_shaders.bone_envelope_outline == NULL) {
542                 g_shaders.bone_envelope_outline = DRW_shader_create(
543                             datatoc_armature_envelope_outline_vert_glsl, NULL,
544                             datatoc_gpu_shader_flat_color_frag_glsl, NULL);
545         }
546
547         DRW_shgroup_instance_format(g_formats.instance_bone_envelope_outline, {
548                 {"headSphere",           DRW_ATTRIB_FLOAT, 4},
549                 {"tailSphere",           DRW_ATTRIB_FLOAT, 4},
550                 {"outlineColorSize",     DRW_ATTRIB_FLOAT, 4},
551                 {"xAxis",                DRW_ATTRIB_FLOAT, 3}
552         });
553
554         DRWShadingGroup *grp = DRW_shgroup_instance_create(
555                 g_shaders.bone_envelope_outline,
556                 pass, DRW_cache_bone_envelope_outline_get(),
557                 g_formats.instance_bone_envelope_outline);
558         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
559
560         return grp;
561 }
562
563 DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass)
564 {
565         if (g_shaders.bone_envelope_distance == NULL) {
566                 g_shaders.bone_envelope_distance = DRW_shader_create(
567                             datatoc_armature_envelope_solid_vert_glsl, NULL,
568                             datatoc_armature_envelope_distance_frag_glsl, NULL);
569         }
570
571         DRW_shgroup_instance_format(g_formats.instance_bone_envelope_distance, {
572                 {"headSphere",           DRW_ATTRIB_FLOAT, 4},
573                 {"tailSphere",           DRW_ATTRIB_FLOAT, 4},
574                 {"xAxis",                DRW_ATTRIB_FLOAT, 3}
575         });
576
577         DRWShadingGroup *grp = DRW_shgroup_instance_create(
578                 g_shaders.bone_envelope_distance,
579                 pass, DRW_cache_bone_envelope_solid_get(),
580                 g_formats.instance_bone_envelope_distance);
581
582         return grp;
583 }
584
585 DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, bool transp)
586 {
587         if (g_shaders.bone_envelope == NULL) {
588                 g_shaders.bone_envelope = DRW_shader_create(
589                             datatoc_armature_envelope_solid_vert_glsl, NULL,
590                             datatoc_armature_envelope_solid_frag_glsl, "#define SMOOTH_ENVELOPE\n");
591         }
592
593         DRW_shgroup_instance_format(g_formats.instance_bone_envelope, {
594                 {"headSphere",           DRW_ATTRIB_FLOAT, 4},
595                 {"tailSphere",           DRW_ATTRIB_FLOAT, 4},
596                 {"boneColor",            DRW_ATTRIB_FLOAT, 3},
597                 {"stateColor",           DRW_ATTRIB_FLOAT, 3},
598                 {"xAxis",                DRW_ATTRIB_FLOAT, 3}
599         });
600
601         DRWShadingGroup *grp = DRW_shgroup_instance_create(
602                 g_shaders.bone_envelope,
603                 pass, DRW_cache_bone_envelope_solid_get(),
604                 g_formats.instance_bone_envelope);
605         DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f);
606
607         return grp;
608 }
609
610 DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass)
611 {
612         if (g_shaders.mball_handles == NULL) {
613                 g_shaders.mball_handles = DRW_shader_create(
614                             datatoc_object_mball_handles_vert_glsl, NULL,
615                             datatoc_gpu_shader_flat_color_frag_glsl, NULL);
616         }
617
618         DRW_shgroup_instance_format(g_formats.instance_mball_handles, {
619                 {"ScaleTranslationMatrix",  DRW_ATTRIB_FLOAT, 12},
620                 {"radius",                  DRW_ATTRIB_FLOAT, 1},
621                 {"color",                   DRW_ATTRIB_FLOAT, 3}
622         });
623
624         DRWShadingGroup *grp = DRW_shgroup_instance_create(
625                 g_shaders.mball_handles, pass,
626                 DRW_cache_screenspace_circle_get(),
627                 g_formats.instance_mball_handles);
628         DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
629
630         return grp;
631 }
632
633 /* Only works with batches with adjacency infos. */
634 DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct GPUBatch *geom)
635 {
636         if (g_shaders.shape_outline == NULL) {
637                 g_shaders.shape_outline = DRW_shader_create(
638                             datatoc_armature_shape_outline_vert_glsl,
639                             datatoc_armature_shape_outline_geom_glsl,
640                             datatoc_gpu_shader_flat_color_frag_glsl,
641                             NULL);
642         }
643
644         DRW_shgroup_instance_format(g_formats.instance_bone_outline, {
645                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
646                 {"outlineColorSize",    DRW_ATTRIB_FLOAT, 4}
647         });
648
649         DRWShadingGroup *grp = DRW_shgroup_instance_create(
650                 g_shaders.shape_outline,
651                 pass, geom, g_formats.instance_bone_outline);
652         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
653
654         return grp;
655 }
656
657 DRWShadingGroup *shgroup_instance_bone_shape_solid(DRWPass *pass, struct GPUBatch *geom, bool transp)
658 {
659         if (g_shaders.shape_solid == NULL) {
660                 g_shaders.shape_solid = DRW_shader_create(
661                             datatoc_armature_shape_solid_vert_glsl, NULL,
662                             datatoc_armature_shape_solid_frag_glsl, NULL);
663         }
664
665         DRW_shgroup_instance_format(g_formats.instance_bone, {
666                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
667                 {"boneColor",            DRW_ATTRIB_FLOAT, 3},
668                 {"stateColor",           DRW_ATTRIB_FLOAT, 3}
669         });
670
671         DRWShadingGroup *grp = DRW_shgroup_instance_create(
672                 g_shaders.shape_solid,
673                 pass, geom, g_formats.instance_bone);
674         DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.6f : 1.0f);
675
676         return grp;
677 }
678
679 DRWShadingGroup *shgroup_instance_bone_sphere_solid(DRWPass *pass, bool transp)
680 {
681         if (g_shaders.bone_sphere == NULL) {
682                 g_shaders.bone_sphere = DRW_shader_create(
683                             datatoc_armature_sphere_solid_vert_glsl, NULL,
684                             datatoc_armature_sphere_solid_frag_glsl, NULL);
685         }
686
687         DRW_shgroup_instance_format(g_formats.instance_bone, {
688                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
689                 {"boneColor",           DRW_ATTRIB_FLOAT, 3},
690                 {"stateColor",          DRW_ATTRIB_FLOAT, 3}
691         });
692
693         DRWShadingGroup *grp = DRW_shgroup_instance_create(
694                 g_shaders.bone_sphere,
695                 pass, DRW_cache_bone_point_get(), g_formats.instance_bone);
696         /* More transparent than the shape to be less distractive. */
697         DRW_shgroup_uniform_float_copy(grp, "alpha", transp ? 0.4f : 1.0f);
698
699         return grp;
700 }
701
702 DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
703 {
704         if (g_shaders.bone_sphere_outline == NULL) {
705                 g_shaders.bone_sphere_outline = DRW_shader_create(
706                             datatoc_armature_sphere_outline_vert_glsl, NULL,
707                             datatoc_gpu_shader_flat_color_frag_glsl, NULL);
708         }
709
710         DRW_shgroup_instance_format(g_formats.instance_bone_outline, {
711                 {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
712                 {"outlineColorSize",    DRW_ATTRIB_FLOAT, 4}
713         });
714
715         DRWShadingGroup *grp = DRW_shgroup_instance_create(
716                 g_shaders.bone_sphere_outline,
717                 pass, DRW_cache_bone_point_wire_outline_get(),
718                 g_formats.instance_bone_outline);
719         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
720
721         return grp;
722 }
723
724 DRWShadingGroup *shgroup_instance_bone_stick(DRWPass *pass)
725 {
726         if (g_shaders.bone_stick == NULL) {
727                 g_shaders.bone_stick = DRW_shader_create(
728                             datatoc_armature_stick_vert_glsl, NULL,
729                             datatoc_armature_stick_frag_glsl, NULL);
730         }
731
732         DRW_shgroup_instance_format(g_formats.instance_bone_stick, {
733                 {"boneStart", DRW_ATTRIB_FLOAT, 3},
734                 {"boneEnd",   DRW_ATTRIB_FLOAT, 3},
735                 {"wireColor", DRW_ATTRIB_FLOAT, 4}, /* TODO port theses to uchar color */
736                 {"boneColor", DRW_ATTRIB_FLOAT, 4},
737                 {"headColor", DRW_ATTRIB_FLOAT, 4},
738                 {"tailColor", DRW_ATTRIB_FLOAT, 4}
739         });
740
741         DRWShadingGroup *grp = DRW_shgroup_instance_create(
742                 g_shaders.bone_stick,
743                 pass, DRW_cache_bone_stick_get(),
744                 g_formats.instance_bone_stick);
745         DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
746
747         return grp;
748 }
749
750 struct GPUShader *mpath_line_shader_get(void)
751 {
752         if (g_shaders.mpath_line_sh == NULL) {
753                 g_shaders.mpath_line_sh = DRW_shader_create_with_lib(
754                         datatoc_animviz_mpath_lines_vert_glsl,
755                         datatoc_animviz_mpath_lines_geom_glsl,
756                         datatoc_gpu_shader_3D_smooth_color_frag_glsl,
757                         datatoc_common_globals_lib_glsl,
758                         NULL);
759         }
760         return g_shaders.mpath_line_sh;
761 }
762
763
764 struct GPUShader *mpath_points_shader_get(void)
765 {
766         if (g_shaders.mpath_points_sh == NULL) {
767                 g_shaders.mpath_points_sh = DRW_shader_create_with_lib(
768                         datatoc_animviz_mpath_points_vert_glsl,
769                         NULL,
770                         datatoc_gpu_shader_point_varying_color_frag_glsl,
771                         datatoc_common_globals_lib_glsl,
772                         NULL);
773         }
774         return g_shaders.mpath_points_sh;
775 }
776
777 struct GPUShader *volume_velocity_shader_get(bool use_needle)
778 {
779         if (use_needle) {
780                 if (g_shaders.volume_velocity_needle_sh == NULL) {
781                         g_shaders.volume_velocity_needle_sh = DRW_shader_create(
782                                 datatoc_volume_velocity_vert_glsl, NULL,
783                                 datatoc_gpu_shader_flat_color_frag_glsl, "#define USE_NEEDLE");
784                 }
785                 return g_shaders.volume_velocity_needle_sh;
786         }
787         else {
788                 if (g_shaders.volume_velocity_sh == NULL) {
789                         g_shaders.volume_velocity_sh = DRW_shader_create(
790                                 datatoc_volume_velocity_vert_glsl, NULL,
791                                 datatoc_gpu_shader_flat_color_frag_glsl, NULL);
792                 }
793                 return g_shaders.volume_velocity_sh;
794         }
795 }
796
797 /* ******************************************** COLOR UTILS *********************************************** */
798
799 /* TODO FINISH */
800 /**
801  * Get the wire color theme_id of an object based on it's state
802  * \a r_color is a way to get a pointer to the static color var associated
803  */
804 int DRW_object_wire_theme_get(Object *ob, ViewLayer *view_layer, float **r_color)
805 {
806         const DRWContextState *draw_ctx = DRW_context_state_get();
807         const bool is_edit = (draw_ctx->object_mode & OB_MODE_EDIT) != 0;
808         const bool active = (view_layer->basact && view_layer->basact->object == ob);
809         /* confusing logic here, there are 2 methods of setting the color
810          * 'colortab[colindex]' and 'theme_id', colindex overrides theme_id.
811          *
812          * note: no theme yet for 'colindex' */
813         int theme_id = is_edit ? TH_WIRE_EDIT : TH_WIRE;
814
815         if (//(scene->obedit == NULL) &&
816             ((G.moving & G_TRANSFORM_OBJ) != 0) &&
817             ((ob->base_flag & BASE_SELECTED) != 0))
818         {
819                 theme_id = TH_TRANSFORM;
820         }
821         else {
822                 /* Sets the 'theme_id' or fallback to wire */
823                 if ((ob->base_flag & BASE_SELECTED) != 0) {
824                         theme_id = (active) ? TH_ACTIVE : TH_SELECT;
825                 }
826                 else {
827                         if (ob->type == OB_LAMP) theme_id = TH_LAMP;
828                         else if (ob->type == OB_SPEAKER) theme_id = TH_SPEAKER;
829                         else if (ob->type == OB_CAMERA) theme_id = TH_CAMERA;
830                         else if (ob->type == OB_EMPTY) theme_id = TH_EMPTY;
831                         else if (ob->type == OB_LIGHTPROBE) theme_id = TH_EMPTY; /* TODO add lightprobe color */
832                         /* fallback to TH_WIRE */
833                 }
834         }
835
836         if (r_color != NULL) {
837                 switch (theme_id) {
838                         case TH_WIRE_EDIT:    *r_color = ts.colorWireEdit; break;
839                         case TH_ACTIVE:       *r_color = ts.colorActive; break;
840                         case TH_SELECT:       *r_color = ts.colorSelect; break;
841                         case TH_TRANSFORM:    *r_color = ts.colorTransform; break;
842                         case TH_SPEAKER:      *r_color = ts.colorSpeaker; break;
843                         case TH_CAMERA:       *r_color = ts.colorCamera; break;
844                         case TH_EMPTY:        *r_color = ts.colorEmpty; break;
845                         case TH_LAMP:         *r_color = ts.colorLamp; break;
846                         default:              *r_color = ts.colorWire; break;
847                 }
848         }
849
850         return theme_id;
851 }
852
853 /* XXX This is very stupid, better find something more general. */
854 float *DRW_color_background_blend_get(int theme_id)
855 {
856         static float colors[11][4];
857         float *ret;
858
859         switch (theme_id) {
860                 case TH_WIRE_EDIT:    ret = colors[0]; break;
861                 case TH_ACTIVE:       ret = colors[1]; break;
862                 case TH_SELECT:       ret = colors[2]; break;
863                 case TH_TRANSFORM:    ret = colors[5]; break;
864                 case TH_SPEAKER:      ret = colors[6]; break;
865                 case TH_CAMERA:       ret = colors[7]; break;
866                 case TH_EMPTY:        ret = colors[8]; break;
867                 case TH_LAMP:         ret = colors[9]; break;
868                 default:              ret = colors[10]; break;
869         }
870
871         UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, 0, ret);
872
873         return ret;
874 }