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