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