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