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