Overlay-Next: Initial implementation #107045
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue