DRW: Remove legacy DRWView
No functional change expected.
This commit is contained in:
@@ -184,7 +184,7 @@ void Instance::view_update()
|
||||
/** \name Sync
|
||||
*
|
||||
* Sync will gather data from the scene that can change over a time step (i.e: motion steps).
|
||||
* IMPORTANT: xxx.sync() functions area responsible for creating DRW resources (i.e: DRWView) as
|
||||
* IMPORTANT: xxx.sync() functions area responsible for creating DRW resources as
|
||||
* well as querying temp texture pool. All DRWPasses should be ready by the end end_sync().
|
||||
* \{ */
|
||||
|
||||
|
||||
@@ -82,7 +82,6 @@ typedef struct DRWPass DRWPass;
|
||||
typedef struct DRWShaderLibrary DRWShaderLibrary;
|
||||
typedef struct DRWShadingGroup DRWShadingGroup;
|
||||
typedef struct DRWUniform DRWUniform;
|
||||
typedef struct DRWView DRWView;
|
||||
|
||||
/* TODO: Put it somewhere else? */
|
||||
struct BoundSphere {
|
||||
@@ -294,35 +293,6 @@ enum eDRWAttrType {
|
||||
DRW_ATTR_FLOAT,
|
||||
};
|
||||
|
||||
/* Views. */
|
||||
|
||||
/**
|
||||
* Create a view with culling.
|
||||
*/
|
||||
DRWView *DRW_view_create(const float viewmat[4][4],
|
||||
const float winmat[4][4],
|
||||
const float (*culling_viewmat)[4],
|
||||
const float (*culling_winmat)[4]);
|
||||
/**
|
||||
* Create a view with culling done by another view.
|
||||
*/
|
||||
DRWView *DRW_view_create_sub(const DRWView *parent_view,
|
||||
const float viewmat[4][4],
|
||||
const float winmat[4][4]);
|
||||
|
||||
/**
|
||||
* Update matrices of a view created with #DRW_view_create.
|
||||
*/
|
||||
void DRW_view_update(DRWView *view,
|
||||
const float viewmat[4][4],
|
||||
const float winmat[4][4],
|
||||
const float (*culling_viewmat)[4],
|
||||
const float (*culling_winmat)[4]);
|
||||
/**
|
||||
* Update matrices of a view created with #DRW_view_create_sub.
|
||||
*/
|
||||
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4]);
|
||||
|
||||
/* Viewport. */
|
||||
|
||||
const float *DRW_viewport_size_get();
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include "draw_common_shader_shared.hh"
|
||||
|
||||
struct DRWView;
|
||||
struct FluidModifierData;
|
||||
struct GPUMaterial;
|
||||
struct GPUTexture;
|
||||
|
||||
@@ -376,7 +376,6 @@ DRWData *DRW_viewport_data_create()
|
||||
drw_data->callbuffers = BLI_memblock_create(sizeof(DRWCallBuffer));
|
||||
drw_data->shgroups = BLI_memblock_create(sizeof(DRWShadingGroup));
|
||||
drw_data->uniforms = BLI_memblock_create(sizeof(DRWUniformChunk));
|
||||
drw_data->views = BLI_memblock_create(sizeof(DRWView));
|
||||
drw_data->images = BLI_memblock_create(sizeof(GPUTexture *));
|
||||
drw_data->obattrs_ubo_pool = DRW_uniform_attrs_pool_new();
|
||||
drw_data->vlattrs_name_cache = BLI_ghash_new(
|
||||
@@ -446,7 +445,6 @@ static void drw_viewport_data_reset(DRWData *drw_data)
|
||||
BLI_memblock_clear(drw_data->shgroups, nullptr);
|
||||
BLI_memblock_clear(drw_data->uniforms, nullptr);
|
||||
BLI_memblock_clear(drw_data->passes, nullptr);
|
||||
BLI_memblock_clear(drw_data->views, nullptr);
|
||||
BLI_memblock_clear(drw_data->images, nullptr);
|
||||
DRW_uniform_attrs_pool_clear_all(drw_data->obattrs_ubo_pool);
|
||||
DRW_instance_data_list_free_unused(drw_data->idatalist);
|
||||
@@ -467,7 +465,6 @@ void DRW_viewport_data_free(DRWData *drw_data)
|
||||
BLI_memblock_destroy(drw_data->cullstates, nullptr);
|
||||
BLI_memblock_destroy(drw_data->shgroups, nullptr);
|
||||
BLI_memblock_destroy(drw_data->uniforms, nullptr);
|
||||
BLI_memblock_destroy(drw_data->views, nullptr);
|
||||
BLI_memblock_destroy(drw_data->passes, nullptr);
|
||||
BLI_memblock_destroy(drw_data->images, nullptr);
|
||||
DRW_uniform_attrs_pool_free(drw_data->obattrs_ubo_pool);
|
||||
@@ -588,11 +585,7 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
|
||||
|
||||
if (rv3d != nullptr) {
|
||||
dst->pixsize = rv3d->pixsize;
|
||||
dst->view_default = DRW_view_create(rv3d->viewmat, rv3d->winmat, nullptr, nullptr);
|
||||
blender::draw::View::default_set(float4x4(rv3d->viewmat), float4x4(rv3d->winmat));
|
||||
|
||||
dst->view_active = dst->view_default;
|
||||
dst->view_previous = nullptr;
|
||||
}
|
||||
else if (region) {
|
||||
View2D *v2d = ®ion->v2d;
|
||||
@@ -608,16 +601,10 @@ static void drw_manager_init(DRWManager *dst, GPUViewport *viewport, const int s
|
||||
winmat[3][0] = -1.0f;
|
||||
winmat[3][1] = -1.0f;
|
||||
|
||||
dst->view_default = DRW_view_create(viewmat, winmat, nullptr, nullptr);
|
||||
blender::draw::View::default_set(float4x4(viewmat), float4x4(winmat));
|
||||
dst->view_active = dst->view_default;
|
||||
dst->view_previous = nullptr;
|
||||
}
|
||||
else {
|
||||
dst->pixsize = 1.0f;
|
||||
dst->view_default = nullptr;
|
||||
dst->view_active = nullptr;
|
||||
dst->view_previous = nullptr;
|
||||
}
|
||||
|
||||
/* fclem: Is this still needed ? */
|
||||
|
||||
@@ -450,42 +450,6 @@ struct DRWPass {
|
||||
char name[MAX_PASS_NAME];
|
||||
};
|
||||
|
||||
#define MAX_CULLED_VIEWS 32
|
||||
|
||||
struct DRWView {
|
||||
/**
|
||||
* These float4x4 (as well as the ViewMatrices) have alignment requirements in C++
|
||||
* (see math::MatBase) that isn't fulfilled in C. So they need to be manually aligned.
|
||||
* Since the DRWView are allocated using BLI_memblock, the chunks are given to be 16 bytes
|
||||
* aligned (equal to the alignment of float4x4). We then assert that the DRWView itself is 16
|
||||
* bytes aligned.
|
||||
*/
|
||||
float4x4 persmat;
|
||||
float4x4 persinv;
|
||||
ViewMatrices storage;
|
||||
|
||||
/** Parent view if this is a sub view. nullptr otherwise. */
|
||||
DRWView *parent;
|
||||
|
||||
float4 clip_planes[6];
|
||||
|
||||
/** Number of active clip planes. */
|
||||
int clip_planes_len;
|
||||
/** Does culling result needs to be updated. */
|
||||
bool is_dirty;
|
||||
/** Does facing needs to be reversed? */
|
||||
bool is_inverted;
|
||||
/** Culling */
|
||||
uint32_t culling_mask;
|
||||
BoundBox frustum_corners;
|
||||
BoundSphere frustum_bsphere;
|
||||
float frustum_planes[6][4];
|
||||
/** Custom visibility function. */
|
||||
void *user_data;
|
||||
};
|
||||
/* Needed to assert that alignment is the same in C++ and C. */
|
||||
BLI_STATIC_ASSERT_ALIGN(DRWView, 16);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@@ -551,7 +515,6 @@ struct DRWData {
|
||||
BLI_memblock *cullstates;
|
||||
BLI_memblock *shgroups;
|
||||
BLI_memblock *uniforms;
|
||||
BLI_memblock *views;
|
||||
BLI_memblock *passes;
|
||||
BLI_memblock *images;
|
||||
GPUUniformBuf **matrices_ubo;
|
||||
@@ -662,9 +625,6 @@ struct DRWManager {
|
||||
/** True, when drawing is in progress, see #DRW_draw_in_progress. */
|
||||
bool in_progress;
|
||||
|
||||
DRWView *view_default;
|
||||
DRWView *view_active;
|
||||
DRWView *view_previous;
|
||||
uint primary_view_num;
|
||||
|
||||
#ifdef USE_GPU_SELECT
|
||||
|
||||
@@ -59,331 +59,3 @@ eDRWCommandType command_type_get(const uint64_t *command_type_bits, int index)
|
||||
{
|
||||
return eDRWCommandType((command_type_bits[index / 16] >> ((index % 16) * 4)) & 0xF);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name View (DRW_view)
|
||||
* \{ */
|
||||
|
||||
/* Extract the 8 corners from a Projection Matrix.
|
||||
* Although less accurate, this solution can be simplified as follows:
|
||||
* BKE_boundbox_init_from_minmax(&bbox, (const float[3]){-1.0f, -1.0f, -1.0f}, (const
|
||||
* float[3]){1.0f, 1.0f, 1.0f}); for (int i = 0; i < 8; i++) {mul_project_m4_v3(projinv,
|
||||
* bbox.vec[i]);}
|
||||
*/
|
||||
static void draw_frustum_boundbox_calc(const float (*viewinv)[4],
|
||||
const float (*projmat)[4],
|
||||
BoundBox *r_bbox)
|
||||
{
|
||||
float left, right, bottom, top, near, far;
|
||||
bool is_persp = projmat[3][3] == 0.0f;
|
||||
|
||||
#if 0 /* Equivalent to this but it has accuracy problems. */
|
||||
BKE_boundbox_init_from_minmax(
|
||||
&bbox, blender::float3{-1.0f, -1.0f, -1.0f}, blender::float3{1.0f, 1.0f, 1.0f});
|
||||
for (int i = 0; i < 8; i++) {
|
||||
mul_project_m4_v3(projinv, bbox.vec[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
projmat_dimensions(projmat, &left, &right, &bottom, &top, &near, &far);
|
||||
|
||||
r_bbox->vec[0][2] = r_bbox->vec[3][2] = r_bbox->vec[7][2] = r_bbox->vec[4][2] = -near;
|
||||
r_bbox->vec[0][0] = r_bbox->vec[3][0] = left;
|
||||
r_bbox->vec[4][0] = r_bbox->vec[7][0] = right;
|
||||
r_bbox->vec[0][1] = r_bbox->vec[4][1] = bottom;
|
||||
r_bbox->vec[7][1] = r_bbox->vec[3][1] = top;
|
||||
|
||||
/* Get the coordinates of the far plane. */
|
||||
if (is_persp) {
|
||||
float sca_far = far / near;
|
||||
left *= sca_far;
|
||||
right *= sca_far;
|
||||
bottom *= sca_far;
|
||||
top *= sca_far;
|
||||
}
|
||||
|
||||
r_bbox->vec[1][2] = r_bbox->vec[2][2] = r_bbox->vec[6][2] = r_bbox->vec[5][2] = -far;
|
||||
r_bbox->vec[1][0] = r_bbox->vec[2][0] = left;
|
||||
r_bbox->vec[6][0] = r_bbox->vec[5][0] = right;
|
||||
r_bbox->vec[1][1] = r_bbox->vec[5][1] = bottom;
|
||||
r_bbox->vec[2][1] = r_bbox->vec[6][1] = top;
|
||||
|
||||
/* Transform into world space. */
|
||||
for (int i = 0; i < 8; i++) {
|
||||
mul_m4_v3(viewinv, r_bbox->vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_frustum_culling_planes_calc(const float (*persmat)[4], float (*frustum_planes)[4])
|
||||
{
|
||||
planes_from_projmat(persmat,
|
||||
frustum_planes[0],
|
||||
frustum_planes[5],
|
||||
frustum_planes[1],
|
||||
frustum_planes[3],
|
||||
frustum_planes[4],
|
||||
frustum_planes[2]);
|
||||
|
||||
/* Normalize. */
|
||||
for (int p = 0; p < 6; p++) {
|
||||
frustum_planes[p][3] /= normalize_v3(frustum_planes[p]);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_frustum_bound_sphere_calc(const BoundBox *bbox,
|
||||
const float (*viewinv)[4],
|
||||
const float (*projmat)[4],
|
||||
const float (*projinv)[4],
|
||||
BoundSphere *bsphere)
|
||||
{
|
||||
/* Extract Bounding Sphere */
|
||||
if (projmat[3][3] != 0.0f) {
|
||||
/* Orthographic */
|
||||
/* The most extreme points on the near and far plane. (normalized device coords). */
|
||||
const float *nearpoint = bbox->vec[0];
|
||||
const float *farpoint = bbox->vec[6];
|
||||
|
||||
/* just use median point */
|
||||
mid_v3_v3v3(bsphere->center, farpoint, nearpoint);
|
||||
bsphere->radius = len_v3v3(bsphere->center, farpoint);
|
||||
}
|
||||
else if (projmat[2][0] == 0.0f && projmat[2][1] == 0.0f) {
|
||||
/* Perspective with symmetrical frustum. */
|
||||
|
||||
/* We obtain the center and radius of the circumscribed circle of the
|
||||
* isosceles trapezoid composed by the diagonals of the near and far clipping plane */
|
||||
|
||||
/* center of each clipping plane */
|
||||
float mid_min[3], mid_max[3];
|
||||
mid_v3_v3v3(mid_min, bbox->vec[3], bbox->vec[4]);
|
||||
mid_v3_v3v3(mid_max, bbox->vec[2], bbox->vec[5]);
|
||||
|
||||
/* square length of the diagonals of each clipping plane */
|
||||
float a_sq = len_squared_v3v3(bbox->vec[3], bbox->vec[4]);
|
||||
float b_sq = len_squared_v3v3(bbox->vec[2], bbox->vec[5]);
|
||||
|
||||
/* distance squared between clipping planes */
|
||||
float h_sq = len_squared_v3v3(mid_min, mid_max);
|
||||
|
||||
float fac = (4 * h_sq + b_sq - a_sq) / (8 * h_sq);
|
||||
|
||||
/* The goal is to get the smallest sphere,
|
||||
* not the sphere that passes through each corner */
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
|
||||
interp_v3_v3v3(bsphere->center, mid_min, mid_max, fac);
|
||||
|
||||
/* distance from the center to one of the points of the far plane (1, 2, 5, 6) */
|
||||
bsphere->radius = len_v3v3(bsphere->center, bbox->vec[1]);
|
||||
}
|
||||
else {
|
||||
/* Perspective with asymmetrical frustum. */
|
||||
|
||||
/* We put the sphere center on the line that goes from origin
|
||||
* to the center of the far clipping plane. */
|
||||
|
||||
/* Detect which of the corner of the far clipping plane is the farthest to the origin */
|
||||
float nfar[4]; /* most extreme far point in NDC space */
|
||||
float farxy[2]; /* far-point projection onto the near plane */
|
||||
float farpoint[3] = {0.0f}; /* most extreme far point in camera coordinate */
|
||||
float nearpoint[3]; /* most extreme near point in camera coordinate */
|
||||
float farcenter[3] = {0.0f}; /* center of far clipping plane in camera coordinate */
|
||||
float F = -1.0f, N; /* square distance of far and near point to origin */
|
||||
float f, n; /* distance of far and near point to z axis. f is always > 0 but n can be < 0 */
|
||||
float e, s; /* far and near clipping distance (<0) */
|
||||
float c; /* slope of center line = distance of far clipping center
|
||||
* to z axis / far clipping distance. */
|
||||
float z; /* projection of sphere center on z axis (<0) */
|
||||
|
||||
/* Find farthest corner and center of far clip plane. */
|
||||
float corner[3] = {1.0f, 1.0f, 1.0f}; /* in clip space */
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float point[3];
|
||||
mul_v3_project_m4_v3(point, projinv, corner);
|
||||
float len = len_squared_v3(point);
|
||||
if (len > F) {
|
||||
copy_v3_v3(nfar, corner);
|
||||
copy_v3_v3(farpoint, point);
|
||||
F = len;
|
||||
}
|
||||
add_v3_v3(farcenter, point);
|
||||
/* rotate by 90 degree to walk through the 4 points of the far clip plane */
|
||||
float tmp = corner[0];
|
||||
corner[0] = -corner[1];
|
||||
corner[1] = tmp;
|
||||
}
|
||||
|
||||
/* the far center is the average of the far clipping points */
|
||||
mul_v3_fl(farcenter, 0.25f);
|
||||
/* the extreme near point is the opposite point on the near clipping plane */
|
||||
copy_v3_fl3(nfar, -nfar[0], -nfar[1], -1.0f);
|
||||
mul_v3_project_m4_v3(nearpoint, projinv, nfar);
|
||||
/* this is a frustum projection */
|
||||
N = len_squared_v3(nearpoint);
|
||||
e = farpoint[2];
|
||||
s = nearpoint[2];
|
||||
/* distance to view Z axis */
|
||||
f = len_v2(farpoint);
|
||||
/* get corresponding point on the near plane */
|
||||
mul_v2_v2fl(farxy, farpoint, s / e);
|
||||
/* this formula preserve the sign of n */
|
||||
sub_v2_v2(nearpoint, farxy);
|
||||
n = f * s / e - len_v2(nearpoint);
|
||||
c = len_v2(farcenter) / e;
|
||||
/* the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case */
|
||||
z = (F - N) / (2.0f * (e - s + c * (f - n)));
|
||||
|
||||
bsphere->center[0] = farcenter[0] * z / e;
|
||||
bsphere->center[1] = farcenter[1] * z / e;
|
||||
bsphere->center[2] = z;
|
||||
|
||||
/* For XR, the view matrix may contain a scale factor. Then, transforming only the center
|
||||
* into world space after calculating the radius will result in incorrect behavior. */
|
||||
mul_m4_v3(viewinv, bsphere->center); /* Transform to world space. */
|
||||
mul_m4_v3(viewinv, farpoint);
|
||||
bsphere->radius = len_v3v3(bsphere->center, farpoint);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_view_matrix_state_update(DRWView *view,
|
||||
const float viewmat[4][4],
|
||||
const float winmat[4][4])
|
||||
{
|
||||
ViewMatrices *storage = &view->storage;
|
||||
|
||||
copy_m4_m4(storage->viewmat.ptr(), viewmat);
|
||||
invert_m4_m4(storage->viewinv.ptr(), storage->viewmat.ptr());
|
||||
|
||||
copy_m4_m4(storage->winmat.ptr(), winmat);
|
||||
invert_m4_m4(storage->wininv.ptr(), storage->winmat.ptr());
|
||||
|
||||
mul_m4_m4m4(view->persmat.ptr(), winmat, viewmat);
|
||||
invert_m4_m4(view->persinv.ptr(), view->persmat.ptr());
|
||||
}
|
||||
|
||||
DRWView *DRW_view_create(const float viewmat[4][4],
|
||||
const float winmat[4][4],
|
||||
const float (*culling_viewmat)[4],
|
||||
const float (*culling_winmat)[4])
|
||||
{
|
||||
DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
|
||||
|
||||
if (DST.primary_view_num < MAX_CULLED_VIEWS) {
|
||||
view->culling_mask = 1u << DST.primary_view_num++;
|
||||
}
|
||||
else {
|
||||
BLI_assert(0);
|
||||
view->culling_mask = 0u;
|
||||
}
|
||||
view->clip_planes_len = 0;
|
||||
view->parent = nullptr;
|
||||
|
||||
DRW_view_update(view, viewmat, winmat, culling_viewmat, culling_winmat);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
DRWView *DRW_view_create_sub(const DRWView *parent_view,
|
||||
const float viewmat[4][4],
|
||||
const float winmat[4][4])
|
||||
{
|
||||
/* Search original parent. */
|
||||
const DRWView *ori_view = parent_view;
|
||||
while (ori_view->parent != nullptr) {
|
||||
ori_view = ori_view->parent;
|
||||
}
|
||||
|
||||
DRWView *view = static_cast<DRWView *>(BLI_memblock_alloc(DST.vmempool->views));
|
||||
|
||||
/* Perform copy. */
|
||||
*view = *ori_view;
|
||||
view->parent = (DRWView *)ori_view;
|
||||
|
||||
DRW_view_update_sub(view, viewmat, winmat);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/* DRWView Update:
|
||||
* This is meant to be done on existing views when rendering in a loop and there is no
|
||||
* need to allocate more DRWViews. */
|
||||
|
||||
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4])
|
||||
{
|
||||
BLI_assert(view->parent != nullptr);
|
||||
|
||||
view->is_dirty = true;
|
||||
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
|
||||
|
||||
draw_view_matrix_state_update(view, viewmat, winmat);
|
||||
}
|
||||
|
||||
void DRW_view_update(DRWView *view,
|
||||
const float viewmat[4][4],
|
||||
const float winmat[4][4],
|
||||
const float (*culling_viewmat)[4],
|
||||
const float (*culling_winmat)[4])
|
||||
{
|
||||
/* DO NOT UPDATE THE DEFAULT VIEW.
|
||||
* Create sub-views instead, or a copy. */
|
||||
BLI_assert(view != DST.view_default);
|
||||
BLI_assert(view->parent == nullptr);
|
||||
|
||||
view->is_dirty = true;
|
||||
view->is_inverted = (is_negative_m4(viewmat) == is_negative_m4(winmat));
|
||||
|
||||
draw_view_matrix_state_update(view, viewmat, winmat);
|
||||
|
||||
/* Prepare frustum culling. */
|
||||
|
||||
#ifdef DRW_DEBUG_CULLING
|
||||
static float mv[MAX_CULLED_VIEWS][4][4], mw[MAX_CULLED_VIEWS][4][4];
|
||||
|
||||
/* Select view here. */
|
||||
if (view->culling_mask != 0) {
|
||||
uint index = bitscan_forward_uint(view->culling_mask);
|
||||
|
||||
if (G.debug_value == 0) {
|
||||
copy_m4_m4(mv[index], culling_viewmat ? culling_viewmat : viewmat);
|
||||
copy_m4_m4(mw[index], culling_winmat ? culling_winmat : winmat);
|
||||
}
|
||||
else {
|
||||
culling_winmat = mw[index];
|
||||
culling_viewmat = mv[index];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
float wininv[4][4];
|
||||
if (culling_winmat) {
|
||||
winmat = culling_winmat;
|
||||
invert_m4_m4(wininv, winmat);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(wininv, view->storage.wininv.ptr());
|
||||
}
|
||||
|
||||
float viewinv[4][4];
|
||||
if (culling_viewmat) {
|
||||
viewmat = culling_viewmat;
|
||||
invert_m4_m4(viewinv, viewmat);
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(viewinv, view->storage.viewinv.ptr());
|
||||
}
|
||||
|
||||
draw_frustum_boundbox_calc(viewinv, winmat, &view->frustum_corners);
|
||||
draw_frustum_culling_planes_calc(view->persmat.ptr(), view->frustum_planes);
|
||||
draw_frustum_bound_sphere_calc(
|
||||
&view->frustum_corners, viewinv, winmat, wininv, &view->frustum_bsphere);
|
||||
|
||||
#ifdef DRW_DEBUG_CULLING
|
||||
if (G.debug_value != 0) {
|
||||
DRW_debug_sphere(
|
||||
view->frustum_bsphere.center, view->frustum_bsphere.radius, blender::float4{1, 1, 0, 1});
|
||||
DRW_debug_bbox(&view->frustum_corners, blender::float4{1, 1, 0, 1});
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
@@ -211,14 +211,6 @@ void drw_state_set(DRWState state)
|
||||
GPU_shadow_offset(false);
|
||||
}
|
||||
|
||||
/* TODO: this should be part of shader state. */
|
||||
if (state & DRW_STATE_CLIP_PLANES) {
|
||||
GPU_clip_distances(DST.view_active->clip_planes_len);
|
||||
}
|
||||
else {
|
||||
GPU_clip_distances(0);
|
||||
}
|
||||
|
||||
if (state & DRW_STATE_IN_FRONT_SELECT) {
|
||||
/* XXX `GPU_depth_range` is not a perfect solution
|
||||
* since very distant geometries can still be occluded.
|
||||
@@ -332,90 +324,6 @@ void DRW_state_reset()
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Culling (DRW_culling)
|
||||
* \{ */
|
||||
|
||||
static bool draw_call_is_culled(const DRWResourceHandle *handle, DRWView *view)
|
||||
{
|
||||
DRWCullingState *culling = static_cast<DRWCullingState *>(
|
||||
DRW_memblock_elem_from_handle(DST.vmempool->cullstates, handle));
|
||||
return (culling->mask & view->culling_mask) != 0;
|
||||
}
|
||||
|
||||
/* Return True if the given BoundSphere intersect the current view frustum */
|
||||
static bool draw_culling_sphere_test(const BoundSphere *frustum_bsphere,
|
||||
const float (*frustum_planes)[4],
|
||||
const BoundSphere *bsphere)
|
||||
{
|
||||
/* Bypass test if radius is negative. */
|
||||
if (bsphere->radius < 0.0f) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Do a rough test first: Sphere VS Sphere intersect. */
|
||||
float center_dist_sq = len_squared_v3v3(bsphere->center, frustum_bsphere->center);
|
||||
float radius_sum = bsphere->radius + frustum_bsphere->radius;
|
||||
if (center_dist_sq > square_f(radius_sum)) {
|
||||
return false;
|
||||
}
|
||||
/* TODO: we could test against the inscribed sphere of the frustum to early out positively. */
|
||||
|
||||
/* Test against the 6 frustum planes. */
|
||||
/* TODO: order planes with sides first then far then near clip. Should be better culling
|
||||
* heuristic when sculpting. */
|
||||
for (int p = 0; p < 6; p++) {
|
||||
float dist = plane_point_side_v3(frustum_planes[p], bsphere->center);
|
||||
if (dist < -bsphere->radius) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void draw_compute_culling(DRWView *view)
|
||||
{
|
||||
view = view->parent ? view->parent : view;
|
||||
|
||||
/* TODO(fclem): multi-thread this. */
|
||||
/* TODO(fclem): compute all dirty views at once. */
|
||||
if (!view->is_dirty) {
|
||||
return;
|
||||
}
|
||||
|
||||
BLI_memblock_iter iter;
|
||||
BLI_memblock_iternew(DST.vmempool->cullstates, &iter);
|
||||
DRWCullingState *cull;
|
||||
while ((cull = static_cast<DRWCullingState *>(BLI_memblock_iterstep(&iter)))) {
|
||||
if (cull->bsphere.radius < 0.0) {
|
||||
cull->mask = 0;
|
||||
}
|
||||
else {
|
||||
bool culled = !draw_culling_sphere_test(
|
||||
&view->frustum_bsphere, view->frustum_planes, &cull->bsphere);
|
||||
|
||||
#ifdef DRW_DEBUG_CULLING
|
||||
if (G.debug_value != 0) {
|
||||
if (culled) {
|
||||
DRW_debug_sphere(
|
||||
cull->bsphere.center, cull->bsphere.radius, blender::float4{1, 0, 0, 1});
|
||||
}
|
||||
else {
|
||||
DRW_debug_sphere(
|
||||
cull->bsphere.center, cull->bsphere.radius, blender::float4{0, 1, 0, 1});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
SET_FLAG_FROM_TEST(cull->mask, culled, view->culling_mask);
|
||||
}
|
||||
}
|
||||
|
||||
view->is_dirty = false;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Draw (DRW_draw)
|
||||
* \{ */
|
||||
@@ -716,7 +624,6 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa
|
||||
bool neg_scale = DRW_handle_negative_scale_get(handle);
|
||||
if (neg_scale != state->neg_scale) {
|
||||
state->neg_scale = neg_scale;
|
||||
GPU_front_facing(neg_scale != DST.view_active->is_inverted);
|
||||
}
|
||||
|
||||
int chunk = DRW_handle_chunk_get(handle);
|
||||
@@ -870,7 +777,6 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState
|
||||
|
||||
/* Reset state */
|
||||
if (state->neg_scale) {
|
||||
GPU_front_facing(DST.view_active->is_inverted);
|
||||
}
|
||||
if (state->obmats_loc != -1) {
|
||||
GPU_uniformbuf_unbind(DST.vmempool->matrices_ubo[state->resource_chunk]);
|
||||
@@ -949,9 +855,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
case DRW_CMD_DRAW:
|
||||
case DRW_CMD_DRAW_INDIRECT:
|
||||
case DRW_CMD_DRAW_INSTANCE:
|
||||
if (draw_call_is_culled(&cmd->instance.handle, DST.view_active)) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1071,15 +974,6 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
|
||||
}
|
||||
}
|
||||
|
||||
static void drw_update_view()
|
||||
{
|
||||
/* TODO(fclem): update a big UBO and only bind ranges here. */
|
||||
GPU_uniformbuf_update(G_draw.view_ubo, &DST.view_active->storage);
|
||||
GPU_uniformbuf_update(G_draw.clipping_ubo, &DST.view_active->clip_planes);
|
||||
|
||||
draw_compute_culling(DST.view_active);
|
||||
}
|
||||
|
||||
static void drw_draw_pass_ex(DRWPass *pass,
|
||||
DRWShadingGroup *start_group,
|
||||
DRWShadingGroup *end_group)
|
||||
@@ -1098,12 +992,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
|
||||
BLI_assert_msg(DST.buffer_finish_called,
|
||||
"DRW_render_instance_buffer_finish had not been called before drawing");
|
||||
|
||||
if (DST.view_previous != DST.view_active || DST.view_active->is_dirty) {
|
||||
drw_update_view();
|
||||
DST.view_active->is_dirty = false;
|
||||
DST.view_previous = DST.view_active;
|
||||
}
|
||||
|
||||
/* GPU_framebuffer_clear calls can change the state outside the DRW module.
|
||||
* Force reset the affected states to avoid problems later. */
|
||||
drw_state_set(DST.state | DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR);
|
||||
@@ -1111,10 +999,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
|
||||
drw_state_set(pass->state);
|
||||
drw_state_validate();
|
||||
|
||||
if (DST.view_active->is_inverted) {
|
||||
GPU_front_facing(true);
|
||||
}
|
||||
|
||||
DRW_stats_query_start(pass->name);
|
||||
|
||||
for (DRWShadingGroup *shgroup = start_group; shgroup; shgroup = shgroup->next) {
|
||||
@@ -1148,11 +1032,6 @@ static void drw_draw_pass_ex(DRWPass *pass,
|
||||
drw_state_set((DST.state & ~DRW_STATE_RASTERIZER_ENABLED) | DRW_STATE_DEFAULT);
|
||||
}
|
||||
|
||||
/* Reset default. */
|
||||
if (DST.view_active->is_inverted) {
|
||||
GPU_front_facing(false);
|
||||
}
|
||||
|
||||
DRW_stats_query_end();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user