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