aa9af704280e92e720a43ef4cb88d72efd2e6b18
[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 #include "DNA_object_types.h"   /* SELECT */
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BKE_context.h"
40 #include "BKE_movieclip.h"
41 #include "BKE_tracking.h"
42
43 #include "IMB_imbuf_types.h"
44 #include "IMB_imbuf.h"
45
46 #include "BLI_utildefines.h"
47 #include "BLI_math.h"
48 #include "BLI_string.h"
49 #include "BLI_rect.h"
50 #include "BLI_math_base.h"
51
52 #include "ED_screen.h"
53 #include "ED_clip.h"
54 #include "ED_gpencil.h"
55
56 #include "BIF_gl.h"
57 #include "BIF_glutil.h"
58
59 #include "WM_api.h"
60 #include "WM_types.h"
61
62 #include "UI_interface.h"
63 #include "UI_resources.h"
64 #include "UI_view2d.h"
65
66 #include "RNA_access.h"
67
68 #include "BLF_api.h"
69
70 #include "clip_intern.h"        // own include
71
72 /*********************** main area drawing *************************/
73
74 void clip_draw_curfra_label(SpaceClip *sc, float x, float y)
75 {
76         uiStyle *style = UI_GetStyle();
77         int fontid = style->widget.uifont_id;
78         char numstr[32];
79         float font_dims[2] = {0.0f, 0.0f};
80
81         /* frame number */
82         BLF_size(fontid, 11.0f, U.dpi);
83         BLI_snprintf(numstr, sizeof(numstr), "%d", sc->user.framenr);
84
85         BLF_width_and_height(fontid, numstr, &font_dims[0], &font_dims[1]);
86
87         glRecti(x, y, x + font_dims[0] + 6.0f, y + font_dims[1] + 4.0f);
88
89         UI_ThemeColor(TH_TEXT);
90         BLF_position(fontid, x + 2.0f, y + 2.0f, 0.0f);
91         BLF_draw(fontid, numstr, sizeof(numstr));
92 }
93
94 static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
95 {
96         float x;
97         int *points, totseg, i, a;
98         float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
99         MovieTrackingTrack *act_track = BKE_tracking_active_track(&clip->tracking);
100         MovieTrackingReconstruction *reconstruction = BKE_tracking_get_reconstruction(&clip->tracking);
101
102         glEnable(GL_BLEND);
103
104         /* cache background */
105         glColor4ub(128, 128, 255, 64);
106         glRecti(0, 0, ar->winx, 8);
107
108         /* cached segments -- could be usefu lto debug caching strategies */
109         BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
110         if (totseg) {
111                 glColor4ub(128, 128, 255, 128);
112
113                 for (a = 0; a < totseg; a++) {
114                         float x1, x2;
115
116                         x1 = (points[a * 2] - sfra) / (efra - sfra + 1) * ar->winx;
117                         x2 = (points[a * 2 + 1] - sfra + 1) / (efra - sfra + 1) * ar->winx;
118
119                         glRecti(x1, 0, x2, 8);
120                 }
121         }
122
123         /* track */
124         if (act_track) {
125                 MovieTrackingTrack *track = act_track;
126
127                 for (i = sfra, a = 0; i <= efra; i++) {
128                         int framenr;
129                         MovieTrackingMarker *marker;
130
131                         while (a < track->markersnr) {
132                                 if (track->markers[a].framenr >= i)
133                                         break;
134
135                                 if (a < track->markersnr - 1 && track->markers[a + 1].framenr > i)
136                                         break;
137
138                                 a++;
139                         }
140
141                         if (a < track->markersnr)
142                                 marker = &track->markers[a];
143                         else
144                                 marker = &track->markers[track->markersnr - 1];
145
146                         if ((marker->flag & MARKER_DISABLED) == 0) {
147                                 framenr = marker->framenr;
148
149                                 if (framenr != i)
150                                         glColor4ub(128, 128, 0, 96);
151                                 else if ((marker->flag & MARKER_TRACKED) == 0)
152                                         glColor4ub(255, 255, 0, 196);
153                                 else
154                                         glColor4ub(255, 255, 0, 96);
155
156                                 glRecti((i - sfra) * framelen, 0, (i - sfra + 1)*framelen, 4);
157                         }
158                 }
159         }
160
161         /* failed frames */
162         if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
163                 int n = reconstruction->camnr;
164                 MovieReconstructedCamera *cameras = reconstruction->cameras;
165
166                 glColor4ub(255, 0, 0, 96);
167
168                 for (i = sfra, a = 0; i <= efra; i++) {
169                         int ok = FALSE;
170
171                         while (a < n) {
172                                 if (cameras[a].framenr == i) {
173                                         ok = TRUE;
174                                         break;
175                                 }
176                                 else if (cameras[a].framenr > i) {
177                                         break;
178                                 }
179
180                                 a++;
181                         }
182
183                         if (!ok)
184                                 glRecti((i - sfra) * framelen, 0, (i - sfra + 1) * framelen, 8);
185                 }
186         }
187
188         glDisable(GL_BLEND);
189
190         /* current frame */
191         x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;
192
193         UI_ThemeColor(TH_CFRAME);
194         glRecti(x, 0, x + framelen, 8);
195
196         clip_draw_curfra_label(sc, x, 8.0f);
197 }
198
199 static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
200 {
201         MovieClip *clip = ED_space_clip(sc);
202         MovieTracking *tracking = &clip->tracking;
203         char str[256] = {0};
204         int block = FALSE;
205
206         if (tracking->stats) {
207                 BLI_strncpy(str, tracking->stats->message, sizeof(str));
208                 block = TRUE;
209         }
210         else {
211                 if (sc->flag & SC_LOCK_SELECTION)
212                         strcpy(str, "Locked");
213         }
214
215         if (str[0])
216                 ED_region_info_draw(ar, str, block, 0.6f);
217 }
218
219 static void verify_buffer_float(ImBuf *ibuf)
220 {
221         if (ibuf->rect_float && (ibuf->rect == NULL || (ibuf->userflags & IB_RECT_INVALID))) {
222                 IMB_rect_from_float(ibuf);
223         }
224 }
225
226 static void draw_movieclip_buffer(SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
227                                   int width, int height, float zoomx, float zoomy)
228 {
229         int x, y;
230         MovieClip *clip = ED_space_clip(sc);
231
232         /* find window pixel coordinates of origin */
233         UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
234
235         if (sc->flag & SC_MUTE_FOOTAGE) {
236                 glColor3f(0.0f, 0.0f, 0.0f);
237                 glRectf(x, y, x + zoomx * width, y + zoomy * height);
238         }
239         else {
240                 verify_buffer_float(ibuf);
241
242                 if (ibuf->rect) {
243                         int need_fallback = 1;
244
245                         if (ED_space_clip_texture_buffer_supported(sc)) {
246                                 if (ED_space_clip_load_movieclip_buffer(sc, ibuf)) {
247                                         glPushMatrix();
248                                         glTranslatef(x, y, 0.0f);
249                                         glScalef(zoomx, zoomy, 1.0f);
250
251                                         glBegin(GL_QUADS);
252                                                 glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f,  0.0f);
253                                                 glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
254                                                 glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
255                                                 glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f,  height);
256                                         glEnd();
257
258                                         glPopMatrix();
259
260                                         ED_space_clip_unload_movieclip_buffer(sc);
261
262                                         need_fallback = 0;
263                                 }
264                         }
265
266                         /* if texture buffers aren't efifciently supported or texture is too large to
267                          * be binder fallback to simple draw pixels solution */
268                         if (need_fallback) {
269                                 /* set zoom */
270                                 glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
271
272                                 glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
273
274                                 /* reset zoom */
275                                 glPixelZoom(1.0f, 1.0f);
276                         }
277                 }
278         }
279
280         /* draw boundary border for frame if stabilization is enabled */
281         if (sc->flag & SC_SHOW_STABLE && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
282                 glColor3f(0.0f, 0.0f, 0.0f);
283                 glLineStipple(3, 0xaaaa);
284                 glEnable(GL_LINE_STIPPLE);
285                 glEnable(GL_COLOR_LOGIC_OP);
286                 glLogicOp(GL_NOR);
287
288                 glPushMatrix();
289                 glTranslatef(x, y, 0.0f);
290
291                 glScalef(zoomx, zoomy, 1.0f);
292                 glMultMatrixf(sc->stabmat);
293
294                 glBegin(GL_LINE_LOOP);
295                         glVertex2f(0.0f, 0.0f);
296                         glVertex2f(width, 0.0f);
297                         glVertex2f(width, height);
298                         glVertex2f(0.0f, height);
299                 glEnd();
300
301                 glPopMatrix();
302
303                 glDisable(GL_COLOR_LOGIC_OP);
304                 glDisable(GL_LINE_STIPPLE);
305         }
306 }
307
308 static void draw_track_path(SpaceClip *sc, MovieClip *UNUSED(clip), MovieTrackingTrack *track)
309 {
310         int count = sc->path_length;
311         int i, a, b, curindex = -1;
312         float path[102][2];
313         int tiny = sc->flag & SC_SHOW_TINY_MARKER, framenr;
314         MovieTrackingMarker *marker;
315
316         if (count == 0)
317                 return;
318
319         marker = BKE_tracking_get_marker(track, sc->user.framenr);
320         if (marker->framenr != sc->user.framenr || marker->flag & MARKER_DISABLED)
321                 return;
322
323         framenr = marker->framenr;
324
325         a = count;
326         i = framenr - 1;
327         while (i >= framenr - count) {
328                 marker = BKE_tracking_get_marker(track, i);
329
330                 if (!marker || marker->flag & MARKER_DISABLED)
331                         break;
332
333                 if (marker->framenr == i) {
334                         add_v2_v2v2(path[--a], marker->pos, track->offset);
335                         ED_clip_point_undistorted_pos(sc, path[a], path[a]);
336
337                         if (marker->framenr == sc->user.framenr)
338                                 curindex = a;
339                 }
340                 else {
341                         break;
342                 }
343
344                 i--;
345         }
346
347         b = count;
348         i = framenr;
349         while (i <= framenr + count) {
350                 marker = BKE_tracking_get_marker(track, i);
351
352                 if (!marker || marker->flag & MARKER_DISABLED)
353                         break;
354
355                 if (marker->framenr == i) {
356                         if (marker->framenr == sc->user.framenr)
357                                 curindex = b;
358
359                         add_v2_v2v2(path[b++], marker->pos, track->offset);
360                         ED_clip_point_undistorted_pos(sc, path[b - 1], path[b - 1]);
361                 }
362                 else
363                         break;
364
365                 i++;
366         }
367
368         if (!tiny) {
369                 UI_ThemeColor(TH_MARKER_OUTLINE);
370
371                 if (TRACK_VIEW_SELECTED(sc, track)) {
372                         glPointSize(5.0f);
373                         glBegin(GL_POINTS);
374                                 for (i = a; i < b; i++) {
375                                         if (i != curindex)
376                                                 glVertex2f(path[i][0], path[i][1]);
377                                 }
378                         glEnd();
379                 }
380
381                 glLineWidth(3.0f);
382                 glBegin(GL_LINE_STRIP);
383                         for (i = a; i < b; i++)
384                                 glVertex2f(path[i][0], path[i][1]);
385                 glEnd();
386                 glLineWidth(1.0f);
387         }
388
389         UI_ThemeColor(TH_PATH_BEFORE);
390
391         if (TRACK_VIEW_SELECTED(sc, track)) {
392                 glPointSize(3.0f);
393                 glBegin(GL_POINTS);
394                         for (i = a; i < b; i++) {
395                                 if (i == count + 1)
396                                         UI_ThemeColor(TH_PATH_AFTER);
397
398                                 if (i != curindex)
399                                         glVertex2f(path[i][0], path[i][1]);
400                         }
401                 glEnd();
402         }
403
404         UI_ThemeColor(TH_PATH_BEFORE);
405
406         glBegin(GL_LINE_STRIP);
407                 for (i = a; i < b; i++) {
408                         if (i == count + 1)
409                                 UI_ThemeColor(TH_PATH_AFTER);
410
411                         glVertex2f(path[i][0], path[i][1]);
412                 }
413         glEnd();
414         glPointSize(1.0f);
415 }
416
417 static void draw_marker_outline(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
418                                 float marker_pos[2], int width, int height)
419 {
420         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
421         int show_search = FALSE;
422         float px[2];
423
424         UI_ThemeColor(TH_MARKER_OUTLINE);
425
426         px[0] = 1.0f / width / sc->zoom;
427         px[1] = 1.0f / height / sc->zoom;
428
429         if ((marker->flag & MARKER_DISABLED) == 0) {
430                 float pos[2];
431                 float p[2];
432
433                 add_v2_v2v2(pos, marker->pos, track->offset);
434
435                 ED_clip_point_undistorted_pos(sc, pos, pos);
436
437                 sub_v2_v2v2(p, pos, marker_pos);
438
439                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
440                                         marker->pattern_corners[2], marker->pattern_corners[3]))
441                 {
442                         if (tiny) glPointSize(3.0f);
443                         else glPointSize(4.0f);
444                         glBegin(GL_POINTS);
445                                 glVertex2f(pos[0], pos[1]);
446                         glEnd();
447                         glPointSize(1.0f);
448                 }
449                 else {
450                         if (!tiny) glLineWidth(3.0f);
451                         glBegin(GL_LINES);
452                                 glVertex2f(pos[0] + px[0]*2, pos[1]);
453                                 glVertex2f(pos[0] + px[0]*8, pos[1]);
454
455                                 glVertex2f(pos[0] - px[0]*2, pos[1]);
456                                 glVertex2f(pos[0] - px[0]*8, pos[1]);
457
458                                 glVertex2f(pos[0], pos[1] - px[1]*2);
459                                 glVertex2f(pos[0], pos[1] - px[1]*8);
460
461                                 glVertex2f(pos[0], pos[1] + px[1]*2);
462                                 glVertex2f(pos[0], pos[1] + px[1]*8);
463                         glEnd();
464                         if (!tiny) glLineWidth(1.0f);
465                 }
466         }
467
468         /* pattern and search outline */
469         glPushMatrix();
470         glTranslatef(marker_pos[0], marker_pos[1], 0);
471
472         if (!tiny)
473                 glLineWidth(3.0f);
474
475         if (sc->flag & SC_SHOW_MARKER_PATTERN) {
476                 glBegin(GL_LINE_LOOP);
477                         glVertex2fv(marker->pattern_corners[0]);
478                         glVertex2fv(marker->pattern_corners[1]);
479                         glVertex2fv(marker->pattern_corners[2]);
480                         glVertex2fv(marker->pattern_corners[3]);
481                 glEnd();
482         }
483
484         show_search = TRACK_VIEW_SELECTED(sc, track) &&
485                       ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0);
486         if (sc->flag & SC_SHOW_MARKER_SEARCH && show_search) {
487                 glBegin(GL_LINE_LOOP);
488                         glVertex2f(track->search_min[0], track->search_min[1]);
489                         glVertex2f(track->search_max[0], track->search_min[1]);
490                         glVertex2f(track->search_max[0], track->search_max[1]);
491                         glVertex2f(track->search_min[0], track->search_max[1]);
492                 glEnd();
493         }
494         glPopMatrix();
495
496         if (!tiny)
497                 glLineWidth(1.0f);
498 }
499
500 static void track_colors(MovieTrackingTrack *track, int act, float col[3], float scol[3])
501 {
502         if (track->flag & TRACK_CUSTOMCOLOR) {
503                 if (act)
504                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
505                 else
506                         copy_v3_v3(scol, track->color);
507
508                 mul_v3_v3fl(col, track->color, 0.5f);
509         }
510         else {
511                 UI_GetThemeColor3fv(TH_MARKER, col);
512
513                 if (act)
514                         UI_GetThemeColor3fv(TH_ACT_MARKER, scol);
515                 else
516                         UI_GetThemeColor3fv(TH_SEL_MARKER, scol);
517         }
518 }
519
520 static void draw_marker_areas(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
521                              float marker_pos[2], int width, int height, int act, int sel)
522 {
523         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
524         int show_search = 0;
525         float col[3], scol[3], px[2];
526
527         track_colors(track, act, col, scol);
528
529         px[0] = 1.0f / width / sc->zoom;
530         px[1] = 1.0f / height / sc->zoom;
531
532         /* marker position and offset position */
533         if ((track->flag & SELECT) == sel && (marker->flag & MARKER_DISABLED) == 0) {
534                 float pos[2], p[2];
535
536                 if (track->flag & TRACK_LOCKED) {
537                         if (act)
538                                 UI_ThemeColor(TH_ACT_MARKER);
539                         else if (track->flag & SELECT)
540                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
541                         else
542                                 UI_ThemeColor(TH_LOCK_MARKER);
543                 }
544                 else {
545                         if (track->flag & SELECT)
546                                 glColor3fv(scol);
547                         else
548                                 glColor3fv(col);
549                 }
550
551                 add_v2_v2v2(pos, marker->pos, track->offset);
552                 ED_clip_point_undistorted_pos(sc, pos, pos);
553
554                 sub_v2_v2v2(p, pos, marker_pos);
555
556                 if (isect_point_quad_v2(p, marker->pattern_corners[0], marker->pattern_corners[1],
557                                         marker->pattern_corners[2], marker->pattern_corners[3]))
558                 {
559                         if (!tiny)
560                                 glPointSize(2.0f);
561
562                         glBegin(GL_POINTS);
563                                 glVertex2f(pos[0], pos[1]);
564                         glEnd();
565
566                         if (!tiny)
567                                 glPointSize(1.0f);
568                 }
569                 else {
570                         glBegin(GL_LINES);
571                                 glVertex2f(pos[0] + px[0]*3, pos[1]);
572                                 glVertex2f(pos[0] + px[0]*7, pos[1]);
573
574                                 glVertex2f(pos[0] - px[0]*3, pos[1]);
575                                 glVertex2f(pos[0] - px[0]*7, pos[1]);
576
577                                 glVertex2f(pos[0], pos[1] - px[1]*3);
578                                 glVertex2f(pos[0], pos[1] - px[1]*7);
579
580                                 glVertex2f(pos[0], pos[1] + px[1]*3);
581                                 glVertex2f(pos[0], pos[1] + px[1]*7);
582                         glEnd();
583
584                         glColor3f(0.0f, 0.0f, 0.0f);
585                         glLineStipple(3, 0xaaaa);
586                         glEnable(GL_LINE_STIPPLE);
587                         glEnable(GL_COLOR_LOGIC_OP);
588                         glLogicOp(GL_NOR);
589
590                         glBegin(GL_LINES);
591                                 glVertex2fv(pos);
592                                 glVertex2fv(marker_pos);
593                         glEnd();
594
595                         glDisable(GL_COLOR_LOGIC_OP);
596                         glDisable(GL_LINE_STIPPLE);
597                 }
598         }
599
600         /* pattern */
601         glPushMatrix();
602         glTranslatef(marker_pos[0], marker_pos[1], 0);
603
604         if (tiny) {
605                 glLineStipple(3, 0xaaaa);
606                 glEnable(GL_LINE_STIPPLE);
607         }
608
609         if ((track->pat_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_PATTERN)) {
610                 if (track->flag & TRACK_LOCKED) {
611                         if (act)
612                                 UI_ThemeColor(TH_ACT_MARKER);
613                         else if (track->pat_flag & SELECT)
614                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
615                         else UI_ThemeColor(TH_LOCK_MARKER);
616                 }
617                 else if (marker->flag & MARKER_DISABLED) {
618                         if (act)
619                                 UI_ThemeColor(TH_ACT_MARKER);
620                         else if (track->pat_flag & SELECT)
621                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
622                         else UI_ThemeColor(TH_DIS_MARKER);
623                 }
624                 else {
625                         if (track->pat_flag & SELECT)
626                                 glColor3fv(scol);
627                         else glColor3fv(col);
628                 }
629
630                 glBegin(GL_LINE_LOOP);
631                         glVertex2fv(marker->pattern_corners[0]);
632                         glVertex2fv(marker->pattern_corners[1]);
633                         glVertex2fv(marker->pattern_corners[2]);
634                         glVertex2fv(marker->pattern_corners[3]);
635                 glEnd();
636         }
637
638         /* search */
639         show_search = TRACK_VIEW_SELECTED(sc, track) &&
640                      ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0);
641         if ((track->search_flag & SELECT) == sel && (sc->flag & SC_SHOW_MARKER_SEARCH) && show_search) {
642                 if (track->flag & TRACK_LOCKED) {
643                         if (act)
644                                 UI_ThemeColor(TH_ACT_MARKER);
645                         else if (track->search_flag & SELECT)
646                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
647                         else UI_ThemeColor(TH_LOCK_MARKER);
648                 }
649                 else if (marker->flag & MARKER_DISABLED) {
650                         if (act)
651                                 UI_ThemeColor(TH_ACT_MARKER);
652                         else if (track->search_flag & SELECT)
653                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
654                         else UI_ThemeColor(TH_DIS_MARKER);
655                 }
656                 else {
657                         if (track->search_flag & SELECT)
658                                 glColor3fv(scol);
659                         else
660                                 glColor3fv(col);
661                 }
662
663                 glBegin(GL_LINE_LOOP);
664                         glVertex2f(track->search_min[0], track->search_min[1]);
665                         glVertex2f(track->search_max[0], track->search_min[1]);
666                         glVertex2f(track->search_max[0], track->search_max[1]);
667                         glVertex2f(track->search_min[0], track->search_max[1]);
668                 glEnd();
669         }
670
671         /* pyramid */
672         if (sel && TRACK_VIEW_SELECTED(sc, track) &&
673             (track->tracker == TRACKER_KLT) &&
674                 (marker->flag & MARKER_DISABLED) == 0)
675         {
676                 if (track->flag & TRACK_LOCKED) {
677                         if (act)
678                                 UI_ThemeColor(TH_ACT_MARKER);
679                         else if (track->pat_flag & SELECT)
680                                 UI_ThemeColorShade(TH_LOCK_MARKER, 64);
681                         else UI_ThemeColor(TH_LOCK_MARKER);
682                 }
683                 else if (marker->flag & MARKER_DISABLED) {
684                         if (act)
685                                 UI_ThemeColor(TH_ACT_MARKER);
686                         else if (track->pat_flag & SELECT)
687                                 UI_ThemeColorShade(TH_DIS_MARKER, 128);
688                         else UI_ThemeColor(TH_DIS_MARKER);
689                 }
690                 else {
691                         if (track->pat_flag & SELECT)
692                                 glColor3fv(scol);
693                         else
694                                 glColor3fv(col);
695                 }
696
697                 {
698                         int i = 0;
699                         glPushMatrix();
700                         glEnable(GL_LINE_STIPPLE);
701                         for (i = 1; i < track->pyramid_levels; ++i) {
702                                 glScalef(2.0f, 2.0f, 1.0);
703                         }
704                         /* only draw a pattern for the coarsest level */
705                         glBegin(GL_LINE_LOOP);
706                                 glVertex2fv(marker->pattern_corners[0]);
707                                 glVertex2fv(marker->pattern_corners[1]);
708                                 glVertex2fv(marker->pattern_corners[2]);
709                                 glVertex2fv(marker->pattern_corners[3]);
710                         glEnd();
711                         glDisable(GL_LINE_STIPPLE);
712                         glPopMatrix();
713                 }
714         }
715
716         if (tiny)
717                 glDisable(GL_LINE_STIPPLE);
718
719         glPopMatrix();
720 }
721
722 static float get_shortest_pattern_side(MovieTrackingMarker *marker)
723 {
724         int i, next;
725         float len = FLT_MAX;
726
727         for (i = 0; i < 4; i++) {
728                 float cur_len;
729
730                 next = (i + 1) % 4;
731
732                 cur_len = len_v2v2(marker->pattern_corners[i], marker->pattern_corners[next]);
733
734                 len = MIN2(cur_len, len);
735         }
736
737         return len;
738 }
739
740 static void draw_marker_slide_square(float x, float y, float dx, float dy, int outline, float px[2])
741 {
742         float tdx, tdy;
743
744         tdx = dx;
745         tdy = dy;
746
747         if (outline) {
748                 tdx += px[0];
749                 tdy += px[1];
750         }
751
752         glBegin(GL_QUADS);
753                 glVertex3f(x - tdx, y + tdy, 0.0f);
754                 glVertex3f(x + tdx, y + tdy, 0.0f);
755                 glVertex3f(x + tdx, y - tdy, 0.0f);
756                 glVertex3f(x - tdx, y - tdy, 0.0f);
757         glEnd();
758 }
759
760 static void draw_marker_slide_triangle(float x, float y, float dx, float dy, int outline, float px[2])
761 {
762         float tdx, tdy;
763
764         tdx = dx * 2.0f;
765         tdy = dy * 2.0f;
766
767         if (outline) {
768                 tdx += px[0];
769                 tdy += px[1];
770         }
771
772         glBegin(GL_TRIANGLES);
773                 glVertex3f(x,       y,       0.0f);
774                 glVertex3f(x - tdx, y,       0.0f);
775                 glVertex3f(x,       y + tdy, 0.0f);
776         glEnd();
777 }
778
779 static void draw_marker_slide_zones(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
780                                     float marker_pos[2], int outline, int sel, int act, int width, int height)
781 {
782         float dx, dy, patdx, patdy, searchdx, searchdy;
783         int tiny = sc->flag & SC_SHOW_TINY_MARKER;
784         float col[3], scol[3], px[2], side;
785
786         if ((tiny && outline) || (marker->flag & MARKER_DISABLED))
787                 return;
788
789         if (!TRACK_VIEW_SELECTED(sc, track) || track->flag & TRACK_LOCKED)
790                 return;
791
792         track_colors(track, act, col, scol);
793
794         if (outline) {
795                 glLineWidth(3.0f);
796                 UI_ThemeColor(TH_MARKER_OUTLINE);
797         }
798
799         glPushMatrix();
800         glTranslatef(marker_pos[0], marker_pos[1], 0);
801
802         dx = 6.0f / width / sc->zoom;
803         dy = 6.0f / height / sc->zoom;
804
805         side = get_shortest_pattern_side(marker);
806         patdx = MIN2(dx * 2.0f / 3.0f, side / 6.0f);
807         patdy = MIN2(dy * 2.0f / 3.0f, side * width / height / 6.0f);
808
809         searchdx = MIN2(dx, (track->search_max[0] - track->search_min[0]) / 6.0f);
810         searchdy = MIN2(dy, (track->search_max[1] - track->search_min[1]) / 6.0f);
811
812         px[0] = 1.0f / sc->zoom / width / sc->scale;
813         px[1] = 1.0f / sc->zoom / height / sc->scale;
814
815         if ((sc->flag & SC_SHOW_MARKER_SEARCH) && ((track->search_flag & SELECT) == sel || outline)) {
816                 if (!outline) {
817                         if (track->search_flag & SELECT)
818                                 glColor3fv(scol);
819                         else
820                                 glColor3fv(col);
821                 }
822
823                 /* search offset square */
824                 draw_marker_slide_square(track->search_min[0], track->search_max[1], searchdx, searchdy, outline, px);
825
826                 /* search re-sizing triangle */
827                 draw_marker_slide_triangle(track->search_max[0], track->search_min[1], searchdx, searchdy, outline, px);
828         }
829
830         if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) {
831                 if (!outline) {
832                         if (track->pat_flag & SELECT)
833                                 glColor3fv(scol);
834                         else
835                                 glColor3fv(col);
836                 }
837
838                 /* XXX: need to be real check if affine tracking is enabled, but for now not
839                  *      sure how to do this, so assume affine tracker is always enabled */
840                 if (TRUE) {
841                         int i;
842
843                         /* pattern's corners sliding squares */
844                         for (i = 0; i < 4; i++) {
845                                 draw_marker_slide_square(marker->pattern_corners[i][0], marker->pattern_corners[i][1],
846                                                          patdx / 1.5f, patdy / 1.5f, outline, px);
847                         }
848                 }
849                 else {
850                         /* pattern offset square */
851                         draw_marker_slide_square(marker->pattern_corners[3][0], marker->pattern_corners[3][1],
852                                                  patdx, patdy, outline, px);
853
854                         /* pattern re-sizing triangle */
855                         draw_marker_slide_triangle(marker->pattern_corners[1][0], marker->pattern_corners[1][1],
856                                                    patdx, patdy, outline, px);
857                 }
858         }
859
860         glPopMatrix();
861
862         if (outline)
863                 glLineWidth(1.0f);
864 }
865
866 static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTrackingMarker *marker,
867                               float marker_pos[2], int act, int width, int height, float zoomx, float zoomy)
868 {
869         char str[128] = {0}, state[64] = {0};
870         float dx = 0.0f, dy = 0.0f, fontsize, pos[3];
871         uiStyle *style = U.uistyles.first;
872         int fontid = style->widget.uifont_id;
873
874         if (!TRACK_VIEW_SELECTED(sc, track))
875                 return;
876
877         BLF_size(fontid, 11.0f, U.dpi);
878         fontsize = BLF_height_max(fontid);
879
880         if (marker->flag & MARKER_DISABLED) {
881                 if (act)
882                         UI_ThemeColor(TH_ACT_MARKER);
883                 else
884                         UI_ThemeColorShade(TH_DIS_MARKER, 128);
885         }
886         else {
887                 if (act)
888                         UI_ThemeColor(TH_ACT_MARKER);
889                 else
890                         UI_ThemeColor(TH_SEL_MARKER);
891         }
892
893         if ((sc->flag & SC_SHOW_MARKER_SEARCH) &&
894            ((marker->flag & MARKER_DISABLED) == 0 || (sc->flag & SC_SHOW_MARKER_PATTERN) == 0))
895         {
896                 dx = track->search_min[0];
897                 dy = track->search_min[1];
898         }
899         else if (sc->flag & SC_SHOW_MARKER_PATTERN) {
900                 float pat_min[2], pat_max[2];
901
902                 BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
903                 dx = pat_min[0];
904                 dy = pat_min[1];
905         }
906
907         pos[0] = (marker_pos[0] + dx) * width;
908         pos[1] = (marker_pos[1] + dy) * height;
909         pos[2] = 0.0f;
910
911         mul_m4_v3(sc->stabmat, pos);
912
913         pos[0] = pos[0]*zoomx;
914         pos[1] = pos[1]*zoomy - fontsize;
915
916         if (marker->flag & MARKER_DISABLED)
917                 strcpy(state, "disabled");
918         else if (marker->framenr != sc->user.framenr)
919                 strcpy(state, "estimated");
920         else if (marker->flag & MARKER_TRACKED)
921                 strcpy(state, "tracked");
922         else
923                 strcpy(state, "keyframed");
924
925         if (state[0])
926                 BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
927         else
928                 BLI_snprintf(str, sizeof(str), "%s", track->name);
929
930         BLF_position(fontid, pos[0], pos[1], 0.0f);
931         BLF_draw(fontid, str, sizeof(str));
932         pos[1] -= fontsize;
933
934         if (track->flag & TRACK_HAS_BUNDLE) {
935                 BLI_snprintf(str, sizeof(str), "Average error: %.3f", track->error);
936                 BLF_position(fontid, pos[0], pos[1], 0.0f);
937                 BLF_draw(fontid, str, sizeof(str));
938                 pos[1] -= fontsize;
939         }
940
941         if (track->flag & TRACK_LOCKED) {
942                 BLF_position(fontid, pos[0], pos[1], 0.0f);
943                 BLF_draw(fontid, "locked", 6);
944         }
945 }
946
947 static void view2d_to_region_float(View2D *v2d, float x, float y, float *regionx, float *regiony)
948 {
949         /* express given coordinates as proportional values */
950         x = -v2d->cur.xmin / (v2d->cur.xmax - v2d->cur.xmin);
951         y = -v2d->cur.ymin / (v2d->cur.ymax - v2d->cur.ymin);
952
953         /* convert proportional distances to screen coordinates */
954         *regionx = v2d->mask.xmin + x*(v2d->mask.xmax - v2d->mask.xmin);
955         *regiony = v2d->mask.ymin + y*(v2d->mask.ymax - v2d->mask.ymin);
956 }
957
958 static void draw_tracking_tracks(SpaceClip *sc, ARegion *ar, MovieClip *clip,
959                                  int width, int height, float zoomx, float zoomy)
960 {
961         float x, y;
962         MovieTracking *tracking = &clip->tracking;
963         ListBase *tracksbase = BKE_tracking_get_tracks(tracking);
964         MovieTrackingTrack *track, *act_track;
965         MovieTrackingMarker *marker;
966         int framenr = sc->user.framenr;
967         int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
968         float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];
969
970         /* ** find window pixel coordinates of origin ** */
971
972         /* UI_view2d_to_region_no_clip return integer values, this could
973          * lead to 1px flickering when view is locked to selection during playbeck.
974          * to avoid this flickering, calculate base point in the same way as it happens
975          * in UI_view2d_to_region_no_clip, but do it in floats here */
976
977         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
978
979         glPushMatrix();
980         glTranslatef(x, y, 0);
981
982         glPushMatrix();
983         glScalef(zoomx, zoomy, 0);
984         glMultMatrixf(sc->stabmat);
985         glScalef(width, height, 0);
986
987         act_track = BKE_tracking_active_track(tracking);
988
989         if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
990                 int count = 0;
991
992                 /* count */
993                 track = tracksbase->first;
994                 while (track) {
995                         if ((track->flag & TRACK_HIDDEN) == 0) {
996                                 marker = BKE_tracking_get_marker(track, framenr);
997
998                                 if (MARKER_VISIBLE(sc, track, marker))
999                                         count++;
1000                         }
1001
1002                         track = track->next;
1003                 }
1004
1005                 /* undistort */
1006                 if (count) {
1007                         marker_pos = MEM_callocN(2*sizeof(float)*count, "draw_tracking_tracks marker_pos");
1008
1009                         track = tracksbase->first;
1010                         fp = marker_pos;
1011                         while (track) {
1012                                 if ((track->flag & TRACK_HIDDEN) == 0) {
1013                                         marker = BKE_tracking_get_marker(track, framenr);
1014
1015                                         if (MARKER_VISIBLE(sc, track, marker)) {
1016                                                 ED_clip_point_undistorted_pos(sc, marker->pos, fp);
1017
1018                                                 if (track == act_track)
1019                                                         active_pos = fp;
1020
1021                                                 fp += 2;
1022                                         }
1023                                 }
1024
1025                                 track = track->next;
1026                         }
1027                 }
1028         }
1029
1030         if (sc->flag & SC_SHOW_TRACK_PATH) {
1031                 track = tracksbase->first;
1032                 while (track) {
1033                         if ((track->flag & TRACK_HIDDEN) == 0)
1034                                 draw_track_path(sc, clip, track);
1035
1036                         track = track->next;
1037                 }
1038         }
1039
1040         /* markers outline and non-selected areas */
1041         track = tracksbase->first;
1042         fp = marker_pos;
1043         while (track) {
1044                 if ((track->flag & TRACK_HIDDEN) == 0) {
1045                         marker = BKE_tracking_get_marker(track, framenr);
1046
1047                         if (MARKER_VISIBLE(sc, track, marker)) {
1048                                 copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1049
1050                                 draw_marker_outline(sc, track, marker, cur_pos, width, height);
1051                                 draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
1052                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
1053                                 draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);
1054
1055                                 if (fp)
1056                                         fp += 2;
1057                         }
1058                 }
1059
1060                 track = track->next;
1061         }
1062
1063         /* selected areas only, so selection wouldn't be overlapped by
1064          * non-selected areas */
1065         track = tracksbase->first;
1066         fp = marker_pos;
1067         while (track) {
1068                 if ((track->flag & TRACK_HIDDEN) == 0) {
1069                         int act = track == act_track;
1070                         marker = BKE_tracking_get_marker(track, framenr);
1071
1072                         if (MARKER_VISIBLE(sc, track, marker)) {
1073                                 if (!act) {
1074                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1075
1076                                         draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
1077                                         draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
1078                                 }
1079
1080                                 if (fp)
1081                                         fp += 2;
1082                         }
1083                 }
1084
1085                 track = track->next;
1086         }
1087
1088         /* active marker would be displayed on top of everything else */
1089         if (act_track) {
1090                 if ((act_track->flag & TRACK_HIDDEN) == 0) {
1091                         marker = BKE_tracking_get_marker(act_track, framenr);
1092
1093                         if (MARKER_VISIBLE(sc, act_track, marker)) {
1094                                 copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);
1095
1096                                 draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
1097                                 draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
1098                         }
1099                 }
1100         }
1101
1102         if (sc->flag & SC_SHOW_BUNDLES) {
1103                 MovieTrackingObject *object = BKE_tracking_active_object(tracking);
1104                 float pos[4], vec[4], mat[4][4], aspy;
1105
1106                 glEnable(GL_POINT_SMOOTH);
1107                 glPointSize(3.0f);
1108
1109                 aspy = 1.0f / clip->tracking.camera.pixel_aspect;
1110                 BKE_tracking_projection_matrix(tracking, object, framenr, width, height, mat);
1111
1112                 track = tracksbase->first;
1113                 while (track) {
1114                         if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
1115                                 marker = BKE_tracking_get_marker(track, framenr);
1116
1117                                 if (MARKER_VISIBLE(sc, track, marker)) {
1118                                         float npos[2];
1119                                         copy_v4_v4(vec, track->bundle_pos);
1120                                         vec[3] = 1;
1121
1122                                         mul_v4_m4v4(pos, mat, vec);
1123
1124                                         pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
1125                                         pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;
1126
1127                                         BKE_tracking_apply_intrinsics(tracking, pos, npos);
1128
1129                                         if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
1130                                                 vec[0] = (marker->pos[0] + track->offset[0]) * width;
1131                                                 vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;
1132
1133                                                 sub_v2_v2(vec, npos);
1134
1135                                                 if (len_v2(vec) < 3.0f)
1136                                                         glColor3f(0.0f, 1.0f, 0.0f);
1137                                                 else
1138                                                         glColor3f(1.0f, 0.0f, 0.0f);
1139
1140                                                 glBegin(GL_POINTS);
1141                                                         if (undistort)
1142                                                                 glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0);
1143                                                         else
1144                                                                 glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0);
1145                                                 glEnd();
1146                                         }
1147                                 }
1148                         }
1149
1150                         track = track->next;
1151                 }
1152
1153                 glPointSize(1.0f);
1154                 glDisable(GL_POINT_SMOOTH);
1155         }
1156
1157         glPopMatrix();
1158
1159         if (sc->flag & SC_SHOW_NAMES) {
1160                 /* scaling should be cleared before drawing texts, otherwise font would also be scaled */
1161                 track = tracksbase->first;
1162                 fp = marker_pos;
1163                 while (track) {
1164                         if ((track->flag & TRACK_HIDDEN) == 0) {
1165                                 marker = BKE_tracking_get_marker(track, framenr);
1166
1167                                 if (MARKER_VISIBLE(sc, track, marker)) {
1168                                         int act = track == act_track;
1169
1170                                         copy_v2_v2(cur_pos, fp ? fp : marker->pos);
1171
1172                                         draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);
1173
1174                                         if (fp)
1175                                                 fp += 2;
1176                                 }
1177                         }
1178
1179                         track = track->next;
1180                 }
1181         }
1182
1183         glPopMatrix();
1184
1185         if (marker_pos)
1186                 MEM_freeN(marker_pos);
1187 }
1188
1189 static void draw_distortion(SpaceClip *sc, ARegion *ar, MovieClip *clip,
1190                             int width, int height, float zoomx, float zoomy)
1191 {
1192         float x, y;
1193         const int n = 10;
1194         int i, j, a;
1195         float pos[2], tpos[2], grid[11][11][2];
1196         MovieTracking *tracking = &clip->tracking;
1197         bGPdata *gpd = NULL;
1198         float aspy = 1.0f / tracking->camera.pixel_aspect;
1199         float dx = (float)width / n, dy = (float)height / n * aspy;
1200         float offsx = 0.0f, offsy = 0.0f;
1201
1202         if (sc->mode != SC_MODE_DISTORTION)
1203                 return;
1204
1205         if (!tracking->camera.focal)
1206                 return;
1207
1208         if ((sc->flag & SC_SHOW_GRID) == 0 && (sc->flag & SC_MANUAL_CALIBRATION) == 0)
1209                 return;
1210
1211         view2d_to_region_float(&ar->v2d, 0.0f, 0.0f, &x, &y);
1212
1213         glPushMatrix();
1214         glTranslatef(x, y, 0);
1215         glScalef(zoomx, zoomy, 0);
1216         glMultMatrixf(sc->stabmat);
1217         glScalef(width, height, 0);
1218
1219         /* grid */
1220         if (sc->flag & SC_SHOW_GRID) {
1221                 float val[4][2], idx[4][2];
1222                 float min[2], max[2];
1223
1224                 for (a = 0; a < 4; a++) {
1225                         if (a < 2)
1226                                 val[a][a % 2] = FLT_MAX;
1227                         else
1228                                 val[a][a % 2] = -FLT_MAX;
1229                 }
1230
1231                 zero_v2(pos);
1232                 for (i = 0; i <= n; i++) {
1233                         for (j = 0; j <= n; j++) {
1234                                 if (i == 0 || j == 0 || i == n || j == n) {
1235                                         BKE_tracking_apply_intrinsics(tracking, pos, tpos);
1236
1237                                         for (a = 0; a < 4; a++) {
1238                                                 int ok;
1239
1240                                                 if (a < 2)
1241                                                         ok = tpos[a % 2] < val[a][a % 2];
1242                                                 else
1243                                                         ok = tpos[a % 2] > val[a][a % 2];
1244
1245                                                 if (ok) {
1246                                                         copy_v2_v2(val[a], tpos);
1247                                                         idx[a][0] = j;
1248                                                         idx[a][1] = i;
1249                                                 }
1250                                         }
1251                                 }
1252
1253                                 pos[0] += dx;
1254                         }
1255
1256                         pos[0] = 0.0f;
1257                         pos[1] += dy;
1258                 }
1259
1260                 INIT_MINMAX2(min, max);
1261
1262                 for (a = 0; a < 4; a++) {
1263                         pos[0] = idx[a][0] * dx;
1264                         pos[1] = idx[a][1] * dy;
1265
1266                         BKE_tracking_invert_intrinsics(tracking, pos, tpos);
1267
1268                         DO_MINMAX2(tpos, min, max);
1269                 }
1270
1271                 copy_v2_v2(pos, min);
1272                 dx = (max[0] - min[0]) / n;
1273                 dy = (max[1] - min[1]) / n;
1274
1275                 for (i = 0; i <= n; i++) {
1276                         for (j = 0; j <= n; j++) {
1277                                 BKE_tracking_apply_intrinsics(tracking, pos, grid[i][j]);
1278
1279                                 grid[i][j][0] /= width;
1280                                 grid[i][j][1] /= height*aspy;
1281
1282                                 pos[0] += dx;
1283                         }
1284
1285                         pos[0] = min[0];
1286                         pos[1] += dy;
1287                 }
1288
1289                 glColor3f(1.0f, 0.0f, 0.0f);
1290
1291                 for (i = 0; i <= n; i++) {
1292                         glBegin(GL_LINE_STRIP);
1293                                 for (j = 0; j <= n; j++) {
1294                                         glVertex2fv(grid[i][j]);
1295                                 }
1296                         glEnd();
1297                 }
1298
1299                 for (j = 0; j <= n; j++) {
1300                         glBegin(GL_LINE_STRIP);
1301                                 for (i = 0; i <= n; i++) {
1302                                         glVertex2fv(grid[i][j]);
1303                                 }
1304                         glEnd();
1305                 }
1306         }
1307
1308         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1309                 MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking);
1310
1311                 if (track) {
1312                         int framenr = sc->user.framenr;
1313                         MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
1314
1315                         offsx = marker->pos[0];
1316                         offsy = marker->pos[1];
1317
1318                         gpd = track->gpd;
1319                 }
1320
1321         }
1322         else {
1323                 gpd = clip->gpd;
1324         }
1325
1326         if (sc->flag & SC_MANUAL_CALIBRATION && gpd) {
1327                 bGPDlayer *layer = gpd->layers.first;
1328
1329                 while (layer) {
1330                         bGPDframe *frame = layer->frames.first;
1331
1332                         if (layer->flag & GP_LAYER_HIDE) {
1333                                 layer = layer->next;
1334                                 continue;
1335                         }
1336
1337                         glColor4fv(layer->color);
1338                         glLineWidth(layer->thickness);
1339                         glPointSize((float)(layer->thickness + 2));
1340
1341                         while (frame) {
1342                                 bGPDstroke *stroke = frame->strokes.first;
1343
1344                                 while (stroke) {
1345                                         if (stroke->flag & GP_STROKE_2DSPACE) {
1346                                                 if (stroke->totpoints > 1) {
1347                                                         glBegin(GL_LINE_STRIP);
1348                                                                 for (i = 0; i < stroke->totpoints - 1; i++) {
1349                                                                         float npos[2], dpos[2], len;
1350                                                                         int steps;
1351
1352                                                                         pos[0] = (stroke->points[i].x + offsx) * width;
1353                                                                         pos[1] = (stroke->points[i].y + offsy) * height * aspy;
1354
1355                                                                         npos[0] = (stroke->points[i + 1].x + offsx) * width;
1356                                                                         npos[1] = (stroke->points[i + 1].y + offsy) * height * aspy;
1357
1358                                                                         len = len_v2v2(pos, npos);
1359                                                                         steps = ceil(len / 5.0f);
1360
1361                                                                         /* we want to distort only long straight lines */
1362                                                                         if (stroke->totpoints == 2) {
1363                                                                                 BKE_tracking_invert_intrinsics(tracking, pos, pos);
1364                                                                                 BKE_tracking_invert_intrinsics(tracking, npos, npos);
1365                                                                         }
1366
1367                                                                         sub_v2_v2v2(dpos, npos, pos);
1368                                                                         mul_v2_fl(dpos, 1.0f / steps);
1369
1370                                                                         for (j = 0; j <= steps; j++) {
1371                                                                                 BKE_tracking_apply_intrinsics(tracking, pos, tpos);
1372                                                                                 glVertex2f(tpos[0] / width, tpos[1] / (height*aspy));
1373
1374                                                                                 add_v2_v2(pos, dpos);
1375                                                                         }
1376                                                                 }
1377                                                         glEnd();
1378                                                 }
1379                                                 else if (stroke->totpoints == 1) {
1380                                                         glBegin(GL_POINTS);
1381                                                                 glVertex2f(stroke->points[0].x + offsx, stroke->points[0].y + offsy);
1382                                                         glEnd();
1383                                                 }
1384                                         }
1385
1386                                         stroke = stroke->next;
1387                                 }
1388
1389                                 frame = frame->next;
1390                         }
1391
1392                         layer = layer->next;
1393                 }
1394
1395                 glLineWidth(1.0f);
1396                 glPointSize(1.0f);
1397         }
1398
1399         glPopMatrix();
1400 }
1401
1402 void clip_draw_main(SpaceClip *sc, ARegion *ar, Scene *scene)
1403 {
1404         MovieClip *clip = ED_space_clip(sc);
1405         ImBuf *ibuf;
1406         int width, height;
1407         float zoomx, zoomy;
1408
1409         /* if no clip, nothing to do */
1410         if (!clip)
1411                 return;
1412
1413         ED_space_clip_size(sc, &width, &height);
1414         ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
1415
1416         if (sc->flag & SC_SHOW_STABLE) {
1417                 float smat[4][4], ismat[4][4];
1418
1419                 ibuf = ED_space_clip_get_stable_buffer(sc, sc->loc, &sc->scale, &sc->angle);
1420
1421                 if (ibuf) {
1422                         float loc[2];
1423                         float aspect = clip->tracking.camera.pixel_aspect;
1424
1425                         if (width != ibuf->x)
1426                                 mul_v2_v2fl(loc, sc->loc, (float)width / ibuf->x);
1427                         else
1428                                 copy_v2_v2(loc, sc->loc);
1429
1430                         BKE_tracking_stabdata_to_mat4(width, height, aspect, loc, sc->scale, sc->angle, sc->stabmat);
1431
1432                         unit_m4(smat);
1433                         smat[0][0] = 1.0f / width;
1434                         smat[1][1] = 1.0f / height;
1435                         invert_m4_m4(ismat, smat);
1436
1437                         mul_serie_m4(sc->unistabmat, smat, sc->stabmat, ismat, NULL, NULL, NULL, NULL, NULL);
1438                 }
1439         }
1440         else {
1441                 ibuf = ED_space_clip_get_buffer(sc);
1442
1443                 zero_v2(sc->loc);
1444                 sc->scale = 1.0f;
1445                 unit_m4(sc->stabmat);
1446                 unit_m4(sc->unistabmat);
1447         }
1448
1449         if (ibuf) {
1450                 draw_movieclip_buffer(sc, ar, ibuf, width, height, zoomx, zoomy);
1451                 IMB_freeImBuf(ibuf);
1452         }
1453         else {
1454                 ED_region_grid_draw(ar, zoomx, zoomy);
1455         }
1456
1457         if (width && height) {
1458                 draw_tracking_tracks(sc, ar, clip, width, height, zoomx, zoomy);
1459                 draw_distortion(sc, ar, clip, width, height, zoomx, zoomy);
1460         }
1461
1462         draw_movieclip_cache(sc, ar, clip, scene);
1463         draw_movieclip_notes(sc, ar);
1464 }
1465
1466 /* draw grease pencil */
1467 void clip_draw_grease_pencil(bContext *C, int onlyv2d)
1468 {
1469         SpaceClip *sc = CTX_wm_space_clip(C);
1470         MovieClip *clip = ED_space_clip(sc);
1471         ImBuf *ibuf;
1472
1473         if (!clip)
1474                 return;
1475
1476         if (onlyv2d) {
1477                 /* if manual calibration is used then grease pencil data is already
1478                  * drawed in draw_distortion */
1479                 if ((sc->flag & SC_MANUAL_CALIBRATION) == 0 || sc->mode != SC_MODE_DISTORTION) {
1480                         ibuf = ED_space_clip_get_buffer(sc);
1481
1482                         if (ibuf) {
1483                                 glPushMatrix();
1484                                 glMultMatrixf(sc->unistabmat);
1485
1486                                 if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
1487                                         MovieTrackingTrack *track = BKE_tracking_active_track(&sc->clip->tracking);
1488
1489                                         if (track) {
1490                                                 int framenr = sc->user.framenr;
1491                                                 MovieTrackingMarker *marker = BKE_tracking_exact_marker(track, framenr);
1492
1493                                                 glTranslatef(marker->pos[0], marker->pos[1], 0.0f);
1494                                         }
1495                                 }
1496
1497                                 draw_gpencil_2dimage(C, ibuf);
1498
1499                                 IMB_freeImBuf(ibuf);
1500                                 glPopMatrix();
1501                         }
1502                 }
1503         }
1504         else {
1505                 draw_gpencil_view2d(C, 0);
1506         }
1507 }