Overlay-Next: Initial implementation #107045

Closed
Clément Foucault wants to merge 28 commits from fclem/blender:overlay-next into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 191 additions and 79 deletions
Showing only changes of commit 64d9660fc4 - Show all commits

View File

@ -6,6 +6,8 @@
#pragma once
#include "DEG_depsgraph_query.h"
#include "DNA_camera_types.h"
#include "DNA_space_types.h"
#include "ED_view3d.h"
@ -17,21 +19,22 @@
namespace blender::draw::overlay {
class Grid {
public:
private:
UniformBuffer<OVERLAY_GridData> data_;
bool enabled = false;
PassSimple grid_ps_ = {"grid_ps_"};
float3 grid_axes = float3(0.0f);
float3 zplane_axes = float3(0.0f);
OVERLAY_GridBits grid_flag_;
OVERLAY_GridBits zneg_flag_;
OVERLAY_GridBits zpos_flag_;
float3 grid_axes_ = float3(0.0f);
float3 zplane_axes_ = float3(0.0f);
OVERLAY_GridBits grid_flag_ = OVERLAY_GridBits(0);
OVERLAY_GridBits zneg_flag_ = OVERLAY_GridBits(0);
OVERLAY_GridBits zpos_flag_ = OVERLAY_GridBits(0);
bool enabled_ = false;
public:
void update_ubo()
void update_ubo(const State &state, const View &view)
{
float grid_steps[SI_GRID_STEPS_LEN] = {
0.001f, 0.01f, 0.1f, 1.0f, 10.0f, 100.0f, 1000.0f, 10000.0f};
@ -40,31 +43,25 @@ class Grid {
/* Default, nothing is drawn. */
grid_flag_ = zneg_flag_ = zpos_flag_ = OVERLAY_GridBits(0);
/* SPACE_VIEW3D */
Scene *scene = DRW_context_state_get()->scene;
View3D *v3d = DRW_context_state_get()->v3d;
RegionView3D *rv3d = DRW_context_state_get()->rv3d;
View3D *v3d = state.v3d;
RegionView3D *rv3d = state.rv3d;
const bool show_axis_x = true; //(pd->v3d_gridflag & V3D_SHOW_X) != 0;
const bool show_axis_y = true; //(pd->v3d_gridflag & V3D_SHOW_Y) != 0;
const bool show_axis_z = true; //(pd->v3d_gridflag & V3D_SHOW_Z) != 0;
const bool show_floor = true; //(pd->v3d_gridflag & V3D_SHOW_FLOOR) != 0;
const bool show_ortho_grid = true; //(pd->v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
const bool show_axis_x = (state.v3d_gridflag & V3D_SHOW_X) != 0;
const bool show_axis_y = (state.v3d_gridflag & V3D_SHOW_Y) != 0;
const bool show_axis_z = (state.v3d_gridflag & V3D_SHOW_Z) != 0;
const bool show_floor = (state.v3d_gridflag & V3D_SHOW_FLOOR) != 0;
const bool show_ortho_grid = (state.v3d_gridflag & V3D_SHOW_ORTHO_GRID) != 0;
const bool show_any = show_axis_x || show_axis_y || show_axis_z || show_floor ||
show_ortho_grid;
// if (pd->hide_overlays || !(pd->v3d_gridflag & (V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z |
// V3D_SHOW_FLOOR | V3D_SHOW_ORTHO_GRID))) {
// return;
// }
enabled_ = !state.hide_overlays && show_any;
float viewinv[4][4], wininv[4][4];
float viewmat[4][4], winmat[4][4];
DRW_view_winmat_get(nullptr, winmat, false);
DRW_view_winmat_get(nullptr, wininv, true);
DRW_view_viewmat_get(nullptr, viewmat, false);
DRW_view_viewmat_get(nullptr, viewinv, true);
if (!enabled_) {
return;
}
/* If perspective view or non-axis aligned view. */
if (winmat[3][3] == 0.0f || rv3d->view == RV3D_VIEW_USER) {
if (view.is_persp() || rv3d->view == RV3D_VIEW_USER) {
if (show_axis_x) {
grid_flag_ |= PLANE_XY | SHOW_AXIS_X;
}
@ -87,17 +84,16 @@ class Grid {
}
}
grid_axes[0] = float((grid_flag_ & (PLANE_XZ | PLANE_XY)) != 0);
grid_axes[1] = float((grid_flag_ & (PLANE_YZ | PLANE_XY)) != 0);
grid_axes[2] = float((grid_flag_ & (PLANE_YZ | PLANE_XZ)) != 0);
grid_axes_[0] = float((grid_flag_ & (PLANE_XZ | PLANE_XY)) != 0);
grid_axes_[1] = float((grid_flag_ & (PLANE_YZ | PLANE_XY)) != 0);
grid_axes_[2] = float((grid_flag_ & (PLANE_YZ | PLANE_XZ)) != 0);
/* Z axis if needed */
if (((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) && show_axis_z) {
zpos_flag_ = SHOW_AXIS_Z;
float zvec[3], campos[3];
negate_v3_v3(zvec, viewinv[2]);
copy_v3_v3(campos, viewinv[3]);
float3 zvec = -float3(view.viewinv()[2]);
float3 campos = float3(view.viewinv()[3]);
/* z axis : chose the most facing plane */
if (fabsf(zvec[0]) < fabsf(zvec[1])) {
@ -106,13 +102,11 @@ class Grid {
else {
zpos_flag_ |= PLANE_YZ;
}
zneg_flag_ = zpos_flag_;
/* Perspective: If camera is below floor plane, we switch clipping.
* Orthographic: If eye vector is looking up, we switch clipping. */
if (((winmat[3][3] == 0.0f) && (campos[2] > 0.0f)) ||
((winmat[3][3] != 0.0f) && (zvec[2] < 0.0f))) {
if ((view.is_persp() && (campos[2] > 0.0f)) || (!view.is_persp() && (zvec[2] < 0.0f))) {
zpos_flag_ |= CLIP_ZPOS;
zneg_flag_ |= CLIP_ZNEG;
}
@ -121,44 +115,44 @@ class Grid {
zneg_flag_ |= CLIP_ZPOS;
}
zplane_axes[0] = float((zpos_flag_ & (PLANE_XZ | PLANE_XY)) != 0);
zplane_axes[1] = float((zpos_flag_ & (PLANE_YZ | PLANE_XY)) != 0);
zplane_axes[2] = float((zpos_flag_ & (PLANE_YZ | PLANE_XZ)) != 0);
zplane_axes_[0] = float((zpos_flag_ & (PLANE_XZ | PLANE_XY)) != 0);
zplane_axes_[1] = float((zpos_flag_ & (PLANE_YZ | PLANE_XY)) != 0);
zplane_axes_[2] = float((zpos_flag_ & (PLANE_YZ | PLANE_XZ)) != 0);
}
else {
zneg_flag_ = zpos_flag_ = CLIP_ZNEG | CLIP_ZPOS;
}
float dist;
// if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) {
// Object *camera_object = DEG_get_evaluated_object(draw_ctx->depsgraph, v3d->camera);
// dist = ((Camera *)(camera_object->data))->clip_end;
// grid_flag_ |= GRID_CAMERA;
// zneg_flag_ |= GRID_CAMERA;
// zpos_flag_ |= GRID_CAMERA;
// }
// else {
dist = v3d->clip_end;
// }
if (winmat[3][3] == 0.0f) {
copy_v3_fl(data_.size, dist);
if (rv3d->persp == RV3D_CAMOB && v3d->camera && v3d->camera->type == OB_CAMERA) {
Object *camera_object = DEG_get_evaluated_object(state.depsgraph, v3d->camera);
dist = ((Camera *)(camera_object->data))->clip_end;
grid_flag_ |= GRID_CAMERA;
zneg_flag_ |= GRID_CAMERA;
zpos_flag_ |= GRID_CAMERA;
}
else {
float viewdist = 1.0f / min_ff(fabsf(winmat[0][0]), fabsf(winmat[1][1]));
copy_v3_fl(data_.size, viewdist * dist);
dist = v3d->clip_end;
}
if (view.is_persp()) {
data_.size = float4(dist);
}
else {
float viewdist = 1.0f / min_ff(fabsf(view.winmat()[0][0]), fabsf(view.winmat()[1][1]));
data_.size = float4(viewdist * dist);
}
data_.distance = dist / 2.0f;
ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps);
ED_view3d_grid_steps(state.scene, v3d, rv3d, grid_steps);
if ((v3d->flag & (V3D_XR_SESSION_SURFACE | V3D_XR_SESSION_MIRROR)) != 0) {
/* The calculations for the grid parameters assume that the view matrix has no scale
* component, which may not be correct if the user is "shrunk" or "enlarged" by zooming in or
* out. Therefore, we need to compensate the values here. */
/* Assumption is uniform scaling (all column vectors are of same length). */
float viewinvscale = len_v3(viewinv[0]);
float viewinvscale = len_v3(view.viewinv()[0]);
data_.distance *= viewinvscale;
}
@ -171,26 +165,45 @@ class Grid {
data_.push_update();
}
void begin_sync()
void begin_sync(Resources &res, const State &state, const View &view)
{
update_ubo();
this->update_ubo(state, view);
if (!enabled_) {
return;
}
grid_ps_.init();
grid_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA);
grid_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f));
grid_ps_.shader_set(OVERLAY_shader_grid());
grid_ps_.bind_ubo("grid_buf", &data_);
grid_ps_.bind_ubo("globalsBlock", &G_draw.block_ubo);
grid_ps_.bind_texture("depth_tx", &DRW_viewport_texture_list_get()->depth);
grid_ps_.push_constant("grid_flag", grid_flag_);
grid_ps_.push_constant("plane_axes", grid_axes);
grid_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 0.0f));
grid_ps_.draw(DRW_cache_grid_get());
grid_ps_.bind_ubo("globalsBlock", &res.globals_buf);
grid_ps_.bind_texture("depth_tx", &res.depth_tx);
if (zneg_flag_ & SHOW_AXIS_Z) {
grid_ps_.push_constant("grid_flag", zneg_flag_);
grid_ps_.push_constant("plane_axes", zplane_axes_);
grid_ps_.draw(DRW_cache_grid_get());
}
if (grid_flag_) {
grid_ps_.push_constant("grid_flag", grid_flag_);
grid_ps_.push_constant("plane_axes", grid_axes_);
grid_ps_.draw(DRW_cache_grid_get());
}
if (zpos_flag_ & SHOW_AXIS_Z) {
grid_ps_.push_constant("grid_flag", zpos_flag_);
grid_ps_.push_constant("plane_axes", zplane_axes_);
grid_ps_.draw(DRW_cache_grid_get());
}
}
void draw(Manager &manager, View &view)
void draw(Resources &res, Manager &manager, View &view)
{
if (!enabled_) {
return;
}
GPU_framebuffer_bind(res.overlay_color_only_fb);
manager.submit(grid_ps_, view);
}
};

View File

@ -10,14 +10,57 @@ namespace blender::draw::overlay {
void Instance::init()
{
GPUTexture *viewport_depth_tx = DRW_viewport_texture_list_get()->depth;
GPUTexture *viewport_color_tx = DRW_viewport_texture_list_get()->color_overlay;
overlay_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(viewport_color_tx));
resources.depth_tx.wrap(DRW_viewport_texture_list_get()->depth);
resources.color_tx.wrap(DRW_viewport_texture_list_get()->color_overlay);
/* TODO(fclem): Remove DRW global usage. */
const DRWContextState *ctx = DRW_context_state_get();
state.depsgraph = ctx->depsgraph;
state.scene = ctx->scene;
state.v3d = ctx->v3d;
state.rv3d = ctx->rv3d;
state.pixelsize = U.pixelsize;
state.ctx_mode = CTX_data_mode_enum_ex(ctx->object_edit, ctx->obact, ctx->object_mode);
state.clear_in_front = (state.v3d->shading.type != OB_SOLID);
state.use_in_front = (state.v3d->shading.type <= OB_SOLID) ||
BKE_scene_uses_blender_workbench(state.scene);
state.is_wireframe_mode = (state.v3d->shading.type == OB_WIRE);
state.hide_overlays = (state.v3d->flag2 & V3D_HIDE_OVERLAYS) != 0;
state.xray_enabled = XRAY_ACTIVE(state.v3d);
state.xray_enabled_and_not_wire = state.xray_enabled && (state.v3d->shading.type > OB_WIRE);
state.xray_opacity = XRAY_ALPHA(state.v3d);
state.cfra = DEG_get_ctime(state.depsgraph);
state.clipping_state = RV3D_CLIPPING_ENABLED(state.v3d, state.rv3d) ? DRW_STATE_CLIP_PLANES :
DRWState(0);
if (!state.hide_overlays) {
state.overlay = state.v3d->overlay;
state.v3d_flag = state.v3d->flag;
state.v3d_gridflag = state.v3d->gridflag;
}
else {
memset(&state.overlay, 0, sizeof(state.overlay));
state.v3d_flag = 0;
state.v3d_gridflag = 0;
state.overlay.flag = V3D_OVERLAY_HIDE_TEXT | V3D_OVERLAY_HIDE_MOTION_PATHS |
V3D_OVERLAY_HIDE_BONES | V3D_OVERLAY_HIDE_OBJECT_XTRAS |
V3D_OVERLAY_HIDE_OBJECT_ORIGINS;
state.overlay.wireframe_threshold = state.v3d->overlay.wireframe_threshold;
state.overlay.wireframe_opacity = state.v3d->overlay.wireframe_opacity;
}
/* TODO(fclem): Remove DRW global usage. */
resources.globals_buf = G_draw.block_ubo;
}
void Instance::begin_sync()
{
grid.begin_sync();
const DRWView *view_legacy = DRW_view_default_get();
View view("OverlayView", view_legacy);
grid.begin_sync(resources, state, view);
}
void Instance::object_sync(ObjectRef &ob_ref)
@ -31,11 +74,24 @@ void Instance::end_sync()
void Instance::draw(Manager &manager)
{
const DRWView *view_old = DRW_view_default_get();
View view("OverlayView", view_old);
const DRWView *view_legacy = DRW_view_default_get();
View view("OverlayView", view_legacy);
GPU_framebuffer_bind(overlay_fb);
grid.draw(manager, view);
resources.line_tx.acquire(int2(resources.depth_tx.size()), GPU_RGBA8);
resources.overlay_color_only_fb.ensure(GPU_ATTACHMENT_NONE,
GPU_ATTACHMENT_TEXTURE(resources.color_tx));
resources.overlay_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
GPU_ATTACHMENT_TEXTURE(resources.color_tx));
resources.overlay_line_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx),
GPU_ATTACHMENT_TEXTURE(resources.color_tx),
GPU_ATTACHMENT_TEXTURE(resources.line_tx));
grid.draw(resources, manager, view);
// anti_aliasing.draw(resources, manager, view);
resources.line_tx.release();
}
} // namespace blender::draw::overlay

View File

@ -51,8 +51,8 @@ class Instance {
/* WORKAROUND: Legacy. Move to grid pass. */
GPUUniformBuf *grid_ubo = nullptr;
Framebuffer overlay_fb = {"overlay_fb"};
Resources resources;
State state;
Grid grid;
~Instance()

View File

@ -7,6 +7,7 @@
#pragma once
#include "DRW_gpu_wrapper.hh"
#include "DRW_render.h"
#include "overlay_shader_shared.h"
@ -29,7 +30,49 @@ struct ImBuf;
namespace blender::draw::overlay {
class Instance;
}
struct State {
Depsgraph *depsgraph;
Scene *scene;
View3D *v3d;
RegionView3D *rv3d;
View3DOverlay overlay;
float pixelsize;
enum eContextObjectMode ctx_mode;
bool clear_in_front;
bool use_in_front;
bool is_wireframe_mode;
bool hide_overlays;
bool xray_enabled;
bool xray_enabled_and_not_wire;
float xray_opacity;
short v3d_flag; /* TODO: move to #View3DOverlay. */
short v3d_gridflag; /* TODO: move to #View3DOverlay. */
int cfra;
DRWState clipping_state;
};
using blender::draw::Framebuffer;
using blender::draw::Texture;
using blender::draw::TextureFromPool;
using blender::draw::TextureRef;
struct Resources {
Framebuffer overlay_fb = {"overlay_fb"};
Framebuffer overlay_in_front_fb = {"overlay_in_front_fb"};
Framebuffer overlay_color_only_fb = {"overlay_color_only_fb"};
Framebuffer overlay_line_fb = {"overlay_line_fb"};
Framebuffer overlay_line_in_front_fb = {"overlay_line_in_front_fb"};
TextureFromPool line_tx = {"line_tx"};
/* References, not owned. */
GPUUniformBuf *globals_buf;
TextureRef depth_tx;
TextureRef color_tx;
};
} // namespace blender::draw::overlay
typedef struct OVERLAY_FramebufferList {
struct GPUFrameBuffer *overlay_default_fb;