Merge branch 'master' into blender2.8
[blender.git] / source / blender / editors / space_view3d / view3d_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) 2008 Blender Foundation.
19  * All rights reserved.
20  *
21  * 
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/editors/space_view3d/view3d_draw.c
28  *  \ingroup spview3d
29  */
30
31 #include <math.h>
32
33 #include "BIF_gl.h"
34 #include "BIF_glutil.h"
35
36 #include "BKE_camera.h"
37 #include "BKE_context.h"
38 #include "BKE_scene.h"
39 #include "BKE_unit.h"
40
41 #include "BLF_api.h"
42
43 #include "BLI_math.h"
44 #include "BLI_rect.h"
45 #include "BLI_threads.h"
46
47 #include "DNA_camera_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_object_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_windowmanager_types.h"
52
53 #include "ED_screen.h"
54 #include "ED_transform.h"
55
56 #include "GPU_matrix.h"
57 #include "GPU_immediate.h"
58 #include "GPU_material.h"
59 #include "GPU_viewport.h"
60
61 #include "MEM_guardedalloc.h"
62
63 #include "UI_interface.h"
64 #include "UI_resources.h"
65
66 #include "RE_engine.h"
67
68 #include "WM_api.h"
69
70 #include "view3d_intern.h"  /* own include */
71
72 /* prototypes */
73 static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth);
74
75 typedef struct DrawData {
76         rcti border_rect;
77         bool render_border;
78         bool clip_border;
79         bool is_render;
80         GPUViewport *viewport;
81 } DrawData;
82
83 static void view3d_draw_data_init(const bContext *C, ARegion *ar, RegionView3D *rv3d, DrawData *draw_data)
84 {
85         Scene *scene = CTX_data_scene(C);
86         View3D *v3d = CTX_wm_view3d(C);
87
88         draw_data->is_render = (v3d->drawtype == OB_RENDER);
89
90         draw_data->render_border = ED_view3d_calc_render_border(scene, v3d, ar, &draw_data->border_rect);
91         draw_data->clip_border = (draw_data->render_border && !BLI_rcti_compare(&ar->drawrct, &draw_data->border_rect));
92
93         draw_data->viewport = rv3d->viewport;
94 }
95
96 /* ******************** general functions ***************** */
97
98 static bool use_depth_doit(Scene *scene, View3D *v3d)
99 {
100         if (v3d->drawtype > OB_WIRE)
101                 return true;
102
103         /* special case (depth for wire color) */
104         if (v3d->drawtype <= OB_WIRE) {
105                 if (scene->obedit && scene->obedit->type == OB_MESH) {
106                         Mesh *me = scene->obedit->data;
107                         if (me->drawflag & ME_DRAWEIGHT) {
108                                 return true;
109                         }
110                 }
111         }
112         return false;
113 }
114
115 static bool use_depth(const bContext *C)
116 {
117         View3D *v3d = CTX_wm_view3d(C);
118         Scene *scene = CTX_data_scene(C);
119         return use_depth_doit(scene, v3d);
120 }
121
122 /**
123  * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
124  */
125 void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
126 {
127         RegionView3D *rv3d = ar->regiondata;
128
129
130         /* setup window matrices */
131         if (winmat)
132                 copy_m4_m4(rv3d->winmat, winmat);
133         else
134                 view3d_winmatrix_set(ar, v3d, NULL);
135
136         /* setup view matrix */
137         if (viewmat)
138                 copy_m4_m4(rv3d->viewmat, viewmat);
139         else
140                 view3d_viewmatrix_set(scene, v3d, rv3d);  /* note: calls BKE_object_where_is_calc for camera... */
141
142         /* update utility matrices */
143         mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
144         invert_m4_m4(rv3d->persinv, rv3d->persmat);
145         invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
146
147         /* calculate GLSL view dependent values */
148
149         /* store window coordinates scaling/offset */
150         if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
151                 rctf cameraborder;
152                 ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
153                 rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
154                 rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
155
156                 rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
157                 rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
158         }
159         else {
160                 rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
161                 rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
162         }
163
164         /* calculate pixelsize factor once, is used for lamps and obcenters */
165         {
166                 /* note:  '1.0f / len_v3(v1)'  replaced  'len_v3(rv3d->viewmat[0])'
167                 * because of float point precision problems at large values [#23908] */
168                 float v1[3], v2[3];
169                 float len_px, len_sc;
170
171                 v1[0] = rv3d->persmat[0][0];
172                 v1[1] = rv3d->persmat[1][0];
173                 v1[2] = rv3d->persmat[2][0];
174
175                 v2[0] = rv3d->persmat[0][1];
176                 v2[1] = rv3d->persmat[1][1];
177                 v2[2] = rv3d->persmat[2][1];
178
179                 len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
180                 len_sc = (float)MAX2(ar->winx, ar->winy);
181
182                 rv3d->pixsize = len_px / len_sc;
183         }
184 }
185
186 static void view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
187 {
188         RegionView3D *rv3d = ar->regiondata;
189
190         ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat);
191
192         /* set for opengl */
193         glMatrixMode(GL_PROJECTION);
194         glLoadMatrixf(rv3d->winmat);
195         glMatrixMode(GL_MODELVIEW);
196         glLoadMatrixf(rv3d->viewmat);
197 }
198
199 static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
200 {
201         wmWindow *win = CTX_wm_window(C);
202
203         if ((scene->r.scemode & R_MULTIVIEW) == 0)
204                 return false;
205
206         if (WM_stereo3d_enabled(win, true) == false)
207                 return false;
208
209         if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
210                 return false;
211
212         if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
213                 if (v3d->stereo3d_camera == STEREO_MONO_ID)
214                         return false;
215
216                 return BKE_scene_multiview_is_stereo3d(&scene->r);
217         }
218
219         return true;
220 }
221
222 /* setup the view and win matrices for the multiview cameras
223  *
224  * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
225  * we have no winmatrix (i.e., projection matrix) defined at that time.
226  * Since the camera and the camera shift are needed for the winmat calculation
227  * we do a small hack to replace it temporarily so we don't need to change the
228  * view3d)main_region_setup_view() code to account for that.
229  */
230 static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
231 {
232         bool is_left;
233         const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
234         const char *viewname;
235
236         /* show only left or right camera */
237         if (v3d->stereo3d_camera != STEREO_3D_ID)
238                 v3d->multiview_eye = v3d->stereo3d_camera;
239
240         is_left = v3d->multiview_eye == STEREO_LEFT_ID;
241         viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
242
243         /* update the viewport matrices with the new camera */
244         if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
245                 Camera *data;
246                 float viewmat[4][4];
247                 float shiftx;
248
249                 data = (Camera *)v3d->camera->data;
250                 shiftx = data->shiftx;
251
252                 BLI_lock_thread(LOCK_VIEW3D);
253                 data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
254
255                 BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
256                 view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
257
258                 data->shiftx = shiftx;
259                 BLI_unlock_thread(LOCK_VIEW3D);
260         }
261         else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
262                 float viewmat[4][4];
263                 Object *view_ob = v3d->camera;
264                 Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
265
266                 BLI_lock_thread(LOCK_VIEW3D);
267                 v3d->camera = camera;
268
269                 BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
270                 view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
271
272                 v3d->camera = view_ob;
273                 BLI_unlock_thread(LOCK_VIEW3D);
274         }
275 }
276
277 /* ******************** debug ***************** */
278
279 #define VIEW3D_DRAW_DEBUG 1
280 /* TODO: expand scope of this flag so UI reflects the underlying code */
281
282 #if VIEW3D_DRAW_DEBUG
283
284 static void view3d_draw_debug_store_depth(ARegion *ar, DrawData *draw_data)
285 {
286         GPUViewport *viewport = draw_data->viewport;
287         GLint viewport_size[4];
288         glGetIntegerv(GL_VIEWPORT, viewport_size);
289
290         const int x = viewport_size[0];
291         const int y = viewport_size[1];
292         const int w = viewport_size[2];
293         const int h = viewport_size[3];
294
295         if (GPU_viewport_debug_depth_is_valid(viewport)) {
296                 if ((GPU_viewport_debug_depth_width(viewport) != w) ||
297                         (GPU_viewport_debug_depth_height(viewport) != h))
298                 {
299                         GPU_viewport_debug_depth_free(viewport);
300                 }
301         }
302
303         if (!GPU_viewport_debug_depth_is_valid(viewport)) {
304                 char error[256];
305                 if (!GPU_viewport_debug_depth_create(viewport, w, h, 0, error)) {
306                         fprintf(stderr, "Failed to create depth buffer for debug: %s\n", error);
307                         return;
308                 }
309         }
310
311         GPU_viewport_debug_depth_store(viewport, x, y);
312 }
313
314 static void view3d_draw_debug_post_solid(const bContext *C, ARegion *ar, DrawData *draw_data)
315 {
316         View3D *v3d = CTX_wm_view3d(C);
317
318         if ((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_SCENE_DEPTH) != 0) {
319                 view3d_draw_debug_store_depth(ar, draw_data);
320         }
321 }
322
323 static void view3d_draw_debug(const bContext *C, ARegion *ar, DrawData *draw_data)
324 {
325         View3D *v3d = CTX_wm_view3d(C);
326
327         if ((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_COMBINED_DEPTH) != 0) {
328                 /* store */
329                 view3d_draw_debug_store_depth(ar, draw_data);
330         }
331
332         if (((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_SCENE_DEPTH) != 0) ||
333                 ((v3d->tmp_compat_flag & V3D_DEBUG_SHOW_COMBINED_DEPTH) != 0))
334         {
335                 /* draw */
336                 if (GPU_viewport_debug_depth_is_valid(draw_data->viewport)) {
337                         GPU_viewport_debug_depth_draw(draw_data->viewport, v3d->debug.znear, v3d->debug.zfar);
338                 }
339         }
340         else {
341                 /* cleanup */
342                 GPU_viewport_debug_depth_free(draw_data->viewport);
343         }
344 }
345
346 #endif /* VIEW3D_DRAW_DEBUG */
347
348 /* ******************** view border ***************** */
349
350 static void view3d_camera_border(
351         const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
352         rctf *r_viewborder, const bool no_shift, const bool no_zoom)
353 {
354         CameraParams params;
355         rctf rect_view, rect_camera;
356
357         /* get viewport viewplane */
358         BKE_camera_params_init(&params);
359         BKE_camera_params_from_view3d(&params, v3d, rv3d);
360         if (no_zoom)
361                 params.zoom = 1.0f;
362         BKE_camera_params_compute_viewplane(&params, ar->winx, ar->winy, 1.0f, 1.0f);
363         rect_view = params.viewplane;
364
365         /* get camera viewplane */
366         BKE_camera_params_init(&params);
367         /* fallback for non camera objects */
368         params.clipsta = v3d->near;
369         params.clipend = v3d->far;
370         BKE_camera_params_from_object(&params, v3d->camera);
371         if (no_shift) {
372                 params.shiftx = 0.0f;
373                 params.shifty = 0.0f;
374         }
375         BKE_camera_params_compute_viewplane(&params, scene->r.xsch, scene->r.ysch, scene->r.xasp, scene->r.yasp);
376         rect_camera = params.viewplane;
377
378         /* get camera border within viewport */
379         r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
380         r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
381         r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
382         r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
383 }
384
385 void ED_view3d_calc_camera_border_size(
386         const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
387         float r_size[2])
388 {
389         rctf viewborder;
390
391         view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, true, true);
392         r_size[0] = BLI_rctf_size_x(&viewborder);
393         r_size[1] = BLI_rctf_size_y(&viewborder);
394 }
395
396 void ED_view3d_calc_camera_border(
397         const Scene *scene, const ARegion *ar, const View3D *v3d, const RegionView3D *rv3d,
398         rctf *r_viewborder, const bool no_shift)
399 {
400         view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false);
401 }
402
403 static void drawviewborder_grid3(unsigned pos, float x1, float x2, float y1, float y2, float fac)
404 {
405         float x3, y3, x4, y4;
406
407         x3 = x1 + fac * (x2 - x1);
408         y3 = y1 + fac * (y2 - y1);
409         x4 = x1 + (1.0f - fac) * (x2 - x1);
410         y4 = y1 + (1.0f - fac) * (y2 - y1);
411
412         immBegin(GL_LINES, 8);
413         immVertex2f(pos, x1, y3);
414         immVertex2f(pos, x2, y3);
415
416         immVertex2f(pos, x1, y4);
417         immVertex2f(pos, x2, y4);
418
419         immVertex2f(pos, x3, y1);
420         immVertex2f(pos, x3, y2);
421
422         immVertex2f(pos, x4, y1);
423         immVertex2f(pos, x4, y2);
424         immEnd();
425 }
426
427 /* harmonious triangle */
428 static void drawviewborder_triangle(unsigned pos, float x1, float x2, float y1, float y2, const char golden, const char dir)
429 {
430         float ofs;
431         float w = x2 - x1;
432         float h = y2 - y1;
433
434         immBegin(GL_LINES, 6);
435         if (w > h) {
436                 if (golden) {
437                         ofs = w * (1.0f - (1.0f / 1.61803399f));
438                 }
439                 else {
440                         ofs = h * (h / w);
441                 }
442                 if (dir == 'B') SWAP(float, y1, y2);
443
444                 immVertex2f(pos, x1, y1);
445                 immVertex2f(pos, x2, y2);
446
447                 immVertex2f(pos, x2, y1);
448                 immVertex2f(pos, x1 + (w - ofs), y2);
449
450                 immVertex2f(pos, x1, y2);
451                 immVertex2f(pos, x1 + ofs, y1);
452         }
453         else {
454                 if (golden) {
455                         ofs = h * (1.0f - (1.0f / 1.61803399f));
456                 }
457                 else {
458                         ofs = w * (w / h);
459                 }
460                 if (dir == 'B') SWAP(float, x1, x2);
461
462                 immVertex2f(pos, x1, y1);
463                 immVertex2f(pos, x2, y2);
464
465                 immVertex2f(pos, x2, y1);
466                 immVertex2f(pos, x1, y1 + ofs);
467
468                 immVertex2f(pos, x1, y2);
469                 immVertex2f(pos, x2, y1 + (h - ofs));
470         }
471         immEnd();
472 }
473
474 static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
475 {
476         float x1, x2, y1, y2;
477         float x1i, x2i, y1i, y2i;
478
479         rctf viewborder;
480         Camera *ca = NULL;
481         RegionView3D *rv3d = ar->regiondata;
482
483         if (v3d->camera == NULL)
484                 return;
485         if (v3d->camera->type == OB_CAMERA)
486                 ca = v3d->camera->data;
487
488         ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
489         /* the offsets */
490         x1 = viewborder.xmin;
491         y1 = viewborder.ymin;
492         x2 = viewborder.xmax;
493         y2 = viewborder.ymax;
494
495         glLineWidth(1.0f);
496
497         /* apply offsets so the real 3D camera shows through */
498
499         /* note: quite un-scientific but without this bit extra
500          * 0.0001 on the lower left the 2D border sometimes
501          * obscures the 3D camera border */
502         /* note: with VIEW3D_CAMERA_BORDER_HACK defined this error isn't noticeable
503          * but keep it here in case we need to remove the workaround */
504         x1i = (int)(x1 - 1.0001f);
505         y1i = (int)(y1 - 1.0001f);
506         x2i = (int)(x2 + (1.0f - 0.0001f));
507         y2i = (int)(y2 + (1.0f - 0.0001f));
508
509         /* use the same program for everything */
510         unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
511         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
512
513         /* passepartout, specified in camera edit buttons */
514         if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
515                 const float winx = (ar->winx + 1);
516                 const float winy = (ar->winy + 1);
517
518                 float alpha = 1.0f;
519
520                 if (ca->passepartalpha != 1.0f) {
521                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
522                         glEnable(GL_BLEND);
523                         alpha = ca->passepartalpha;
524                 }
525
526                 immUniformColor4f(0.0f, 0.0f, 0.0f, alpha);
527
528                 if (x1i > 0.0f)
529                         immRectf(pos, 0.0f, winy, x1i, 0.0f);
530                 if (x2i < winx)
531                         immRectf(pos, x2i, winy, winx, 0.0f);
532                 if (y2i < winy)
533                         immRectf(pos, x1i, winy, x2i, y2i);
534                 if (y2i > 0.0f)
535                         immRectf(pos, x1i, y1i, x2i, 0.0f);
536
537                 glDisable(GL_BLEND);
538         }
539
540         setlinestyle(0);
541
542         immUniformThemeColor(TH_BACK);
543         imm_draw_line_box(pos, x1i, y1i, x2i, y2i);
544
545 #ifdef VIEW3D_CAMERA_BORDER_HACK
546         if (view3d_camera_border_hack_test == true) {
547                 immUniformColor3ubv(view3d_camera_border_hack_col);
548                 imm_draw_line_box(pos, x1i + 1, y1i + 1, x2i - 1, y2i - 1);
549                 view3d_camera_border_hack_test = false;
550         }
551 #endif
552
553         setlinestyle(3);
554
555         /* outer line not to confuse with object selecton */
556         if (v3d->flag2 & V3D_LOCK_CAMERA) {
557                 immUniformThemeColor(TH_REDALERT);
558                 imm_draw_line_box(pos, x1i - 1, y1i - 1, x2i + 1, y2i + 1);
559         }
560
561         immUniformThemeColor(TH_VIEW_OVERLAY);
562         imm_draw_line_box(pos, x1i, y1i, x2i, y2i);
563
564         /* border */
565         if (scene->r.mode & R_BORDER) {
566                 float x3, y3, x4, y4;
567
568                 x3 = floorf(x1 + (scene->r.border.xmin * (x2 - x1))) - 1;
569                 y3 = floorf(y1 + (scene->r.border.ymin * (y2 - y1))) - 1;
570                 x4 = floorf(x1 + (scene->r.border.xmax * (x2 - x1))) + (U.pixelsize - 1);
571                 y4 = floorf(y1 + (scene->r.border.ymax * (y2 - y1))) + (U.pixelsize - 1);
572
573                 imm_cpack(0x4040FF);
574                 imm_draw_line_box(pos, x3, y3, x4, y4);
575         }
576
577         /* safety border */
578         if (ca) {
579                 if (ca->dtx & CAM_DTX_CENTER) {
580                         float x3, y3;
581
582                         x3 = x1 + 0.5f * (x2 - x1);
583                         y3 = y1 + 0.5f * (y2 - y1);
584
585                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
586                         immBegin(GL_LINES, 4);
587
588                         immVertex2f(pos, x1, y3);
589                         immVertex2f(pos, x2, y3);
590
591                         immVertex2f(pos, x3, y1);
592                         immVertex2f(pos, x3, y2);
593
594                         immEnd();
595                 }
596
597                 if (ca->dtx & CAM_DTX_CENTER_DIAG) {
598
599                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
600                         immBegin(GL_LINES, 4);
601
602                         immVertex2f(pos, x1, y1);
603                         immVertex2f(pos, x2, y2);
604
605                         immVertex2f(pos, x1, y2);
606                         immVertex2f(pos, x2, y1);
607
608                         immEnd();
609                 }
610
611                 if (ca->dtx & CAM_DTX_THIRDS) {
612                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
613                         drawviewborder_grid3(pos, x1, x2, y1, y2, 1.0f / 3.0f);
614                 }
615
616                 if (ca->dtx & CAM_DTX_GOLDEN) {
617                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
618                         drawviewborder_grid3(pos, x1, x2, y1, y2, 1.0f - (1.0f / 1.61803399f));
619                 }
620
621                 if (ca->dtx & CAM_DTX_GOLDEN_TRI_A) {
622                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
623                         drawviewborder_triangle(pos, x1, x2, y1, y2, 0, 'A');
624                 }
625
626                 if (ca->dtx & CAM_DTX_GOLDEN_TRI_B) {
627                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
628                         drawviewborder_triangle(pos, x1, x2, y1, y2, 0, 'B');
629                 }
630
631                 if (ca->dtx & CAM_DTX_HARMONY_TRI_A) {
632                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
633                         drawviewborder_triangle(pos, x1, x2, y1, y2, 1, 'A');
634                 }
635
636                 if (ca->dtx & CAM_DTX_HARMONY_TRI_B) {
637                         immUniformThemeColorBlendShade(TH_VIEW_OVERLAY, TH_BACK, 0.25f, 0);
638                         drawviewborder_triangle(pos, x1, x2, y1, y2, 1, 'B');
639                 }
640
641                 if (ca->flag & CAM_SHOW_SAFE_MARGINS) {
642                         UI_draw_safe_areas(
643                                 pos, x1, x2, y1, y2,
644                                 scene->safe_areas.title,
645                                 scene->safe_areas.action);
646
647                         if (ca->flag & CAM_SHOW_SAFE_CENTER) {
648                                 UI_draw_safe_areas(
649                                         pos, x1, x2, y1, y2,
650                                         scene->safe_areas.title_center,
651                                         scene->safe_areas.action_center);
652                         }
653                 }
654
655                 if (ca->flag & CAM_SHOWSENSOR) {
656                         /* determine sensor fit, and get sensor x/y, for auto fit we
657                          * assume and square sensor and only use sensor_x */
658                         float sizex = scene->r.xsch * scene->r.xasp;
659                         float sizey = scene->r.ysch * scene->r.yasp;
660                         int sensor_fit = BKE_camera_sensor_fit(ca->sensor_fit, sizex, sizey);
661                         float sensor_x = ca->sensor_x;
662                         float sensor_y = (ca->sensor_fit == CAMERA_SENSOR_FIT_AUTO) ? ca->sensor_x : ca->sensor_y;
663
664                         /* determine sensor plane */
665                         rctf rect;
666
667                         if (sensor_fit == CAMERA_SENSOR_FIT_HOR) {
668                                 float sensor_scale = (x2i - x1i) / sensor_x;
669                                 float sensor_height = sensor_scale * sensor_y;
670
671                                 rect.xmin = x1i;
672                                 rect.xmax = x2i;
673                                 rect.ymin = (y1i + y2i) * 0.5f - sensor_height * 0.5f;
674                                 rect.ymax = rect.ymin + sensor_height;
675                         }
676                         else {
677                                 float sensor_scale = (y2i - y1i) / sensor_y;
678                                 float sensor_width = sensor_scale * sensor_x;
679
680                                 rect.xmin = (x1i + x2i) * 0.5f - sensor_width * 0.5f;
681                                 rect.xmax = rect.xmin + sensor_width;
682                                 rect.ymin = y1i;
683                                 rect.ymax = y2i;
684                         }
685
686                         /* draw */
687                         float color[4];
688                         UI_GetThemeColorShade4fv(TH_VIEW_OVERLAY, 100, color);
689                         UI_draw_roundbox_gl_mode(GL_LINE_LOOP, rect.xmin, rect.ymin, rect.xmax, rect.ymax, 2.0f, color);
690                 }
691         }
692
693         setlinestyle(0);
694
695         /* camera name - draw in highlighted text color */
696         if (ca && (ca->flag & CAM_SHOWNAME)) {
697                 UI_ThemeColor(TH_TEXT_HI);
698                 BLF_draw_default(
699                         x1i, y1i - (0.7f * U.widget_unit), 0.0f,
700                         v3d->camera->id.name + 2, sizeof(v3d->camera->id.name) - 2);
701         }
702
703         immUnbindProgram();
704 }
705
706 static void drawrenderborder(ARegion *ar, View3D *v3d)
707 {
708         /* use the same program for everything */
709         unsigned pos = add_attrib(immVertexFormat(), "pos", COMP_F32, 2, KEEP_FLOAT);
710         immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
711
712         glLineWidth(1.0f);
713         setlinestyle(3);
714         imm_cpack(0x4040FF);
715
716         imm_draw_line_box(
717             pos, v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy,
718             v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy);
719
720         setlinestyle(0);
721
722         immUnbindProgram();
723 }
724
725 /* ******************** offline engine ***************** */
726
727 static bool view3d_draw_render_draw(const bContext *C, Scene *scene,
728         ARegion *ar, View3D *v3d,
729         bool clip_border, const rcti *border_rect)
730 {
731         RegionView3D *rv3d = ar->regiondata;
732         RenderEngineType *type;
733         GLint scissor[4];
734
735         /* create render engine */
736         if (!rv3d->render_engine) {
737                 RenderEngine *engine;
738
739                 type = RE_engines_find(scene->r.engine);
740
741                 if (!(type->view_update && type->view_draw))
742                         return false;
743
744                 engine = RE_engine_create_ex(type, true);
745
746                 engine->tile_x = scene->r.tilex;
747                 engine->tile_y = scene->r.tiley;
748
749                 type->view_update(engine, C);
750
751                 rv3d->render_engine = engine;
752         }
753
754         /* background draw */
755         glMatrixMode(GL_PROJECTION);
756         glPushMatrix();
757         glMatrixMode(GL_MODELVIEW);
758         glPushMatrix();
759         ED_region_pixelspace(ar);
760
761         if (clip_border) {
762                 /* for border draw, we only need to clear a subset of the 3d view */
763                 if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
764                         glGetIntegerv(GL_SCISSOR_BOX, scissor);
765                         glScissor(border_rect->xmin, border_rect->ymin,
766                                 BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
767                 }
768                 else {
769                         return false;
770                 }
771         }
772
773         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
774         /* don't change depth buffer */
775         glClear(GL_COLOR_BUFFER_BIT); /* is this necessary? -- merwin */
776
777         /* render result draw */
778         type = rv3d->render_engine->type;
779         type->view_draw(rv3d->render_engine, C);
780
781         if (clip_border) {
782                 /* restore scissor as it was before */
783                 glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
784         }
785
786         glMatrixMode(GL_PROJECTION);
787         glPopMatrix();
788         glMatrixMode(GL_MODELVIEW);
789         glPopMatrix();
790
791         return true;
792 }
793
794 /* ******************** background plates ***************** */
795
796 static void view3d_draw_background_gradient()
797 {
798         gpuMatrixBegin3D(); /* TODO: finish 2D API */
799
800         glClear(GL_DEPTH_BUFFER_BIT);
801
802         VertexFormat *format = immVertexFormat();
803         unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
804         unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
805         unsigned char col_hi[3], col_lo[3];
806
807         immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR);
808
809         UI_GetThemeColor3ubv(TH_LOW_GRAD, col_lo);
810         UI_GetThemeColor3ubv(TH_HIGH_GRAD, col_hi);
811
812         immBegin(GL_QUADS, 4);
813         immAttrib3ubv(color, col_lo);
814         immVertex2f(pos, -1.0f, -1.0f);
815         immVertex2f(pos, 1.0f, -1.0f);
816
817         immAttrib3ubv(color, col_hi);
818         immVertex2f(pos, 1.0f, 1.0f);
819         immVertex2f(pos, -1.0f, 1.0f);
820         immEnd();
821
822         immUnbindProgram();
823
824         gpuMatrixEnd();
825 }
826
827 static void view3d_draw_background_none()
828 {
829         if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
830                 view3d_draw_background_gradient();
831         }
832         else {
833                 UI_ThemeClearColorAlpha(TH_HIGH_GRAD, 1.0f);
834                 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
835         }
836 }
837
838 static void view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
839 {
840         if (scene->world) {
841                 GPUMaterial *gpumat = GPU_material_world(scene, scene->world);
842
843                 /* calculate full shader for background */
844                 GPU_material_bind(gpumat, 1, 1, 1.0f, false, rv3d->viewmat, rv3d->viewinv, rv3d->viewcamtexcofac, (v3d->scenelock != 0));
845
846                 if (GPU_material_bound(gpumat)) {
847
848                         glClear(GL_DEPTH_BUFFER_BIT);
849
850                         /* TODO viewport (dfelinto): GPU_material_bind relies on immediate mode,
851                         * we can't get rid of the following code without a bigger refactor
852                         * or we dropping this functionality. */
853
854                         glBegin(GL_TRIANGLE_STRIP);
855                         glVertex2f(-1.0f, -1.0f);
856                         glVertex2f(1.0f, -1.0f);
857                         glVertex2f(-1.0f, 1.0f);
858                         glVertex2f(1.0f, 1.0f);
859                         glEnd();
860
861                         GPU_material_unbind(gpumat);
862                 }
863                 else {
864                         view3d_draw_background_none();
865                 }
866         }
867         else {
868                 view3d_draw_background_none();
869         }
870 }
871
872 /* ******************** solid plates ***************** */
873
874 /**
875  * Clear the buffer and draw the proper shader
876  */
877 static void view3d_draw_background(const bContext *C)
878 {
879         Scene *scene = CTX_data_scene(C);
880         View3D *v3d = CTX_wm_view3d(C);
881         RegionView3D *rv3d = CTX_wm_region_view3d(C);
882
883         glDisable(GL_DEPTH_TEST);
884         glDepthMask(GL_TRUE);
885         /* Background functions do not read or write depth, but they do clear or completely
886          * overwrite color buffer. It's more efficient to clear color & depth in once call, so
887          * background functions do this even though they don't use depth.
888          */
889
890         switch (v3d->debug.background) {
891                 case V3D_DEBUG_BACKGROUND_WORLD:
892                         view3d_draw_background_world(scene, v3d, rv3d);
893                         break;
894                 case V3D_DEBUG_BACKGROUND_GRADIENT:
895                         view3d_draw_background_gradient();
896                         break;
897                 case V3D_DEBUG_BACKGROUND_NONE:
898                 default:
899                         view3d_draw_background_none();
900                         break;
901         }
902 }
903
904 /**
905  *
906  */
907 static void view3d_draw_render_solid_surfaces(const bContext *C, ARegion *ar, const bool run_screen_shaders)
908 {
909         /* TODO viewport */
910         draw_all_objects(C, ar, false, use_depth(C));
911 }
912
913 /**
914  *
915  */
916 static void view3d_draw_render_transparent_surfaces(const bContext *C)
917 {
918         /* TODO viewport */
919 }
920
921 /**
922  *
923  */
924 static void view3d_draw_post_draw(const bContext *C)
925 {
926         /* TODO viewport */
927 }
928
929 /* ******************** geometry overlay ***************** */
930
931 /**
932  * Front/back wire frames
933  */
934 static void view3d_draw_wire_plates(const bContext *C)
935 {
936         /* TODO viewport */
937 }
938
939 /**
940  * Special treatment for selected objects
941  */
942 static void view3d_draw_outline_plates(const bContext *C)
943 {
944         /* TODO viewport */
945 }
946
947 /* ******************** other elements ***************** */
948
949
950 #define DEBUG_GRID 0
951
952 static void gridline_range(double x0, double dx, double max, int* first_out, int* count_out)
953 {
954         /* determine range of gridlines that appear in this Area -- similar calc but separate ranges for x & y
955         * x0 is gridline 0, the axis in screen space
956         * Area covers [0 .. max) pixels */
957
958         int first = (int)ceil(-x0 / dx);
959         int last = (int)floor((max - x0) / dx);
960
961         if (first <= last) {
962                 *first_out = first;
963                 *count_out = last - first + 1;
964         }
965         else {
966                 *first_out = 0;
967                 *count_out = 0;
968         }
969
970 #if DEBUG_GRID
971         printf("   first %d * dx = %f\n", first, x0 + first * dx);
972         printf("   last %d * dx = %f\n", last, x0 + last * dx);
973         printf("   count = %d\n", *count_out);
974 #endif
975 }
976
977 static int gridline_count(ARegion *ar, double x0, double y0, double dx)
978 {
979         /* x0 & y0 establish the "phase" of the grid within this 2D region
980         * dx is the frequency, shared by x & y directions
981         * pass in dx of smallest (highest precision) grid we want to draw */
982
983 #if DEBUG_GRID
984         printf("  %s(%f, %f, dx:%f)\n", __FUNCTION__, x0, y0, dx);
985 #endif
986
987         int first, x_ct, y_ct;
988
989         gridline_range(x0, dx, ar->winx, &first, &x_ct);
990         gridline_range(y0, dx, ar->winy, &first, &y_ct);
991
992         int total_ct = x_ct + y_ct;
993
994 #if DEBUG_GRID
995         printf("   %d + %d = %d gridlines\n", x_ct, y_ct, total_ct);
996 #endif
997
998         return total_ct;
999 }
1000
1001 static bool drawgrid_draw(ARegion *ar, double x0, double y0, double dx, int skip_mod, unsigned pos, unsigned col, GLubyte col_value[3])
1002 {
1003         /* skip every skip_mod lines relative to each axis; they will be overlaid by another drawgrid_draw
1004         * always skip exact x0 & y0 axes; they will be drawn later in color
1005         *
1006         * set grid color once, just before the first line is drawn
1007         * it's harmless to set same color for every line, or every vertex
1008         * but if no lines are drawn, color must not be set! */
1009
1010 #if DEBUG_GRID
1011         printf("  %s(%f, %f, dx:%f, skip_mod:%d)\n", __FUNCTION__, x0, y0, dx, skip_mod);
1012 #endif
1013
1014         const float x_max = (float)ar->winx;
1015         const float y_max = (float)ar->winy;
1016
1017         int first, ct;
1018         int x_ct = 0, y_ct = 0; /* count of lines actually drawn */
1019         int lines_skipped_for_next_unit = 0;
1020
1021         /* draw vertical lines */
1022         gridline_range(x0, dx, x_max, &first, &ct);
1023
1024         for (int i = first; i < first + ct; ++i) {
1025                 if (i == 0)
1026                         continue;
1027                 else if (skip_mod && (i % skip_mod) == 0) {
1028                         ++lines_skipped_for_next_unit;
1029                         continue;
1030                 }
1031
1032                 if (x_ct == 0)
1033                         immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
1034
1035                 float x = (float)(x0 + i * dx);
1036                 immVertex2f(pos, x, 0.0f);
1037                 immVertex2f(pos, x, y_max);
1038                 ++x_ct;
1039         }
1040
1041         /* draw horizontal lines */
1042         gridline_range(y0, dx, y_max, &first, &ct);
1043
1044         for (int i = first; i < first + ct; ++i) {
1045                 if (i == 0)
1046                         continue;
1047                 else if (skip_mod && (i % skip_mod) == 0) {
1048                         ++lines_skipped_for_next_unit;
1049                         continue;
1050                 }
1051
1052                 if (x_ct + y_ct == 0)
1053                         immAttrib3ub(col, col_value[0], col_value[1], col_value[2]);
1054
1055                 float y = (float)(y0 + i * dx);
1056                 immVertex2f(pos, 0.0f, y);
1057                 immVertex2f(pos, x_max, y);
1058                 ++y_ct;
1059         }
1060
1061 #if DEBUG_GRID
1062         int total_ct = x_ct + y_ct;
1063         printf("    %d + %d = %d gridlines drawn, %d skipped for next unit\n", x_ct, y_ct, total_ct, lines_skipped_for_next_unit);
1064 #endif
1065
1066         return lines_skipped_for_next_unit > 0;
1067 }
1068
1069 #define GRID_MIN_PX_D 6.0
1070 #define GRID_MIN_PX_F 6.0f
1071
1072 static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
1073 {
1074         RegionView3D *rv3d = ar->regiondata;
1075
1076 #if DEBUG_GRID
1077         printf("%s width %d, height %d\n", __FUNCTION__, ar->winx, ar->winy);
1078 #endif
1079
1080         double fx = rv3d->persmat[3][0];
1081         double fy = rv3d->persmat[3][1];
1082         double fw = rv3d->persmat[3][3];
1083
1084         const double wx = 0.5 * ar->winx;  /* use double precision to avoid rounding errors */
1085         const double wy = 0.5 * ar->winy;
1086
1087         double x = wx * fx / fw;
1088         double y = wy * fy / fw;
1089
1090         double vec4[4] = { v3d->grid, v3d->grid, 0.0, 1.0 };
1091         mul_m4_v4d(rv3d->persmat, vec4);
1092         fx = vec4[0];
1093         fy = vec4[1];
1094         fw = vec4[3];
1095
1096         double dx = fabs(x - wx * fx / fw);
1097         if (dx == 0) dx = fabs(y - wy * fy / fw);
1098
1099         x += wx;
1100         y += wy;
1101
1102         /* now x, y, and dx have their final values
1103         * (x,y) is the world origin (0,0,0) mapped to Area-relative screen space
1104         * dx is the distance in pixels between grid lines -- same for horiz or vert grid lines */
1105
1106         glLineWidth(1.0f);
1107
1108 #if 0 /* TODO: write to UI/widget depth buffer, not scene depth */
1109         glDepthMask(GL_FALSE);  /* disable write in zbuffer */
1110 #endif
1111
1112         VertexFormat* format = immVertexFormat();
1113         unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
1114         unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
1115
1116         immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
1117
1118         unsigned char col[3], col2[3];
1119         UI_GetThemeColor3ubv(TH_GRID, col);
1120
1121         if (unit->system) {
1122                 const void *usys;
1123                 int len;
1124
1125                 bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
1126
1127                 bool first = true;
1128
1129                 if (usys) {
1130                         int i = len;
1131                         while (i--) {
1132                                 double scalar = bUnit_GetScaler(usys, i);
1133
1134                                 double dx_scalar = dx * scalar / (double)unit->scale_length;
1135                                 if (dx_scalar < (GRID_MIN_PX_D * 2.0)) {
1136                                         /* very very small grid items are less useful when dealing with units */
1137                                         continue;
1138                                 }
1139
1140                                 if (first) {
1141                                         first = false;
1142
1143                                         /* Store the smallest drawn grid size units name so users know how big each grid cell is */
1144                                         *grid_unit = bUnit_GetNameDisplay(usys, i);
1145                                         rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
1146
1147                                         int gridline_ct = gridline_count(ar, x, y, dx_scalar);
1148                                         if (gridline_ct == 0)
1149                                                 goto drawgrid_cleanup; /* nothing to draw */
1150
1151                                         immBegin(GL_LINES, gridline_ct * 2);
1152                                 }
1153
1154                                 float blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
1155                                 /* tweak to have the fade a bit nicer */
1156                                 blend_fac = (blend_fac * blend_fac) * 2.0f;
1157                                 CLAMP(blend_fac, 0.3f, 1.0f);
1158
1159                                 UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, blend_fac, col2);
1160
1161                                 const int skip_mod = (i == 0) ? 0 : (int)round(bUnit_GetScaler(usys, i - 1) / scalar);
1162 #if DEBUG_GRID
1163                                 printf("%s %f, ", bUnit_GetNameDisplay(usys, i), scalar);
1164                                 if (i > 0)
1165                                         printf("next unit is %d times larger\n", skip_mod);
1166                                 else
1167                                         printf("largest unit\n");
1168 #endif
1169                                 if (!drawgrid_draw(ar, x, y, dx_scalar, skip_mod, pos, color, col2))
1170                                         break;
1171                         }
1172                 }
1173         }
1174         else {
1175                 const double sublines = v3d->gridsubdiv;
1176                 const float  sublines_fl = v3d->gridsubdiv;
1177
1178                 int grids_to_draw = 2; /* first the faint fine grid, then the bold coarse grid */
1179
1180                 if (dx < GRID_MIN_PX_D) {
1181                         rv3d->gridview *= sublines_fl;
1182                         dx *= sublines;
1183                         if (dx < GRID_MIN_PX_D) {
1184                                 rv3d->gridview *= sublines_fl;
1185                                 dx *= sublines;
1186                                 if (dx < GRID_MIN_PX_D) {
1187                                         rv3d->gridview *= sublines_fl;
1188                                         dx *= sublines;
1189                                         grids_to_draw = (dx < GRID_MIN_PX_D) ? 0 : 1;
1190                                 }
1191                         }
1192                 }
1193                 else {
1194                         if (dx >(GRID_MIN_PX_D * 10.0)) {  /* start blending in */
1195                                 rv3d->gridview /= sublines_fl;
1196                                 dx /= sublines;
1197                                 if (dx > (GRID_MIN_PX_D * 10.0)) {  /* start blending in */
1198                                         rv3d->gridview /= sublines_fl;
1199                                         dx /= sublines;
1200                                         if (dx > (GRID_MIN_PX_D * 10.0)) {
1201                                                 grids_to_draw = 1;
1202                                         }
1203                                 }
1204                         }
1205                 }
1206
1207                 int gridline_ct = gridline_count(ar, x, y, dx);
1208                 if (gridline_ct == 0)
1209                         goto drawgrid_cleanup; /* nothing to draw */
1210
1211                 immBegin(GL_LINES, gridline_ct * 2);
1212
1213                 if (grids_to_draw == 2) {
1214                         UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
1215                         if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2))
1216                                 drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
1217                 }
1218                 else if (grids_to_draw == 1) {
1219                         drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
1220                 }
1221         }
1222
1223         /* draw visible axes */
1224         /* horizontal line */
1225         if (0 <= y && y < ar->winy) {
1226                 UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
1227                 immAttrib3ub(color, col2[0], col2[1], col2[2]);
1228                 immVertex2f(pos, 0.0f, y);
1229                 immVertex2f(pos, (float)ar->winx, y);
1230         }
1231
1232         /* vertical line */
1233         if (0 <= x && x < ar->winx) {
1234                 UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
1235                 immAttrib3ub(color, col2[0], col2[1], col2[2]);
1236                 immVertex2f(pos, x, 0.0f);
1237                 immVertex2f(pos, x, (float)ar->winy);
1238         }
1239
1240         immEnd();
1241
1242 drawgrid_cleanup:
1243         immUnbindProgram();
1244
1245 #if 0 /* depth write is left enabled above */
1246         glDepthMask(GL_TRUE);  /* enable write in zbuffer */
1247 #endif
1248 }
1249
1250 #undef DEBUG_GRID
1251 #undef GRID_MIN_PX_D
1252 #undef GRID_MIN_PX_F
1253
1254 static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
1255 {
1256         /* draw only if there is something to draw */
1257         if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
1258                 /* draw how many lines?
1259                 * trunc(v3d->gridlines / 2) * 4
1260                 * + 2 for xy axes (possibly with special colors)
1261                 * + 1 for z axis (the only line not in xy plane)
1262                 * even v3d->gridlines are honored, odd rounded down */
1263                 const int gridlines = v3d->gridlines / 2;
1264                 const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
1265                 const float grid = gridlines * grid_scale;
1266
1267                 const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
1268
1269                 bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
1270                 bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
1271                 bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
1272
1273                 unsigned char col_grid[3], col_axis[3];
1274
1275                 glLineWidth(1.0f);
1276
1277                 UI_GetThemeColor3ubv(TH_GRID, col_grid);
1278
1279                 if (!write_depth)
1280                         glDepthMask(GL_FALSE);
1281
1282                 if (show_floor) {
1283                         const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
1284                         const int sublines = v3d->gridsubdiv;
1285
1286                         unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
1287
1288                         VertexFormat* format = immVertexFormat();
1289                         unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
1290                         unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
1291
1292                         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
1293
1294                         immBegin(GL_LINES, vertex_ct);
1295
1296                         /* draw normal grid lines */
1297                         UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
1298
1299                         for (int a = 1; a <= gridlines; a++) {
1300                                 /* skip emphasised divider lines */
1301                                 if (a % sublines != 0) {
1302                                         const float line = a * grid_scale;
1303
1304                                         immAttrib3ubv(color, col_grid_light);
1305
1306                                         immVertex2f(pos, -grid, -line);
1307                                         immVertex2f(pos, +grid, -line);
1308                                         immVertex2f(pos, -grid, +line);
1309                                         immVertex2f(pos, +grid, +line);
1310
1311                                         immVertex2f(pos, -line, -grid);
1312                                         immVertex2f(pos, -line, +grid);
1313                                         immVertex2f(pos, +line, -grid);
1314                                         immVertex2f(pos, +line, +grid);
1315                                 }
1316                         }
1317
1318                         /* draw emphasised grid lines */
1319                         UI_GetThemeColor3ubv(TH_BACK, col_bg);
1320                         /* emphasise division lines lighter instead of darker, if background is darker than grid */
1321                         UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
1322                                 (col_grid[0] + col_grid[1] + col_grid[2] + 30 >
1323                                 col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
1324
1325                         if (sublines <= gridlines) {
1326                                 immAttrib3ubv(color, col_grid_emphasise);
1327
1328                                 for (int a = sublines; a <= gridlines; a += sublines) {
1329                                         const float line = a * grid_scale;
1330
1331                                         immVertex2f(pos, -grid, -line);
1332                                         immVertex2f(pos, +grid, -line);
1333                                         immVertex2f(pos, -grid, +line);
1334                                         immVertex2f(pos, +grid, +line);
1335
1336                                         immVertex2f(pos, -line, -grid);
1337                                         immVertex2f(pos, -line, +grid);
1338                                         immVertex2f(pos, +line, -grid);
1339                                         immVertex2f(pos, +line, +grid);
1340                                 }
1341                         }
1342
1343                         /* draw X axis */
1344                         if (show_axis_x) {
1345                                 show_axis_x = false; /* drawing now, won't need to draw later */
1346                                 UI_make_axis_color(col_grid, col_axis, 'X');
1347                                 immAttrib3ubv(color, col_axis);
1348                         }
1349                         else
1350                                 immAttrib3ubv(color, col_grid_emphasise);
1351
1352                         immVertex2f(pos, -grid, 0.0f);
1353                         immVertex2f(pos, +grid, 0.0f);
1354
1355                         /* draw Y axis */
1356                         if (show_axis_y) {
1357                                 show_axis_y = false; /* drawing now, won't need to draw later */
1358                                 UI_make_axis_color(col_grid, col_axis, 'Y');
1359                                 immAttrib3ubv(color, col_axis);
1360                         }
1361                         else
1362                                 immAttrib3ubv(color, col_grid_emphasise);
1363
1364                         immVertex2f(pos, 0.0f, -grid);
1365                         immVertex2f(pos, 0.0f, +grid);
1366
1367                         immEnd();
1368                         immUnbindProgram();
1369
1370                         /* done with XY plane */
1371                 }
1372
1373                 if (show_axis_x || show_axis_y || show_axis_z) {
1374                         /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
1375
1376                         VertexFormat* format = immVertexFormat();
1377                         unsigned pos = add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
1378                         unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
1379
1380                         immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
1381                         immBegin(GL_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
1382
1383                         if (show_axis_x) {
1384                                 UI_make_axis_color(col_grid, col_axis, 'X');
1385                                 immAttrib3ubv(color, col_axis);
1386                                 immVertex3f(pos, -grid, 0.0f, 0.0f);
1387                                 immVertex3f(pos, +grid, 0.0f, 0.0f);
1388                         }
1389
1390                         if (show_axis_y) {
1391                                 UI_make_axis_color(col_grid, col_axis, 'Y');
1392                                 immAttrib3ubv(color, col_axis);
1393                                 immVertex3f(pos, 0.0f, -grid, 0.0f);
1394                                 immVertex3f(pos, 0.0f, +grid, 0.0f);
1395                         }
1396
1397                         if (show_axis_z) {
1398                                 UI_make_axis_color(col_grid, col_axis, 'Z');
1399                                 immAttrib3ubv(color, col_axis);
1400                                 immVertex3f(pos, 0.0f, 0.0f, -grid);
1401                                 immVertex3f(pos, 0.0f, 0.0f, +grid);
1402                         }
1403
1404                         immEnd();
1405                         immUnbindProgram();
1406                 }
1407
1408                 if (!write_depth)
1409                         glDepthMask(GL_TRUE);
1410         }
1411 }
1412
1413 /** could move this elsewhere, but tied into #ED_view3d_grid_scale */
1414 float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
1415 {
1416         /* apply units */
1417         if (scene->unit.system) {
1418                 const void *usys;
1419                 int len;
1420
1421                 bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
1422
1423                 if (usys) {
1424                         int i = bUnit_GetBaseUnit(usys);
1425                         if (grid_unit)
1426                                 *grid_unit = bUnit_GetNameDisplay(usys, i);
1427                         return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
1428                 }
1429         }
1430
1431         return 1.0f;
1432 }
1433
1434 float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
1435 {
1436         return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
1437 }
1438
1439 /**
1440  *
1441  */
1442 static void view3d_draw_grid(const bContext *C, ARegion *ar)
1443 {
1444         /* TODO viewport
1445          * Missing is the flags to check whether to draw it
1446          * for now now we are using the flags in v3d itself.
1447          *
1448          * Also for now always assume depth is there, so we
1449          * draw on top of it.
1450          */
1451         /**
1452          * Calculate pixel-size factor once, is used for lamps and object centers.
1453          * Used by #ED_view3d_pixel_size and typically not accessed directly.
1454          *
1455          * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
1456          * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
1457          * but in perspective mode its offset by the near-clip.
1458          *
1459          * 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
1460          */
1461         Scene *scene = CTX_data_scene(C);
1462         View3D *v3d = CTX_wm_view3d(C);
1463         RegionView3D *rv3d = ar->regiondata;
1464
1465         const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
1466         const char *grid_unit = NULL;
1467
1468         /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
1469          * objects if done last
1470          * needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views.
1471          */
1472         rv3d->gridview = ED_view3d_grid_scale(scene, v3d, &grid_unit);
1473
1474         glEnable(GL_DEPTH_TEST);
1475         glDepthMask(GL_FALSE); /* read & test depth, but don't alter it. TODO: separate UI depth buffer */
1476
1477         if (!draw_floor) {
1478                 ED_region_pixelspace(ar);
1479                 *(&grid_unit) = NULL;  /* drawgrid need this to detect/affect smallest valid unit... */
1480                 drawgrid(&scene->unit, ar, v3d, &grid_unit);
1481
1482                 glMatrixMode(GL_PROJECTION);
1483                 glLoadMatrixf(rv3d->winmat);
1484                 glMatrixMode(GL_MODELVIEW);
1485                 glLoadMatrixf(rv3d->viewmat);
1486         }
1487         else {
1488                 drawfloor(scene, v3d, &grid_unit, false);
1489         }
1490
1491         glDisable(GL_DEPTH_TEST);
1492 }
1493
1494 /* ******************** non-meshes ***************** */
1495
1496 static void view3d_draw_non_mesh(
1497 Scene *scene, Object *ob, Base *base, View3D *v3d,
1498 RegionView3D *rv3d, const bool is_boundingbox, const unsigned char color[4])
1499 {
1500         glMatrixMode(GL_PROJECTION);
1501         glPushMatrix();
1502         glMatrixMode(GL_MODELVIEW);
1503         glPushMatrix();
1504
1505         /* multiply view with object matrix.
1506         * local viewmat and persmat, to calculate projections */
1507         ED_view3d_init_mats_rv3d_gl(ob, rv3d);
1508
1509         switch (ob->type) {
1510                 case OB_MESH:
1511                 case OB_FONT:
1512                 case OB_CURVE:
1513                 case OB_SURF:
1514                 case OB_MBALL:
1515                         if (is_boundingbox) {
1516                                 draw_bounding_volume(ob, ob->boundtype);
1517                         }
1518                         break;
1519                 case OB_EMPTY:
1520                         drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, color);
1521                         break;
1522                 case OB_LAMP:
1523                         drawlamp(v3d, rv3d, base, OB_SOLID, DRAW_CONSTCOLOR, color, ob == OBACT);
1524                         break;
1525                 case OB_CAMERA:
1526                         drawcamera(scene, v3d, rv3d, base, DRAW_CONSTCOLOR, color);
1527                         break;
1528                 case OB_SPEAKER:
1529                         drawspeaker(color);
1530                         break;
1531                 case OB_LATTICE:
1532                         /* TODO */
1533                         break;
1534                 case OB_ARMATURE:
1535                         /* TODO */
1536                         break;
1537                 default:
1538                 /* TODO Viewport: handle the other cases*/
1539                         break;
1540         }
1541
1542         if (ob->rigidbody_object) {
1543                 draw_rigidbody_shape(ob);
1544         }
1545
1546         ED_view3d_clear_mats_rv3d(rv3d);
1547
1548         glMatrixMode(GL_PROJECTION);
1549         glPopMatrix();
1550         glMatrixMode(GL_MODELVIEW);
1551         glPopMatrix();
1552 }
1553
1554 /* ******************** info ***************** */
1555
1556 /**
1557 * Render and camera border
1558 */
1559 static void view3d_draw_border(const bContext *C, ARegion *ar)
1560 {
1561         Scene *scene = CTX_data_scene(C);
1562         RegionView3D *rv3d = ar->regiondata;
1563         View3D *v3d = CTX_wm_view3d(C);
1564
1565         if (rv3d->persp == RV3D_CAMOB) {
1566                 drawviewborder(scene, ar, v3d);
1567         }
1568         else if (v3d->flag2 & V3D_RENDER_BORDER) {
1569                 drawrenderborder(ar, v3d);
1570         }
1571 }
1572
1573 /**
1574 * Grease Pencil
1575 */
1576 static void view3d_draw_grease_pencil(const bContext *C)
1577 {
1578         /* TODO viewport */
1579 }
1580
1581 /* ******************** view loop ***************** */
1582
1583 /**
1584  * Set the correct matrices
1585  */
1586 static void view3d_draw_setup_view(const bContext *C, ARegion *ar)
1587 {
1588         Scene *scene = CTX_data_scene(C);
1589         View3D *v3d = CTX_wm_view3d(C);
1590         RegionView3D *rv3d = ar->regiondata;
1591
1592         /* setup the view matrix */
1593         if (view3d_stereo3d_active(C, scene, v3d, rv3d))
1594                 view3d_stereo3d_setup(scene, v3d, ar);
1595         else
1596                 view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
1597 }
1598
1599 static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth)
1600 {
1601         Scene *scene = CTX_data_scene(C);
1602         View3D *v3d = CTX_wm_view3d(C);
1603         Base *base;
1604
1605         if (only_depth)
1606                 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1607
1608         if (only_depth || use_depth) {
1609                 glEnable(GL_DEPTH_TEST);
1610                 glDepthFunc(GL_LESS);
1611                 glDepthMask(GL_TRUE);
1612                 v3d->zbuf = true;
1613         }
1614
1615         for (base = scene->base.first; base; base = base->next) {
1616                 if (v3d->lay & base->lay) {
1617                         /* dupli drawing */
1618                         if (base->object->transflag & OB_DUPLI)
1619                                 draw_dupli_objects(scene, ar, v3d, base);
1620
1621                         draw_object(scene, ar, v3d, base, 0);
1622                 }
1623         }
1624
1625         if (only_depth)
1626                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1627
1628         if (only_depth || use_depth) {
1629                 glDisable(GL_DEPTH_TEST);
1630                 v3d->zbuf = false;
1631         }
1632 }
1633
1634 /**
1635  * Draw only the scene depth buffer
1636  */
1637 static void draw_depth_buffer(const bContext *C, ARegion *ar)
1638 {
1639         draw_all_objects(C, ar, true, true);
1640 }
1641
1642 /**
1643  * Required if the shaders need it or external engines
1644  * (e.g., Cycles requires depth buffer handled separately).
1645  */
1646 static void view3d_draw_prerender_buffers(const bContext *C, ARegion *ar, DrawData *draw_data)
1647 {
1648         View3D *v3d = CTX_wm_view3d(C);
1649
1650         /* TODO viewport */
1651         if (draw_data->is_render && ((!draw_data->clip_border) || (v3d->drawtype <= OB_WIRE))) {
1652                 draw_depth_buffer(C, ar);
1653         }
1654 }
1655
1656 /**
1657  * Draw all the plates that will fill the RGBD buffer
1658  */
1659 static void view3d_draw_solid_plates(const bContext *C, ARegion *ar, DrawData *draw_data)
1660 {
1661         Scene *scene = CTX_data_scene(C);
1662         View3D *v3d = CTX_wm_view3d(C);
1663
1664         /* realtime plates */
1665         if ((!draw_data->is_render) || draw_data->clip_border) {
1666                 view3d_draw_background(C);
1667                 view3d_draw_render_solid_surfaces(C, ar, true);
1668                 view3d_draw_render_transparent_surfaces(C);
1669                 view3d_draw_post_draw(C);
1670         }
1671
1672         /* offline plates*/
1673         if (draw_data->is_render) {
1674                 view3d_draw_render_draw(C, scene, ar, v3d, draw_data->clip_border, &draw_data->border_rect);
1675         }
1676
1677 #if VIEW3D_DRAW_DEBUG
1678         view3d_draw_debug_post_solid(C, ar, draw_data);
1679 #endif
1680 }
1681
1682 /**
1683  * Wires, outline, ...
1684  */
1685 static void view3d_draw_geometry_overlay(const bContext *C)
1686 {
1687         view3d_draw_wire_plates(C);
1688         view3d_draw_outline_plates(C);
1689 }
1690
1691 /* drawing cameras, lamps, ... */
1692 static void view3d_draw_non_meshes(const bContext *C, ARegion *ar)
1693 {
1694         /* TODO viewport
1695          * for now we draw them all, in the near future
1696          * we filter them based on the plates/layers
1697          */
1698         Scene *scene = CTX_data_scene(C);
1699         View3D *v3d = CTX_wm_view3d(C);
1700         RegionView3D *rv3d = ar->regiondata;
1701         Object *ob_act = CTX_data_active_object(C);
1702         Base *base;
1703
1704         bool is_boundingbox = ((v3d->drawtype == OB_BOUNDBOX) ||
1705                                 ((v3d->drawtype == OB_RENDER) && (v3d->prev_drawtype == OB_BOUNDBOX)));
1706
1707         unsigned char ob_wire_col[4];            /* dont initialize this */
1708
1709         glEnable(GL_DEPTH_TEST);
1710         glDepthMask(GL_TRUE);
1711         /* TODO Viewport
1712          * we are already temporarily writing to zbuffer in draw_object()
1713          * for now let's avoid writing again to zbuffer to prevent glitches
1714          */
1715
1716         for (base = scene->base.first; base; base = base->next) {
1717                 if (v3d->lay & base->lay) {
1718                         Object *ob = base->object;
1719
1720                         draw_object_wire_color(scene, base, ob_wire_col);
1721                         view3d_draw_non_mesh(scene, ob, base, v3d, rv3d, is_boundingbox, ob_wire_col);
1722                 }
1723         }
1724
1725         glDepthMask(GL_FALSE);
1726         glDisable(GL_DEPTH_TEST);
1727 }
1728
1729 /**
1730 * Parent lines, grid, ...
1731 */
1732 static void view3d_draw_other_elements(const bContext *C, ARegion *ar)
1733 {
1734         /* TODO viewport */
1735         view3d_draw_grid(C, ar);
1736 }
1737
1738 /**
1739  * Paint brushes, armatures, ...
1740  */
1741 static void view3d_draw_tool_ui(const bContext *C)
1742 {
1743         /* TODO viewport */
1744 }
1745
1746 /**
1747  * Blueprint images
1748  */
1749 static void view3d_draw_reference_images(const bContext *C)
1750 {
1751         /* TODO viewport */
1752 }
1753
1754 /**
1755 * 3D manipulators
1756 */
1757 static void view3d_draw_manipulator(const bContext *C)
1758 {
1759         View3D *v3d = CTX_wm_view3d(C);
1760         v3d->zbuf = false;
1761         BIF_draw_manipulator(C);
1762 }
1763
1764 /**
1765 * Information drawn on top of the solid plates and composed data
1766 */
1767 static void view3d_draw_region_info(const bContext *C, ARegion *ar)
1768 {
1769         rcti rect;
1770
1771         /* correct projection matrix */
1772         ED_region_pixelspace(ar);
1773
1774         /* local coordinate visible rect inside region, to accomodate overlapping ui */
1775         ED_region_visible_rect(ar, &rect);
1776
1777         view3d_draw_border(C, ar);
1778         view3d_draw_grease_pencil(C);
1779
1780         /* TODO viewport */
1781 }
1782
1783 /**
1784  * This could run once per view, or even in parallel
1785  * for each of them. What is a "view"?
1786  * - a viewport with the camera elsewhere
1787  * - left/right stereo
1788  * - panorama / fisheye individual cubemap faces
1789  */
1790 static void view3d_draw_view(const bContext *C, ARegion *ar, DrawData *draw_data)
1791 {
1792         /* TODO - Technically this should be drawn to a few FBO, so we can handle
1793          * compositing better, but for now this will get the ball rolling (dfelinto) */
1794
1795         view3d_draw_setup_view(C, ar);
1796         view3d_draw_prerender_buffers(C, ar, draw_data);
1797         view3d_draw_solid_plates(C, ar, draw_data);
1798         view3d_draw_geometry_overlay(C);
1799         view3d_draw_non_meshes(C, ar);
1800         view3d_draw_other_elements(C, ar);
1801         view3d_draw_tool_ui(C);
1802         view3d_draw_reference_images(C);
1803         view3d_draw_manipulator(C);
1804         view3d_draw_region_info(C, ar);
1805
1806 #if VIEW3D_DRAW_DEBUG
1807         view3d_draw_debug(C, ar, draw_data);
1808 #endif
1809 }
1810
1811 void view3d_main_region_draw(const bContext *C, ARegion *ar)
1812 {
1813         View3D *v3d = CTX_wm_view3d(C);
1814         RegionView3D *rv3d = ar->regiondata;
1815
1816         if (IS_VIEWPORT_LEGACY(v3d)) {
1817                 view3d_main_region_draw_legacy(C, ar);
1818                 return;
1819         }
1820
1821         if (!rv3d->viewport)
1822                 rv3d->viewport = GPU_viewport_create();
1823
1824         /* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
1825          * before we even call the drawing routine, but let's move on for now (dfelinto)
1826          * but this is a provisory way to start seeing things in the viewport */
1827         DrawData draw_data;
1828         view3d_draw_data_init(C, ar, rv3d, &draw_data);
1829         view3d_draw_view(C, ar, &draw_data);
1830
1831         v3d->flag |= V3D_INVALID_BACKBUF;
1832 }
1833
1834 /* ******************** legacy interface ***************** */
1835 /**
1836  * This will be removed once the viewport gets replaced
1837  * meanwhile it should keep the old viewport working.
1838  */
1839
1840 void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
1841 {
1842         drawgrid(unit, ar, v3d, grid_unit);
1843 }
1844
1845 void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
1846 {
1847         drawfloor(scene, v3d, grid_unit, write_depth);
1848 }
1849
1850 void VP_legacy_view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
1851 {
1852         view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
1853 }
1854
1855 bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
1856 {
1857         return view3d_stereo3d_active(C, scene, v3d, rv3d);
1858 }
1859
1860 void VP_legacy_view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
1861 {
1862         view3d_stereo3d_setup(scene, v3d, ar);
1863 }
1864
1865 bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
1866 {
1867         return use_depth_doit(scene, v3d);
1868 }
1869
1870 void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
1871 {
1872         drawviewborder(scene, ar, v3d);
1873 }
1874
1875 void VP_drawrenderborder(ARegion *ar, View3D *v3d)
1876 {
1877         drawrenderborder(ar, v3d);
1878 }
1879
1880 void VP_view3d_draw_background_none(void)
1881 {
1882         view3d_draw_background_none();
1883 }
1884
1885 void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv3d)
1886 {
1887         view3d_draw_background_world(scene, v3d, rv3d);
1888 }