Manipulator: fix cage2d cancel not resetting
[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         int count = sc->path_length;
388         int i, a, b, curindex = -1;
389         float path[102][2];
390         int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr, start_frame;
391         MovieTrackingMarker *marker;
392
393         if (count == 0)
394                 return;
395
396         start_frame = framenr = ED_space_clip_get_clip_frame_number(sc);
397
398         marker = BKE_tracking_marker_get(track, framenr);
399         if (marker->framenr != framenr || marker->flag & MARKER_DISABLED)
400                 return;
401
402         a = count;
403         i = framenr - 1;
404         while (i >= framenr - count) {
405                 marker = BKE_tracking_marker_get(track, i);
406
407                 if (!marker || marker->flag & MARKER_DISABLED)
408                         break;
409
410                 if (marker->framenr == i) {
411                         add_v2_v2v2(path[--a], marker->pos, track->offset);
412                         ED_clip_point_undistorted_pos(sc, path[a], path[a]);
413
414                         if (marker->framenr == start_frame)
415                                 curindex = a;
416                 }
417                 else {
418                         break;
419                 }
420
421                 i--;
422         }
423
424         b = count;
425         i = framenr;
426         while (i <= framenr + count) {
427                 marker = BKE_tracking_marker_get(track, i);
428
429                 if (!marker || marker->flag & MARKER_DISABLED)
430                         break;
431
432                 if (marker->framenr == i) {
433                         if (marker->framenr == start_frame)
434                                 curindex = b;
435
436                         add_v2_v2v2(path[b++], marker->pos, track->offset);
437                         ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
438                 }
439                 else
440                         break;
441
442                 i++;
443         }
444
445         unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
446
447         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
448
449         if (!tiny) {
450                 immUniformThemeColor(TH_MARKER_OUTLINE);
451
452                 if (TRACK_VIEW_SELECTED(sc, track)) {
453                         if ((b - a - 1) >= 1) {
454                                 glPointSize(5.0f);
455
456                                 immBegin(GWN_PRIM_POINTS, b - a - 1);
457
458                                 for (i = a; i < b; i++) {
459                                         if (i != curindex) {
460                                                 immVertex2f(pos, path[i][0], path[i][1]);
461                                         }
462                                 }
463
464                                 immEnd();
465                         }
466                 }
467
468                 if ((b - a) >= 2) {
469                         glLineWidth(3.0f);
470
471                         immBegin(GWN_PRIM_LINE_STRIP, b - a);
472
473                         for (i = a; i < b; i++) {
474                                 immVertex2f(pos, path[i][0], path[i][1]);
475                         }
476
477                         immEnd();
478                 }
479         }
480
481         if (TRACK_VIEW_SELECTED(sc, track)) {
482                 glPointSize(3.0f);
483
484                 if ((curindex - a) >= 1) {
485                         immUniformThemeColor(TH_PATH_BEFORE);
486
487                         immBegin(GWN_PRIM_POINTS, curindex - a);
488
489                         for (i = a; i < curindex; i++) {
490                                 immVertex2f(pos, path[i][0], path[i][1]);
491                         }
492
493                         immEnd();
494                 }
495
496                 if ((b - curindex - 1) >= 1) {
497                         immUniformThemeColor(TH_PATH_AFTER);
498
499                         immBegin(GWN_PRIM_POINTS, b - curindex - 1);
500
501                         for (i = curindex + 1; i < b; i++) {
502                                 immVertex2f(pos, path[i][0], path[i][1]);
503                         }
504
505                         immEnd();
506                 }
507         }
508
509         glLineWidth(1);
510
511         if ((curindex - a + 1) >= 2) {
512                 immUniformThemeColor(TH_PATH_BEFORE);
513
514                 immBegin(GWN_PRIM_LINE_STRIP, curindex - a + 1);
515
516                 for (i = a; i <= curindex; i++) {
517                         immVertex2f(pos, path[i][0], path[i][1]);
518                 }
519
520                 immEnd();
521         }
522
523         if ((b - curindex) >= 2) {
524                 immUniformThemeColor(TH_PATH_AFTER);
525
526                 immBegin(GWN_PRIM_LINE_STRIP, b - curindex);
527
528                 for (i = curindex; i < b; i++) {
529                         immVertex2f(pos, path[i][0], path[i][1]);
530                 }
531
532                 immEnd();
533         }
534
535         immUnbindProgram();
536 }
537
538 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
539                                 const float marker_pos[2], int width, int height, unsigned int position)
540 {
541         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
542         bool show_search = false;
543         float px[2];
544
545         px[0] = 1.0f / width / sc->zoom;
546         px[1] = 1.0f / height / sc->zoom;
547
548         glLineWidth(tiny ? 1.0f : 3.0f);
549
550         immUniformThemeColor(TH_MARKER_OUTLINE);
551
552         if ((marker->flag & MARKER_DISABLED) == 0) {
553                 float pos[2];
554                 float p[2];
555
556                 add_v2_v2v2(pos, marker->pos, track->offset);
557
558                 ED_clip_point_undistorted_pos(sc, pos, pos);
559
560                 sub_v2_v2v2(p, pos, marker_pos);
561
562                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
563                                         marker->pattern_corners[2], marker->pattern_corners[3]))
564                 {
565                         glPointSize(tiny ? 3.0f : 4.0f);
566
567                         immBegin(GWN_PRIM_POINTS, 1);
568                         immVertex2f(position, pos[0], pos[1]);
569                         immEnd();
570                 }
571                 else {
572                         immBegin(GWN_PRIM_LINES, 8);
573
574                         immVertex2f(position, pos[0] + px[0] * 2, pos[1]);
575                         immVertex2f(position, pos[0] + px[0] * 8, pos[1]);
576
577                         immVertex2f(position, pos[0] - px[0] * 2, pos[1]);
578                         immVertex2f(position, pos[0] - px[0] * 8, pos[1]);
579
580                         immVertex2f(position, pos[0], pos[1] - px[1] * 2);
581                         immVertex2f(position, pos[0], pos[1] - px[1] * 8);
582
583                         immVertex2f(position, pos[0], pos[1] + px[1] * 2);
584                         immVertex2f(position, pos[0], pos[1] + px[1] * 8);
585
586                         immEnd();
587                 }
588         }
589
590         /* pattern and search outline */
591         gpuPushMatrix();
592         gpuTranslate2fv(marker_pos);
593
594         if (sc->flag & SC_SHOW_MARKER_PATTERN) {
595                 immBegin(GWN_PRIM_LINE_LOOP, 4);
596                 immVertex2fv(position, marker->pattern_corners[0]);
597                 immVertex2fv(position, marker->pattern_corners[1]);
598                 immVertex2fv(position, marker->pattern_corners[2]);
599                 immVertex2fv(position, marker->pattern_corners[3]);
600                 immEnd();
601         }
602
603         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
604                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
605
606         if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
607                 imm_draw_line_box(position, marker->search_min[0],
608                                             marker->search_min[1],
609                                             marker->search_max[0],
610                                             marker->search_max[1]);
611         }
612
613         gpuPopMatrix();
614 }
615
616 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
617 {
618         if (track->flag & TRACK_CUSTOMCOLOR) {
619                 if (act)
620                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
621                 else
622                         copy_v3_v3(scol, track->color);
623
624                 mul_v3_v3fl(col, track->color, 0.5f);
625         }
626         else {
627                 UI_GetThemeColor3fv(TH_MARKER, col);
628
629                 if (act)
630                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
631                 else
632                         UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
633         }
634 }
635
636 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
637                               const float marker_pos[2], int width, int height, int act, int sel, const uint shdr_pos)
638 {
639         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
640         bool show_search = false;
641         float col[3], scol[3];
642         float px[2];
643
644         track_colors(track, act, col, scol);
645
646         px[0] = 1.0f / width / sc->zoom;
647         px[1] = 1.0f / height / sc->zoom;
648
649         glLineWidth(1.0f);
650
651         /* Since we are switching solid and dashed lines in rather complex logic here, just always go with dashed shader. */
652         immUnbindProgram();
653
654         immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
655
656         float viewport_size[4];
657         glGetFloatv(GL_VIEWPORT, viewport_size);
658         immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
659
660         immUniform1i("num_colors", 0);  /* "simple" mode */
661
662         /* marker position and offset position */
663         if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
664                 float pos[2], p[2];
665
666                 if (track->flag & TRACK_LOCKED) {
667                         if (act) {
668                                 immUniformThemeColor(TH_ACT_MARKER);
669                         }
670                         else if (track->flag & SELECT) {
671                                 immUniformThemeColorShade(TH_LOCK_MARKER, 64);
672                         }
673                         else {
674                                 immUniformThemeColor(TH_LOCK_MARKER);
675                         }
676                 }
677                 else {
678                         immUniformColor3fv((track->flag & SELECT) ? scol : col);
679                 }
680
681                 add_v2_v2v2(pos, marker->pos, track->offset);
682                 ED_clip_point_undistorted_pos(sc, pos, pos);
683
684                 sub_v2_v2v2(p, pos, marker_pos);
685
686                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
687                                         marker->pattern_corners[2], marker->pattern_corners[3]))
688                 {
689                         glPointSize(tiny ? 1.0f : 2.0f);
690
691                         immUniform1f("dash_factor", 2.0f);  /* Solid "line" */
692
693                         immBegin(GWN_PRIM_POINTS, 1);
694                         immVertex2f(shdr_pos, pos[0], pos[1]);
695                         immEnd();
696                 }
697                 else {
698                         immUniform1f("dash_factor", 2.0f);  /* Solid line */
699
700                         immBegin(GWN_PRIM_LINES, 8);
701
702                         immVertex2f(shdr_pos, pos[0] + px[0] * 3, pos[1]);
703                         immVertex2f(shdr_pos, pos[0] + px[0] * 7, pos[1]);
704
705                         immVertex2f(shdr_pos, pos[0] - px[0] * 3, pos[1]);
706                         immVertex2f(shdr_pos, pos[0] - px[0] * 7, pos[1]);
707
708                         immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 3);
709                         immVertex2f(shdr_pos, pos[0], pos[1] - px[1] * 7);
710
711                         immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 3);
712                         immVertex2f(shdr_pos, pos[0], pos[1] + px[1] * 7);
713
714                         immEnd();
715
716                         immUniformColor4f(1.0f, 1.0f, 1.0f, 0.0f);
717                         immUniform1f("dash_width", 6.0f);
718                         immUniform1f("dash_factor", 0.5f);
719
720                         glEnable(GL_COLOR_LOGIC_OP);
721                         glLogicOp(GL_XOR);
722
723                         immBegin(GWN_PRIM_LINES, 2);
724                         immVertex2fv(shdr_pos, pos);
725                         immVertex2fv(shdr_pos, marker_pos);
726                         immEnd();
727
728                         glDisable(GL_COLOR_LOGIC_OP);
729                 }
730         }
731
732         /* pattern */
733         gpuPushMatrix();
734         gpuTranslate2fv(marker_pos);
735
736         if (track->flag & TRACK_LOCKED) {
737                 if (act) {
738                         immUniformThemeColor(TH_ACT_MARKER);
739                 }
740                 else if (track->pat_flag & SELECT) {
741                         immUniformThemeColorShade(TH_LOCK_MARKER, 64);
742                 }
743                 else {
744                         immUniformThemeColor(TH_LOCK_MARKER);
745                 }
746         }
747         else if (marker->flag & MARKER_DISABLED) {
748                 if (act) {
749                         immUniformThemeColor(TH_ACT_MARKER);
750                 }
751                 else if (track->pat_flag & SELECT) {
752                         immUniformThemeColorShade(TH_DIS_MARKER, 128);
753                 }
754                 else {
755                         immUniformThemeColor(TH_DIS_MARKER);
756                 }
757         }
758         else {
759                 immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
760         }
761
762         if (tiny) {
763                 immUniform1f("dash_width", 6.0f);
764                 immUniform1f("dash_factor", 0.5f);
765         }
766         else {
767                 immUniform1f("dash_factor", 2.0f);  /* Solid line */
768         }
769
770         if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
771                 immBegin(GWN_PRIM_LINE_LOOP, 4);
772                 immVertex2fv(shdr_pos, marker->pattern_corners[0]);
773                 immVertex2fv(shdr_pos, marker->pattern_corners[1]);
774                 immVertex2fv(shdr_pos, marker->pattern_corners[2]);
775                 immVertex2fv(shdr_pos, marker->pattern_corners[3]);
776                 immEnd();
777         }
778
779         /* search */
780         show_search = (TRACK_VIEW_SELECTED(sc, track) &&
781                        ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0)) != 0;
782
783         if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
784                 imm_draw_line_box(shdr_pos, marker->search_min[0], marker->search_min[1],
785                                             marker->search_max[0], marker->search_max[1]);
786         }
787
788         gpuPopMatrix();
789
790         /* Restore default shader */
791         immUnbindProgram();
792
793         const uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
794         BLI_assert(pos == shdr_pos);
795         UNUSED_VARS_NDEBUG(pos);
796
797         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
798 }
799
800 static float get_shortest_pattern_side(MovieTrackingMarker *marker)
801 {
802         int i, next;
803         float len_sq = FLT_MAX;
804
805         for (i = 0; i < 4; i++) {
806                 float cur_len;
807
808                 next = (i + 1) % 4;
809
810                 cur_len = len_squared_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);
811
812                 len_sq = min_ff(cur_len, len_sq);
813         }
814
815         return sqrtf(len_sq);
816 }
817
818 static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
819 {
820         float tdx, tdy;
821
822         tdx = dx;
823         tdy = dy;
824
825         if (outline) {
826                 tdx += px[0];
827                 tdy += px[1];
828         }
829
830         immRectf(pos, x - tdx, y - tdy, x + tdx, y + tdy);
831 }
832
833 static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2], unsigned int pos)
834 {
835         float tdx, tdy;
836
837         tdx = dx * 2.0f;
838         tdy = dy * 2.0f;
839
840         if (outline) {
841                 tdx += px[0];
842                 tdy += px[1];
843         }
844
845         immBegin(GWN_PRIM_TRIS, 3);
846         immVertex2f(pos, x, y);
847         immVertex2f(pos, x - tdx, y);
848         immVertex2f(pos, x, y + tdy);
849         immEnd();
850 }
851
852 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
853                                     const float marker_pos[2], int outline, int sel, int act,
854                                     int width, int height, unsigned int pos)
855 {
856         float dx, dy, patdx, patdy, searchdx, searchdy;
857         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
858         float col[3], scol[3], px[2], side;
859
860         if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
861                 return;
862
863         if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
864                 return;
865
866         track_colors(track, act, col, scol);
867
868         if (outline) {
869                 immUniformThemeColor(TH_MARKER_OUTLINE);
870         }
871
872         gpuPushMatrix();
873         gpuTranslate2fv(marker_pos);
874
875         dx = 6.0f / width / sc->zoom;
876         dy = 6.0f / height / sc->zoom;
877
878         side = get_shortest_pattern_side(marker);
879         patdx = min_ff(dx * 2.0f / 3.0f, side / 6.0f) * UI_DPI_FAC;
880         patdy = min_ff(dy * 2.0f / 3.0f, side * width / height / 6.0f) * UI_DPI_FAC;
881
882         searchdx = min_ff(dx, (marker->search_max[0] - marker->search_min[0]) / 6.0f) * UI_DPI_FAC;
883         searchdy = min_ff(dy, (marker->search_max[1] - marker->search_min[1]) / 6.0f) * UI_DPI_FAC;
884
885         px[0] = 1.0f / sc->zoom / width / sc->scale;
886         px[1] = 1.0f / sc->zoom / height / sc->scale;
887
888         if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
889                 if (!outline) {
890                         immUniformColor3fv((track->search_flag & SELECT) ? scol : col);
891                 }
892
893                 /* search offset square */
894                 draw_marker_slide_square(marker->search_min[0], marker->search_max[1], searchdx, searchdy, outline, px, pos);
895
896                 /* search re-sizing triangle */
897                 draw_marker_slide_triangle(marker->search_max[0], marker->search_min[1], searchdx, searchdy, outline, px, pos);
898         }
899
900         if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
901                 int i;
902                 float pat_min[2], pat_max[2];
903 /*              float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */
904                 float tilt_ctrl[2];
905
906                 if (!outline) {
907                         immUniformColor3fv((track->pat_flag & SELECT) ? scol : col);
908                 }
909
910                 /* pattern's corners sliding squares */
911                 for (i = 0; i < 4; i++) {
912                         draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
913                                                  patdx / 1.5f, patdy / 1.5f, outline, px, pos);
914                 }
915
916                 /* ** sliders to control overall pattern  ** */
917                 add_v2_v2v2(tilt_ctrl, marker->pattern_corners[1], marker->pattern_corners[2]);
918
919                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
920
921                 glLineWidth(outline ? 3.0f : 1.0f);
922
923                 immBegin(GWN_PRIM_LINES, 2);
924                 immVertex2f(pos, 0.0f, 0.0f);
925                 immVertex2fv(pos, tilt_ctrl);
926                 immEnd();
927
928                 /* slider to control pattern tilt */
929                 draw_marker_slide_square(tilt_ctrl[0], tilt_ctrl[1], patdx, patdy, outline, px, pos);
930         }
931
932         gpuPopMatrix();
933 }
934
935 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
936                               const float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
937 {
938         char str[128] = {0}, state[64] = {0};
939         float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
940         uiStyle *style = U.uistyles.first;
941         int fontid = style->widget.uifont_id;
942
943         if (!TRACK_VIEW_SELECTED(sc, track))
944                 return;
945
946         BLF_size(fontid, 11.0f * U.pixelsize, U.dpi);
947         fontsize = BLF_height_max(fontid);
948
949         if (marker->flag & MARKER_DISABLED) {
950                 if (act) {
951                         UI_FontThemeColor(fontid, TH_ACT_MARKER);
952                 }
953                 else {
954                         unsigned char color[4];
955                         UI_GetThemeColorShade4ubv(TH_DIS_MARKER, 128, color);
956                         BLF_color4ubv(fontid, color);
957                 }
958         }
959         else {
960                 UI_FontThemeColor(fontid, act ? TH_ACT_MARKER : TH_SEL_MARKER);
961         }
962
963         if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
964             ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
965         {
966                 dx = marker->search_min[0];
967                 dy = marker->search_min[1];
968         }
969         else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
970                 float pat_min[2], pat_max[2];
971
972                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
973                 dx = pat_min[0];
974                 dy = pat_min[1];
975         }
976
977         pos[0] = (marker_pos[0] + dx) * width;
978         pos[1] = (marker_pos[1] + dy) * height;
979         pos[2] = 0.0f;
980
981         mul_m4_v3(sc->stabmat, pos);
982
983         pos[0] = pos[0] * zoomx;
984         pos[1] = pos[1] * zoomy - fontsize;
985
986         if (marker->flag & MARKER_DISABLED)
987                 strcpy(state, "disabled");
988         else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc))
989                 strcpy(state, "estimated");
990         else if (marker->flag & MARKER_TRACKED)
991                 strcpy(state, "tracked");
992         else
993                 strcpy(state, "keyframed");
994
995         if (state[0])
996                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
997         else
998                 BLI_strncpy(str, track->name, sizeof(str));
999
1000         BLF_position(fontid, pos[0], pos[1], 0.0f);
1001         BLF_draw(fontid, str, sizeof(str));
1002         pos[1] -= fontsize;
1003
1004         if (track->flag & TRACK_HAS_BUNDLE) {
1005                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
1006                 BLF_position(fontid, pos[0], pos[1], 0.0f);
1007                 BLF_draw(fontid, str, sizeof(str));
1008                 pos[1] -= fontsize;
1009         }
1010
1011         if (track->flag & TRACK_LOCKED) {
1012                 BLF_position(fontid, pos[0], pos[1], 0.0f);
1013                 BLF_draw(fontid, "locked", 6);
1014         }
1015 }
1016
1017 static void plane_track_colors(bool is_active, float color[3], float selected_color[3])
1018 {
1019         UI_GetThemeColor3fv(TH_MARKER, color);
1020
1021         UI_GetThemeColor3fv(is_active ? TH_ACT_MARKER : TH_SEL_MARKER, selected_color);
1022 }
1023
1024 static void getArrowEndPoint(const int width, const int height, const float zoom,
1025                              const float start_corner[2], const float end_corner[2],
1026                              float end_point[2])
1027 {
1028         float direction[2];
1029         float max_length;
1030
1031         sub_v2_v2v2(direction, end_corner, start_corner);
1032
1033         direction[0] *= width;
1034         direction[1] *= height;
1035         max_length = normalize_v2(direction);
1036         mul_v2_fl(direction, min_ff(32.0f / zoom, max_length));
1037         direction[0] /= width;
1038         direction[1] /= height;
1039
1040         add_v2_v2v2(end_point, start_corner, direction);
1041 }
1042
1043 static void homogeneous_2d_to_gl_matrix(/*const*/ float matrix[3][3],
1044                                         float gl_matrix[4][4])
1045 {
1046         gl_matrix[0][0] = matrix[0][0];
1047         gl_matrix[0][1] = matrix[0][1];
1048         gl_matrix[0][2] = 0.0f;
1049         gl_matrix[0][3] = matrix[0][2];
1050
1051         gl_matrix[1][0] = matrix[1][0];
1052         gl_matrix[1][1] = matrix[1][1];
1053         gl_matrix[1][2] = 0.0f;
1054         gl_matrix[1][3] = matrix[1][2];
1055
1056         gl_matrix[2][0] = 0.0f;
1057         gl_matrix[2][1] = 0.0f;
1058         gl_matrix[2][2] = 1.0f;
1059         gl_matrix[2][3] = 0.0f;
1060
1061         gl_matrix[3][0] = matrix[2][0];
1062         gl_matrix[3][1] = matrix[2][1];
1063         gl_matrix[3][2] = 0.0f;
1064         gl_matrix[3][3] = matrix[2][2];
1065 }
1066
1067 static void draw_plane_marker_image(Scene *scene,
1068                                     MovieTrackingPlaneTrack *plane_track,
1069                                     MovieTrackingPlaneMarker *plane_marker)
1070 {
1071         Image *image = plane_track->image;
1072         ImBuf *ibuf;
1073         void *lock;
1074
1075         if (image == NULL) {
1076                 return;
1077         }
1078
1079         ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
1080
1081         if (ibuf) {
1082                 unsigned char *display_buffer;
1083                 void *cache_handle;
1084
1085                 if (image->flag & IMA_VIEW_AS_RENDER) {
1086                         display_buffer = IMB_display_buffer_acquire(ibuf,
1087                                                                     &scene->view_settings,
1088                                                                     &scene->display_settings,
1089                                                                     &cache_handle);
1090                 }
1091                 else {
1092                         display_buffer = IMB_display_buffer_acquire(ibuf, NULL,
1093                                                                     &scene->display_settings,
1094                                                                     &cache_handle);
1095                 }
1096
1097                 if (display_buffer) {
1098                         GLuint texid;
1099                         float frame_corners[4][2] = {{0.0f, 0.0f},
1100                                                      {1.0f, 0.0f},
1101                                                      {1.0f, 1.0f},
1102                                                      {0.0f, 1.0f}};
1103                         float perspective_matrix[3][3];
1104                         float gl_matrix[4][4];
1105                         bool transparent = false;
1106                         BKE_tracking_homography_between_two_quads(frame_corners,
1107                                                                   plane_marker->corners,
1108                                                                   perspective_matrix);
1109
1110                         homogeneous_2d_to_gl_matrix(perspective_matrix, gl_matrix);
1111
1112                         if (plane_track->image_opacity != 1.0f || ibuf->planes == 32) {
1113                                 transparent = true;
1114                                 glEnable(GL_BLEND);
1115                                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);
1116                         }
1117
1118                         glGenTextures(1, (GLuint *)&texid);
1119
1120                         glBindTexture(GL_TEXTURE_2D, texid);
1121
1122                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1123                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1124
1125                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA,
1126                                      GL_UNSIGNED_BYTE, display_buffer);
1127
1128                         gpuPushMatrix();
1129                         gpuMultMatrix(gl_matrix);
1130
1131                         Gwn_VertFormat *imm_format = immVertexFormat();
1132                         unsigned int pos = GWN_vertformat_attr_add(imm_format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1133                         unsigned int texCoord = GWN_vertformat_attr_add(imm_format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1134
1135                         immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
1136                         immUniformColor4f(1.0f, 1.0f, 1.0f, plane_track->image_opacity);
1137                         immUniform1i("image", GL_TEXTURE0);
1138
1139                         immBegin(GWN_PRIM_TRI_FAN, 4);
1140
1141                         immAttrib2f(texCoord, 0.0f, 0.0f);
1142                         immVertex2f(pos, 0.0f, 0.0f);
1143
1144                         immAttrib2f(texCoord, 1.0f, 0.0f);
1145                         immVertex2f(pos, 1.0f, 0.0f);
1146
1147                         immAttrib2f(texCoord, 1.0f, 1.0f);
1148                         immVertex2f(pos, 1.0f, 1.0f);
1149
1150                         immAttrib2f(texCoord, 0.0f, 1.0f);
1151                         immVertex2f(pos, 0.0f, 1.0f);
1152
1153                         immEnd();
1154
1155                         immUnbindProgram();
1156
1157                         gpuPopMatrix();
1158
1159                         glBindTexture(GL_TEXTURE_2D, 0);
1160
1161                         if (transparent) {
1162                                 glDisable(GL_BLEND);
1163                         }
1164                 }
1165
1166                 IMB_display_buffer_release(cache_handle);
1167         }
1168
1169         BKE_image_release_ibuf(image, ibuf, lock);
1170 }
1171
1172 static void draw_plane_marker_ex(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1173                                  MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1174                                  bool draw_outline, int width, int height)
1175 {
1176         bool tiny = (sc->flag & SC_SHOW_TINY_MARKER) != 0;
1177         bool is_selected_track = (plane_track->flag & SELECT) != 0;
1178         const bool has_image = plane_track->image != NULL &&
1179                                BKE_image_has_ibuf(plane_track->image, NULL);
1180         const bool draw_plane_quad = !has_image || plane_track->image_opacity == 0.0f;
1181         float px[2];
1182         float color[3], selected_color[3];
1183
1184         px[0] = 1.0f / width / sc->zoom;
1185         px[1] = 1.0f / height / sc->zoom;
1186
1187         /* Draw image */
1188         if (draw_outline == false) {
1189                 draw_plane_marker_image(scene, plane_track, plane_marker);
1190         }
1191
1192         if (draw_plane_quad || is_selected_track) {
1193                 const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1194
1195                 immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
1196
1197                 float viewport_size[4];
1198                 glGetFloatv(GL_VIEWPORT, viewport_size);
1199                 immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
1200
1201                 immUniform1i("num_colors", 0);  /* "simple" mode */
1202
1203                 if (draw_plane_quad) {
1204                         const bool stipple = !draw_outline && tiny;
1205                         const bool thick = draw_outline && !tiny;
1206
1207                         glLineWidth(thick ? 3.0f : 1.0f);
1208
1209                         if (stipple) {
1210                                 immUniform1f("dash_width", 6.0f);
1211                                 immUniform1f("dash_factor", 0.5f);
1212                         }
1213                         else {
1214                                 immUniform1f("dash_factor", 2.0f);  /* Solid line */
1215                         }
1216
1217                         if (draw_outline) {
1218                                 immUniformThemeColor(TH_MARKER_OUTLINE);
1219                         }
1220                         else {
1221                                 plane_track_colors(is_active_track, color, selected_color);
1222                                 immUniformColor3fv(is_selected_track ? selected_color : color);
1223                         }
1224
1225                         /* Draw rectangle itself. */
1226                         immBegin(GWN_PRIM_LINE_LOOP, 4);
1227                         immVertex2fv(shdr_pos, plane_marker->corners[0]);
1228                         immVertex2fv(shdr_pos, plane_marker->corners[1]);
1229                         immVertex2fv(shdr_pos, plane_marker->corners[2]);
1230                         immVertex2fv(shdr_pos, plane_marker->corners[3]);
1231                         immEnd();
1232
1233                         /* Draw axis. */
1234                         if (!draw_outline) {
1235                                 float end_point[2];
1236
1237                                 immUniformColor3f(1.0f, 0.0f, 0.0f);
1238
1239                                 immBegin(GWN_PRIM_LINES, 2);
1240
1241                                 getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[1], end_point);
1242                                 immVertex2fv(shdr_pos, plane_marker->corners[0]);
1243                                 immVertex2fv(shdr_pos, end_point);
1244
1245                                 immEnd();
1246
1247                                 immUniformColor3f(0.0f, 1.0f, 0.0f);
1248
1249                                 immBegin(GWN_PRIM_LINES, 2);
1250
1251                                 getArrowEndPoint(width, height, sc->zoom, plane_marker->corners[0], plane_marker->corners[3], end_point);
1252                                 immVertex2fv(shdr_pos, plane_marker->corners[0]);
1253                                 immVertex2fv(shdr_pos, end_point);
1254
1255                                 immEnd();
1256                         }
1257                 }
1258
1259                 /* Draw sliders. */
1260                 if (is_selected_track) {
1261                         immUniform1f("dash_factor", 2.0f);  /* Solid line */
1262
1263                         if (draw_outline) {
1264                                 immUniformThemeColor(TH_MARKER_OUTLINE);
1265                         }
1266                         else {
1267                                 immUniformColor3fv(selected_color);
1268                         }
1269
1270                         int i;
1271                         for (i = 0; i < 4; i++) {
1272                                 draw_marker_slide_square(plane_marker->corners[i][0], plane_marker->corners[i][1],
1273                                                          3.0f * px[0], 3.0f * px[1], draw_outline, px, shdr_pos);
1274                         }
1275                 }
1276
1277                 immUnbindProgram();
1278         }
1279 }
1280
1281 static void draw_plane_marker_outline(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1282                                       MovieTrackingPlaneMarker *plane_marker, int width, int height)
1283 {
1284         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, false, true, width, height);
1285 }
1286
1287 static void draw_plane_marker(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1288                               MovieTrackingPlaneMarker *plane_marker, bool is_active_track,
1289                               int width, int height)
1290 {
1291         draw_plane_marker_ex(sc, scene, plane_track, plane_marker, is_active_track, false, width, height);
1292 }
1293
1294 static void draw_plane_track(SpaceClip *sc, Scene *scene, MovieTrackingPlaneTrack *plane_track,
1295                              int framenr, bool is_active_track, int width, int height)
1296 {
1297         MovieTrackingPlaneMarker *plane_marker;
1298
1299         plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
1300
1301         draw_plane_marker_outline(sc, scene, plane_track, plane_marker, width, height);
1302         draw_plane_marker(sc, scene, plane_track, plane_marker, is_active_track, width, height);
1303 }
1304
1305 /* Draw all kind of tracks. */
1306 static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip,
1307                                  int width, int height, float zoomx, float zoomy)
1308 {
1309         float x, y;
1310         MovieTracking *tracking = &clip->tracking;
1311         ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
1312         ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
1313         MovieTrackingTrack *track, *act_track;
1314         MovieTrackingPlaneTrack *plane_track, *active_plane_track;
1315         MovieTrackingMarker *marker;
1316         int framenr = ED_space_clip_get_clip_frame_number(sc);
1317         int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
1318         float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];
1319
1320         /* ** find window pixel coordinates of origin ** */
1321
1322         /* UI_view2d_view_to_region_no_clip return integer values, this could
1323          * lead to 1px flickering when view is locked to selection during playback.
1324          * to avoid this flickering, calculate base point in the same way as it happens
1325          * in UI_view2d_view_to_region_no_clip, but do it in floats here */
1326
1327         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1328
1329         gpuPushMatrix();
1330         gpuTranslate2f(x, y);
1331
1332         gpuPushMatrix();
1333         gpuScale2f(zoomx, zoomy);
1334         gpuMultMatrix(sc->stabmat);
1335         gpuScale2f(width, height);
1336
1337         act_track = BKE_tracking_track_get_active(tracking);
1338
1339         /* Draw plane tracks */
1340         active_plane_track = BKE_tracking_plane_track_get_active(tracking);
1341         for (plane_track = plane_tracks_base->first;
1342              plane_track;
1343              plane_track = plane_track->next)
1344         {
1345                 if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
1346                         draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
1347                 }
1348         }
1349
1350         if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
1351                 int count = 0;
1352
1353                 /* count */
1354                 track = tracksbase->first;
1355                 while (track) {
1356                         if ((track->flag & TRACK_HIDDEN) == 0) {
1357                                 marker = BKE_tracking_marker_get(track, framenr);
1358
1359                                 if (MARKER_VISIBLE(sc, track, marker))
1360                                         count++;
1361                         }
1362
1363                         track = track->next;
1364                 }
1365
1366                 /* undistort */
1367                 if (count) {
1368                         marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos");
1369
1370                         track = tracksbase->first;
1371                         fp = marker_pos;
1372                         while (track) {
1373                                 if ((track->flag & TRACK_HIDDEN) == 0) {
1374                                         marker = BKE_tracking_marker_get(track, framenr);
1375
1376                                         if (MARKER_VISIBLE(sc, track, marker)) {
1377                                                 ED_clip_point_undistorted_pos(sc, marker->pos, fp);
1378
1379                                                 if (track == act_track)
1380                                                         active_pos = fp;
1381
1382                                                 fp += 2;
1383                                         }
1384                                 }
1385
1386                                 track = track->next;
1387                         }
1388                 }
1389         }
1390
1391         if (sc->flag & SC_SHOW_TRACK_PATH) {
1392                 track = tracksbase->first;
1393                 while (track) {
1394                         if ((track->flag & TRACK_HIDDEN) == 0)
1395                                 draw_track_path(sc, clip, track);
1396
1397                         track = track->next;
1398                 }
1399         }
1400
1401         unsigned int position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1402
1403         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
1404
1405         /* markers outline and non-selected areas */
1406         track = tracksbase->first;
1407         fp = marker_pos;
1408         while (track) {
1409                 if ((track->flag & TRACK_HIDDEN) == 0) {
1410                         marker = BKE_tracking_marker_get(track, framenr);
1411
1412                         if (MARKER_VISIBLE(sc, track, marker)) {
1413                                 copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1414
1415                                 draw_marker_outline(sc, track, marker, cur_pos, width, height, position);
1416                                 draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0, position);
1417                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height, position);
1418                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height, position);
1419
1420                                 if (fp)
1421                                         fp += 2;
1422                         }
1423                 }
1424
1425                 track = track->next;
1426         }
1427
1428         /* selected areas only, so selection wouldn't be overlapped by
1429          * non-selected areas */
1430         track = tracksbase->first;
1431         fp = marker_pos;
1432         while (track) {
1433                 if ((track->flag & TRACK_HIDDEN) == 0) {
1434                         int act = track == act_track;
1435                         marker = BKE_tracking_marker_get(track, framenr);
1436
1437                         if (MARKER_VISIBLE(sc, track, marker)) {
1438                                 if (!act) {
1439                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1440
1441                                         draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1, position);
1442                                         draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height, position);
1443                                 }
1444
1445                                 if (fp)
1446                                         fp += 2;
1447                         }
1448                 }
1449
1450                 track = track->next;
1451         }
1452
1453         /* active marker would be displayed on top of everything else */
1454         if (act_track) {
1455                 if ((act_track->flag & TRACK_HIDDEN) == 0) {
1456                         marker = BKE_tracking_marker_get(act_track, framenr);
1457
1458                         if (MARKER_VISIBLE(sc, act_track, marker)) {
1459                                 copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
1460
1461                                 draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1, position);
1462                                 draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height, position);
1463                         }
1464                 }
1465         }
1466
1467         if (sc->flag & SC_SHOW_BUNDLES) {
1468                 MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
1469                 float pos[4], vec[4], mat[4][4], aspy;
1470
1471                 glPointSize(3.0f);
1472
1473                 aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1474                 BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);
1475
1476                 track = tracksbase->first;
1477                 while (track) {
1478                         if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
1479                                 marker = BKE_tracking_marker_get(track, framenr);
1480
1481                                 if (MARKER_VISIBLE(sc, track, marker)) {
1482                                         float npos[2];
1483                                         copy_v3_v3(vec, track->bundle_pos);
1484                                         vec[3] = 1;
1485
1486                                         mul_v4_m4v4(pos, mat, vec);
1487
1488                                         pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
1489                                         pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
1490
1491                                         BKE_tracking_distort_v2(tracking, pos, npos);
1492
1493                                         if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
1494                                                 vec[0] = (marker->pos[0] + track->offset[0]) * width;
1495                                                 vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;
1496
1497                                                 sub_v2_v2(vec, npos);
1498
1499                                                 if (len_squared_v2(vec) < (3.0f * 3.0f)) {
1500                                                         immUniformColor3f(0.0f, 1.0f, 0.0f);
1501                                                 }
1502                                                 else {
1503                                                         immUniformColor3f(1.0f, 0.0f, 0.0f);
1504                                                 }
1505
1506                                                 immBegin(GWN_PRIM_POINTS, 1);
1507
1508                                                 if (undistort) {
1509                                                         immVertex2f(position, pos[0] / width, pos[1] / (height * aspy));
1510                                                 }
1511                                                 else {
1512                                                         immVertex2f(position, npos[0] / width, npos[1] / (height * aspy));
1513                                                 }
1514
1515                                                 immEnd();
1516                                         }
1517                                 }
1518                         }
1519
1520                         track = track->next;
1521                 }
1522         }
1523
1524         immUnbindProgram();
1525
1526         gpuPopMatrix();
1527
1528         if (sc->flag & SC_SHOW_NAMES) {
1529                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
1530                 track = tracksbase->first;
1531                 fp = marker_pos;
1532                 while (track) {
1533                         if ((track->flag & TRACK_HIDDEN) == 0) {
1534                                 marker = BKE_tracking_marker_get(track, framenr);
1535
1536                                 if (MARKER_VISIBLE(sc, track, marker)) {
1537                                         int act = track == act_track;
1538
1539                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1540
1541                                         draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
1542
1543                                         if (fp)
1544                                                 fp += 2;
1545                                 }
1546                         }
1547
1548                         track = track->next;
1549                 }
1550         }
1551
1552         gpuPopMatrix();
1553
1554         if (marker_pos)
1555                 MEM_freeN(marker_pos);
1556 }
1557
1558 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
1559                             int width, int height, float zoomx, float zoomy)
1560 {
1561         float x, y;
1562         const int n = 10;
1563         int i, j, a;
1564         float pos[2], tpos[2], grid[11][11][2];
1565         MovieTracking *tracking = &clip->tracking;
1566         bGPdata *gpd = NULL;
1567         float aspy = 1.0f / tracking->camera.pixel_aspect;
1568         float dx = (float)width / n, dy = (float)height / n * aspy;
1569         float offsx = 0.0f, offsy = 0.0f;
1570
1571         if (!tracking->camera.focal)
1572                 return;
1573
1574         if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
1575                 return;
1576
1577         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
1578
1579         gpuPushMatrix();
1580         gpuTranslate2f(x, y);
1581         gpuScale2f(zoomx, zoomy);
1582         gpuMultMatrix(sc->stabmat);
1583         gpuScale2f(width, height);
1584
1585         unsigned int position = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
1586
1587         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
1588
1589         /* grid */
1590         if (sc->flag & SC_SHOW_GRID) {
1591                 float val[4][2], idx[4][2];
1592                 float min[2], max[2];
1593
1594                 for (a = 0; a < 4; a++) {
1595                         if (a < 2)
1596                                 val[a][a % 2] = FLT_MAX;
1597                         else
1598                                 val[a][a % 2] = -FLT_MAX;
1599                 }
1600
1601                 zero_v2(pos);
1602                 for (i = 0; i <= n; i++) {
1603                         for (j = 0; j <= n; j++) {
1604                                 if (i == 0 || j == 0 || i == n || j == n) {
1605                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1606
1607                                         for (a = 0; a < 4; a++) {
1608                                                 int ok;
1609
1610                                                 if (a < 2)
1611                                                         ok = tpos[a % 2] < val[a][a % 2];
1612                                                 else
1613                                                         ok = tpos[a % 2] > val[a][a % 2];
1614
1615                                                 if (ok) {
1616                                                         copy_v2_v2(val[a], tpos);
1617                                                         idx[a][0] = j;
1618                                                         idx[a][1] = i;
1619                                                 }
1620                                         }
1621                                 }
1622
1623                                 pos[0] += dx;
1624                         }
1625
1626                         pos[0] = 0.0f;
1627                         pos[1] += dy;
1628                 }
1629
1630                 INIT_MINMAX2(min, max);
1631
1632                 for (a = 0; a < 4; a++) {
1633                         pos[0] = idx[a][0] * dx;
1634                         pos[1] = idx[a][1] * dy;
1635
1636                         BKE_tracking_undistort_v2(tracking, pos, tpos);
1637
1638                         minmax_v2v2_v2(min, max, tpos);
1639                 }
1640
1641                 copy_v2_v2(pos, min);
1642                 dx = (max[0] - min[0]) / n;
1643                 dy = (max[1] - min[1]) / n;
1644
1645                 for (i = 0; i <= n; i++) {
1646                         for (j = 0; j <= n; j++) {
1647                                 BKE_tracking_distort_v2(tracking, pos, grid[i][j]);
1648
1649                                 grid[i][j][0] /= width;
1650                                 grid[i][j][1] /= height * aspy;
1651
1652                                 pos[0] += dx;
1653                         }
1654
1655                         pos[0] = min[0];
1656                         pos[1] += dy;
1657                 }
1658
1659                 immUniformColor3f(1.0f, 0.0f, 0.0f);
1660
1661                 for (i = 0; i <= n; i++) {
1662                         immBegin(GWN_PRIM_LINE_STRIP, n + 1);
1663
1664                         for (j = 0; j <= n; j++) {
1665                                 immVertex2fv(position, grid[i][j]);
1666                         }
1667
1668                         immEnd();
1669                 }
1670
1671                 for (j = 0; j <= n; j++) {
1672                         immBegin(GWN_PRIM_LINE_STRIP, n + 1);
1673
1674                         for (i = 0; i <= n; i++) {
1675                                 immVertex2fv(position, grid[i][j]);
1676                         }
1677
1678                         immEnd();
1679                 }
1680         }
1681
1682         if (sc->gpencil_src != SC_GPENCIL_SRC_TRACK) {
1683                 gpd = clip->gpd;
1684         }
1685
1686         if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
1687                 bGPDlayer *layer = gpd->layers.first;
1688
1689                 while (layer) {
1690                         bGPDframe *frame = layer->frames.first;
1691
1692                         if (layer->flag & GP_LAYER_HIDE) {
1693                                 layer = layer->next;
1694                                 continue;
1695                         }
1696
1697                         immUniformColor4fv(layer->color);
1698
1699                         glLineWidth(layer->thickness);
1700                         glPointSize((float)(layer->thickness + 2));
1701
1702                         while (frame) {
1703                                 bGPDstroke *stroke = frame->strokes.first;
1704
1705                                 while (stroke) {
1706                                         if (stroke->flag & GP_STROKE_2DSPACE) {
1707                                                 if (stroke->totpoints > 1) {
1708                                                         for (i = 0; i < stroke->totpoints - 1; i++) {
1709                                                                 float npos[2], dpos[2], len;
1710                                                                 int steps;
1711
1712                                                                 pos[0] = (stroke->points[i].x + offsx) * width;
1713                                                                 pos[1] = (stroke->points[i].y + offsy) * height * aspy;
1714
1715                                                                 npos[0] = (stroke->points[i + 1].x + offsx) * width;
1716                                                                 npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;
1717
1718                                                                 len = len_v2v2(pos, npos);
1719                                                                 steps = ceil(len / 5.0f);
1720
1721                                                                 /* we want to distort only long straight lines */
1722                                                                 if (stroke->totpoints == 2) {
1723                                                                         BKE_tracking_undistort_v2(tracking, pos, pos);
1724                                                                         BKE_tracking_undistort_v2(tracking, npos, npos);
1725                                                                 }
1726
1727                                                                 sub_v2_v2v2(dpos, npos, pos);
1728                                                                 mul_v2_fl(dpos, 1.0f / steps);
1729
1730                                                                 immBegin(GWN_PRIM_LINE_STRIP, steps + 1);
1731
1732                                                                 for (j = 0; j <= steps; j++) {
1733                                                                         BKE_tracking_distort_v2(tracking, pos, tpos);
1734                                                                         immVertex2f(position, tpos[0] / width, tpos[1] / (height * aspy));
1735
1736                                                                         add_v2_v2(pos, dpos);
1737                                                                 }
1738
1739                                                                 immEnd();
1740                                                         }
1741                                                 }
1742                                                 else if (stroke->totpoints == 1) {
1743                                                         immBegin(GWN_PRIM_POINTS, 1);
1744                                                         immVertex2f(position, stroke->points[0].x + offsx, stroke->points[0].y + offsy);
1745                                                         immEnd();
1746                                                 }
1747                                         }
1748
1749                                         stroke = stroke->next;
1750                                 }
1751
1752                                 frame = frame->next;
1753                         }
1754
1755                         layer = layer->next;
1756                 }
1757         }
1758
1759         immUnbindProgram();
1760
1761         gpuPopMatrix();
1762 }
1763
1764 void clip_draw_main(const bContext *C, SpaceClip *sc, ARegion *ar)
1765 {
1766         MovieClip *clip = ED_space_clip_get_clip(sc);
1767         Scene *scene = CTX_data_scene(C);
1768         ImBuf *ibuf = NULL;
1769         int width, height;
1770         float zoomx, zoomy;
1771
1772         ED_space_clip_get_size(sc, &width, &height);
1773         ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
1774
1775         /* if no clip, nothing to do */
1776         if (!clip) {
1777                 ED_region_grid_draw(ar, zoomx, zoomy);
1778                 return;
1779         }
1780
1781         if (sc->flag & SC_SHOW_STABLE) {
1782                 float translation[2];
1783                 float aspect = clip->tracking.camera.pixel_aspect;
1784                 float smat[4][4], ismat[4][4];
1785
1786                 if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
1787                         ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc,
1788                                                                &sc->scale, &sc->angle);
1789                 }
1790
1791                 if (ibuf != NULL && width != ibuf->x)
1792                         mul_v2_v2fl(translation, sc->loc, (float)width / ibuf->x);
1793                 else
1794                         copy_v2_v2(translation, sc->loc);
1795
1796                 BKE_tracking_stabilization_data_to_mat4(width, height, aspect, translation,
1797                                                         sc->scale, sc->angle, sc->stabmat);
1798
1799                 unit_m4(smat);
1800                 smat[0][0] = 1.0f / width;
1801                 smat[1][1] = 1.0f / height;
1802                 invert_m4_m4(ismat, smat);
1803
1804                 mul_m4_series(sc->unistabmat, smat, sc->stabmat, ismat);
1805         }
1806         else if ((sc->flag & SC_MUTE_FOOTAGE) == 0) {
1807                 ibuf = ED_space_clip_get_buffer(sc);
1808
1809                 zero_v2(sc->loc);
1810                 sc->scale = 1.0f;
1811                 unit_m4(sc->stabmat);
1812                 unit_m4(sc->unistabmat);
1813         }
1814
1815         if (ibuf) {
1816                 draw_movieclip_buffer(C, sc, ar, ibuf, width, height, zoomx, zoomy);
1817                 IMB_freeImBuf(ibuf);
1818         }
1819         else if (sc->flag & SC_MUTE_FOOTAGE) {
1820                 draw_movieclip_muted(ar, width, height, zoomx, zoomy);
1821         }
1822         else {
1823                 ED_region_grid_draw(ar, zoomx, zoomy);
1824         }
1825
1826         if (width && height) {
1827                 draw_stabilization_border(sc, ar, width, height, zoomx, zoomy);
1828                 draw_tracking_tracks(sc, scene, ar, clip, width, height, zoomx, zoomy);
1829                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1830         }
1831 }
1832
1833 void clip_draw_cache_and_notes(const bContext *C, SpaceClip *sc, ARegion *ar)
1834 {
1835         Scene *scene = CTX_data_scene(C);
1836         MovieClip *clip = ED_space_clip_get_clip(sc);
1837         if (clip) {
1838                 draw_movieclip_cache(sc, ar, clip, scene);
1839                 draw_movieclip_notes(sc, ar);
1840         }
1841 }
1842
1843 /* draw grease pencil */
1844 void clip_draw_grease_pencil(bContext *C, int onlyv2d)
1845 {
1846         SpaceClip *sc = CTX_wm_space_clip(C);
1847         MovieClip *clip = ED_space_clip_get_clip(sc);
1848
1849         if (!clip)
1850                 return;
1851
1852         if (onlyv2d) {
1853                 bool is_track_source = sc->gpencil_src == SC_GPENCIL_SRC_TRACK;
1854                 /* if manual calibration is used then grease pencil data
1855                  * associated with the clip is already drawn in draw_distortion
1856                  */
1857                 if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || is_track_source) {
1858                         gpuPushMatrix();
1859                         gpuMultMatrix(sc->unistabmat);
1860
1861                         if (is_track_source) {
1862                                 MovieTrackingTrack *track = BKE_tracking_track_get_active(&sc->clip->tracking);
1863
1864                                 if (track) {
1865                                         int framenr = ED_space_clip_get_clip_frame_number(sc);
1866                                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
1867
1868                                         gpuTranslate2fv(marker->pos);
1869                                 }
1870                         }
1871
1872                         ED_gpencil_draw_2dimage(C);
1873
1874                         gpuPopMatrix();
1875                 }
1876         }
1877         else {
1878                 ED_gpencil_draw_view2d(C, 0);
1879         }
1880 }