Viewport: MSAA support during ViewportRendering
authorJeroen Bakker <j.bakker@atmind.nl>
Tue, 21 May 2019 08:33:45 +0000 (10:33 +0200)
committerJeroen Bakker <j.bakker@atmind.nl>
Tue, 21 May 2019 14:10:48 +0000 (16:10 +0200)
When rendering viewport to an offscreen buffer the buffer was
constructed for non anti aliasing (0 samples). This made the objects
that are drawn by the `object_mode` including `wireframe` draw type
non-anti-aliased.

The offscreen buffers will be constructed based on the user setting for
viewport multisampling (`U.ogl_multisamples`). The same setting will
also be used when previewing scene strips in the sequencer. For now
this only improves wireframe drawing in the scene strips. To improve the
Anti aliasing in the scene strips we need to get finer control in the
draw manager. This will be part of a different patch I am preparing.

Please note that this patch also cleansup some unused code in the offscreen rendering (FSAA code was still existing, but never called)

Reviewed By: brecht

Maniphest Tasks: T64849

Differential Revision: https://developer.blender.org/D4907

source/blender/blenkernel/intern/sequencer.c
source/blender/editors/include/ED_view3d.h
source/blender/editors/render/render_opengl.c
source/blender/editors/sculpt_paint/paint_image_proj.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/makesdna/DNA_view3d_types.h
source/blender/windowmanager/intern/wm_files.c

index c7dd5db..92f951e 100644 (file)
@@ -3546,7 +3546,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context,
         IB_rect,
         draw_flags,
         scene->r.alphamode,
-        0, /* no aa samples */
+        U.ogl_multisamples,
         viewname,
         context->gpu_offscreen,
         err_out);
index 055bd36..5ce9133 100644 (file)
@@ -584,7 +584,6 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf(struct Depsgraph *depsgraph,
                                              int sizex,
                                              int sizey,
                                              unsigned int flag,
-                                             unsigned int draw_flags,
                                              int alpha_mode,
                                              int samples,
                                              const char *viewname,
index 342c626..20229b6 100644 (file)
@@ -114,7 +114,6 @@ typedef struct OGLRender {
 
   GPUOffScreen *ofs;
   int ofs_samples;
-  bool ofs_full_samples;
   int sizex, sizey;
   int write_still;
 
@@ -356,9 +355,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
     ImBuf *ibuf_view;
     const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL;
 
-    unsigned int draw_flags = V3D_OFSDRAW_NONE;
-    draw_flags |= (oglrender->ofs_full_samples) ? V3D_OFSDRAW_USE_FULL_SAMPLE : 0;
-
     if (view_context) {
       ibuf_view = ED_view3d_draw_offscreen_imbuf(depsgraph,
                                                  scene,
@@ -368,7 +364,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
                                                  sizex,
                                                  sizey,
                                                  IB_rectfloat,
-                                                 draw_flags,
                                                  alpha_mode,
                                                  oglrender->ofs_samples,
                                                  viewname,
@@ -381,7 +376,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
       }
     }
     else {
-      draw_flags |= V3D_OFSDRAW_SHOW_ANNOTATION;
       ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
                                                         scene,
                                                         NULL,
@@ -390,7 +384,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R
                                                         oglrender->sizex,
                                                         oglrender->sizey,
                                                         IB_rectfloat,
-                                                        draw_flags,
+                                                        V3D_OFSDRAW_SHOW_ANNOTATION,
                                                         alpha_mode,
                                                         oglrender->ofs_samples,
                                                         viewname,
@@ -532,6 +526,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
   const bool is_animation = RNA_boolean_get(op->ptr, "animation");
   const bool is_sequencer = RNA_boolean_get(op->ptr, "sequencer");
   const bool is_write_still = RNA_boolean_get(op->ptr, "write_still");
+  const int samples = U.ogl_multisamples;
   char err_out[256] = "unknown";
 
   if (G.background) {
@@ -576,7 +571,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
 
   /* corrects render size with actual size, not every card supports non-power-of-two dimensions */
   DRW_opengl_context_enable(); /* Offscreen creation needs to be done in DRW context. */
-  ofs = GPU_offscreen_create(sizex, sizey, 0, true, true, err_out);
+  ofs = GPU_offscreen_create(sizex, sizey, samples, true, true, err_out);
   DRW_opengl_context_disable();
 
   if (!ofs) {
@@ -597,6 +592,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
   oglrender->view_layer = CTX_data_view_layer(C);
   oglrender->depsgraph = CTX_data_depsgraph(C);
   oglrender->cfrao = scene->r.cfra;
+  oglrender->ofs_samples = samples;
 
   oglrender->write_still = is_write_still && !is_animation;
   oglrender->is_animation = is_animation;
index d7553d1..303c3fa 100644 (file)
@@ -6188,7 +6188,6 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
                                         w,
                                         h,
                                         IB_rect,
-                                        V3D_OFSDRAW_NONE,
                                         R_ALPHAPREMUL,
                                         0,
                                         NULL,
index 54955c8..2ce67bf 100644 (file)
@@ -1595,7 +1595,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
                                       int sizex,
                                       int sizey,
                                       uint flag,
-                                      uint draw_flags,
                                       int alpha_mode,
                                       int samples,
                                       const char *viewname,
@@ -1605,7 +1604,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
 {
   RegionView3D *rv3d = ar->regiondata;
   const bool draw_sky = (alpha_mode == R_ADDSKY);
-  const bool use_full_sample = (draw_flags & V3D_OFSDRAW_USE_FULL_SAMPLE);
 
   /* view state */
   bool is_ortho = false;
@@ -1627,7 +1625,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
 
   if (own_ofs) {
     /* bind */
-    ofs = GPU_offscreen_create(sizex, sizey, use_full_sample ? 0 : samples, true, false, err_out);
+    ofs = GPU_offscreen_create(sizex, sizey, samples, true, false, err_out);
     if (ofs == NULL) {
       DRW_opengl_context_disable();
       return NULL;
@@ -1683,120 +1681,28 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Depsgraph *depsgraph,
     }
   }
 
-  if ((samples && use_full_sample) == 0) {
-    const bool do_color_management = (ibuf->rect_float == NULL);
-    /* Single-pass render, common case */
-    ED_view3d_draw_offscreen(depsgraph,
-                             scene,
-                             drawtype,
-                             v3d,
-                             ar,
-                             sizex,
-                             sizey,
-                             NULL,
-                             winmat,
-                             draw_sky,
-                             !is_ortho,
-                             viewname,
-                             do_color_management,
-                             ofs,
-                             NULL);
-
-    if (ibuf->rect_float) {
-      GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
-    }
-    else if (ibuf->rect) {
-      GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
-    }
-  }
-  else {
-    /* Multi-pass render, use accumulation buffer & jitter for 'full' oversampling.
-     * Use because OpenGL may use a lower quality MSAA, and only over-sample edges. */
-    static float jit_ofs[32][2];
-    float winmat_jitter[4][4];
-    float *rect_temp = (ibuf->rect_float) ?
-                           ibuf->rect_float :
-                           MEM_mallocN(sizex * sizey * sizeof(float[4]), "rect_temp");
-    float *accum_buffer = MEM_mallocN(sizex * sizey * sizeof(float[4]), "accum_buffer");
-    GPUViewport *viewport = GPU_viewport_create_from_offscreen(ofs);
-
-    BLI_jitter_init(jit_ofs, samples);
-
-    /* first sample buffer, also initializes 'rv3d->persmat' */
-    ED_view3d_draw_offscreen(depsgraph,
-                             scene,
-                             drawtype,
-                             v3d,
-                             ar,
-                             sizex,
-                             sizey,
-                             NULL,
-                             winmat,
-                             draw_sky,
-                             !is_ortho,
-                             viewname,
-                             false,
-                             ofs,
-                             viewport);
-    GPU_offscreen_read_pixels(ofs, GL_FLOAT, accum_buffer);
-
-    /* skip the first sample */
-    for (int j = 1; j < samples; j++) {
-      copy_m4_m4(winmat_jitter, winmat);
-      window_translate_m4(winmat_jitter,
-                          rv3d->persmat,
-                          (jit_ofs[j][0] * 2.0f) / sizex,
-                          (jit_ofs[j][1] * 2.0f) / sizey);
-
-      ED_view3d_draw_offscreen(depsgraph,
-                               scene,
-                               drawtype,
-                               v3d,
-                               ar,
-                               sizex,
-                               sizey,
-                               NULL,
-                               winmat_jitter,
-                               draw_sky,
-                               !is_ortho,
-                               viewname,
-                               false,
-                               ofs,
-                               viewport);
-      GPU_offscreen_read_pixels(ofs, GL_FLOAT, rect_temp);
-
-      uint i = sizex * sizey * 4;
-      while (i--) {
-        accum_buffer[i] += rect_temp[i];
-      }
-    }
-
-    {
-      /* don't free data owned by 'ofs' */
-      GPU_viewport_clear_from_offscreen(viewport);
-      GPU_viewport_free(viewport);
-    }
+  const bool do_color_management = (ibuf->rect_float == NULL);
+  ED_view3d_draw_offscreen(depsgraph,
+                           scene,
+                           drawtype,
+                           v3d,
+                           ar,
+                           sizex,
+                           sizey,
+                           NULL,
+                           winmat,
+                           draw_sky,
+                           !is_ortho,
+                           viewname,
+                           do_color_management,
+                           ofs,
+                           NULL);
 
-    if (ibuf->rect_float == NULL) {
-      MEM_freeN(rect_temp);
-    }
-
-    if (ibuf->rect_float) {
-      float *rect_float = ibuf->rect_float;
-      uint i = sizex * sizey * 4;
-      while (i--) {
-        rect_float[i] = accum_buffer[i] / samples;
-      }
-    }
-    else {
-      uchar *rect_ub = (uchar *)ibuf->rect;
-      uint i = sizex * sizey * 4;
-      while (i--) {
-        rect_ub[i] = (uchar)(255.0f * accum_buffer[i] / samples);
-      }
-    }
-
-    MEM_freeN(accum_buffer);
+  if (ibuf->rect_float) {
+    GPU_offscreen_read_pixels(ofs, GL_FLOAT, ibuf->rect_float);
+  }
+  else if (ibuf->rect) {
+    GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect);
   }
 
   /* unbind */
@@ -1905,7 +1811,6 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Depsgraph *depsgraph,
                                         width,
                                         height,
                                         flag,
-                                        draw_flags,
                                         alpha_mode,
                                         samples,
                                         viewname,
index d5ac8cc..0170b27 100644 (file)
@@ -584,9 +584,8 @@ enum {
 /** Settings for offscreen rendering */
 enum {
   V3D_OFSDRAW_NONE = (0),
-  V3D_OFSDRAW_USE_FULL_SAMPLE = (1 << 0),
-  V3D_OFSDRAW_SHOW_ANNOTATION = (1 << 1),
-  V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS = (1 << 2),
+  V3D_OFSDRAW_SHOW_ANNOTATION = (1 << 0),
+  V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS = (1 << 1),
 };
 
 #define RV3D_CAMZOOM_MIN -30
index 9cfab63..92c37da 100644 (file)
@@ -1245,7 +1245,6 @@ static ImBuf *blend_file_thumb(const bContext *C,
                                           BLEN_THUMB_SIZE * 2,
                                           BLEN_THUMB_SIZE * 2,
                                           IB_rect,
-                                          V3D_OFSDRAW_NONE,
                                           R_ALPHAPREMUL,
                                           0,
                                           NULL,