Merge branch 'master' into blender2.8
authorLukas Tönne <lukas.toenne@gmail.com>
Thu, 1 Dec 2016 09:29:46 +0000 (10:29 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Thu, 1 Dec 2016 09:29:46 +0000 (10:29 +0100)
45 files changed:
1  2 
build_files/build_environment/install_deps.sh
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_sync.cpp
intern/cycles/blender/blender_sync.h
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowX11.cpp
release/scripts/startup/bl_ui/space_userpref.py
source/blender/alembic/intern/abc_exporter.cc
source/blender/alembic/intern/abc_mesh.cc
source/blender/alembic/intern/abc_points.cc
source/blender/alembic/intern/abc_points.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/depsgraph.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/object_dupli.c
source/blender/blenkernel/intern/rigidbody.c
source/blender/blenkernel/intern/scene.c
source/blender/blenlib/BLI_math_matrix.h
source/blender/blenlib/intern/math_matrix.c
source/blender/blenloader/intern/readfile.c
source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface_eyedropper.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_relations.c
source/blender/editors/space_outliner/outliner_tools.c
source/blender/editors/space_outliner/outliner_tree.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/gpu/intern/gpu_extensions.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesrna/intern/makesrna.c
source/blender/makesrna/intern/rna_ID.c
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_userdef.c

@@@ -1523,22 -1587,40 +1525,35 @@@ class CyclesScene_PT_simplify(CyclesBut
          cscene = scene.cycles
  
          layout.active = rd.use_simplify
-         split = layout.split()
  
-         col = split.column()
-         col.label(text="Viewport:")
-         col.prop(rd, "simplify_subdivision", text="Subdivision")
+         col = layout.column(align=True)
+         col.label(text="Subdivision")
+         row = col.row(align=True)
+         row.prop(rd, "simplify_subdivision", text="Viewport")
+         row.prop(rd, "simplify_subdivision_render", text="Render")
  
-         col = split.column()
-         col.label(text="Render:")
-         col.prop(rd, "simplify_subdivision_render", text="Subdivision")
 -        col = layout.column(align=True)
 -        col.label(text="Child Particles")
 -        row = col.row(align=True)
 -        row.prop(rd, "simplify_child_particles", text="Viewport")
 -        row.prop(rd, "simplify_child_particles_render", text="Render")
  
-         col = layout.column()
+         col = layout.column(align=True)
+         split = col.split()
+         sub = split.column()
+         sub.label(text="Texture Limit Viewport")
+         sub.prop(cscene, "texture_limit", text="")
+         sub = split.column()
+         sub.label(text="Texture Limit Render")
+         sub.prop(cscene, "texture_limit_render", text="")
+         split = layout.split()
+         col = split.column()
          col.prop(cscene, "use_camera_cull")
-         subsub = col.column()
-         subsub.active = cscene.use_camera_cull
-         subsub.prop(cscene, "camera_cull_margin")
+         row = col.row()
+         row.active = cscene.use_camera_cull
+         row.prop(cscene, "camera_cull_margin")
  
+         col = split.column()
+         col.prop(cscene, "use_distance_cull")
+         row = col.row()
+         row.active = cscene.use_distance_cull
+         row.prop(cscene, "distance_cull_margin", text="Distance")
  
  def draw_device(self, context):
      scene = context.scene
@@@ -586,16 -691,22 +662,15 @@@ void BlenderSync::sync_objects(BL::Spac
                                                        BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
  
                                                        /* sync object and mesh or light data */
 -                                                      Object *object = sync_object(b_ob,
 -                                                                                   persistent_id.data,
 -                                                                                   *b_dup,
 -                                                                                   tfm,
 -                                                                                   ob_layer,
 -                                                                                   motion_time,
 -                                                                                   hide_tris,
 -                                                                                   culling,
 -                                                                                   &use_portal);
 -
 -                                                      /* sync possible particle data, note particle_id
 -                                                       * starts counting at 1, first is dummy particle */
 -                                                      if(!motion && object) {
 -                                                              sync_dupli_particle(b_ob, *b_dup, object);
 -                                                      }
 -
 +                                                      sync_object(b_ob,
 +                                                                  persistent_id.data,
 +                                                                  *b_dup,
 +                                                                  tfm,
 +                                                                  ob_layer,
 +                                                                  motion_time,
 +                                                                  hide_tris,
-                                                                   use_camera_cull,
-                                                                   camera_cull_margin,
++                                                                  culling,
 +                                                                  &use_portal);
                                                }
                                        }
  
Simple merge
@@@ -232,15 -219,14 +232,14 @@@ void mat4_to_size(float r[3], const flo
  
  void translate_m4(float mat[4][4], float tx, float ty, float tz);
  void rotate_m4(float mat[4][4], const char axis, const float angle);
- void rotate_m2(float mat[2][2], const float angle);
  void transform_pivot_set_m4(float mat[4][4], const float pivot[3]);
  
 -void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]);
 -void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]);
 -void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]);
 -void mat4_decompose(float loc[3], float quat[4], float size[3], float wmat[4][4]);
 +void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]);
 +void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]);
 +void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4]);
 +void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4]);
  
 -void mat3_polar_decompose(float mat3[3][3], float r_U[3][3], float r_P[3][3]);
 +void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]);
  
  void loc_eul_size_to_mat4(float R[4][4],
                            const float loc[3], const float eul[3], const float size[3]);
@@@ -1680,12 -1625,17 +1680,18 @@@ void translate_m4(float mat[4][4], floa
        mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
  }
  
 +/* TODO: enum for axis? */
+ /**
+  * Rotate a matrix in-place.
+  *
+  * \note To create a new rotation matrix see:
+  * #axis_angle_to_mat4_single, #axis_angle_to_mat3_single, #angle_to_mat2
+  * (axis & angle args are compatible).
+  */
  void rotate_m4(float mat[4][4], const char axis, const float angle)
  {
-       int col;
-       float temp[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-       float cosine, sine;
+       const float angle_cos = cosf(angle);
+       const float angle_sin = sinf(angle);
  
        assert(axis >= 'X' && axis <= 'Z');
  
  #include "view3d_intern.h"  /* own include */
  
  /* prototypes */
 -static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar);
 -static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
 -                                            float winmat[4][4], const char *viewname);
 -
 -/* handy utility for drawing shapes in the viewport for arbitrary code.
 - * could add lines and points too */
 -// #define DEBUG_DRAW
 -#ifdef DEBUG_DRAW
 -static void bl_debug_draw(void);
 -/* add these locally when using these functions for testing */
 -extern void bl_debug_draw_quad_clear(void);
 -extern void bl_debug_draw_quad_add(const float v0[3], const float v1[3], const float v2[3], const float v3[3]);
 -extern void bl_debug_draw_edge_add(const float v0[3], const float v1[3]);
 -extern void bl_debug_color_set(const unsigned int col);
 -#endif
 +static void draw_all_objects(const bContext *C, ARegion *ar, const bool only_depth, const bool use_depth);
  
 -void circf(float x, float y, float rad)
 -{
 -      GLUquadricObj *qobj = gluNewQuadric(); 
 -      
 -      gluQuadricDrawStyle(qobj, GLU_FILL); 
 -      
 -      glPushMatrix(); 
 -      
 -      glTranslatef(x, y, 0.0);
 -      
 -      gluDisk(qobj, 0.0,  rad, 32, 1);
 -      
 -      glPopMatrix(); 
 -      
 -      gluDeleteQuadric(qobj);
 -}
 +typedef struct DrawData {
 +      rcti border_rect;
 +      bool render_border;
 +      bool clip_border;
 +      bool is_render;
 +      GPUViewport *viewport;
 +} DrawData;
  
 -void circ(float x, float y, float rad)
 +static void view3d_draw_data_init(const bContext *C, ARegion *ar, RegionView3D *rv3d, DrawData *draw_data)
  {
 -      GLUquadricObj *qobj = gluNewQuadric(); 
 -      
 -      gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); 
 -      
 -      glPushMatrix(); 
 -      
 -      glTranslatef(x, y, 0.0);
 -      
 -      gluDisk(qobj, 0.0,  rad, 32, 1);
 -      
 -      glPopMatrix(); 
 -      
 -      gluDeleteQuadric(qobj);
 -}
 -
 +      Scene *scene = CTX_data_scene(C);
 +      View3D *v3d = CTX_wm_view3d(C);
  
 -/* ********* custom clipping *********** */
 +      draw_data->is_render = (v3d->drawtype == OB_RENDER);
  
 -static void view3d_draw_clipping(RegionView3D *rv3d)
 -{
 -      BoundBox *bb = rv3d->clipbb;
 -
 -      if (bb) {
 -              const unsigned int clipping_index[6][4] = {
 -                      {0, 1, 2, 3},
 -                      {0, 4, 5, 1},
 -                      {4, 7, 6, 5},
 -                      {7, 3, 2, 6},
 -                      {1, 5, 6, 2},
 -                      {7, 4, 0, 3}
 -              };
 -
 -              /* fill in zero alpha for rendering & re-projection [#31530] */
 -              unsigned char col[4];
 -              UI_GetThemeColor4ubv(TH_V3D_CLIPPING_BORDER, col);
 -              glColor4ubv(col);
 -
 -              glEnable(GL_BLEND);
 -              glEnableClientState(GL_VERTEX_ARRAY);
 -              glVertexPointer(3, GL_FLOAT, 0, bb->vec);
 -              glDrawElements(GL_QUADS, sizeof(clipping_index) / sizeof(unsigned int), GL_UNSIGNED_INT, clipping_index);
 -              glDisableClientState(GL_VERTEX_ARRAY);
 -              glDisable(GL_BLEND);
 -      }
 -}
 +      draw_data->render_border = ED_view3d_calc_render_border(scene, v3d, ar, &draw_data->border_rect);
 +      draw_data->clip_border = (draw_data->render_border && !BLI_rcti_compare(&ar->drawrct, &draw_data->border_rect));
  
 -void ED_view3d_clipping_set(RegionView3D *rv3d)
 -{
 -      double plane[4];
 -      const unsigned int tot = (rv3d->viewlock & RV3D_BOXCLIP) ? 4 : 6;
 -      unsigned int a;
 -
 -      for (a = 0; a < tot; a++) {
 -              copy_v4db_v4fl(plane, rv3d->clip[a]);
 -              glClipPlane(GL_CLIP_PLANE0 + a, plane);
 -              glEnable(GL_CLIP_PLANE0 + a);
 -      }
 +      draw_data->viewport = rv3d->viewport;
  }
  
 -/* use these to temp disable/enable clipping when 'rv3d->rflag & RV3D_CLIPPING' is set */
 -void ED_view3d_clipping_disable(void)
 -{
 -      unsigned int a;
 +/* ******************** general functions ***************** */
  
 -      for (a = 0; a < 6; a++) {
 -              glDisable(GL_CLIP_PLANE0 + a);
 -      }
 -}
 -void ED_view3d_clipping_enable(void)
 +static bool use_depth_doit(Scene *scene, View3D *v3d)
  {
 -      unsigned int a;
 +      if (v3d->drawtype > OB_WIRE)
 +              return true;
  
 -      for (a = 0; a < 6; a++) {
 -              glEnable(GL_CLIP_PLANE0 + a);
 +      /* special case (depth for wire color) */
 +      if (v3d->drawtype <= OB_WIRE) {
 +              if (scene->obedit && scene->obedit->type == OB_MESH) {
 +                      Mesh *me = scene->obedit->data;
 +                      if (me->drawflag & ME_DRAWEIGHT) {
 +                              return true;
 +                      }
 +              }
        }
 +      return false;
  }
  
 -static bool view3d_clipping_test(const float co[3], const float clip[6][4])
 +static bool use_depth(const bContext *C)
  {
 -      if (plane_point_side_v3(clip[0], co) > 0.0f)
 -              if (plane_point_side_v3(clip[1], co) > 0.0f)
 -                      if (plane_point_side_v3(clip[2], co) > 0.0f)
 -                              if (plane_point_side_v3(clip[3], co) > 0.0f)
 -                                      return false;
 -
 -      return true;
 +      View3D *v3d = CTX_wm_view3d(C);
 +      Scene *scene = CTX_data_scene(C);
 +      return use_depth_doit(scene, v3d);
  }
  
 -/* for 'local' ED_view3d_clipping_local must run first
 - * then all comparisons can be done in localspace */
 -bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], const bool is_local)
 +/**
 + * \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
 + */
 +void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
  {
 -      return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
 -}
 +      RegionView3D *rv3d = ar->regiondata;
-       rctf cameraborder;
 -/* ********* end custom clipping *********** */
  
 +      /* setup window matrices */
 +      if (winmat)
 +              copy_m4_m4(rv3d->winmat, winmat);
 +      else
 +              view3d_winmatrix_set(ar, v3d, NULL);
  
 -static void drawgrid_draw(ARegion *ar, double wx, double wy, double x, double y, double dx)
 -{     
 -      double verts[2][2];
 +      /* setup view matrix */
 +      if (viewmat)
 +              copy_m4_m4(rv3d->viewmat, viewmat);
 +      else
 +              view3d_viewmatrix_set(scene, v3d, rv3d);  /* note: calls BKE_object_where_is_calc for camera... */
  
-       /* update utilitity matrices */
 -      x += (wx);
 -      y += (wy);
++      /* update utility matrices */
 +      mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
 +      invert_m4_m4(rv3d->persinv, rv3d->persmat);
 +      invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
  
 -      /* set fixed 'Y' */
 -      verts[0][1] = 0.0f;
 -      verts[1][1] = (double)ar->winy;
 +      /* calculate GLSL view dependent values */
  
 -      /* iter over 'X' */
 -      verts[0][0] = verts[1][0] = x - dx * floor(x / dx);
 -      glEnableClientState(GL_VERTEX_ARRAY);
 -      glVertexPointer(2, GL_DOUBLE, 0, verts);
 +      /* store window coordinates scaling/offset */
 +      if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
++              rctf cameraborder;
 +              ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
 +              rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
 +              rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
  
 -      while (verts[0][0] < ar->winx) {
 -              glDrawArrays(GL_LINES, 0, 2);
 -              verts[0][0] = verts[1][0] = verts[0][0] + dx;
 +              rv3d->viewcamtexcofac[2] = -rv3d->viewcamtexcofac[0] * cameraborder.xmin / (float)ar->winx;
 +              rv3d->viewcamtexcofac[3] = -rv3d->viewcamtexcofac[1] * cameraborder.ymin / (float)ar->winy;
 +      }
 +      else {
 +              rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
 +              rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
        }
  
 -      /* set fixed 'X' */
 -      verts[0][0] = 0.0f;
 -      verts[1][0] = (double)ar->winx;
 +      /* calculate pixelsize factor once, is used for lamps and obcenters */
 +      {
 +              /* note:  '1.0f / len_v3(v1)'  replaced  'len_v3(rv3d->viewmat[0])'
 +              * because of float point precision problems at large values [#23908] */
 +              float v1[3], v2[3];
 +              float len_px, len_sc;
 +
 +              v1[0] = rv3d->persmat[0][0];
 +              v1[1] = rv3d->persmat[1][0];
 +              v1[2] = rv3d->persmat[2][0];
  
 -      /* iter over 'Y' */
 -      verts[0][1] = verts[1][1] = y - dx * floor(y / dx);
 -      while (verts[0][1] < ar->winy) {
 -              glDrawArrays(GL_LINES, 0, 2);
 -              verts[0][1] = verts[1][1] = verts[0][1] + dx;
 -      }
 +              v2[0] = rv3d->persmat[0][1];
 +              v2[1] = rv3d->persmat[1][1];
 +              v2[2] = rv3d->persmat[2][1];
  
 -      glDisableClientState(GL_VERTEX_ARRAY);
 -}
 +              len_px = 2.0f / sqrtf(min_ff(len_squared_v3(v1), len_squared_v3(v2)));
 +              len_sc = (float)MAX2(ar->winx, ar->winy);
  
 -#define GRID_MIN_PX_D   6.0
 -#define GRID_MIN_PX_F 6.0f
 +              rv3d->pixsize = len_px / len_sc;
 +      }
 +}
  
 -static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit)
 +static void view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
  {
 -      /* extern short bgpicmode; */
        RegionView3D *rv3d = ar->regiondata;
 -      double wx, wy, x, y, fw, fx, fy, dx;
 -      double vec4[4];
 -      unsigned char col[3], col2[3];
 -
 -      fx = rv3d->persmat[3][0];
 -      fy = rv3d->persmat[3][1];
 -      fw = rv3d->persmat[3][3];
  
 -      wx = (ar->winx / 2.0); /* because of rounding errors, grid at wrong location */
 -      wy = (ar->winy / 2.0);
 +      ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat);
  
 -      x = (wx) * fx / fw;
 -      y = (wy) * fy / fw;
 +      /* set for opengl */
 +      glMatrixMode(GL_PROJECTION);
 +      glLoadMatrixf(rv3d->winmat);
 +      glMatrixMode(GL_MODELVIEW);
 +      glLoadMatrixf(rv3d->viewmat);
 +}
  
 -      vec4[0] = vec4[1] = v3d->grid;
 +static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
 +{
 +      wmWindow *win = CTX_wm_window(C);
  
 -      vec4[2] = 0.0;
 -      vec4[3] = 1.0;
 -      mul_m4_v4d(rv3d->persmat, vec4);
 -      fx = vec4[0];
 -      fy = vec4[1];
 -      fw = vec4[3];
 +      if ((scene->r.scemode & R_MULTIVIEW) == 0)
 +              return false;
  
 -      dx = fabs(x - (wx) * fx / fw);
 -      if (dx == 0) dx = fabs(y - (wy) * fy / fw);
 -      
 -      glLineWidth(1.0f);
 +      if (WM_stereo3d_enabled(win, true) == false)
 +              return false;
  
 -      glDepthMask(GL_FALSE);     /* disable write in zbuffer */
 +      if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
 +              return false;
  
 -      /* check zoom out */
 -      UI_ThemeColor(TH_GRID);
 -      
 -      if (unit->system) {
 -              /* Use GRID_MIN_PX * 2 for units because very very small grid
 -               * items are less useful when dealing with units */
 -              const void *usys;
 -              int len, i;
 -              double dx_scalar;
 -              float blend_fac;
 +      if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
 +              if (v3d->stereo3d_camera == STEREO_MONO_ID)
 +                      return false;
  
 -              bUnit_GetSystem(unit->system, B_UNIT_LENGTH, &usys, &len);
 +              return BKE_scene_multiview_is_stereo3d(&scene->r);
 +      }
  
 -              if (usys) {
 -                      i = len;
 -                      while (i--) {
 -                              double scalar = bUnit_GetScaler(usys, i);
 +      return true;
 +}
  
 -                              dx_scalar = dx * scalar / (double)unit->scale_length;
 -                              if (dx_scalar < (GRID_MIN_PX_D * 2.0))
 -                                      continue;
 +/* setup the view and win matrices for the multiview cameras
 + *
 + * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
 + * we have no winmatrix (i.e., projection matrix) defined at that time.
 + * Since the camera and the camera shift are needed for the winmat calculation
 + * we do a small hack to replace it temporarily so we don't need to change the
 + * view3d)main_region_setup_view() code to account for that.
 + */
 +static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
 +{
 +      bool is_left;
 +      const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
 +      const char *viewname;
  
 -                              /* Store the smallest drawn grid size units name so users know how big each grid cell is */
 -                              if (*grid_unit == NULL) {
 -                                      *grid_unit = bUnit_GetNameDisplay(usys, i);
 -                                      rv3d->gridview = (float)((scalar * (double)v3d->grid) / (double)unit->scale_length);
 -                              }
 -                              blend_fac = 1.0f - ((GRID_MIN_PX_F * 2.0f) / (float)dx_scalar);
 +      /* show only left or right camera */
 +      if (v3d->stereo3d_camera != STEREO_3D_ID)
 +              v3d->multiview_eye = v3d->stereo3d_camera;
  
 -                              /* tweak to have the fade a bit nicer */
 -                              blend_fac = (blend_fac * blend_fac) * 2.0f;
 -                              CLAMP(blend_fac, 0.3f, 1.0f);
 +      is_left = v3d->multiview_eye == STEREO_LEFT_ID;
 +      viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
  
 +      /* update the viewport matrices with the new camera */
 +      if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
 +              Camera *data;
 +              float viewmat[4][4];
 +              float shiftx;
  
 -                              UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac);
 +              data = (Camera *)v3d->camera->data;
 +              shiftx = data->shiftx;
  
 -                              drawgrid_draw(ar, wx, wy, x, y, dx_scalar);
 -                      }
 -              }
 -      }
 -      else {
 -              const double sublines    = v3d->gridsubdiv;
 -              const float  sublines_fl = v3d->gridsubdiv;
 +              BLI_lock_thread(LOCK_VIEW3D);
 +              data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
  
 -              if (dx < GRID_MIN_PX_D) {
 -                      rv3d->gridview *= sublines_fl;
 -                      dx *= sublines;
 +              BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
 +              view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
  
 -                      if (dx < GRID_MIN_PX_D) {
 -                              rv3d->gridview *= sublines_fl;
 -                              dx *= sublines;
 +              data->shiftx = shiftx;
 +              BLI_unlock_thread(LOCK_VIEW3D);
 +      }
 +      else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
 +              float viewmat[4][4];
 +              Object *view_ob = v3d->camera;
 +              Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
  
 -                              if (dx < GRID_MIN_PX_D) {
 -                                      rv3d->gridview *= sublines_fl;
 -                                      dx *= sublines;
 -                                      if (dx < GRID_MIN_PX_D) {
 -                                              /* pass */
 -                                      }
 -                                      else {
 -                                              UI_ThemeColor(TH_GRID);
 -                                              drawgrid_draw(ar, wx, wy, x, y, dx);
 -                                      }
 -                              }
 -                              else {  /* start blending out */
 -                                      UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
 -                                      drawgrid_draw(ar, wx, wy, x, y, dx);
 +              BLI_lock_thread(LOCK_VIEW3D);
 +              v3d->camera = camera;
  
 -                                      UI_ThemeColor(TH_GRID);
 -                                      drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
 -                              }
 -                      }
 -                      else {  /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */
 -                              UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
 -                              drawgrid_draw(ar, wx, wy, x, y, dx);
 +              BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
 +              view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
  
 -                              UI_ThemeColor(TH_GRID);
 -                              drawgrid_draw(ar, wx, wy, x, y, sublines * dx);
 -                      }
 -              }
 -              else {
 -                      if (dx > (GRID_MIN_PX_D * 10.0)) {  /* start blending in */
 -                              rv3d->gridview /= sublines_fl;
 -                              dx /= sublines;
 -                              if (dx > (GRID_MIN_PX_D * 10.0)) {  /* start blending in */
 -                                      rv3d->gridview /= sublines_fl;
 -                                      dx /= sublines;
 -                                      if (dx > (GRID_MIN_PX_D * 10.0)) {
 -                                              UI_ThemeColor(TH_GRID);
 -                                              drawgrid_draw(ar, wx, wy, x, y, dx);
 -                                      }
 -                                      else {
 -                                              UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
 -                                              drawgrid_draw(ar, wx, wy, x, y, dx);
 -                                              UI_ThemeColor(TH_GRID);
 -                                              drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
 -                                      }
 -                              }
 -                              else {
 -                                      UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
 -                                      drawgrid_draw(ar, wx, wy, x, y, dx);
 -                                      UI_ThemeColor(TH_GRID);
 -                                      drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
 -                              }
 -                      }
 -                      else {
 -                              UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0));
 -                              drawgrid_draw(ar, wx, wy, x, y, dx);
 -                              UI_ThemeColor(TH_GRID);
 -                              drawgrid_draw(ar, wx, wy, x, y, dx * sublines);
 -                      }
 -              }
 +              v3d->camera = view_ob;
 +              BLI_unlock_thread(LOCK_VIEW3D);
        }
 +}
  
 +/* ******************** debug ***************** */
  
 -      x += (wx);
 -      y += (wy);
 -      UI_GetThemeColor3ubv(TH_GRID, col);
 -
 -      setlinestyle(0);
 -      
 -      /* center cross */
 -      /* horizontal line */
 -      if (ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT))
 -              UI_make_axis_color(col, col2, 'Y');
 -      else UI_make_axis_color(col, col2, 'X');
 -      glColor3ubv(col2);
 -      
 -      fdrawline(0.0,  y,  (float)ar->winx,  y); 
 -      
 -      /* vertical line */
 -      if (ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM))
 -              UI_make_axis_color(col, col2, 'Y');
 -      else UI_make_axis_color(col, col2, 'Z');
 -      glColor3ubv(col2);
 -
 -      fdrawline(x, 0.0, x, (float)ar->winy); 
 +#define VIEW3D_DRAW_DEBUG 1
 +/* TODO: expand scope of this flag so UI reflects the underlying code */
  
 -      glDepthMask(GL_TRUE);  /* enable write in zbuffer */
 -}
 -#undef GRID_MIN_PX
 +#if VIEW3D_DRAW_DEBUG
  
 -/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
 -float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
 +static void view3d_draw_debug_store_depth(ARegion *ar, DrawData *draw_data)
  {
 -      /* apply units */
 -      if (scene->unit.system) {
 -              const void *usys;
 -              int len;
 +      GPUViewport *viewport = draw_data->viewport;
 +      GLint viewport_size[4];
 +      glGetIntegerv(GL_VIEWPORT, viewport_size);
  
 -              bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
 +      const int x = viewport_size[0];
 +      const int y = viewport_size[1];
 +      const int w = viewport_size[2];
 +      const int h = viewport_size[3];
  
 -              if (usys) {
 -                      int i = bUnit_GetBaseUnit(usys);
 -                      if (grid_unit)
 -                              *grid_unit = bUnit_GetNameDisplay(usys, i);
 -                      return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
 +      if (GPU_viewport_debug_depth_is_valid(viewport)) {
 +              if ((GPU_viewport_debug_depth_width(viewport) != w) ||
 +                      (GPU_viewport_debug_depth_height(viewport) != h))
 +              {
 +                      GPU_viewport_debug_depth_free(viewport);
                }
        }
  
@@@ -1203,359 -3326,385 +1204,369 @@@ static void drawgrid(UnitSettings *unit
                        }
                }
  
 -              MEM_freeN(accum_buffer);
 +              int gridline_ct = gridline_count(ar, x, y, dx);
 +              if (gridline_ct == 0)
 +                      goto drawgrid_cleanup; /* nothing to draw */
 +
 +              immBegin(GL_LINES, gridline_ct * 2);
 +
 +              if (grids_to_draw == 2) {
 +                      UI_GetThemeColorBlend3ubv(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0), col2);
 +                      if (drawgrid_draw(ar, x, y, dx, v3d->gridsubdiv, pos, color, col2))
 +                              drawgrid_draw(ar, x, y, dx * sublines, 0, pos, color, col);
 +              }
 +              else if (grids_to_draw == 1) {
 +                      drawgrid_draw(ar, x, y, dx, 0, pos, color, col);
 +              }
        }
  
 -      /* unbind */
 -      GPU_offscreen_unbind(ofs, true);
 +      /* draw visible axes */
 +      /* horizontal line */
 +      if (0 <= y && y < ar->winy) {
 +              UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT) ? 'Y' : 'X');
 +              immAttrib3ub(color, col2[0], col2[1], col2[2]);
 +              immVertex2f(pos, 0.0f, y);
 +              immVertex2f(pos, (float)ar->winx, y);
 +      }
  
 -      if (own_ofs) {
 -              GPU_offscreen_free(ofs);
 +      /* vertical line */
 +      if (0 <= x && x < ar->winx) {
 +              UI_make_axis_color(col, col2, ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM) ? 'Y' : 'Z');
 +              immAttrib3ub(color, col2[0], col2[1], col2[2]);
 +              immVertex2f(pos, x, 0.0f);
 +              immVertex2f(pos, x, (float)ar->winy);
        }
  
 -      if (ibuf->rect_float && ibuf->rect)
 -              IMB_rect_from_float(ibuf);
 +      immEnd();
  
 -      return ibuf;
 +drawgrid_cleanup:
 +      immUnbindProgram();
 +
 +#if 0 /* depth write is left enabled above */
 +      glDepthMask(GL_TRUE);  /* enable write in zbuffer */
 +#endif
  }
  
 -/**
 - * Creates own fake 3d views (wrapping #ED_view3d_draw_offscreen_imbuf)
 - *
 - * \param ofs: Optional off-screen buffer can be NULL.
 - * (avoids re-creating when doing multiple GL renders).
 - *
 - * \note used by the sequencer
 - */
 -ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
 -        Scene *scene, Object *camera, int width, int height,
 -        unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
 -        int alpha_mode, int samples, bool full_samples, const char *viewname,
 -        GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
 +#undef DEBUG_GRID
 +#undef GRID_MIN_PX_D
 +#undef GRID_MIN_PX_F
 +
 +static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth)
  {
 -      View3D v3d = {NULL};
 -      ARegion ar = {NULL};
 -      RegionView3D rv3d = {{{0}}};
 -
 -      /* connect data */
 -      v3d.regionbase.first = v3d.regionbase.last = &ar;
 -      ar.regiondata = &rv3d;
 -      ar.regiontype = RGN_TYPE_WINDOW;
 -
 -      v3d.camera = camera;
 -      v3d.lay = scene->lay;
 -      v3d.drawtype = drawtype;
 -      v3d.flag2 = V3D_RENDER_OVERRIDE;
 -      
 -      if (use_gpencil)
 -              v3d.flag2 |= V3D_SHOW_GPENCIL;
 -
 -      if (use_solid_tex)
 -              v3d.flag2 |= V3D_SOLID_TEX;
 -              
 -      if (draw_background)
 -              v3d.flag3 |= V3D_SHOW_WORLD;
 -
 -      rv3d.persp = RV3D_CAMOB;
 -
 -      copy_m4_m4(rv3d.viewinv, v3d.camera->obmat);
 -      normalize_m4(rv3d.viewinv);
 -      invert_m4_m4(rv3d.viewmat, rv3d.viewinv);
 +      /* draw only if there is something to draw */
 +      if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) {
 +              /* draw how many lines?
 +              * trunc(v3d->gridlines / 2) * 4
 +              * + 2 for xy axes (possibly with special colors)
 +              * + 1 for z axis (the only line not in xy plane)
 +              * even v3d->gridlines are honored, odd rounded down */
 +              const int gridlines = v3d->gridlines / 2;
 +              const float grid_scale = ED_view3d_grid_scale(scene, v3d, grid_unit);
 +              const float grid = gridlines * grid_scale;
  
 -      {
 -              CameraParams params;
 -              Object *view_camera = BKE_camera_multiview_render(scene, v3d.camera, viewname);
 -
 -              BKE_camera_params_init(&params);
 -              BKE_camera_params_from_object(&params, view_camera);
 -              BKE_camera_multiview_params(&scene->r, &params, view_camera, viewname);
 -              BKE_camera_params_compute_viewplane(&params, width, height, scene->r.xasp, scene->r.yasp);
 -              BKE_camera_params_compute_matrix(&params);
 -
 -              copy_m4_m4(rv3d.winmat, params.winmat);
 -              v3d.near = params.clipsta;
 -              v3d.far = params.clipend;
 -              v3d.lens = params.lens;
 -      }
 +              const bool show_floor = (v3d->gridflag & V3D_SHOW_FLOOR) && gridlines >= 1;
  
 -      mul_m4_m4m4(rv3d.persmat, rv3d.winmat, rv3d.viewmat);
 -      invert_m4_m4(rv3d.persinv, rv3d.viewinv);
 +              bool show_axis_x = v3d->gridflag & V3D_SHOW_X;
 +              bool show_axis_y = v3d->gridflag & V3D_SHOW_Y;
 +              bool show_axis_z = v3d->gridflag & V3D_SHOW_Z;
  
 -      return ED_view3d_draw_offscreen_imbuf(
 -              scene, &v3d, &ar, width, height, flag,
 -              draw_background, alpha_mode, samples, full_samples, viewname,
 -              fx, ofs, err_out);
 -}
 +              unsigned char col_grid[3], col_axis[3];
  
 +              glLineWidth(1.0f);
  
 -/**
 - * \note The info that this uses is updated in #ED_refresh_viewport_fps,
 - * which currently gets called during #SCREEN_OT_animation_step.
 - */
 -void ED_scene_draw_fps(Scene *scene, const rcti *rect)
 -{
 -      ScreenFrameRateInfo *fpsi = scene->fps_info;
 -      float fps;
 -      char printable[16];
 -      int i, tot;
 -      
 -      if (!fpsi || !fpsi->lredrawtime || !fpsi->redrawtime)
 -              return;
 -      
 -      printable[0] = '\0';
 -      
 -#if 0
 -      /* this is too simple, better do an average */
 -      fps = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime))
 -#else
 -      fpsi->redrawtimes_fps[fpsi->redrawtime_index] = (float)(1.0 / (fpsi->lredrawtime - fpsi->redrawtime));
 -      
 -      for (i = 0, tot = 0, fps = 0.0f; i < REDRAW_FRAME_AVERAGE; i++) {
 -              if (fpsi->redrawtimes_fps[i]) {
 -                      fps += fpsi->redrawtimes_fps[i];
 -                      tot++;
 -              }
 -      }
 -      if (tot) {
 -              fpsi->redrawtime_index = (fpsi->redrawtime_index + 1) % REDRAW_FRAME_AVERAGE;
 -              
 -              //fpsi->redrawtime_index++;
 -              //if (fpsi->redrawtime >= REDRAW_FRAME_AVERAGE)
 -              //      fpsi->redrawtime = 0;
 -              
 -              fps = fps / tot;
 -      }
 -#endif
 +              UI_GetThemeColor3ubv(TH_GRID, col_grid);
  
 -      /* is this more than half a frame behind? */
 -      if (fps + 0.5f < (float)(FPS)) {
 -              UI_ThemeColor(TH_REDALERT);
 -              BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps);
 -      }
 -      else {
 -              UI_ThemeColor(TH_TEXT_HI);
 -              BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f));
 -      }
 +              if (!write_depth)
 +                      glDepthMask(GL_FALSE);
  
 -#ifdef WITH_INTERNATIONAL
 -      BLF_draw_default(rect->xmin + U.widget_unit,  rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
 -#else
 -      BLF_draw_default_ascii(rect->xmin + U.widget_unit,  rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable));
 -#endif
 -}
 +              if (show_floor) {
 +                      const unsigned vertex_ct = 2 * (gridlines * 4 + 2);
 +                      const int sublines = v3d->gridsubdiv;
  
 -static bool view3d_main_region_do_render_draw(Scene *scene)
 -{
 -      RenderEngineType *type = RE_engines_find(scene->r.engine);
 +                      unsigned char col_bg[3], col_grid_emphasise[3], col_grid_light[3];
  
 -      return (type && type->view_update && type->view_draw);
 -}
 +                      VertexFormat* format = immVertexFormat();
 +                      unsigned pos = add_attrib(format, "pos", COMP_F32, 2, KEEP_FLOAT);
 +                      unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
  
 -bool ED_view3d_calc_render_border(Scene *scene, View3D *v3d, ARegion *ar, rcti *rect)
 -{
 -      RegionView3D *rv3d = ar->regiondata;
 -      rctf viewborder;
 -      bool use_border;
 +                      immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
  
 -      /* test if there is a 3d view rendering */
 -      if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene))
 -              return false;
 +                      immBegin(GL_LINES, vertex_ct);
  
 -      /* test if there is a border render */
 -      if (rv3d->persp == RV3D_CAMOB)
 -              use_border = (scene->r.mode & R_BORDER) != 0;
 -      else
 -              use_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0;
 -      
 -      if (!use_border)
 -              return false;
 +                      /* draw normal grid lines */
 +                      UI_GetColorPtrShade3ubv(col_grid, col_grid_light, 10);
  
 -      /* compute border */
 -      if (rv3d->persp == RV3D_CAMOB) {
 -              ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false);
 +                      for (int a = 1; a <= gridlines; a++) {
 +                              /* skip emphasised divider lines */
 +                              if (a % sublines != 0) {
 +                                      const float line = a * grid_scale;
  
 -              rect->xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder);
 -              rect->ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder);
 -              rect->xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder);
 -              rect->ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder);
 -      }
 -      else {
 -              rect->xmin = v3d->render_border.xmin * ar->winx;
 -              rect->xmax = v3d->render_border.xmax * ar->winx;
 -              rect->ymin = v3d->render_border.ymin * ar->winy;
 -              rect->ymax = v3d->render_border.ymax * ar->winy;
 -      }
 +                                      immAttrib3ubv(color, col_grid_light);
  
 -      BLI_rcti_translate(rect, ar->winrct.xmin, ar->winrct.ymin);
 -      BLI_rcti_isect(&ar->winrct, rect, rect);
 +                                      immVertex2f(pos, -grid, -line);
 +                                      immVertex2f(pos, +grid, -line);
 +                                      immVertex2f(pos, -grid, +line);
 +                                      immVertex2f(pos, +grid, +line);
  
 -      return true;
 -}
 +                                      immVertex2f(pos, -line, -grid);
 +                                      immVertex2f(pos, -line, +grid);
 +                                      immVertex2f(pos, +line, -grid);
 +                                      immVertex2f(pos, +line, +grid);
 +                              }
 +                      }
  
 -static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
 -                                         ARegion *ar, View3D *v3d,
 -                                         bool clip_border, const rcti *border_rect)
 -{
 -      RegionView3D *rv3d = ar->regiondata;
 -      RenderEngineType *type;
 -      GLint scissor[4];
 +                      /* draw emphasised grid lines */
 +                      UI_GetThemeColor3ubv(TH_BACK, col_bg);
 +                      /* emphasise division lines lighter instead of darker, if background is darker than grid */
 +                      UI_GetColorPtrShade3ubv(col_grid, col_grid_emphasise,
 +                              (col_grid[0] + col_grid[1] + col_grid[2] + 30 >
 +                              col_bg[0] + col_bg[1] + col_bg[2]) ? 20 : -10);
  
 -      /* create render engine */
 -      if (!rv3d->render_engine) {
 -              RenderEngine *engine;
 +                      if (sublines <= gridlines) {
 +                              immAttrib3ubv(color, col_grid_emphasise);
  
 -              type = RE_engines_find(scene->r.engine);
 +                              for (int a = sublines; a <= gridlines; a += sublines) {
 +                                      const float line = a * grid_scale;
  
 -              if (!(type->view_update && type->view_draw))
 -                      return false;
 +                                      immVertex2f(pos, -grid, -line);
 +                                      immVertex2f(pos, +grid, -line);
 +                                      immVertex2f(pos, -grid, +line);
 +                                      immVertex2f(pos, +grid, +line);
  
 -              engine = RE_engine_create_ex(type, true);
 +                                      immVertex2f(pos, -line, -grid);
 +                                      immVertex2f(pos, -line, +grid);
 +                                      immVertex2f(pos, +line, -grid);
 +                                      immVertex2f(pos, +line, +grid);
 +                              }
 +                      }
  
 -              engine->tile_x = scene->r.tilex;
 -              engine->tile_y = scene->r.tiley;
 +                      /* draw X axis */
 +                      if (show_axis_x) {
 +                              show_axis_x = false; /* drawing now, won't need to draw later */
 +                              UI_make_axis_color(col_grid, col_axis, 'X');
 +                              immAttrib3ubv(color, col_axis);
 +                      }
 +                      else
 +                              immAttrib3ubv(color, col_grid_emphasise);
  
 -              type->view_update(engine, C);
 +                      immVertex2f(pos, -grid, 0.0f);
 +                      immVertex2f(pos, +grid, 0.0f);
  
 -              rv3d->render_engine = engine;
 -      }
 +                      /* draw Y axis */
 +                      if (show_axis_y) {
 +                              show_axis_y = false; /* drawing now, won't need to draw later */
 +                              UI_make_axis_color(col_grid, col_axis, 'Y');
 +                              immAttrib3ubv(color, col_axis);
 +                      }
 +                      else
 +                              immAttrib3ubv(color, col_grid_emphasise);
  
 -      /* setup view matrices */
 -      view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
 +                      immVertex2f(pos, 0.0f, -grid);
 +                      immVertex2f(pos, 0.0f, +grid);
  
 -      /* background draw */
 -      ED_region_pixelspace(ar);
 +                      immEnd();
 +                      immUnbindProgram();
  
 -      if (clip_border) {
 -              /* for border draw, we only need to clear a subset of the 3d view */
 -              if (border_rect->xmax > border_rect->xmin && border_rect->ymax > border_rect->ymin) {
 -                      glGetIntegerv(GL_SCISSOR_BOX, scissor);
 -                      glScissor(border_rect->xmin, border_rect->ymin,
 -                                BLI_rcti_size_x(border_rect), BLI_rcti_size_y(border_rect));
 -              }
 -              else {
 -                      return false;
 +                      /* done with XY plane */
                }
 -      }
 -
 -      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 -      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
 -      if (v3d->flag & V3D_DISPBGPICS)
 -              view3d_draw_bgpic_test(scene, ar, v3d, false, true);
 -      else
 -              fdrawcheckerboard(0, 0, ar->winx, ar->winy);
 -
 -      /* render result draw */
 -      type = rv3d->render_engine->type;
 -      type->view_draw(rv3d->render_engine, C);
 +              if (show_axis_x || show_axis_y || show_axis_z) {
 +                      /* draw axis lines -- sometimes grid floor is off, other times we still need to draw the Z axis */
  
 -      if (v3d->flag & V3D_DISPBGPICS)
 -              view3d_draw_bgpic_test(scene, ar, v3d, true, true);
 +                      VertexFormat* format = immVertexFormat();
 +                      unsigned pos = add_attrib(format, "pos", COMP_F32, 3, KEEP_FLOAT);
 +                      unsigned color = add_attrib(format, "color", COMP_U8, 3, NORMALIZE_INT_TO_FLOAT);
  
 -      if (clip_border) {
 -              /* restore scissor as it was before */
 -              glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
 -      }
 +                      immBindBuiltinProgram(GPU_SHADER_3D_FLAT_COLOR);
 +                      immBegin(GL_LINES, (show_axis_x + show_axis_y + show_axis_z) * 2);
  
 -      return true;
 -}
 +                      if (show_axis_x) {
 +                              UI_make_axis_color(col_grid, col_axis, 'X');
 +                              immAttrib3ubv(color, col_axis);
 +                              immVertex3f(pos, -grid, 0.0f, 0.0f);
 +                              immVertex3f(pos, +grid, 0.0f, 0.0f);
 +                      }
  
 -static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d, ARegion *ar, bool render_border)
 -{
 -      float fill_color[4] = {0.0f, 0.0f, 0.0f, 0.25f};
 +                      if (show_axis_y) {
 +                              UI_make_axis_color(col_grid, col_axis, 'Y');
 +                              immAttrib3ubv(color, col_axis);
 +                              immVertex3f(pos, 0.0f, -grid, 0.0f);
 +                              immVertex3f(pos, 0.0f, +grid, 0.0f);
 +                      }
  
 -      if (!rv3d->render_engine || !rv3d->render_engine->text[0])
 -              return;
 -      
 -      if (render_border) {
 -              /* draw darkened background color. no alpha because border render does
 -               * partial redraw and will not redraw the region behind this info bar */
 -              float alpha = 1.0f - fill_color[3];
 -              Camera *camera = ED_view3d_camera_data_get(v3d, rv3d);
 -
 -              if (camera) {
 -                      if (camera->flag & CAM_SHOWPASSEPARTOUT) {
 -                              alpha *= (1.0f - camera->passepartalpha);
 +                      if (show_axis_z) {
 +                              UI_make_axis_color(col_grid, col_axis, 'Z');
 +                              immAttrib3ubv(color, col_axis);
 +                              immVertex3f(pos, 0.0f, 0.0f, -grid);
 +                              immVertex3f(pos, 0.0f, 0.0f, +grid);
                        }
 +
 +                      immEnd();
 +                      immUnbindProgram();
                }
  
 -              UI_GetThemeColor3fv(TH_HIGH_GRAD, fill_color);
 -              mul_v3_fl(fill_color, alpha);
 -              fill_color[3] = 1.0f;
 +              if (!write_depth)
 +                      glDepthMask(GL_TRUE);
        }
 -
 -      ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
  }
  
 -static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
 +/** could move this elsewhere, but tied into #ED_view3d_grid_scale */
 +float ED_scene_grid_scale(Scene *scene, const char **grid_unit)
  {
 -      wmWindow *win = CTX_wm_window(C);
 -
 -      if ((scene->r.scemode & R_MULTIVIEW) == 0)
 -              return false;
 -
 -      if (WM_stereo3d_enabled(win, true) == false)
 -              return false;
 -
 -      if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
 -              return false;
 +      /* apply units */
 +      if (scene->unit.system) {
 +              const void *usys;
 +              int len;
  
 -      if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
 -              if (v3d->stereo3d_camera == STEREO_MONO_ID)
 -                      return false;
 +              bUnit_GetSystem(scene->unit.system, B_UNIT_LENGTH, &usys, &len);
  
 -              return BKE_scene_multiview_is_stereo3d(&scene->r);
 +              if (usys) {
 +                      int i = bUnit_GetBaseUnit(usys);
 +                      if (grid_unit)
 +                              *grid_unit = bUnit_GetNameDisplay(usys, i);
 +                      return (float)bUnit_GetScaler(usys, i) / scene->unit.scale_length;
 +              }
        }
  
 -      return true;
 +      return 1.0f;
 +}
 +
 +float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
 +{
 +      return v3d->grid * ED_scene_grid_scale(scene, grid_unit);
  }
  
 -/* setup the view and win matrices for the multiview cameras
 - *
 - * unlike view3d_stereo3d_setup_offscreen, when view3d_stereo3d_setup is called
 - * we have no winmatrix (i.e., projection matrix) defined at that time.
 - * Since the camera and the camera shift are needed for the winmat calculation
 - * we do a small hack to replace it temporarily so we don't need to change the
 - * view3d)main_region_setup_view() code to account for that.
 - */
 -static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
 -{
 -      bool is_left;
 -      const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
 -      const char *viewname;
 +/**
 + *
 + */
 +static void view3d_draw_grid(const bContext *C, ARegion *ar)
 +{
 +      /* TODO viewport
 +       * Missing is the flags to check whether to draw it
 +       * for now now we are using the flags in v3d itself.
 +       *
 +       * Also for now always assume depth is there, so we
 +       * draw on top of it.
 +       */
++      /**
++       * Calculate pixel-size factor once, is used for lamps and object centers.
++       * Used by #ED_view3d_pixel_size and typically not accessed directly.
++       *
++       * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
++       * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
++       * but in perspective mode its offset by the near-clip.
++       *
++       * 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
++       */
 +      Scene *scene = CTX_data_scene(C);
 +      View3D *v3d = CTX_wm_view3d(C);
 +      RegionView3D *rv3d = ar->regiondata;
 +
 +      const bool draw_floor = (rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO);
 +      const char *grid_unit = NULL;
  
 -      /* show only left or right camera */
 -      if (v3d->stereo3d_camera != STEREO_3D_ID)
 -              v3d->multiview_eye = v3d->stereo3d_camera;
 +      /* ortho grid goes first, does not write to depth buffer and doesn't need depth test so it will override
 +       * objects if done last
 +       * needs to be done always, gridview is adjusted in drawgrid() now, but only for ortho views.
 +       */
 +      rv3d->gridview = ED_view3d_grid_scale(scene, v3d, &grid_unit);
  
 -      is_left = v3d->multiview_eye == STEREO_LEFT_ID;
 -      viewname = names[is_left ? STEREO_LEFT_ID : STEREO_RIGHT_ID];
 +      glEnable(GL_DEPTH_TEST);
 +      glDepthMask(GL_FALSE); /* read & test depth, but don't alter it. TODO: separate UI depth buffer */
  
 -      /* update the viewport matrices with the new camera */
 -      if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
 -              Camera *data;
 -              float viewmat[4][4];
 -              float shiftx;
 +      if (!draw_floor) {
 +              ED_region_pixelspace(ar);
 +              *(&grid_unit) = NULL;  /* drawgrid need this to detect/affect smallest valid unit... */
 +              drawgrid(&scene->unit, ar, v3d, &grid_unit);
  
 -              data = (Camera *)v3d->camera->data;
 -              shiftx = data->shiftx;
 +              glMatrixMode(GL_PROJECTION);
 +              glLoadMatrixf(rv3d->winmat);
 +              glMatrixMode(GL_MODELVIEW);
 +              glLoadMatrixf(rv3d->viewmat);
 +      }
 +      else {
 +              drawfloor(scene, v3d, &grid_unit, false);
 +      }
  
 -              BLI_lock_thread(LOCK_VIEW3D);
 -              data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
 +      glDisable(GL_DEPTH_TEST);
 +}
  
 -              BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
 -              view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
 +/* ******************** non-meshes ***************** */
  
 -              data->shiftx = shiftx;
 -              BLI_unlock_thread(LOCK_VIEW3D);
 +static void view3d_draw_non_mesh(
 +Scene *scene, Object *ob, Base *base, View3D *v3d,
 +RegionView3D *rv3d, const bool is_boundingbox, const unsigned char color[4])
 +{
 +      glMatrixMode(GL_PROJECTION);
 +      glPushMatrix();
 +      glMatrixMode(GL_MODELVIEW);
 +      glPushMatrix();
 +
 +      /* multiply view with object matrix.
 +      * local viewmat and persmat, to calculate projections */
 +      ED_view3d_init_mats_rv3d_gl(ob, rv3d);
 +
 +      switch (ob->type) {
 +              case OB_MESH:
 +              case OB_FONT:
 +              case OB_CURVE:
 +              case OB_SURF:
 +              case OB_MBALL:
 +                      if (is_boundingbox) {
 +                              draw_bounding_volume(ob, ob->boundtype);
 +                      }
 +                      break;
 +              case OB_EMPTY:
 +                      drawaxes(rv3d->viewmatob, ob->empty_drawsize, ob->empty_drawtype, color);
 +                      break;
 +              case OB_LAMP:
 +                      drawlamp(v3d, rv3d, base, OB_SOLID, DRAW_CONSTCOLOR, color, ob == OBACT);
 +                      break;
 +              case OB_CAMERA:
 +                      drawcamera(scene, v3d, rv3d, base, DRAW_CONSTCOLOR, color);
 +                      break;
 +              case OB_SPEAKER:
 +                      drawspeaker(color);
 +                      break;
 +              case OB_LATTICE:
 +                      /* TODO */
 +                      break;
 +              case OB_ARMATURE:
 +                      /* TODO */
 +                      break;
 +              default:
 +              /* TODO Viewport: handle the other cases*/
 +                      break;
        }
 -      else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
 -              float viewmat[4][4];
 -              Object *view_ob = v3d->camera;
 -              Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
  
 -              BLI_lock_thread(LOCK_VIEW3D);
 -              v3d->camera = camera;
 +      if (ob->rigidbody_object) {
 +              draw_rigidbody_shape(ob);
 +      }
  
 -              BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
 -              view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
 +      ED_view3d_clear_mats_rv3d(rv3d);
  
 -              v3d->camera = view_ob;
 -              BLI_unlock_thread(LOCK_VIEW3D);
 -      }
 +      glMatrixMode(GL_PROJECTION);
 +      glPopMatrix();
 +      glMatrixMode(GL_MODELVIEW);
 +      glPopMatrix();
  }
  
 -static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
 -                                            float winmat[4][4], const char *viewname)
 +/* ******************** info ***************** */
 +
 +/**
 +* Render and camera border
 +*/
 +static void view3d_draw_border(const bContext *C, ARegion *ar)
  {
 -      /* update the viewport matrices with the new camera */
 -      if (scene->r.views_format == SCE_VIEWS_FORMAT_STEREO_3D) {
 -              float viewmat[4][4];
 -              const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
 +      Scene *scene = CTX_data_scene(C);
 +      RegionView3D *rv3d = ar->regiondata;
 +      View3D *v3d = CTX_wm_view3d(C);
  
 -              BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
 -              view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
 +      if (rv3d->persp == RV3D_CAMOB) {
 +              drawviewborder(scene, ar, v3d);
        }
 -      else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
 -              float viewmat[4][4];
 -              Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
 -
 -              BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
 -              view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
 +      else if (v3d->flag2 & V3D_RENDER_BORDER) {
 +              drawrenderborder(ar, v3d);
        }
  }
  
Simple merge