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