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