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