This refactor part of `draw_manager_c.cc` to make it more understandable and less bug prone. - Splits the context handing to `draw_gpu_context.cc` - Rename `draw_manager_c.cc` to `draw_context.cc` - Merge `DRWContextState` into `DRWContext` - Merge lots of static functions into `DRWContext` to avoid global access - Deduplicate code between entry point functions - Move context init logic to `DRWContext` constructor - Move resource init logic to `DRWContext::acquire_data` - Move extraction `TaskGraph` out of `DRWContext` - Reduce / centralize complexity of enabling draw engines - Reduce the amount of `drw_get` calls - Remove unused code Pull Request: https://projects.blender.org/blender/blender/pulls/135821
675 lines
20 KiB
C++
675 lines
20 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*/
|
|
|
|
#include "DNA_curve_types.h"
|
|
#include "DNA_curves_types.h"
|
|
#include "DNA_grease_pencil_types.h"
|
|
#include "DNA_lattice_types.h"
|
|
#include "DNA_mesh_types.h"
|
|
#include "DNA_modifier_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_particle_types.h"
|
|
#include "DNA_pointcloud_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_volume_types.h"
|
|
|
|
#include "UI_resources.hh"
|
|
|
|
#include "BLI_ghash.h"
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_string.h"
|
|
#include "BLI_utildefines.h"
|
|
|
|
#include "BKE_context.hh"
|
|
#include "BKE_object.hh"
|
|
|
|
#include "GPU_batch.hh"
|
|
#include "GPU_batch_utils.hh"
|
|
#include "GPU_capabilities.hh"
|
|
|
|
#include "draw_cache.hh"
|
|
#include "draw_cache_impl.hh"
|
|
#include "draw_context_private.hh"
|
|
|
|
using blender::Span;
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Internal Defines
|
|
* \{ */
|
|
|
|
#define VCLASS_LIGHT_AREA_SHAPE (1 << 0)
|
|
#define VCLASS_LIGHT_SPOT_SHAPE (1 << 1)
|
|
#define VCLASS_LIGHT_SPOT_BLEND (1 << 2)
|
|
#define VCLASS_LIGHT_SPOT_CONE (1 << 3)
|
|
#define VCLASS_LIGHT_DIST (1 << 4)
|
|
|
|
#define VCLASS_CAMERA_FRAME (1 << 5)
|
|
#define VCLASS_CAMERA_DIST (1 << 6)
|
|
#define VCLASS_CAMERA_VOLUME (1 << 7)
|
|
|
|
#define VCLASS_SCREENSPACE (1 << 8)
|
|
#define VCLASS_SCREENALIGNED (1 << 9)
|
|
|
|
#define VCLASS_EMPTY_SCALED (1 << 10)
|
|
#define VCLASS_EMPTY_AXES (1 << 11)
|
|
#define VCLASS_EMPTY_AXES_NAME (1 << 12)
|
|
#define VCLASS_EMPTY_AXES_SHADOW (1 << 13)
|
|
#define VCLASS_EMPTY_SIZE (1 << 14)
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Common
|
|
* \{ */
|
|
|
|
namespace blender::draw {
|
|
|
|
void DRW_vertbuf_create_wiredata(blender::gpu::VertBuf *vbo, const int vert_len)
|
|
{
|
|
static struct {
|
|
uint wd;
|
|
} attr_id;
|
|
|
|
static const GPUVertFormat format = [&]() {
|
|
GPUVertFormat format{};
|
|
/* initialize vertex format */
|
|
if (!GPU_crappy_amd_driver()) {
|
|
/* Some AMD drivers strangely crash with a vbo with this format. */
|
|
attr_id.wd = GPU_vertformat_attr_add(
|
|
&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
|
}
|
|
else {
|
|
attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
|
}
|
|
return format;
|
|
}();
|
|
|
|
GPU_vertbuf_init_with_format(*vbo, format);
|
|
GPU_vertbuf_data_alloc(*vbo, vert_len);
|
|
|
|
if (GPU_vertbuf_get_format(vbo)->stride == 1) {
|
|
memset(vbo->data<uint8_t>().data(), 0xFF, size_t(vert_len));
|
|
}
|
|
else {
|
|
GPUVertBufRaw wd_step;
|
|
GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
|
|
for (int i = 0; i < vert_len; i++) {
|
|
*((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
} // namespace blender::draw
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Common Object API
|
|
*
|
|
* \note Curve and text objects evaluate to the evaluated geometry set's mesh component if
|
|
* they have a surface, so curve objects themselves do not have a surface (the mesh component
|
|
* is presented to render engines as a separate object).
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_object_all_edges_get(Object *ob)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_all_edges_get(ob);
|
|
/* TODO: should match #DRW_cache_object_surface_get. */
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_object_face_wireframe_get(const Scene *scene, Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_face_wireframe_get(ob);
|
|
case OB_POINTCLOUD:
|
|
return DRW_pointcloud_batch_cache_get_dots(ob);
|
|
case OB_VOLUME:
|
|
return DRW_cache_volume_face_wireframe_get(ob);
|
|
case OB_GREASE_PENCIL:
|
|
return DRW_cache_grease_pencil_face_wireframe_get(scene, ob);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_object_loose_edges_get(Object *ob)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_loose_edges_get(ob);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_object_surface_get(Object *ob)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_surface_get(ob);
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
blender::gpu::VertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf_unchecked(ob);
|
|
short type = (mesh != nullptr) ? short(OB_MESH) : ob->type;
|
|
|
|
switch (type) {
|
|
case OB_MESH:
|
|
return DRW_mesh_batch_cache_pos_vertbuf_get(
|
|
*static_cast<Mesh *>((mesh != nullptr) ? mesh : ob->data));
|
|
default:
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
Span<blender::gpu::Batch *> DRW_cache_object_surface_material_get(
|
|
Object *ob, const Span<const GPUMaterial *> materials)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
return DRW_cache_mesh_surface_shaded_get(ob, materials);
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Meshes
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_all_verts_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_all_verts(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_all_edges_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_all_edges(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_loose_edges_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_loose_edges(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_edge_detection(*static_cast<Mesh *>(ob->data), r_is_manifold);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_edges_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_edges(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
Span<blender::gpu::Batch *> DRW_cache_mesh_surface_shaded_get(
|
|
Object *ob, const blender::Span<const GPUMaterial *> materials)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_shaded(*ob, *static_cast<Mesh *>(ob->data), materials);
|
|
}
|
|
|
|
Span<blender::gpu::Batch *> DRW_cache_mesh_surface_texpaint_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_texpaint(*ob, *static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_texpaint_single(*ob, *static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_vertpaint_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_vertpaint(*ob, *static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_sculpt(*ob, *static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_weights_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_weights(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_face_wireframe_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_wireframes_face(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_edit_mesh_analysis(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_viewer_attribute_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_MESH);
|
|
return DRW_mesh_batch_cache_get_surface_viewer_attribute(*static_cast<Mesh *>(ob->data));
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Curve
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_wire_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_wire_edge_viewer_attribute(cu);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_normal_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_normal_edge(cu);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_overlay_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF));
|
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_edit_edges(cu);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_curve_vert_overlay_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF));
|
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_edit_verts(cu);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Font
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_text_edge_wire_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_FONT);
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Surface
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_surf_edge_wire_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_SURF);
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Lattice
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_lattice_verts_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
|
return DRW_lattice_batch_cache_get_all_verts(lt);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
|
int actdef = -1;
|
|
|
|
if (use_weight && !BLI_listbase_is_empty(<->vertex_group_names) && lt->editlatt->latt->dvert) {
|
|
actdef = lt->vertex_group_active_index - 1;
|
|
}
|
|
|
|
return DRW_lattice_batch_cache_get_all_edges(lt, use_weight, actdef);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_lattice_vert_overlay_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
|
return DRW_lattice_batch_cache_get_edit_verts(lt);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name PointCloud
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_pointcloud_vert_overlay_get(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
BLI_assert(ob->type == OB_POINTCLOUD);
|
|
|
|
PointCloud *pointcloud = static_cast<PointCloud *>(ob->data);
|
|
return DRW_pointcloud_batch_cache_get_edit_dots(pointcloud);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Volume
|
|
* \{ */
|
|
|
|
namespace blender::draw {
|
|
|
|
blender::gpu::Batch *DRW_cache_volume_face_wireframe_get(Object *ob)
|
|
{
|
|
BLI_assert(ob->type == OB_VOLUME);
|
|
return DRW_volume_batch_cache_get_wireframes_face(static_cast<Volume *>(ob->data));
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_volume_selection_surface_get(Object *ob)
|
|
{
|
|
BLI_assert(ob->type == OB_VOLUME);
|
|
return DRW_volume_batch_cache_get_selection_surface(static_cast<Volume *>(ob->data));
|
|
}
|
|
|
|
} // namespace blender::draw
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Particles
|
|
* \{ */
|
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_hair(Object *object,
|
|
ParticleSystem *psys,
|
|
ModifierData *md)
|
|
{
|
|
using namespace blender::draw;
|
|
return DRW_particles_batch_cache_get_hair(object, psys, md);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
|
|
{
|
|
using namespace blender::draw;
|
|
return DRW_particles_batch_cache_get_dots(object, psys);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_strands(Object *object,
|
|
ParticleSystem *psys,
|
|
PTCacheEdit *edit,
|
|
bool use_weight)
|
|
{
|
|
using namespace blender::draw;
|
|
return DRW_particles_batch_cache_get_edit_strands(object, psys, edit, use_weight);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_inner_points(Object *object,
|
|
ParticleSystem *psys,
|
|
PTCacheEdit *edit)
|
|
{
|
|
using namespace blender::draw;
|
|
return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit);
|
|
}
|
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_tip_points(Object *object,
|
|
ParticleSystem *psys,
|
|
PTCacheEdit *edit)
|
|
{
|
|
using namespace blender::draw;
|
|
return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit);
|
|
}
|
|
|
|
/** \} */
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Batch Cache Implementation (common)
|
|
* \{ */
|
|
|
|
void drw_batch_cache_validate(Object *ob)
|
|
{
|
|
using namespace blender::draw;
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
DRW_mesh_batch_cache_validate(*(Mesh *)ob->data);
|
|
break;
|
|
case OB_CURVES_LEGACY:
|
|
case OB_FONT:
|
|
case OB_SURF:
|
|
DRW_curve_batch_cache_validate((Curve *)ob->data);
|
|
break;
|
|
case OB_LATTICE:
|
|
DRW_lattice_batch_cache_validate((Lattice *)ob->data);
|
|
break;
|
|
case OB_CURVES:
|
|
DRW_curves_batch_cache_validate((Curves *)ob->data);
|
|
break;
|
|
case OB_POINTCLOUD:
|
|
DRW_pointcloud_batch_cache_validate((PointCloud *)ob->data);
|
|
break;
|
|
case OB_VOLUME:
|
|
DRW_volume_batch_cache_validate((Volume *)ob->data);
|
|
break;
|
|
case OB_GREASE_PENCIL:
|
|
DRW_grease_pencil_batch_cache_validate((GreasePencil *)ob->data);
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void drw_batch_cache_generate_requested(Object *ob, TaskGraph &task_graph)
|
|
{
|
|
using namespace blender::draw;
|
|
const DRWContext *draw_ctx = DRW_context_get();
|
|
const Scene *scene = draw_ctx->scene;
|
|
const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
|
|
draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
|
|
const bool is_paint_mode = ELEM(
|
|
mode, CTX_MODE_SCULPT, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT);
|
|
|
|
const bool use_hide = ((ob->type == OB_MESH) &&
|
|
((is_paint_mode && (ob == draw_ctx->obact) &&
|
|
DRW_object_use_hide_faces(ob)) ||
|
|
((mode == CTX_MODE_EDIT_MESH) && (ob->mode == OB_MODE_EDIT))));
|
|
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
DRW_mesh_batch_cache_create_requested(
|
|
task_graph, *ob, *(Mesh *)ob->data, *scene, is_paint_mode, use_hide);
|
|
break;
|
|
case OB_CURVES_LEGACY:
|
|
case OB_FONT:
|
|
case OB_SURF:
|
|
DRW_curve_batch_cache_create_requested(ob, scene);
|
|
break;
|
|
case OB_CURVES:
|
|
DRW_curves_batch_cache_create_requested(ob);
|
|
break;
|
|
case OB_POINTCLOUD:
|
|
DRW_pointcloud_batch_cache_create_requested(ob);
|
|
break;
|
|
/* TODO: all cases. */
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob, TaskGraph &task_graph)
|
|
{
|
|
using namespace blender::draw;
|
|
/* NOTE: Logic here is duplicated from #drw_batch_cache_generate_requested. */
|
|
|
|
const DRWContext *draw_ctx = DRW_context_get();
|
|
const Scene *scene = draw_ctx->scene;
|
|
const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
|
|
draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
|
|
const bool is_paint_mode = ELEM(
|
|
mode, CTX_MODE_SCULPT, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT);
|
|
|
|
const bool use_hide = ((ob->type == OB_MESH) &&
|
|
((is_paint_mode && (ob == draw_ctx->obact) &&
|
|
DRW_object_use_hide_faces(ob)) ||
|
|
((mode == CTX_MODE_EDIT_MESH) && (ob->mode == OB_MODE_EDIT))));
|
|
|
|
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf_unchecked(ob);
|
|
/* Try getting the mesh first and if that fails, try getting the curve data.
|
|
* If the curves are surfaces or have certain modifiers applied to them, the will have mesh data
|
|
* of the final result.
|
|
*/
|
|
if (mesh != nullptr) {
|
|
DRW_mesh_batch_cache_create_requested(task_graph, *ob, *mesh, *scene, is_paint_mode, use_hide);
|
|
}
|
|
else if (ELEM(ob->type, OB_CURVES_LEGACY, OB_FONT, OB_SURF)) {
|
|
DRW_curve_batch_cache_create_requested(ob, scene);
|
|
}
|
|
}
|
|
|
|
void drw_batch_cache_generate_requested_delayed(Object *ob)
|
|
{
|
|
DRWContext &draw_ctx = drw_get();
|
|
if (draw_ctx.delayed_extraction == nullptr) {
|
|
draw_ctx.delayed_extraction = BLI_gset_ptr_new(__func__);
|
|
}
|
|
BLI_gset_add(draw_ctx.delayed_extraction, ob);
|
|
}
|
|
|
|
namespace blender::draw {
|
|
void DRW_batch_cache_free_old(Object *ob, int ctime)
|
|
{
|
|
switch (ob->type) {
|
|
case OB_MESH:
|
|
DRW_mesh_batch_cache_free_old((Mesh *)ob->data, ctime);
|
|
break;
|
|
case OB_CURVES:
|
|
DRW_curves_batch_cache_free_old((Curves *)ob->data, ctime);
|
|
break;
|
|
case OB_POINTCLOUD:
|
|
DRW_pointcloud_batch_cache_free_old((PointCloud *)ob->data, ctime);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
} // namespace blender::draw
|
|
|
|
/** \} */
|
|
|
|
void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format,
|
|
const char *base_name,
|
|
const int data_type,
|
|
const char *layer_name,
|
|
bool is_active_render,
|
|
bool is_active_layer)
|
|
{
|
|
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
|
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
|
|
|
/* Attribute layer name. */
|
|
SNPRINTF(attr_name, "%s%s", base_name, attr_safe_name);
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
/* Auto layer name. */
|
|
SNPRINTF(attr_name, "a%s", attr_safe_name);
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
/* Active render layer name. */
|
|
if (is_active_render) {
|
|
GPU_vertformat_alias_add(format, data_type == CD_PROP_FLOAT2 ? "a" : base_name);
|
|
}
|
|
|
|
/* Active display layer name. */
|
|
if (is_active_layer) {
|
|
SNPRINTF(attr_name, "a%s", base_name);
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
}
|
|
}
|