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