Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_clip / clip_draw.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2011 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation,
23  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_clip/clip_draw.c
29  *  \ingroup spclip
30  */
31
32 #include "DNA_gpencil_types.h"
33 #include "DNA_movieclip_types.h"
34 #include "DNA_scene_types.h"
35
36 #include "MEM_guardedalloc.h"
37
38 #include "IMB_colormanagement.h"
39 #include "IMB_imbuf_types.h"
40 #include "IMB_imbuf.h"
41
42 #include "BLI_utildefines.h"
43 #include "BLI_math.h"
44 #include "BLI_string.h"
45 #include "BLI_math_base.h"
46 #include "BLI_rect.h"
47
48 #include "BKE_context.h"
49 #include "BKE_image.h"
50 #include "BKE_movieclip.h"
51 #include "BKE_tracking.h"
52
53 #include "ED_screen.h"
54 #include "ED_clip.h"
55 #include "ED_mask.h"
56 #include "ED_gpencil.h"
57
58 #include "BIF_glutil.h"
59
60 #include "GPU_immediate.h"
61 #include "GPU_immediate_util.h"
62 #include "GPU_matrix.h"
63
64 #include "WM_types.h"
65
66 #include "UI_interface.h"
67 #include "UI_resources.h"
68 #include "UI_view2d.h"
69
70 #include "BLF_api.h"
71
72 #include "clip_intern.h"    // own include
73
74 /*********************** main area drawing *************************/
75
76 static void draw_keyframe(int frame, int cfra, int sfra, float framelen, int width, unsigned int pos)
77 {
78         int height = (frame == cfra) ? 22 : 10;
79         int x = (frame - sfra) * framelen;
80
81         if (width == 1) {
82                 immBegin(GWN_PRIM_LINES, 2);
83                 immVertex2i(pos, x, 0);
84                 immVertex2i(pos, x, height * UI_DPI_FAC);
85                 immEnd();
86         }
87         else {
88                 immRecti(pos, x, 0, x + width, height * UI_DPI_FAC);
89         }
90 }
91
92 static int generic_track_get_markersnr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track)
93 {
94         if (track) {
95                 return track->markersnr;
96         }
97         else if (plane_track) {
98                 return plane_track->markersnr;
99         }
100
101         return 0;
102 }
103
104 static int generic_track_get_marker_framenr(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
105                                             int marker_index)
106 {
107         if (track) {
108                 BLI_assert(marker_index < track->markersnr);
109                 return track->markers[marker_index].framenr;
110         }
111         else if (plane_track) {
112                 BLI_assert(marker_index < plane_track->markersnr);
113                 return plane_track->markers[marker_index].framenr;
114         }
115
116         return 0;
117 }
118
119 static bool generic_track_is_marker_enabled(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
120                                             int marker_index)
121 {
122         if (track) {
123                 BLI_assert(marker_index < track->markersnr);
124                 return (track->markers[marker_index].flag & MARKER_DISABLED) == 0;
125         }
126         else if (plane_track) {
127                 return true;
128         }
129
130         return false;
131 }
132
133 static bool generic_track_is_marker_keyframed(MovieTrackingTrack *track, MovieTrackingPlaneTrack *plane_track,
134                                               int marker_index)
135 {
136         if (track) {
137                 BLI_assert(marker_index < track->markersnr);
138                 return (track->markers[marker_index].flag & MARKER_TRACKED) == 0;
139         }
140         else if (plane_track) {
141                 BLI_assert(marker_index < plane_track->markersnr);
142                 return (plane_track->markers[marker_index].flag & PLANE_MARKER_TRACKED) == 0;
143         }
144
145         return false;
146 }
147
148 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
149 {
150         float x;
151         int *points, totseg, i, a;
152         float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
153         MovieTracking *tracking = &clip->tracking;
154         MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
155         MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
156         MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
157         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);
158
159         glEnable(GL_BLEND);
160         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
161
162         /* cache background */
163         ED_region_cache_draw_background(ar);
164
165         /* cached segments -- could be usefu lto debug caching strategies */
166         BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
167         ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);
168
169         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
170         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
171
172         /* track */
173         if (act_track || act_plane_track) {
174                 for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
175                         int framenr;
176                         int markersnr = generic_track_get_markersnr(act_track, act_plane_track);
177
178                         while (a < markersnr) {
179                                 int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
180
181                                 if (marker_framenr >= i)
182                                         break;
183
184                                 if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i)
185                                         break;
186
187                                 a++;
188                         }
189
190                         a = min_ii(a, markersnr - 1);
191
192                         if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
193                                 framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);
194
195                                 if (framenr != i) {
196                                         immUniformColor4ub(128, 128, 0, 96);
197                                 }
198                                 else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a)) {
199                                         immUniformColor4ub(255, 255, 0, 196);
200                                 }
201                                 else {
202                                         immUniformColor4ub(255, 255, 0, 96);
203                                 }
204
205                                 immRecti(pos, (i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
206                         }
207                 }
208         }
209
210         /* failed frames */
211         if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
212                 int n = reconstruction->camnr;
213                 MovieReconstructedCamera *cameras = reconstruction->cameras;
214
215                 immUniformColor4ub(255, 0, 0, 96);
216
217                 for (i = sfra, a = 0; i <= efra; i++) {
218                         bool ok = false;
219
220                         while (a < n) {
221                                 if (cameras[a].framenr == i) {
222                                         ok = true;
223                                         break;
224                                 }
225                                 else if (cameras[a].framenr > i) {
226                                         break;
227                                 }
228
229                                 a++;
230                         }
231
232                         if (!ok) {
233                                 immRecti(pos, (i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
234                         }
235                 }
236         }
237
238         glDisable(GL_BLEND);
239
240         /* current frame */
241         x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
242
243         immUniformThemeColor(TH_CFRAME);
244         immRecti(pos, x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);
245
246         immUnbindProgram();
247
248         ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);
249
250         pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_I32, 2, GWN_FETCH_INT_TO_FLOAT);
251         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
252
253         /* solver keyframes */
254         immUniformColor4ub(175, 255, 0, 255);
255         draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2, pos);
256         draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2, pos);
257
258         immUnbindProgram();
259
260         /* movie clip animation */
261         if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
262                 ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra);
263         }
264 }
265
266 static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
267 {
268         MovieClip *clip = ED_space_clip_get_clip(sc);
269         MovieTracking *tracking = &clip->tracking;
270         char str[256] = {0};
271         bool full_redraw = false;
272
273         if (tracking->stats) {
274                 BLI_strncpy(str, tracking->stats->message, sizeof(str));
275                 full_redraw = true;
276         }
277         else {
278                 if (sc->flag & SC_LOCK_SELECTION)
279                         strcpy(str, "Locked");
280         }
281
282         if (str[0]) {
283                 float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.6f};
284                 ED_region_info_draw(ar, str, fill_color, full_redraw);
285         }
286 }
287
288 static void draw_movieclip_muted(ARegion *ar, int width, int height, float zoomx, float zoomy)
289 {
290         int x, y;
291
292         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
293         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
294
295         /* find window pixel coordinates of origin */
296         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
297
298         immUniformColor3f(0.0f, 0.0f, 0.0f);
299         immRectf(pos, x, y, x + zoomx * width, y + zoomy * height);
300
301         immUnbindProgram();
302 }
303
304 static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
305                                   int width, int height, float zoomx, float zoomy)
306 {
307         MovieClip *clip = ED_space_clip_get_clip(sc);
308         int filter = GL_LINEAR;
309         int x, y;
310
311         /* find window pixel coordinates of origin */
312         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
313
314         /* checkerboard for case alpha */
315         if (ibuf->planes == 32) {
316                 glEnable(GL_BLEND);
317                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
318
319                 imm_draw_checker_box(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
320         }
321
322         /* non-scaled proxy shouldn't use filtering */
323         if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
324             ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
325         {
326                 filter = GL_NEAREST;
327         }
328
329         glaDrawImBuf_glsl_ctx(C, ibuf, x, y, filter, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
330
331         if (sc->flag & SC_SHOW_METADATA) {
332                 rctf frame;
333                 BLI_rctf_init(&frame, 0.0f, ibuf->x, 0.0f, ibuf->y);
334                 ED_region_image_metadata_draw(x, y, ibuf, &frame, zoomx * width / ibuf->x, zoomy * height / ibuf->y);
335         }
336
337         if (ibuf->planes == 32)
338                 glDisable(GL_BLEND);
339 }
340
341 static void draw_stabilization_border(SpaceClip *sc, ARegion *ar, int width, int height, float zoomx, float zoomy)
342 {
343         int x, y;
344         MovieClip *clip = ED_space_clip_get_clip(sc);
345
346         /* find window pixel coordinates of origin */
347         UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);
348
349         /* draw boundary border for frame if stabilization is enabled */
350         if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
351                 const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
352
353                 /* Exclusive OR allows to get orig value when second operand is 0,
354                  * and negative of orig value when second operand is 1. */
355                 glEnable(GL_COLOR_LOGIC_OP);
356                 glLogicOp(GL_XOR);
357
358                 gpuPushMatrix();
359                 gpuTranslate2f(x, y);
360
361                 gpuScale2f(zoomx, zoomy);
362                 gpuMultMatrix(sc->stabmat);
363
364                 immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
365
366                 float viewport_size[4];
367                 glGetFloatv(GL_VIEWPORT, viewport_size);
368                 immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
369
370                 immUniform1i("num_colors", 0);  /* "simple" mode */
371                 immUniformColor4f(1.0f, 1.0f, 1.0f, 0.0f);
372                 immUniform1f("dash_width", 6.0f);
373                 immUniform1f("dash_factor", 0.5f);
374
375                 imm_draw_line_box(shdr_pos, 0.0f, 0.0f, width, height);
376
377                 immUnbindProgram();
378
379                 gpuPopMatrix();
380
381                 glDisable(GL_COLOR_LOGIC_OP);
382         }
383 }
384
385 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
386 {
387 #define MAX_STATIC_PATH 64
388         int count = sc->path_length;
389         int i, a, b, curindex = -1;
390         float path_static[(MAX_STATIC_PATH + 1) * 2][2];
391         float (*path)[2];
392         int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame;
393         MovieTrackingMarker *marker;
394
395         if (count == 0)
396                 return;
397
398         start_frame = framenr = ED_space_clip_get_clip_frame_number(sc);
399
400         marker = BKE_tracking_marker_get(track, framenr);
401         if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
402                 return;
403
404         if (count < MAX_STATIC_PATH) {
405                 path = path_static;
406         }
407         else {
408                 path = MEM_mallocN(sizeof(*path) * (count + 1) * 2, "path");
409         }
410
411         a = count;
412         i = framenr - 1;
413         while (i >= framenr - count) {
414                 marker = BKE_tracking_marker_get(track, i);
415
416                 if (!marker || marker->flag & MARKER_DISABLED)
417                         break;
418
419                 if (marker->framenr == i) {
420                         add_v2_v2v2(path[--a], marker->pos, track->offset);
421                         ED_clip_point_undistorted_pos(sc, path[a], path[a]);
422
423                         if (marker->framenr == start_frame)
424                                 curindex = a;
425                 }
426                 else {
427                         break;
428                 }
429
430                 i--;
431         }
432
433         b = count;
434         i = framenr;
435         while (i <= framenr + count) {
436                 marker = BKE_tracking_marker_get(track, i);
437
438                 if (!marker || marker->flag & MARKER_DISABLED)
439                         break;
440
441                 if (marker->framenr == i) {
442                         if (marker->framenr == start_frame)
443                                 curindex = b;
444
445                         add_v2_v2v2(path[b++], marker->pos, track->offset);
446                         ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
447                 }
448                 else
449                         break;
450
451                 i++;
452         }
453
454         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
455
456         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
457
458         if (!tiny) {
459                 immUniformThemeColor(TH_MARKER_OUTLINE);
460
461                 if (TRACK_VIEW_SELECTED(sc, track)) {
462                         if ((b - a - 1) >= 1) {
463                                 glPointSize(5.0f);
464
465                                 immBegin(GWN_PRIM_POINTS, b - a - 1);
466
467                                 for (i = a; i < b; i++) {
468                                         if (i != curindex) {
469                                                 immVertex2f(pos, path[i][0], path[i][1]);
470                                         }
471                                 }
472
473                                 immEnd();
474                         }
475                 }
476
477                 if ((b - a) >= 2) {
478                         glLineWidth(3.0f);
479
480                         immBegin(GWN_PRIM_LINE_STRIP, b - a);
481
482                         for (i = a; i < b; i++) {
483                                 immVertex2f(pos, path[i][0], path[i][1]);
484                         }
485
486                         immEnd();
487                 }
488         }
489
490         if (TRACK_VIEW_SELECTED(sc, track)) {
491                 glPointSize(3.0f);
492
493                 if ((curindex - a) >= 1) {
494                         immUniformThemeColor(TH_PATH_BEFORE);
495
496                         immBegin(GWN_PRIM_POINTS, curindex - a);
497
498                         for (i = a; i < curindex; i++) {
499                                 immVertex2f(pos, path[i][0], path[i][1]);
500                         }
501
502                         immEnd();
503                 }
504
505                 if ((b - curindex - 1) >= 1) {
506                         immUniformThemeColor(TH_PATH_AFTER);
507
508                         immBegin(GWN_PRIM_POINTS, b - curindex - 1);
509
510                         for (i = curindex + 1; i < b; i++) {
511                                 immVertex2f(pos, path[i][0], path[i][1]);
512                         }
513
514                         immEnd();
515                 }
516         }
517
518         glLineWidth(1);
519
520         if ((curindex - a + 1) >= 2) {
521                 immUniformThemeColor(TH_PATH_BEFORE);
522
523                 immBegin(GWN_PRIM_LINE_STRIP, curindex - a + 1);
524
525                 for (i = a; i <= curindex; i++) {
526                         immVertex2f(pos, path[i][0], path[i][1]);
527                 }
528
529                 immEnd();
530         }
531
532         if ((b - curindex) >= 2) {
533                 immUniformThemeColor(TH_PATH_AFTER);
534
535                 immBegin(GWN_PRIM_LINE_STRIP, b - curindex);
536
537                 for (i = curindex; i < b; i++) {
538                         immVertex2f(pos, path[i][0], path[i][1]);
539                 }
540
541                 immEnd();
542         }
543
544         immUnbindProgram();
545
546         if (path != path_static) {
547                 MEM_freeN(path);
548         }
549 #undef MAX_STATIC_PATH
550 }
551
552 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
553                                 const float marker_pos[2], int width, int height, unsigned int position)
554 {
555         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
556         bool show_search = false;
557         float px[2];
558
559         px[0] = 1.0f / width / sc->zoom;
560         px[1] = 1.0f / height / sc->zoom;
561
562         glLineWidth(tiny ? 1.0f : 3.0f);
563
564         immUniformThemeColor(TH_MARKER_OUTLINE);
565
566         if ((marker->flag & MARKER_DISABLED) == 0) {
567                 float pos[2];
568                 float p[2];
569
570                 add_v2_v2v2(pos, marker->pos, track->offset);
571
572                 ED_clip_point_undistorted_pos(sc, pos, pos);
573
574                 sub_v2_v2v2(p, pos, marker_pos);
575
576                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
577                                         marker->pattern_corners[2], marker->pattern_corners[3]))
578                 {
579                         glPointSize(tiny ? 3.0f : 4.0f);
580
581                         immBegin(GWN_PRIM_POINTS, 1);
582                         immVertex2f(position, pos[0], pos[1]);
583                         immEnd();
584                 }
585                 else {
586                         immBegin(GWN_PRIM_LINES, 8);
587
588                         immVertex2f(position, pos[0] + px[0] * 2, pos[1]);
589                         immVertex2f(position, pos[0] + px[0] * 8, pos[1]);
590
591                         immVertex2f(position, pos[0] - px[0] * 2, pos[1]);
592                         immVertex2f(position, pos[0] - px[0] * 8, pos[1]);
593
594                         immVertex2f(position, pos[0], pos[1] - px[1] * 2);
595                         immVertex2f(position, pos[0], pos[1] - px[1] * 8);
596
597                         immVertex2f(position, pos[0], pos[1] + px[1] * 2);
598                         immVertex2f(position, pos[0], pos[1] + px[1] * 8);
599
600                         immEnd();
601                 }
602         }
603
604         /* pattern and search outline */
605         gpuPushMatrix();
606         gpuTranslate2fv(marker_pos);
607
608         if (sc->flag & SC_SHOW_MARKER_PATTERN) {
609                 immBegin(GWN_PRIM_LINE_LOOP, 4);
610                 immVertex2fv(position, marker->pattern_corners[0]);
611                 immVertex2fv(position, marker->pattern_corners[1]);
612                 immVertex2fv(position, marker->pattern_corners[2]);
613                 immVertex2fv(position, marker->pattern_corners[3]);
614                 immEnd();
615         }
616
617         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
618                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
619
620         if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
621                 imm_draw_line_box(position, marker->search_min[0],
622                                             marker->search_min[1],
623                                             marker->search_max[0],
624                                             marker->search_max[1]);
625         }
626
627         gpuPopMatrix();
628 }
629
630 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
631 {
632         if (track->flag & TRACK_CUSTOMCOLOR) {
633                 if (act)
634                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
635                 else
636                         copy_v3_v3(scol, track->color);
637
638                 mul_v3_v3fl(col, track->color, 0.5f);
639         }
640         else {
641                 UI_GetThemeColor3fv(TH_MARKER, col);
642
643                 if (act)
644                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
645                 else
646                         UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
647         }
648 }
649
650 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
651                               const float marker_pos[2], int width, int height, int act, int sel, const uint shdr_pos)
652 {
653         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
654         bool show_search = false;
655         float col[3], scol[3];
656         float px[2];
657
658         track_colors(track, act, col, scol);
659
660         px[0] = 1.0f / width / sc->zoom;
661         px[1] = 1.0f / height / sc->zoom;
662
663         glLineWidth(1.0f);
664
665         /* Since we are switching solid and dashed lines in rather complex logic here, just always go with dashed shader. */
666         immUnbindProgram();
667
668         immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
669
670         float viewport_size[4];
671         glGetFloatv(GL_VIEWPORT, viewport_size);
672         immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
673
674         immUniform1i("num_colors", 0);  /* "simple" mode */
675
676         /* marker position and offset position */
677         if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
678                 float pos[2], p[2];
679
680                 if (track->flag & TRACK_LOCKED) {
681                         if (act) {
682                                 immUniformThemeColor(TH_ACT_MARKER);
683                         }
684                         else if (track->flag & SELECT) {
685                                 immUniformThemeColorShade(TH_LOCK_MARKER, 64);
686                         }
687                         else {
688                                 immUniformThemeColor(TH_LOCK_MARKER);
689                         }
690                 }
691                 else {
692                         immUniformColor3fv((track->flag & SELECT) ? scol : col);
693                 }
694
695                 add_v2_v2v2(pos, marker->pos, track->offset);
696                 ED_clip_point_undistorted_pos(sc, pos, pos);
697
698                 sub_v2_v2v2(p, pos, marker_pos);
699
700                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
701                                         marker->pattern_corners[2], marker->pattern_corners[3]))
702                 {
703                         glPointSize(tiny ? 1.0f : 2.0f);
704
705                         immUniform1f("dash_factor", 2.0f);  /* Solid "line" */
706
707                         immBegin(GWN_PRIM_POINTS, 1);
708                         immVertex2f(shdr_pos, pos[0], pos[1]);
709                         immEnd();
710                 }
711                 else {
712                         immUniform1f("dash_factor", 2.0f);  /* Solid line */
713
714                         immBegin(GWN_PRIM_LINES, 8);
715
716                         immVertex2f(shdr_pos, pos[0] + px[0] * 3, pos[1]);
717                         immVertex2f(shdr_pos, pos[0] + px[0] * 7, pos[1]);
718
719                         immVertex2f(shdr_pos, pos[0] - px[0] * 3, pos[1]);
720                         immVertex2f(shdr_pos, pos[0] - px[0] * 7, pos[1]);
721
722                         immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 3);
723                         immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 7);
724
725                         immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 3);
726                         immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 7);
727
728                         immEnd();
729
730                         immUniformColor4f(1.0f, 1.0f, 1.0f, 0.0f);
731                         immUniform1f("dash_width", 6.0f);
732                         immUniform1f("dash_factor", 0.5f);
733
734                         glEnable(GL_COLOR_LOGIC_OP);
735                         glLogicOp(GL_XOR);
736
737                         immBegin(GWN_PRIM_LINES, 2);
738                         immVertex2fv(shdr_pos, pos);
739                         immVertex2fv(shdr_pos, marker_pos);
740                         immEnd();
741
742                         glDisable(GL_COLOR_LOGIC_OP);
743                 }
744         }
745
746         /* pattern */
747         gpuPushMatrix();
748         gpuTranslate2fv(marker_pos);
749
750         if (track->flag & TRACK_LOCKED) {
751                 if (act) {
752                         immUniformThemeColor(TH_ACT_MARKER);
753                 }
754                 else if (track->pat_flag & SELECT) {
755                         immUniformThemeColorShade(TH_LOCK_MARKER, 64);
756                 }
757                 else {
758                         immUniformThemeColor(TH_LOCK_MARKER);
759                 }
760         }
761         else if (marker->flag & MARKER_DISABLED) {
762                 if (act) {
763                         immUniformThemeColor(TH_ACT_MARKER);
764                 }
765                 else if (track->pat_flag & SELECT) {
766                         immUniformThemeColorShade(TH_DIS_MARKER, 128);
767                 }
768                 else {
769                         immUniformThemeColor(TH_DIS_MARKER);
770                 }
771         }
772         else {
773                 immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
774         }
775
776         if (tiny) {
777                 immUniform1f("dash_width", 6.0f);
778                 immUniform1f("dash_factor", 0.5f);
779         }
780         else {
781                 immUniform1f("dash_factor", 2.0f);  /* Solid line */
782         }
783
784         if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
785                 immBegin(GWN_PRIM_LINE_LOOP, 4);
786                 immVertex2fv(shdr_pos, marker->pattern_corners[0]);
787                 immVertex2fv(shdr_pos, marker->pattern_corners[1]);
788                 immVertex2fv(shdr_pos, marker->pattern_corners[2]);
789                 immVertex2fv(shdr_pos, marker->pattern_corners[3]);
790                 immEnd();
791         }
792
793         /* search */
794         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
795                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
796
797         if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
798                 imm_draw_line_box(shdr_pos, marker->search_min[0], marker->search_min[1],
799                                             marker->search_max[0], marker->search_max[1]);
800         }
801
802         gpuPopMatrix();
803
804         /* Restore default shader */
805         immUnbindProgram();
806
807         const uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
808         BLI_assert(pos == shdr_pos);
809         UNUSED_VARS_NDEBUG(pos);
810
811         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
812 }
813
814 static float get_shortest_pattern_side(MovieTrackingMarker *marker)
815 {
816         int i, next;
817         float len_sq = FLT_MAX;
818
819         for (i = 0; i < 4; i++) {
820                 float cur_len;
821
822                 next = (i + 1) % 4;
823
824                 cur_len = len_squared_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);
825
826                 len_sq = min_ff(cur_len, len_sq);
827         }
828
829         return sqrtf(len_sq);
830 }
831
832 static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
833 {
834         float tdx, tdy;
835
836         tdx = dx;
837         tdy = dy;
838
839         if (outline) {
840                 tdx += px[0];
841                 tdy += px[1];
842         }
843
844         immRectf(pos, x - tdx, y - tdy, x + tdx, y + tdy);
845 }
846
847 static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
848 {
849         float tdx, tdy;
850
851         tdx = dx * 2.0f;
852         tdy = dy * 2.0f;
853
854         if (outline) {
855                 tdx += px[0];
856                 tdy += px[1];
857         }
858
859         immBegin(GWN_PRIM_TRIS, 3);
860         immVertex2f(pos, x, y);
861         immVertex2f(pos, x - tdx, y);
862         immVertex2f(pos, x, y + tdy);
863         immEnd();
864 }
865
866 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
867                                     const float marker_pos[2], int outline, int sel, int act,
868                                     int width, int height, unsigned int pos)
869 {
870         float dx, dy, patdx, patdy, searchdx, searchdy;
871         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
872         float col[3], scol[3], px[2], side;
873
874         if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
875                 return;
876
877         if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
878                 return;
879
880         track_colors(track, act, col, scol);
881
882         if (outline) {
883                 immUniformThemeColor(TH_MARKER_OUTLINE);
884         }
885
886         gpuPushMatrix();
887         gpuTranslate2fv(marker_pos);
888
889         dx = 6.0f / width / sc->zoom;
890         dy = 6.0f / height / sc->zoom;
891
892         side = get_shortest_pattern_side(marker);
893         patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
894         patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;
895
896         searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
897         searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;
898
899         px[0] = 1.0f / sc->zoom / width / sc->scale;
900         px[1] = 1.0f / sc->zoom / height / sc->scale;
901
902         if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
903                 if (!outline) {
904                         immUniformColor3fv((track->search_flag & SELECT) ? scol : col);
905                 }
906
907                 /* search offset square */
908                 draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px, pos);
909
910                 /* search re-sizing triangle */
911                 draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px, pos);
912         }
913
914         if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
915                 int i;
916                 float pat_min[2], pat_max[2];
917 /*              float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */
918                 float tilt_ctrl[2];
919
920                 if (!outline) {
921                         immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
922                 }
923
924                 /* pattern's corners sliding squares */
925                 for (i = 0; i < 4; i++) {
926                         draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
927                                                  patdx / 1.5f, patdy / 1.5f, outline, px, pos);
928                 }
929
930                 /* ** sliders to control overall pattern  ** */
931                 add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]);
932
933                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
934
935                 glLineWidth(outline ? 3.0f : 1.0f);
936
937                 immBegin(GWN_PRIM_LINES, 2);
938                 immVertex2f(pos, 0.0f, 0.0f);
939                 immVertex2fv(pos, tilt_ctrl);
940                 immEnd();
941
942                 /* slider to control pattern tilt */
943                 draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px, pos);
944         }
945
946         gpuPopMatrix();
947 }
948
949 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
950                               const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
951 {
952         char str[128] = {0}, state[64] = {0};
953         float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
954         uiStyle *style = U.uistyles.first;
955         int fontid = style->widget.uifont_id;
956
957         if (!TRACK_VIEW_SELECTED(sc, track))
958                 return;
959
960         BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
961         fontsize = BLF_height_max(fontid);
962
963         if (marker->flag & MARKER_DISABLED) {
964                 if (act) {
965                         UI_FontThemeColor(fontid, TH_ACT_MARKER);
966                 }
967                 else {
968                         unsigned char color[4];
969                         UI_GetThemeColorShade4ubv(TH_DIS_MARKER, 128, color);
970                         BLF_color4ubv(fontid, color);
971                 }
972         }
973         else {
974                 UI_FontThemeColor(fontid, act ? TH_ACT_MARKER : TH_SEL_MARKER);
975         }
976
977         if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
978             ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
979         {
980                 dx = marker->search_min[0];
981                 dy = marker->search_min[1];
982         }
983         else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
984                 float pat_min[2], pat_max[2];
985
986                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
987                 dx = pat_min[0];
988                 dy = pat_min[1];
989         }
990
991         pos[0] = (marker_pos[0] + dx) * width;
992         pos[1] = (marker_pos[1] + dy) * height;
993         pos[2] = 0.0f;
994
995         mul_m4_v3(sc->stabmat, pos);
996
997         pos[0] = pos[0] * zoomx;
998         pos[1] = pos[1] * zoomy - fontsize;
999
1000         if (marker->flag & MARKER_DISABLED)
1001                 strcpy(state, "disabled");
1002         else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc))
1003                 strcpy(state, "estimated");
1004         else if (marker->flag & MARKER_TRACKED)
1005                 strcpy(state, "tracked");
1006         else
1007                 strcpy(state, "keyframed");
1008
1009         if (state[0])
1010                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
1011         else
1012                 BLI_strncpy(str, track->name, sizeof(str));
1013
1014         BLF_position(fontid, pos[0], pos[1], 0.0f);
1015         BLF_draw(fontid, str, sizeof(str));
1016         pos[1] -= fontsize;
1017
1018         if (track->flag & TRACK_HAS_BUNDLE) {
1019                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
1020                 BLF_position(fontid, pos[0], pos[1], 0.0f);
1021                 BLF_draw(fontid, str, sizeof(str));
1022                 pos[1] -= fontsize;
1023         }
1024
1025         if (track->flag & TRACK_LOCKED) {
1026                 BLF_position(fontid, pos[0], pos[1], 0.0f);
1027                 BLF_draw(fontid, "locked", 6);
1028         }
1029 }
1030
1031 static void plane_track_colors(bool is_active, float color[3], float selected_color[3])
1032 {
1033         UI_GetThemeColor3fv(TH_MARKER, color);
1034
1035         UI_GetThemeColor3fv(is_active ? TH_ACT_MARKER : TH_SEL_MARKER, selected_color);
1036 }
1037
1038 static void getArrowEndPoint(const int width, const int height, const float zoom,
1039                              const float start_corner[2], const float end_corner[2],
1040                              float end_point[2])
1041 {
1042         float direction[2];
1043         float max_length;
1044
1045         sub_v2_v2v2(direction, end_corner, start_corner);
1046
1047         direction[0] *= width;
1048         direction[1] *= height;
1049         max_length = normalize_v2(direction);
1050         mul_v2_fl(direction, min_ff(32.0f / zoom, max_length));
1051         direction[0] /= width;
1052         direction[1] /= height;
1053
1054         add_v2_v2v2(end_point, start_corner, direction);
1055 }
1056
1057 static void homogeneous_2d_to_gl_matrix(/*const*/ float matrix[3][3],
1058                                         float gl_matrix[4][4])
1059 {
1060         gl_matrix[0][0] = matrix[0][0];
1061         gl_matrix[0][1] = matrix[0][1];
1062         gl_matrix[0][2] = 0.0f;
1063         gl_matrix[0][3] = matrix[0][2];
1064
1065         gl_matrix[1][0] = matrix[1][0];
1066         gl_matrix[1][1] = matrix[1][1];
1067         gl_matrix[1][2] = 0.0f;
1068         gl_matrix[1][3] = matrix[1][2];
1069
1070         gl_matrix[2][0] = 0.0f;
1071         gl_matrix[2][1] = 0.0f;
1072         gl_matrix[2][2] = 1.0f;
1073         gl_matrix[2][3] = 0.0f;
1074
1075         gl_matrix[3][0] = matrix[2][0];
1076         gl_matrix[3][1] = matrix[2][1];
1077         gl_matrix[3][2] = 0.0f;
1078         gl_matrix[3][3] = matrix[2][2];
1079 }
1080
1081 static void draw_plane_marker_image(Scene *scene,
1082                                     MovieTrackingPlaneTrack *plane_track,
1083                                     MovieTrackingPlaneMarker *plane_marker)
1084 {
1085         Image *image = plane_track->image;
1086         ImBuf *ibuf;
1087         void *lock;
1088
1089         if (image == NULL) {
1090                 return;
1091         }
1092
1093         ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
1094
1095         if (ibuf) {
1096                 unsigned char *display_buffer;
1097                 void *cache_handle;
1098
1099                 if (image->flag & IMA_VIEW_AS_RENDER) {
1100                         display_buffer = IMB_display_buffer_acquire(ibuf,
1101                                                                     &scene->view_settings,
1102                                                                     &scene->display_settings,
1103                                                                     &cache_handle);
1104                 }
1105                 else {
1106                         display_buffer = IMB_display_buffer_acquire(ibuf, NULL,
1107                                                                     &scene->display_settings,
1108                                                                     &cache_handle);
1109                 }
1110
1111                 if (display_buffer) {
1112                         GLuint texid;
1113                         float frame_corners[4][2] = {{0.0f, 0.0f},
1114                                                      {1.0f, 0.0f},
1115                                                      {1.0f, 1.0f},
1116                                                      {0.0f, 1.0f}};
1117                         float perspective_matrix[3][3];
1118                         float gl_matrix[4][4];
1119                         bool transparent = false;
1120                         BKE_tracking_homography_between_two_quads(frame_corners,
1121                                                                   plane_marker->corners,
1122                                                                   perspective_matrix);
1123
1124                         homogeneous_2d_to_gl_matrix(perspective_matrix, gl_matrix);
1125
1126                         if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) {
1127                                 transparent = true;
1128                                 glEnable(GL_BLEND);
1129                                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
1130                         }
1131
1132                         glGenTextures(1, (GLuint *)&texid);
1133
1134                         glBindTexture(GL_TEXTURE_2D, texid);
1135
1136                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1137                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1138
1139                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA,
1140                                      GL_UNSIGNED_BYTE, display_buffer);
1141
1142                         gpuPushMatrix();
1143                         gpuMultMatrix(gl_matrix);
1144
1145                         Gwn_VertFormat *imm_format = immVertexFormat();
1146                         unsigned int pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1147                         unsigned int texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1148
1149                         immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
1150                         immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity);
1151                         immUniform1i("image", GL_TEXTURE0);
1152
1153                         immBegin(GWN_PRIM_TRI_FAN, 4);
1154
1155                         immAttrib2f(texCoord, 0.0f, 0.0f);
1156                         immVertex2f(pos, 0.0f, 0.0f);
1157
1158                         immAttrib2f(texCoord, 1.0f, 0.0f);
1159                         immVertex2f(pos, 1.0f, 0.0f);
1160
1161                         immAttrib2f(texCoord, 1.0f, 1.0f);
1162                         immVertex2f(pos, 1.0f, 1.0f);
1163
1164                         immAttrib2f(texCoord, 0.0f, 1.0f);
1165                         immVertex2f(pos, 0.0f, 1.0f);
1166
1167                         immEnd();
1168
1169                         immUnbindProgram();
1170
1171                         gpuPopMatrix();
1172
1173                         glBindTexture(GL_TEXTURE_2D, 0);
1174
1175                         if (transparent) {
1176                                 glDisable(GL_BLEND);
1177                         }
1178                 }
1179
1180                 IMB_display_buffer_release(cache_handle);
1181         }
1182
1183         BKE_image_release_ibuf(image, ibuf, lock);
1184 }
1185
1186 static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1187                                  MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1188                                  bool draw_outline, int width, int height)
1189 {
1190         bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0;
1191         bool is_selected_track = (plane_track->flag & SELECT) != 0;
1192         const bool has_image = plane_track->image != NULL &&
1193                                BKE_image_has_ibuf(plane_track->image, NULL);
1194         const bool draw_plane_quad = !has_image || plane_track->image_opacity == 0.0f;
1195         float px[2];
1196         float color[3], selected_color[3];
1197
1198         px[0] = 1.0f / width / sc->zoom;
1199         px[1] = 1.0f / height / sc->zoom;
1200
1201         /* Draw image */
1202         if (draw_outline == false) {
1203                 draw_plane_marker_image(scene, plane_track, plane_marker);
1204         }
1205
1206         if (draw_plane_quad || is_selected_track) {
1207                 const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1208
1209                 immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
1210
1211                 float viewport_size[4];
1212                 glGetFloatv(GL_VIEWPORT, viewport_size);
1213                 immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
1214
1215                 immUniform1i("num_colors", 0);  /* "simple" mode */
1216
1217                 if (draw_plane_quad) {
1218                         const bool stipple = !draw_outline && tiny;
1219                         const bool thick = draw_outline && !tiny;
1220
1221                         glLineWidth(thick ? 3.0f : 1.0f);
1222
1223                         if (stipple) {
1224                                 immUniform1f("dash_width", 6.0f);
1225                                 immUniform1f("dash_factor", 0.5f);
1226                         }
1227                         else {
1228                                 immUniform1f("dash_factor", 2.0f);  /* Solid line */
1229                         }
1230
1231                         if (draw_outline) {
1232                                 immUniformThemeColor(TH_MARKER_OUTLINE);
1233                         }
1234                         else {
1235                                 plane_track_colors(is_active_track, color, selected_color);
1236                                 immUniformColor3fv(is_selected_track ? selected_color : color);
1237                         }
1238
1239                         /* Draw rectangle itself. */
1240                         immBegin(GWN_PRIM_LINE_LOOP, 4);
1241                         immVertex2fv(shdr_pos, plane_marker->corners[0]);
1242                         immVertex2fv(shdr_pos, plane_marker->corners[1]);
1243                         immVertex2fv(shdr_pos, plane_marker->corners[2]);
1244                         immVertex2fv(shdr_pos, plane_marker->corners[3]);
1245                         immEnd();
1246
1247                         /* Draw axis. */
1248                         if (!draw_outline) {
1249                                 float end_point[2];
1250
1251                                 immUniformColor3f(1.0f, 0.0f, 0.0f);
1252
1253                                 immBegin(GWN_PRIM_LINES, 2);
1254
1255                                 getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
1256                                 immVertex2fv(shdr_pos, plane_marker->corners[0]);
1257                                 immVertex2fv(shdr_pos, end_point);
1258
1259                                 immEnd();
1260
1261                                 immUniformColor3f(0.0f, 1.0f, 0.0f);
1262
1263                                 immBegin(GWN_PRIM_LINES, 2);
1264
1265                                 getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
1266                                 immVertex2fv(shdr_pos, plane_marker->corners[0]);
1267                                 immVertex2fv(shdr_pos, end_point);
1268
1269                                 immEnd();
1270                         }
1271                 }
1272
1273                 /* Draw sliders. */
1274                 if (is_selected_track) {
1275                         immUniform1f("dash_factor", 2.0f);  /* Solid line */
1276
1277                         if (draw_outline) {
1278                                 immUniformThemeColor(TH_MARKER_OUTLINE);
1279                         }
1280                         else {
1281                                 immUniformColor3fv(selected_color);
1282                         }
1283
1284                         int i;
1285                         for (i = 0; i < 4; i++) {
1286                                 draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
1287                                                          3.0f * px[0], 3.0f * px[1], draw_outline, px, shdr_pos);
1288                         }
1289                 }
1290
1291                 immUnbindProgram();
1292         }
1293 }
1294
1295 static void draw_plane_marker_outline(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1296                                       MovieTrackingPlaneMarker *plane_marker, int width, int height)
1297 {
1298         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, false, true, width, height);
1299 }
1300
1301 static void draw_plane_marker(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1302                               MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1303                               int width, int height)
1304 {
1305         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, is_active_track, false, width, height);
1306 }
1307
1308 static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1309                              int framenr, bool is_active_track, int width, int height)
1310 {
1311         MovieTrackingPlaneMarker *plane_marker;
1312
1313         plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
1314
1315         draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height);
1316         draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height);
1317 }
1318
1319 /* Draw all kind of tracks. */
1320 static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip,
1321                                  int width, int height, float zoomx, float zoomy)
1322 {
1323         float x, y;
1324         MovieTracking *tracking = &clip->tracking;
1325         ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
1326         ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1327         MovieTrackingTrack *track, *act_track;
1328         MovieTrackingPlaneTrack *plane_track, *active_plane_track;
1329         MovieTrackingMarker *marker;
1330         int framenr = ED_space_clip_get_clip_frame_number(sc);
1331         int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
1332         float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];
1333
1334         /* ** find window pixel coordinates of origin ** */
1335
1336         /* UI_view2d_view_to_region_no_clip return integer values, this could
1337          * lead to 1px flickering when view is locked to selection during playback.
1338          * to avoid this flickering, calculate base point in the same way as it happens
1339          * in UI_view2d_view_to_region_no_clip, but do it in floats here */
1340
1341         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1342
1343         gpuPushMatrix();
1344         gpuTranslate2f(x, y);
1345
1346         gpuPushMatrix();
1347         gpuScale2f(zoomx, zoomy);
1348         gpuMultMatrix(sc->stabmat);
1349         gpuScale2f(width, height);
1350
1351         act_track = BKE_tracking_track_get_active(tracking);
1352
1353         /* Draw plane tracks */
1354         active_plane_track = BKE_tracking_plane_track_get_active(tracking);
1355         for (plane_track = plane_tracks_base->first;
1356              plane_track;
1357              plane_track = plane_track->next)
1358         {
1359                 if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
1360                         draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
1361                 }
1362         }
1363
1364         if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1365                 int count = 0;
1366
1367                 /* count */
1368                 track = tracksbase->first;
1369                 while (track) {
1370                         if ((track->flag & TRACK_HIDDEN) == 0) {
1371                                 marker = BKE_tracking_marker_get(track, framenr);
1372
1373                                 if (MARKER_VISIBLE(sc, track, marker))
1374                                         count++;
1375                         }
1376
1377                         track = track->next;
1378                 }
1379
1380                 /* undistort */
1381                 if (count) {
1382                         marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos");
1383
1384                         track = tracksbase->first;
1385                         fp = marker_pos;
1386                         while (track) {
1387                                 if ((track->flag & TRACK_HIDDEN) == 0) {
1388                                         marker = BKE_tracking_marker_get(track, framenr);
1389
1390                                         if (MARKER_VISIBLE(sc, track, marker)) {
1391                                                 ED_clip_point_undistorted_pos(sc, marker->pos, fp);
1392
1393                                                 if (track == act_track)
1394                                                         active_pos = fp;
1395
1396                                                 fp += 2;
1397                                         }
1398                                 }
1399
1400                                 track = track->next;
1401                         }
1402                 }
1403         }
1404
1405         if (sc->flag & SC_SHOW_TRACK_PATH) {
1406                 track = tracksbase->first;
1407                 while (track) {
1408                         if ((track->flag & TRACK_HIDDEN) == 0)
1409                                 draw_track_path(sc, clip, track);
1410
1411                         track = track->next;
1412                 }
1413         }
1414
1415         unsigned int position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1416
1417         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
1418
1419         /* markers outline and non-selected areas */
1420         track = tracksbase->first;
1421         fp = marker_pos;
1422         while (track) {
1423                 if ((track->flag & TRACK_HIDDEN) == 0) {
1424                         marker = BKE_tracking_marker_get(track, framenr);
1425
1426                         if (MARKER_VISIBLE(sc, track, marker)) {
1427                                 copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1428
1429                                 draw_marker_outline(sc, track, marker, cur_pos, width, height, position);
1430                                 draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0, position);
1431                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height, position);
1432                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height, position);
1433
1434                                 if (fp)
1435                                         fp += 2;
1436                         }
1437                 }
1438
1439                 track = track->next;
1440         }
1441
1442         /* selected areas only, so selection wouldn't be overlapped by
1443          * non-selected areas */
1444         track = tracksbase->first;
1445         fp = marker_pos;
1446         while (track) {
1447                 if ((track->flag & TRACK_HIDDEN) == 0) {
1448                         int act = track == act_track;
1449                         marker = BKE_tracking_marker_get(track, framenr);
1450
1451                         if (MARKER_VISIBLE(sc, track, marker)) {
1452                                 if (!act) {
1453                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1454
1455                                         draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1, position);
1456                                         draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height, position);
1457                                 }
1458
1459                                 if (fp)
1460                                         fp += 2;
1461                         }
1462                 }
1463
1464                 track = track->next;
1465         }
1466
1467         /* active marker would be displayed on top of everything else */
1468         if (act_track) {
1469                 if ((act_track->flag & TRACK_HIDDEN) == 0) {
1470                         marker = BKE_tracking_marker_get(act_track, framenr);
1471
1472                         if (MARKER_VISIBLE(sc, act_track, marker)) {
1473                                 copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
1474
1475                                 draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1, position);
1476                                 draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height, position);
1477                         }
1478                 }
1479         }
1480
1481         if (sc->flag & SC_SHOW_BUNDLES) {
1482                 MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
1483                 float pos[4], vec[4], mat[4][4], aspy;
1484
1485                 glPointSize(3.0f);
1486
1487                 aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1488                 BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);
1489
1490                 track = tracksbase->first;
1491                 while (track) {
1492                         if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
1493                                 marker = BKE_tracking_marker_get(track, framenr);
1494
1495                                 if (MARKER_VISIBLE(sc, track, marker)) {
1496                                         float npos[2];
1497                                         copy_v3_v3(vec, track->bundle_pos);
1498                                         vec[3] = 1;
1499
1500                                         mul_v4_m4v4(pos, mat, vec);
1501
1502                                         pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
1503                                         pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
1504
1505                                         BKE_tracking_distort_v2(tracking, pos, npos);
1506
1507                                         if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
1508                                                 vec[0] = (marker->pos[0] + track->offset[0]) * width;
1509                                                 vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;
1510
1511                                                 sub_v2_v2(vec, npos);
1512
1513                                                 if (len_squared_v2(vec) < (3.0f * 3.0f)) {
1514                                                         immUniformColor3f(0.0f, 1.0f, 0.0f);
1515                                                 }
1516                                                 else {
1517                                                         immUniformColor3f(1.0f, 0.0f, 0.0f);
1518                                                 }
1519
1520                                                 immBegin(GWN_PRIM_POINTS, 1);
1521
1522                                                 if (undistort) {
1523                                                         immVertex2f(position, pos[0] / width, pos[1] / (height * aspy));
1524                                                 }
1525                                                 else {
1526                                                         immVertex2f(position, npos[0] / width, npos[1] / (height * aspy));
1527                                                 }
1528
1529                                                 immEnd();
1530                                         }
1531                                 }
1532                         }
1533
1534                         track = track->next;
1535                 }
1536         }
1537
1538         immUnbindProgram();
1539
1540         gpuPopMatrix();
1541
1542         if (sc->flag & SC_SHOW_NAMES) {
1543                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
1544                 track = tracksbase->first;
1545                 fp = marker_pos;
1546                 while (track) {
1547                         if ((track->flag & TRACK_HIDDEN) == 0) {
1548                                 marker = BKE_tracking_marker_get(track, framenr);
1549
1550                                 if (MARKER_VISIBLE(sc, track, marker)) {
1551                                         int act = track == act_track;
1552
1553                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1554
1555                                         draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
1556
1557                                         if (fp)
1558                                                 fp += 2;
1559                                 }
1560                         }
1561
1562                         track = track->next;
1563                 }
1564         }
1565
1566         gpuPopMatrix();
1567
1568         if (marker_pos)
1569                 MEM_freeN(marker_pos);
1570 }
1571
1572 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
1573                             int width, int height, float zoomx, float zoomy)
1574 {
1575         float x, y;
1576         const int n = 10;
1577         int i, j, a;
1578         float pos[2], tpos[2], grid[11][11][2];
1579         MovieTracking *tracking = &clip->tracking;
1580         bGPdata *gpd = NULL;
1581         float aspy = 1.0f / tracking->camera.pixel_aspect;
1582         float dx = (float)width / n, dy = (float)height / n * aspy;
1583         float offsx = 0.0f, offsy = 0.0f;
1584
1585         if (!tracking->camera.focal)
1586                 return;
1587
1588         if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
1589                 return;
1590
1591         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1592
1593         gpuPushMatrix();
1594         gpuTranslate2f(x, y);
1595         gpuScale2f(zoomx, zoomy);
1596         gpuMultMatrix(sc->stabmat);
1597         gpuScale2f(width, height);
1598
1599         unsigned int position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1600
1601         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
1602
1603         /* grid */
1604         if (sc->flag & SC_SHOW_GRID) {
1605                 float val[4][2], idx[4][2];
1606                 float min[2], max[2];
1607
1608                 for (a = 0; a < 4; a++) {
1609                         if (a < 2)
1610                                 val[a][a % 2] = FLT_MAX;
1611                         else
1612                                 val[a][a % 2] = -FLT_MAX;
1613                 }
1614
1615                 zero_v2(pos);
1616                 for (i = 0; i <= n; i++) {
1617                         for (j = 0; j <= n; j++) {
1618                                 if (i == 0 || j == 0 || i == n || j == n) {
1619                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1620
1621                                         for (a = 0; a < 4; a++) {
1622                                                 int ok;
1623
1624                                                 if (a < 2)
1625                                                         ok = tpos[a % 2] < val[a][a % 2];
1626                                                 else
1627                                                         ok = tpos[a % 2] > val[a][a % 2];
1628
1629                                                 if (ok) {
1630                                                         copy_v2_v2(val[a], tpos);
1631                                                         idx[a][0] = j;
1632                                                         idx[a][1] = i;
1633                                                 }
1634                                         }
1635                                 }
1636
1637                                 pos[0] += dx;
1638                         }
1639
1640                         pos[0] = 0.0f;
1641                         pos[1] += dy;
1642                 }
1643
1644                 INIT_MINMAX2(min, max);
1645
1646                 for (a = 0; a < 4; a++) {
1647                         pos[0] = idx[a][0] * dx;
1648                         pos[1] = idx[a][1] * dy;
1649
1650                         BKE_tracking_undistort_v2(tracking, pos, tpos);
1651
1652                         minmax_v2v2_v2(min, max, tpos);
1653                 }
1654
1655                 copy_v2_v2(pos, min);
1656                 dx = (max[0] - min[0]) / n;
1657                 dy = (max[1] - min[1]) / n;
1658
1659                 for (i = 0; i <= n; i++) {
1660                         for (j = 0; j <= n; j++) {
1661                                 BKE_tracking_distort_v2(tracking, pos, grid[i][j]);
1662
1663                                 grid[i][j][0] /= width;
1664                                 grid[i][j][1] /= height * aspy;
1665
1666                                 pos[0] += dx;
1667                         }
1668
1669                         pos[0] = min[0];
1670                         pos[1] += dy;
1671                 }
1672
1673                 immUniformColor3f(1.0f, 0.0f, 0.0f);
1674
1675                 for (i = 0; i <= n; i++) {
1676                         immBegin(GWN_PRIM_LINE_STRIP, n + 1);
1677
1678                         for (j = 0; j <= n; j++) {
1679                                 immVertex2fv(position, grid[i][j]);
1680                         }
1681
1682                         immEnd();
1683                 }
1684
1685                 for (j = 0; j <= n; j++) {
1686                         immBegin(GWN_PRIM_LINE_STRIP, n + 1);
1687
1688                         for (i = 0; i <= n; i++) {
1689                                 immVertex2fv(position, grid[i][j]);
1690                         }
1691
1692                         immEnd();
1693                 }
1694         }
1695
1696         if (sc->gpencil_src != SC_GPENCIL_SRC_TRACK) {
1697                 gpd = clip->gpd;
1698         }
1699
1700         if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
1701                 bGPDlayer *layer = gpd->layers.first;
1702
1703                 while (layer) {
1704                         bGPDframe *frame = layer->frames.first;
1705
1706                         if (layer->flag & GP_LAYER_HIDE) {
1707                                 layer = layer->next;
1708                                 continue;
1709                         }
1710
1711                         immUniformColor4fv(layer->color);
1712
1713                         glLineWidth(layer->thickness);
1714                         glPointSize((float)(layer->thickness + 2));
1715
1716                         while (frame) {
1717                                 bGPDstroke *stroke = frame->strokes.first;
1718
1719                                 while (stroke) {
1720                                         if (stroke->flag & GP_STROKE_2DSPACE) {
1721                                                 if (stroke->totpoints > 1) {
1722                                                         for (i = 0; i < stroke->totpoints - 1; i++) {
1723                                                                 float npos[2], dpos[2], len;
1724                                                                 int steps;
1725
1726                                                                 pos[0] = (stroke->points[i].x + offsx) * width;
1727                                                                 pos[1] = (stroke->points[i].y + offsy) * height * aspy;
1728
1729                                                                 npos[0] = (stroke->points[i + 1].x + offsx) * width;
1730                                                                 npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;
1731
1732                                                                 len = len_v2v2(pos, npos);
1733                                                                 steps = ceil(len / 5.0f);
1734
1735                                                                 /* we want to distort only long straight lines */
1736                                                                 if (stroke->totpoints == 2) {
1737                                                                         BKE_tracking_undistort_v2(tracking, pos, pos);
1738                                                                         BKE_tracking_undistort_v2(tracking, npos, npos);
1739                                                                 }
1740
1741                                                                 sub_v2_v2v2(dpos, npos, pos);
1742                                                                 mul_v2_fl(dpos, 1.0f / steps);
1743
1744                                                                 immBegin(GWN_PRIM_LINE_STRIP, steps + 1);
1745
1746                                                                 for (j = 0; j <= steps; j++) {
1747                                                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1748                                                                         immVertex2f(position, tpos[0] / width, tpos[1] / (height * aspy));
1749
1750                                                                         add_v2_v2(pos, dpos);
1751                                                                 }
1752
1753                                                                 immEnd();
1754                                                         }
1755                                                 }
1756                                                 else if (stroke->totpoints == 1) {
1757                                                         immBegin(GWN_PRIM_POINTS, 1);
1758                                                         immVertex2f(position, stroke->points[0].x + offsx, stroke->points[0].y + offsy);
1759                                                         immEnd();
1760                                                 }
1761                                         }
1762
1763                                         stroke = stroke->next;
1764                                 }
1765
1766                                 frame = frame->next;
1767                         }
1768
1769                         layer = layer->next;
1770                 }
1771         }
1772
1773         immUnbindProgram();
1774
1775         gpuPopMatrix();
1776 }
1777
1778 void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
1779 {
1780         MovieClip *clip = ED_space_clip_get_clip(sc);
1781         Scene *scene = CTX_data_scene(C);
1782         ImBuf *ibuf = NULL;
1783         int width, height;
1784         float zoomx, zoomy;
1785
1786         ED_space_clip_get_size(sc, &width, &height);
1787         ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
1788
1789         /* if no clip, nothing to do */
1790         if (!clip) {
1791                 ED_region_grid_draw(ar, zoomx, zoomy);
1792                 return;
1793         }
1794
1795         if (sc->flag & SC_SHOW_STABLE) {
1796                 float translation[2];
1797                 float aspect = clip->tracking.camera.pixel_aspect;
1798                 float smat[4][4], ismat[4][4];
1799
1800                 if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
1801                         ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc,
1802                                                                &sc->scale, &sc->angle);
1803                 }
1804
1805                 if (ibuf != NULL && width != ibuf->x)
1806                         mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x);
1807                 else
1808                         copy_v2_v2(translation, sc->loc);
1809
1810                 BKE_tracking_stabilization_data_to_mat4(width, height, aspect, translation,
1811                                                         sc->scale, sc->angle, sc->stabmat);
1812
1813                 unit_m4(smat);
1814                 smat[0][0] = 1.0f / width;
1815                 smat[1][1] = 1.0f / height;
1816                 invert_m4_m4(ismat, smat);
1817
1818                 mul_m4_series(sc->unistabmat, smat, sc->stabmat, ismat);
1819         }
1820         else if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
1821                 ibuf = ED_space_clip_get_buffer(sc);
1822
1823                 zero_v2(sc->loc);
1824                 sc->scale = 1.0f;
1825                 unit_m4(sc->stabmat);
1826                 unit_m4(sc->unistabmat);
1827         }
1828
1829         if (ibuf) {
1830                 draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
1831                 IMB_freeImBuf(ibuf);
1832         }
1833         else if (sc->flag & SC_MUTE_FOOTAGE) {
1834                 draw_movieclip_muted(ar, width, height, zoomx, zoomy);
1835         }
1836         else {
1837                 ED_region_grid_draw(ar, zoomx, zoomy);
1838         }
1839
1840         if (width && height) {
1841                 draw_stabilization_border(sc, ar, width, height, zoomx, zoomy);
1842                 draw_tracking_tracks(sc, scene, ar, clip, width, height, zoomx, zoomy);
1843                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1844         }
1845 }
1846
1847 void clip_draw_cache_and_notes(const bContext *C, SpaceClip *sc, ARegion *ar)
1848 {
1849         Scene *scene = CTX_data_scene(C);
1850         MovieClip *clip = ED_space_clip_get_clip(sc);
1851         if (clip) {
1852                 draw_movieclip_cache(sc, ar, clip, scene);
1853                 draw_movieclip_notes(sc, ar);
1854         }
1855 }
1856
1857 /* draw grease pencil */
1858 void clip_draw_grease_pencil(bContext *C, int onlyv2d)
1859 {
1860         SpaceClip *sc = CTX_wm_space_clip(C);
1861         MovieClip *clip = ED_space_clip_get_clip(sc);
1862
1863         if (!clip)
1864                 return;
1865
1866         if (onlyv2d) {
1867                 bool is_track_source = sc->gpencil_src == SC_GPENCIL_SRC_TRACK;
1868                 /* if manual calibration is used then grease pencil data
1869                  * associated with the clip is already drawn in draw_distortion
1870                  */
1871                 if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) {
1872                         gpuPushMatrix();
1873                         gpuMultMatrix(sc->unistabmat);
1874
1875                         if (is_track_source) {
1876                                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1877
1878                                 if (track) {
1879                                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1880                                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1881
1882                                         gpuTranslate2fv(marker->pos);
1883                                 }
1884                         }
1885
1886                         ED_gpencil_draw_2dimage(C);
1887
1888                         gpuPopMatrix();
1889                 }
1890         }
1891         else {
1892                 ED_gpencil_draw_view2d(C, 0);
1893         }
1894 }