2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup draw
|
2017-02-07 11:20:15 +01:00
|
|
|
*/
|
|
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_curve_types.h"
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
#include "DNA_curves_types.h"
|
2023-05-30 11:14:16 +02:00
|
|
|
#include "DNA_grease_pencil_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_lattice_types.h"
|
2017-02-07 11:20:15 +01:00
|
|
|
#include "DNA_mesh_types.h"
|
2018-06-11 08:37:56 +02:00
|
|
|
#include "DNA_meta_types.h"
|
2017-06-22 19:19:55 +02:00
|
|
|
#include "DNA_modifier_types.h"
|
2020-03-17 16:27:08 +01:00
|
|
|
#include "DNA_object_types.h"
|
|
|
|
|
#include "DNA_particle_types.h"
|
|
|
|
|
#include "DNA_pointcloud_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
2020-03-17 16:27:08 +01:00
|
|
|
#include "DNA_volume_types.h"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2023-08-05 02:57:52 +02:00
|
|
|
#include "UI_resources.hh"
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2018-09-23 20:41:10 +03:00
|
|
|
|
2023-10-09 23:41:53 +02:00
|
|
|
#include "BKE_object.hh"
|
2023-08-02 22:14:18 +02:00
|
|
|
#include "BKE_paint.hh"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2024-03-23 01:24:18 +01:00
|
|
|
#include "GPU_batch.hh"
|
|
|
|
|
#include "GPU_batch_utils.hh"
|
|
|
|
|
#include "GPU_capabilities.hh"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2018-09-23 20:41:10 +03:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2024-01-05 11:16:57 -05:00
|
|
|
#include "draw_cache.hh"
|
2023-08-03 20:04:50 -04:00
|
|
|
#include "draw_cache_impl.hh"
|
2024-03-22 23:51:35 -04:00
|
|
|
#include "draw_manager_c.hh"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Internal Defines
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
#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)
|
|
|
|
|
|
2020-11-13 08:24:52 +01:00
|
|
|
/* Sphere shape resolution */
|
|
|
|
|
/* Low */
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LATITUDE_LOW 32
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LONGITUDE_LOW 24
|
|
|
|
|
/* Medium */
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LATITUDE_MEDIUM 64
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LONGITUDE_MEDIUM 48
|
|
|
|
|
/* High */
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LATITUDE_HIGH 80
|
|
|
|
|
#define DRW_SPHERE_SHAPE_LONGITUDE_HIGH 60
|
|
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Internal Types
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
struct Vert {
|
2019-12-02 01:40:58 +01:00
|
|
|
float pos[3];
|
2023-07-27 14:16:58 +02:00
|
|
|
int v_class;
|
2019-12-02 01:40:58 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
/** Allows creating a pointer to `Vert` in a single expression. */
|
|
|
|
|
operator const void *() const
|
|
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct VertShaded {
|
2019-12-11 13:35:53 +01:00
|
|
|
float pos[3];
|
2023-07-27 14:16:58 +02:00
|
|
|
int v_class;
|
2019-12-11 13:35:53 +01:00
|
|
|
float nor[3];
|
2023-07-27 14:16:58 +02:00
|
|
|
|
|
|
|
|
operator const void *() const
|
|
|
|
|
{
|
|
|
|
|
return this;
|
|
|
|
|
}
|
|
|
|
|
};
|
2019-12-11 13:35:53 +01:00
|
|
|
|
2023-12-07 12:15:45 +11:00
|
|
|
/* Batch's only (freed as an array). */
|
2017-02-22 18:52:07 +01:00
|
|
|
static struct DRWShapeCache {
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *drw_procedural_verts;
|
|
|
|
|
blender::gpu::Batch *drw_procedural_lines;
|
|
|
|
|
blender::gpu::Batch *drw_procedural_tris;
|
|
|
|
|
blender::gpu::Batch *drw_procedural_tri_strips;
|
|
|
|
|
blender::gpu::Batch *drw_cursor;
|
|
|
|
|
blender::gpu::Batch *drw_cursor_only_circle;
|
|
|
|
|
blender::gpu::Batch *drw_fullscreen_quad;
|
|
|
|
|
blender::gpu::Batch *drw_quad;
|
|
|
|
|
blender::gpu::Batch *drw_quad_wires;
|
|
|
|
|
blender::gpu::Batch *drw_grid;
|
|
|
|
|
blender::gpu::Batch *drw_plain_axes;
|
|
|
|
|
blender::gpu::Batch *drw_single_arrow;
|
|
|
|
|
blender::gpu::Batch *drw_cube;
|
|
|
|
|
blender::gpu::Batch *drw_circle;
|
|
|
|
|
blender::gpu::Batch *drw_normal_arrow;
|
|
|
|
|
blender::gpu::Batch *drw_empty_cube;
|
|
|
|
|
blender::gpu::Batch *drw_empty_sphere;
|
|
|
|
|
blender::gpu::Batch *drw_empty_cylinder;
|
|
|
|
|
blender::gpu::Batch *drw_empty_capsule_body;
|
|
|
|
|
blender::gpu::Batch *drw_empty_capsule_cap;
|
|
|
|
|
blender::gpu::Batch *drw_empty_cone;
|
|
|
|
|
blender::gpu::Batch *drw_field_wind;
|
|
|
|
|
blender::gpu::Batch *drw_field_force;
|
|
|
|
|
blender::gpu::Batch *drw_field_vortex;
|
|
|
|
|
blender::gpu::Batch *drw_field_curve;
|
|
|
|
|
blender::gpu::Batch *drw_field_tube_limit;
|
|
|
|
|
blender::gpu::Batch *drw_field_cone_limit;
|
|
|
|
|
blender::gpu::Batch *drw_field_sphere_limit;
|
|
|
|
|
blender::gpu::Batch *drw_ground_line;
|
|
|
|
|
blender::gpu::Batch *drw_light_icon_inner_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_icon_outer_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_icon_sun_rays;
|
|
|
|
|
blender::gpu::Batch *drw_light_point_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_sun_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_spot_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_spot_volume;
|
|
|
|
|
blender::gpu::Batch *drw_light_area_disk_lines;
|
|
|
|
|
blender::gpu::Batch *drw_light_area_square_lines;
|
|
|
|
|
blender::gpu::Batch *drw_speaker;
|
|
|
|
|
blender::gpu::Batch *drw_lightprobe_cube;
|
|
|
|
|
blender::gpu::Batch *drw_lightprobe_planar;
|
|
|
|
|
blender::gpu::Batch *drw_lightprobe_grid;
|
|
|
|
|
blender::gpu::Batch *drw_bone_octahedral;
|
|
|
|
|
blender::gpu::Batch *drw_bone_octahedral_wire;
|
|
|
|
|
blender::gpu::Batch *drw_bone_box;
|
|
|
|
|
blender::gpu::Batch *drw_bone_box_wire;
|
|
|
|
|
blender::gpu::Batch *drw_bone_envelope;
|
|
|
|
|
blender::gpu::Batch *drw_bone_envelope_outline;
|
|
|
|
|
blender::gpu::Batch *drw_bone_point;
|
|
|
|
|
blender::gpu::Batch *drw_bone_point_wire;
|
|
|
|
|
blender::gpu::Batch *drw_bone_stick;
|
|
|
|
|
blender::gpu::Batch *drw_bone_arrows;
|
|
|
|
|
blender::gpu::Batch *drw_bone_dof_sphere;
|
|
|
|
|
blender::gpu::Batch *drw_bone_dof_lines;
|
|
|
|
|
blender::gpu::Batch *drw_camera_frame;
|
|
|
|
|
blender::gpu::Batch *drw_camera_tria;
|
|
|
|
|
blender::gpu::Batch *drw_camera_tria_wire;
|
|
|
|
|
blender::gpu::Batch *drw_camera_distances;
|
|
|
|
|
blender::gpu::Batch *drw_camera_volume;
|
|
|
|
|
blender::gpu::Batch *drw_camera_volume_wire;
|
|
|
|
|
blender::gpu::Batch *drw_particle_cross;
|
|
|
|
|
blender::gpu::Batch *drw_particle_circle;
|
|
|
|
|
blender::gpu::Batch *drw_particle_axis;
|
|
|
|
|
blender::gpu::Batch *drw_gpencil_dummy_quad;
|
|
|
|
|
blender::gpu::Batch *drw_sphere_lod[DRW_LOD_MAX];
|
2023-07-27 14:16:58 +02:00
|
|
|
} SHC = {nullptr};
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2023-07-28 09:38:07 +10:00
|
|
|
void DRW_shape_cache_free()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2024-03-26 03:06:25 +01:00
|
|
|
uint i = sizeof(SHC) / sizeof(blender::gpu::Batch *);
|
|
|
|
|
blender::gpu::Batch **batch = (blender::gpu::Batch **)&SHC;
|
2017-08-16 19:50:27 +10:00
|
|
|
while (i--) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_BATCH_DISCARD_SAFE(*batch);
|
2017-08-16 19:50:27 +10:00
|
|
|
batch++;
|
|
|
|
|
}
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2019-05-11 17:45:20 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Procedural Batches
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *drw_cache_procedural_points_get()
|
2019-05-11 17:45:20 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_procedural_verts) {
|
2020-09-19 14:32:41 +10:00
|
|
|
/* TODO(fclem): get rid of this dummy VBO. */
|
2019-05-11 17:45:20 +02:00
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-05-11 17:45:20 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_procedural_verts = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_POINTS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-05-11 17:45:20 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_verts;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *drw_cache_procedural_lines_get()
|
2019-05-11 17:45:20 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_procedural_lines) {
|
2020-09-19 14:32:41 +10:00
|
|
|
/* TODO(fclem): get rid of this dummy VBO. */
|
2019-05-11 17:45:20 +02:00
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-05-11 17:45:20 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_procedural_lines = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-05-11 17:45:20 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_lines;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *drw_cache_procedural_triangles_get()
|
2019-05-11 17:45:20 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_procedural_tris) {
|
2020-09-19 14:32:41 +10:00
|
|
|
/* TODO(fclem): get rid of this dummy VBO. */
|
2019-05-11 17:45:20 +02:00
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-05-11 17:45:20 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_procedural_tris = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-05-11 17:45:20 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_tris;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *drw_cache_procedural_triangle_strips_get()
|
2022-08-02 20:35:35 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_procedural_tri_strips) {
|
|
|
|
|
/* TODO(fclem): get rid of this dummy VBO. */
|
|
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2022-08-02 20:35:35 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
SHC.drw_procedural_tri_strips = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2022-08-02 20:35:35 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_tri_strips;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-11 17:45:20 +02:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Helper functions
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2023-07-28 09:38:07 +10:00
|
|
|
static GPUVertFormat extra_vert_format()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
GPU_vertformat_attr_add(&format, "vclass", GPU_COMP_I32, 1, GPU_FETCH_INT);
|
|
|
|
|
return format;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
static void UNUSED_FUNCTION(add_fancy_edge)(blender::gpu::VertBuf *vbo,
|
2018-07-18 00:12:21 +02:00
|
|
|
uint pos_id,
|
|
|
|
|
uint n1_id,
|
|
|
|
|
uint n2_id,
|
2018-05-11 07:48:52 +02:00
|
|
|
uint *v_idx,
|
|
|
|
|
const float co1[3],
|
|
|
|
|
const float co2[3],
|
2018-05-16 19:04:07 +02:00
|
|
|
const float n1[3],
|
|
|
|
|
const float n2[3])
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co1);
|
2017-02-22 13:00:15 +01:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, n1_id, *v_idx, n1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, n2_id, *v_idx, n2);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, co2);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
|
2018-04-27 16:28:49 +02:00
|
|
|
#if 0 /* UNUSED */
|
2024-03-24 16:38:30 +01:00
|
|
|
static void add_lat_lon_vert(blender::gpu::VertBuf *vbo,
|
2019-04-17 08:24:14 +02:00
|
|
|
uint pos_id,
|
|
|
|
|
uint nor_id,
|
|
|
|
|
uint *v_idx,
|
|
|
|
|
const float rad,
|
|
|
|
|
const float lat,
|
|
|
|
|
const float lon)
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
float pos[3], nor[3];
|
|
|
|
|
nor[0] = sinf(lat) * cosf(lon);
|
|
|
|
|
nor[1] = cosf(lat);
|
|
|
|
|
nor[2] = sinf(lat) * sinf(lon);
|
|
|
|
|
mul_v3_v3fl(pos, nor, rad);
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, nor_id, *v_idx, nor);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, pos_id, (*v_idx)++, pos);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
static blender::gpu::VertBuf *fill_arrows_vbo(const float scale)
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
/* Position Only 3D format */
|
2019-04-17 08:24:14 +02:00
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Line */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 6 * 3);
|
2017-02-22 13:00:15 +01:00
|
|
|
|
|
|
|
|
float v1[3] = {0.0, 0.0, 0.0};
|
|
|
|
|
float v2[3] = {0.0, 0.0, 0.0};
|
|
|
|
|
float vtmp1[3], vtmp2[3];
|
|
|
|
|
|
|
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
const int arrow_axis = (axis == 0) ? 1 : 0;
|
|
|
|
|
|
|
|
|
|
v2[axis] = 1.0f;
|
|
|
|
|
mul_v3_v3fl(vtmp1, v1, scale);
|
|
|
|
|
mul_v3_v3fl(vtmp2, v2, scale);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 0, vtmp1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 1, vtmp2);
|
2017-02-22 13:00:15 +01:00
|
|
|
|
|
|
|
|
v1[axis] = 0.85f;
|
|
|
|
|
v1[arrow_axis] = -0.08f;
|
|
|
|
|
mul_v3_v3fl(vtmp1, v1, scale);
|
|
|
|
|
mul_v3_v3fl(vtmp2, v2, scale);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 2, vtmp1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 3, vtmp2);
|
2017-02-22 13:00:15 +01:00
|
|
|
|
|
|
|
|
v1[arrow_axis] = 0.08f;
|
|
|
|
|
mul_v3_v3fl(vtmp1, v1, scale);
|
|
|
|
|
mul_v3_v3fl(vtmp2, v2, scale);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 4, vtmp1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, axis * 6 + 5, vtmp2);
|
2017-02-22 13:00:15 +01:00
|
|
|
|
|
|
|
|
/* reset v1 & v2 to zero */
|
|
|
|
|
v1[arrow_axis] = v1[axis] = v2[axis] = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vbo;
|
|
|
|
|
}
|
2018-08-20 11:29:23 +10:00
|
|
|
#endif /* UNUSED */
|
2017-02-22 13:00:15 +01:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
static blender::gpu::VertBuf *sphere_wire_vbo(const float rad, int flag)
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
2017-06-09 01:14:39 +02:00
|
|
|
#define NSEGMENTS 32
|
2017-02-22 13:00:15 +01:00
|
|
|
/* Position Only 3D format */
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 2 * 3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
2017-02-22 13:00:15 +01:00
|
|
|
/* a single ring of vertices */
|
|
|
|
|
float p[NSEGMENTS][2];
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
|
2017-02-22 13:00:15 +01:00
|
|
|
p[i][0] = rad * cosf(angle);
|
|
|
|
|
p[i][1] = rad * sinf(angle);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
|
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
|
|
|
|
for (int j = 0; j < 2; j++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float cv[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 18:52:07 +01:00
|
|
|
cv[0] = p[(i + j) % NSEGMENTS][0];
|
|
|
|
|
cv[1] = p[(i + j) % NSEGMENTS][1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-31 20:44:49 +10:00
|
|
|
if (axis == 0) {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 0.0f}, flag});
|
2018-07-31 20:44:49 +10:00
|
|
|
}
|
|
|
|
|
else if (axis == 1) {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
|
2018-07-31 20:44:49 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, cv[0], cv[1]}, flag});
|
2018-07-31 20:44:49 +10:00
|
|
|
}
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
return vbo;
|
|
|
|
|
#undef NSEGMENTS
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Quads */
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_fullscreen_quad_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_fullscreen_quad) {
|
2017-05-09 21:46:04 +02:00
|
|
|
/* Use a triangle instead of a real quad */
|
|
|
|
|
/* https://www.slideshare.net/DevCentralAMD/vertex-shader-tricks-bill-bilodeau - slide 14 */
|
2020-08-07 22:36:11 +10:00
|
|
|
const float pos[3][2] = {{-1.0f, -1.0f}, {3.0f, -1.0f}, {-1.0f, 3.0f}};
|
|
|
|
|
const float uvs[3][2] = {{0.0f, 0.0f}, {2.0f, 0.0f}, {0.0f, 2.0f}};
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2017-02-22 19:58:55 +01:00
|
|
|
/* Position Only 2D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2017-05-17 12:22:22 +10:00
|
|
|
static struct {
|
|
|
|
|
uint pos, uvs;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.uvs = GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
GPU_vertformat_alias_add(&format, "texCoord");
|
2023-02-12 14:37:16 +11:00
|
|
|
GPU_vertformat_alias_add(&format, "orco"); /* Fix driver bug (see #70004) */
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 3);
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, i, pos[i]);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]);
|
2017-03-16 23:58:30 +01:00
|
|
|
}
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_fullscreen_quad = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_fullscreen_quad;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_quad_get()
|
2017-09-30 18:54:28 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_quad) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-09-30 18:54:28 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 4);
|
2017-09-30 18:54:28 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
2022-03-30 20:24:39 +02:00
|
|
|
const float p[4][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, {1.0f, -1.0f}};
|
2019-12-02 01:40:58 +01:00
|
|
|
for (int a = 0; a < 4; a++) {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a][0], p[a][1], 0.0f}, flag});
|
2017-09-30 18:54:28 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_quad = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-09-30 18:54:28 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_quad;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_quad_wires_get()
|
2019-03-06 12:39:07 -03:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_quad_wires) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-03-06 12:39:07 -03:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 5);
|
2019-03-06 12:39:07 -03:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
2020-08-07 22:36:11 +10:00
|
|
|
const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
|
2019-12-02 01:40:58 +01:00
|
|
|
for (int a = 0; a < 5; a++) {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a % 4][0], p[a % 4][1], 0.0f}, flag});
|
2019-03-06 12:39:07 -03:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_quad_wires = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-03-06 12:39:07 -03:00
|
|
|
}
|
|
|
|
|
return SHC.drw_quad_wires;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_grid_get()
|
2018-08-23 13:35:10 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_grid) {
|
|
|
|
|
/* Position Only 2D format */
|
|
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-08-23 13:35:10 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 8 * 8 * 2 * 3);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
uint v_idx = 0;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 8; i++) {
|
|
|
|
|
for (int j = 0; j < 8; j++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float pos0[2] = {float(i) / 8.0f, float(j) / 8.0f};
|
|
|
|
|
float pos1[2] = {float(i + 1) / 8.0f, float(j) / 8.0f};
|
|
|
|
|
float pos2[2] = {float(i) / 8.0f, float(j + 1) / 8.0f};
|
|
|
|
|
float pos3[2] = {float(i + 1) / 8.0f, float(j + 1) / 8.0f};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
madd_v2_v2v2fl(pos0, blender::float2{-1.0f, -1.0f}, pos0, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos1, blender::float2{-1.0f, -1.0f}, pos1, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos2, blender::float2{-1.0f, -1.0f}, pos2, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos3, blender::float2{-1.0f, -1.0f}, pos3, 2.0f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos0);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos2);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, pos3);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_grid = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-08-23 13:35:10 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_grid;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-14 13:45:54 +02:00
|
|
|
/* Sphere */
|
2024-03-24 16:38:30 +01:00
|
|
|
static void sphere_lat_lon_vert(blender::gpu::VertBuf *vbo, int *v_ofs, float lat, float lon)
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
float x = sinf(lat) * cosf(lon);
|
|
|
|
|
float y = cosf(lat);
|
|
|
|
|
float z = sinf(lat) * sinf(lon);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, *v_ofs, VertShaded{{x, y, z}, VCLASS_EMPTY_SCALED, {x, y, z}});
|
2019-12-02 01:40:58 +01:00
|
|
|
(*v_ofs)++;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_sphere_get(const eDRWLevelOfDetail level_of_detail)
|
2017-06-14 13:45:54 +02:00
|
|
|
{
|
2020-11-13 08:24:52 +01:00
|
|
|
BLI_assert(level_of_detail >= DRW_LOD_LOW && level_of_detail < DRW_LOD_MAX);
|
|
|
|
|
|
|
|
|
|
if (!SHC.drw_sphere_lod[level_of_detail]) {
|
|
|
|
|
int lat_res;
|
|
|
|
|
int lon_res;
|
|
|
|
|
|
|
|
|
|
switch (level_of_detail) {
|
|
|
|
|
case DRW_LOD_LOW:
|
|
|
|
|
lat_res = DRW_SPHERE_SHAPE_LATITUDE_LOW;
|
|
|
|
|
lon_res = DRW_SPHERE_SHAPE_LONGITUDE_LOW;
|
|
|
|
|
break;
|
|
|
|
|
case DRW_LOD_MEDIUM:
|
|
|
|
|
lat_res = DRW_SPHERE_SHAPE_LATITUDE_MEDIUM;
|
|
|
|
|
lon_res = DRW_SPHERE_SHAPE_LONGITUDE_MEDIUM;
|
|
|
|
|
break;
|
|
|
|
|
case DRW_LOD_HIGH:
|
|
|
|
|
lat_res = DRW_SPHERE_SHAPE_LATITUDE_HIGH;
|
|
|
|
|
lon_res = DRW_SPHERE_SHAPE_LONGITUDE_HIGH;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2020-11-13 08:24:52 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-12-11 13:35:53 +01:00
|
|
|
GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = (lat_res - 1) * lon_res * 6;
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
const float lon_inc = 2 * M_PI / lon_res;
|
|
|
|
|
const float lat_inc = M_PI / lat_res;
|
|
|
|
|
float lon, lat;
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
lon = 0.0f;
|
|
|
|
|
for (int i = 0; i < lon_res; i++, lon += lon_inc) {
|
|
|
|
|
lat = 0.0f;
|
|
|
|
|
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
|
|
|
|
|
if (j != lat_res - 1) { /* Pole */
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon + lon_inc);
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon);
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat, lon);
|
|
|
|
|
}
|
|
|
|
|
if (j != 0) { /* Pole */
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat, lon + lon_inc);
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat + lat_inc, lon + lon_inc);
|
|
|
|
|
sphere_lat_lon_vert(vbo, &v, lat, lon);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-13 08:24:52 +01:00
|
|
|
SHC.drw_sphere_lod[level_of_detail] = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-02-26 19:41:17 +01:00
|
|
|
}
|
2020-11-13 08:24:52 +01:00
|
|
|
return SHC.drw_sphere_lod[level_of_detail];
|
2017-06-14 13:45:54 +02:00
|
|
|
}
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Common
|
|
|
|
|
* \{ */
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static void circle_verts(
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
for (int a = 0; a < segments; a++) {
|
|
|
|
|
for (int b = 0; b < 2; b++) {
|
|
|
|
|
float angle = (2.0f * M_PI * (a + b)) / segments;
|
|
|
|
|
float s = sinf(angle) * radius;
|
|
|
|
|
float c = cosf(angle) * radius;
|
|
|
|
|
int v = *vert_idx;
|
|
|
|
|
*vert_idx = v + 1;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v, Vert{{s, c, z}, flag});
|
2018-07-16 15:01:44 +02:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static void circle_dashed_verts(
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
for (int a = 0; a < segments * 2; a += 2) {
|
|
|
|
|
for (int b = 0; b < 2; b++) {
|
|
|
|
|
float angle = (2.0f * M_PI * (a + b)) / (segments * 2);
|
|
|
|
|
float s = sinf(angle) * radius;
|
|
|
|
|
float c = cosf(angle) * radius;
|
|
|
|
|
int v = *vert_idx;
|
|
|
|
|
*vert_idx = v + 1;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v, Vert{{s, c, z}, flag});
|
2018-07-16 15:01:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-03 23:08:40 +10:00
|
|
|
/* XXX TODO: move that 1 unit cube to more common/generic place? */
|
2019-12-02 01:40:58 +01:00
|
|
|
static const float bone_box_verts[8][3] = {
|
|
|
|
|
{1.0f, 0.0f, 1.0f},
|
|
|
|
|
{1.0f, 0.0f, -1.0f},
|
|
|
|
|
{-1.0f, 0.0f, -1.0f},
|
|
|
|
|
{-1.0f, 0.0f, 1.0f},
|
|
|
|
|
{1.0f, 1.0f, 1.0f},
|
|
|
|
|
{1.0f, 1.0f, -1.0f},
|
|
|
|
|
{-1.0f, 1.0f, -1.0f},
|
|
|
|
|
{-1.0f, 1.0f, 1.0f},
|
|
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static const float bone_box_smooth_normals[8][3] = {
|
|
|
|
|
{M_SQRT3, -M_SQRT3, M_SQRT3},
|
|
|
|
|
{M_SQRT3, -M_SQRT3, -M_SQRT3},
|
|
|
|
|
{-M_SQRT3, -M_SQRT3, -M_SQRT3},
|
|
|
|
|
{-M_SQRT3, -M_SQRT3, M_SQRT3},
|
|
|
|
|
{M_SQRT3, M_SQRT3, M_SQRT3},
|
|
|
|
|
{M_SQRT3, M_SQRT3, -M_SQRT3},
|
|
|
|
|
{-M_SQRT3, M_SQRT3, -M_SQRT3},
|
|
|
|
|
{-M_SQRT3, M_SQRT3, M_SQRT3},
|
|
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static const uint bone_box_wire[24] = {
|
|
|
|
|
0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7,
|
|
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
#if 0 /* UNUSED */
|
|
|
|
|
/* aligned with bone_octahedral_wire
|
|
|
|
|
* Contains adjacent normal index */
|
|
|
|
|
static const uint bone_box_wire_adjacent_face[24] = {
|
|
|
|
|
0, 2, 0, 4, 1, 6, 1, 8, 3, 10, 5, 10, 7, 11, 9, 11, 3, 8, 2, 5, 4, 7, 6, 9,
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static const uint bone_box_solid_tris[12][3] = {
|
|
|
|
|
{0, 2, 1}, /* bottom */
|
|
|
|
|
{0, 3, 2},
|
|
|
|
|
|
|
|
|
|
{0, 1, 5}, /* sides */
|
|
|
|
|
{0, 5, 4},
|
|
|
|
|
|
|
|
|
|
{1, 2, 6},
|
|
|
|
|
{1, 6, 5},
|
|
|
|
|
|
|
|
|
|
{2, 3, 7},
|
|
|
|
|
{2, 7, 6},
|
|
|
|
|
|
|
|
|
|
{3, 0, 4},
|
|
|
|
|
{3, 4, 7},
|
|
|
|
|
|
|
|
|
|
{4, 5, 6}, /* top */
|
|
|
|
|
{4, 6, 7},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Store indices of generated verts from bone_box_solid_tris to define adjacency infos.
|
|
|
|
|
* See bone_octahedral_solid_tris for more infos.
|
|
|
|
|
*/
|
|
|
|
|
static const uint bone_box_wire_lines_adjacency[12][4] = {
|
|
|
|
|
{4, 2, 0, 11},
|
|
|
|
|
{0, 1, 2, 8},
|
|
|
|
|
{2, 4, 1, 14},
|
|
|
|
|
{1, 0, 4, 20}, /* bottom */
|
|
|
|
|
{0, 8, 11, 14},
|
|
|
|
|
{2, 14, 8, 20},
|
|
|
|
|
{1, 20, 14, 11},
|
|
|
|
|
{4, 11, 20, 8}, /* top */
|
|
|
|
|
{20, 0, 11, 2},
|
|
|
|
|
{11, 2, 8, 1},
|
|
|
|
|
{8, 1, 14, 4},
|
|
|
|
|
{14, 4, 20, 0}, /* sides */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if 0 /* UNUSED */
|
|
|
|
|
static const uint bone_box_solid_tris_adjacency[12][6] = {
|
|
|
|
|
{0, 5, 1, 14, 2, 8},
|
|
|
|
|
{3, 26, 4, 20, 5, 1},
|
|
|
|
|
|
|
|
|
|
{6, 2, 7, 16, 8, 11},
|
|
|
|
|
{9, 7, 10, 32, 11, 24},
|
|
|
|
|
|
|
|
|
|
{12, 0, 13, 22, 14, 17},
|
|
|
|
|
{15, 13, 16, 30, 17, 6},
|
|
|
|
|
|
|
|
|
|
{18, 3, 19, 28, 20, 23},
|
|
|
|
|
{21, 19, 22, 33, 23, 12},
|
|
|
|
|
|
|
|
|
|
{24, 4, 25, 10, 26, 29},
|
|
|
|
|
{27, 25, 28, 34, 29, 18},
|
|
|
|
|
|
|
|
|
|
{30, 9, 31, 15, 32, 35},
|
|
|
|
|
{33, 31, 34, 21, 35, 27},
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* aligned with bone_box_solid_tris */
|
|
|
|
|
static const float bone_box_solid_normals[12][3] = {
|
|
|
|
|
{0.0f, -1.0f, 0.0f},
|
|
|
|
|
{0.0f, -1.0f, 0.0f},
|
|
|
|
|
|
|
|
|
|
{1.0f, 0.0f, 0.0f},
|
|
|
|
|
{1.0f, 0.0f, 0.0f},
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
{0.0f, 0.0f, -1.0f},
|
|
|
|
|
{0.0f, 0.0f, -1.0f},
|
|
|
|
|
|
|
|
|
|
{-1.0f, 0.0f, 0.0f},
|
|
|
|
|
{-1.0f, 0.0f, 0.0f},
|
|
|
|
|
|
|
|
|
|
{0.0f, 0.0f, 1.0f},
|
|
|
|
|
{0.0f, 0.0f, 1.0f},
|
|
|
|
|
|
|
|
|
|
{0.0f, 1.0f, 0.0f},
|
|
|
|
|
{0.0f, 1.0f, 0.0f},
|
|
|
|
|
};
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_cube_get()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_cube) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
2020-02-11 15:18:55 +01:00
|
|
|
const int tri_len = ARRAY_SIZE(bone_box_solid_tris);
|
|
|
|
|
const int vert_len = ARRAY_SIZE(bone_box_verts);
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2020-02-11 15:18:55 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, vert_len);
|
|
|
|
|
|
|
|
|
|
GPUIndexBufBuilder elb;
|
|
|
|
|
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tri_len, vert_len);
|
2019-12-02 01:40:58 +01:00
|
|
|
|
|
|
|
|
int v = 0;
|
2020-02-11 15:18:55 +01:00
|
|
|
for (int i = 0; i < vert_len; i++) {
|
|
|
|
|
float x = bone_box_verts[i][0];
|
|
|
|
|
float y = bone_box_verts[i][1] * 2.0f - 1.0f;
|
|
|
|
|
float z = bone_box_verts[i][2];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, VCLASS_EMPTY_SCALED});
|
2020-02-11 15:18:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < tri_len; i++) {
|
|
|
|
|
const uint *tri_indices = bone_box_solid_tris[i];
|
|
|
|
|
GPU_indexbuf_add_tri_verts(&elb, tri_indices[0], tri_indices[1], tri_indices[2]);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-11 15:18:55 +01:00
|
|
|
SHC.drw_cube = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_TRIS, vbo, GPU_indexbuf_build(&elb), GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_cube;
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_circle_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2018-04-27 16:28:49 +02:00
|
|
|
#define CIRCLE_RESOL 64
|
2017-02-07 11:20:15 +01:00
|
|
|
if (!SHC.drw_circle) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
for (int a = 0; a < CIRCLE_RESOL + 1; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float x = sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
|
|
|
|
float z = cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
2019-12-02 01:40:58 +01:00
|
|
|
float y = 0.0f;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, VCLASS_EMPTY_SCALED});
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_circle = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_circle;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_normal_arrow_get()
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_normal_arrow) {
|
|
|
|
|
GPUVertFormat format = {0};
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
|
2017-03-05 05:22:40 +01:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 2);
|
2017-03-05 05:22:40 +01:00
|
|
|
|
2021-07-03 23:08:40 +10:00
|
|
|
/* TODO: real arrow. For now, it's a line positioned in the vertex shader. */
|
2017-03-05 05:22:40 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_normal_arrow = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_normal_arrow;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-01-05 12:20:30 -05:00
|
|
|
namespace blender::draw {
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
void DRW_vertbuf_create_wiredata(blender::gpu::VertBuf *vbo, const int vert_len)
|
2022-08-17 10:20:25 -04:00
|
|
|
{
|
|
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint wd;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
|
/* 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPU_vertbuf_init_with_format(vbo, &format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, vert_len);
|
|
|
|
|
|
|
|
|
|
if (GPU_vertbuf_get_format(vbo)->stride == 1) {
|
2023-07-28 09:38:07 +10:00
|
|
|
memset(GPU_vertbuf_get_data(vbo), 0xFF, size_t(vert_len));
|
2022-08-17 10:20:25 -04:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-05 12:20:30 -05:00
|
|
|
} // namespace blender::draw
|
|
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-03-09 16:27:24 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
2021-07-21 20:40:03 +10:00
|
|
|
/** \name Dummy VBO's
|
2020-03-09 16:27:24 +01:00
|
|
|
*
|
2021-07-21 20:40:03 +10:00
|
|
|
* We need a dummy VBO containing the vertex count to draw instances ranges.
|
2020-03-09 16:27:24 +01:00
|
|
|
*
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_gpencil_dummy_buffer_get()
|
2020-03-09 16:27:24 +01:00
|
|
|
{
|
2023-07-27 14:16:58 +02:00
|
|
|
if (SHC.drw_gpencil_dummy_quad == nullptr) {
|
2020-03-09 16:27:24 +01:00
|
|
|
GPUVertFormat format = {0};
|
2022-09-01 22:14:18 +02:00
|
|
|
/* NOTE: Use GPU_COMP_U32 to satisfy minimum 4-byte vertex stride for Metal backend. */
|
|
|
|
|
GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2020-03-09 16:27:24 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 4);
|
|
|
|
|
|
|
|
|
|
SHC.drw_gpencil_dummy_quad = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2020-03-09 16:27:24 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_gpencil_dummy_quad;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Common Object API
|
Geometry Nodes: Support modifier on curve objects
With this commit, curve objects support the geometry nodes modifier.
Curves objects now evaluate to `CurveEval` unless there was a previous
implicit conversion (tessellating modifiers, mesh modifiers, or the
settings in the curve "Geometry" panel). In the new code, curves are
only considered to be the wire edges-- any generated surface is a mesh
instead, stored in the evaluated geometry set.
The consolidation of concepts mentioned above allows remove a lot of
code that had to do with maintaining the `DispList` type temporarily
for modifiers and rendering. Instead, render engines see a separate
object for the mesh from the mesh geometry component, and when the
curve object evaluates to a curve, the `CurveEval` is always used for
drawing wire edges.
However, currently the `DispList` type is still maintained and used as
an intermediate step in implicit mesh conversion. In the future, more
uses of it could be changed to use `CurveEval` and `Mesh` instead.
This is mostly not changed behavior, it is just a formalization of
existing logic after recent fixes for 2.8 versions last year and two
years ago. Also, in the future more functionality can be converted
to nodes, removing cases of implicit conversions. For more discussion
on that topic, see T89676.
The `use_fill_deform` option is removed. It has not worked properly
since 2.62, and the choice for filling a curve before or after
deformation will work much better and be clearer with a node system.
Applying the geometry nodes modifier to generate a curve is not
implemented with this commit, so applying the modifier won't work
at all. This is a separate technical challenge, and should be solved
in a separate step.
Differential Revision: https://developer.blender.org/D11597
2021-09-11 13:54:40 -05:00
|
|
|
*
|
|
|
|
|
* \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).
|
2019-12-02 01:40:58 +01:00
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_object_all_edges_get(Object *ob)
|
2017-02-09 17:27:01 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
|
|
|
|
return DRW_cache_mesh_all_edges_get(ob);
|
2021-07-03 23:08:40 +10:00
|
|
|
/* TODO: should match #DRW_cache_object_surface_get. */
|
2017-04-28 22:30:21 +10:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2017-04-28 22:30:21 +10:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_object_edge_detection_get(Object *ob, bool *r_is_manifold)
|
2018-05-19 13:31:44 +02:00
|
|
|
{
|
|
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2018-05-21 13:21:26 +02:00
|
|
|
return DRW_cache_mesh_edge_detection_get(ob, r_is_manifold);
|
2018-05-19 13:31:44 +02:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2018-05-19 13:31:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_object_face_wireframe_get(Object *ob)
|
2018-05-31 18:43:19 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-05-31 18:43:19 +02:00
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2018-12-07 05:03:01 +01:00
|
|
|
return DRW_cache_mesh_face_wireframe_get(ob);
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_POINTCLOUD:
|
2020-07-15 20:10:45 +02:00
|
|
|
return DRW_pointcloud_batch_cache_get_dots(ob);
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_VOLUME:
|
|
|
|
|
return DRW_cache_volume_face_wireframe_get(ob);
|
2023-03-08 12:35:58 +01:00
|
|
|
case OB_GPENCIL_LEGACY:
|
2020-03-09 16:27:24 +01:00
|
|
|
return DRW_cache_gpencil_face_wireframe_get(ob);
|
2018-12-07 05:03:01 +01:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2018-05-31 18:43:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_object_loose_edges_get(Object *ob)
|
2018-06-01 11:35:51 +02:00
|
|
|
{
|
|
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
|
|
|
|
return DRW_cache_mesh_loose_edges_get(ob);
|
|
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2018-06-01 11:35:51 +02:00
|
|
|
}
|
|
|
|
|
}
|
2018-05-31 18:43:19 +02:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_object_surface_get(Object *ob)
|
2017-04-21 02:18:14 +10:00
|
|
|
{
|
|
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2018-12-16 15:17:31 +01:00
|
|
|
return DRW_cache_mesh_surface_get(ob);
|
2017-04-21 02:18:14 +10:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-04-21 02:18:14 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *DRW_cache_object_pos_vertbuf_get(Object *ob)
|
2020-06-19 17:02:55 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2023-12-08 16:40:06 -05:00
|
|
|
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(ob);
|
|
|
|
|
short type = (mesh != nullptr) ? short(OB_MESH) : ob->type;
|
2020-06-19 17:02:55 +02:00
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case OB_MESH:
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_pos_vertbuf_get(
|
2023-12-08 16:40:06 -05:00
|
|
|
static_cast<Mesh *>((mesh != nullptr) ? mesh : ob->data));
|
2020-06-19 17:02:55 +02:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2020-06-19 17:02:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-30 19:54:06 -05:00
|
|
|
int DRW_cache_object_material_count_get(const Object *ob)
|
2020-01-28 16:39:33 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2021-03-04 15:27:33 +01:00
|
|
|
short type = ob->type;
|
|
|
|
|
|
2023-12-08 16:40:06 -05:00
|
|
|
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(ob);
|
|
|
|
|
if (mesh != nullptr && type != OB_POINTCLOUD) {
|
Geometry Nodes: Support modifier on curve objects
With this commit, curve objects support the geometry nodes modifier.
Curves objects now evaluate to `CurveEval` unless there was a previous
implicit conversion (tessellating modifiers, mesh modifiers, or the
settings in the curve "Geometry" panel). In the new code, curves are
only considered to be the wire edges-- any generated surface is a mesh
instead, stored in the evaluated geometry set.
The consolidation of concepts mentioned above allows remove a lot of
code that had to do with maintaining the `DispList` type temporarily
for modifiers and rendering. Instead, render engines see a separate
object for the mesh from the mesh geometry component, and when the
curve object evaluates to a curve, the `CurveEval` is always used for
drawing wire edges.
However, currently the `DispList` type is still maintained and used as
an intermediate step in implicit mesh conversion. In the future, more
uses of it could be changed to use `CurveEval` and `Mesh` instead.
This is mostly not changed behavior, it is just a formalization of
existing logic after recent fixes for 2.8 versions last year and two
years ago. Also, in the future more functionality can be converted
to nodes, removing cases of implicit conversions. For more discussion
on that topic, see T89676.
The `use_fill_deform` option is removed. It has not worked properly
since 2.62, and the choice for filling a curve before or after
deformation will work much better and be clearer with a node system.
Applying the geometry nodes modifier to generate a curve is not
implemented with this commit, so applying the modifier won't work
at all. This is a separate technical challenge, and should be solved
in a separate step.
Differential Revision: https://developer.blender.org/D11597
2021-09-11 13:54:40 -05:00
|
|
|
/* Some object types can have one data type in ob->data, but will be rendered as mesh.
|
|
|
|
|
* For point clouds this never happens. Ideally this check would happen at another level
|
|
|
|
|
* and we would just have to care about ob->data here. */
|
2021-03-04 15:27:33 +01:00
|
|
|
type = OB_MESH;
|
|
|
|
|
}
|
2020-01-28 16:39:33 +01:00
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case OB_MESH:
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_material_count_get(
|
2023-12-08 16:40:06 -05:00
|
|
|
ob, static_cast<const Mesh *>((mesh != nullptr) ? mesh : ob->data));
|
2022-02-18 09:50:29 -06:00
|
|
|
case OB_CURVES_LEGACY:
|
2020-01-28 16:39:33 +01:00
|
|
|
case OB_SURF:
|
|
|
|
|
case OB_FONT:
|
2023-11-30 19:54:06 -05:00
|
|
|
return DRW_curve_material_count_get(static_cast<const Curve *>(ob->data));
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
case OB_CURVES:
|
2023-11-30 19:54:06 -05:00
|
|
|
return DRW_curves_material_count_get(static_cast<const Curves *>(ob->data));
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_POINTCLOUD:
|
2023-11-30 19:54:06 -05:00
|
|
|
return DRW_pointcloud_material_count_get(static_cast<const PointCloud *>(ob->data));
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_VOLUME:
|
2023-11-30 19:54:06 -05:00
|
|
|
return DRW_volume_material_count_get(static_cast<const Volume *>(ob->data));
|
2023-03-08 12:35:58 +01:00
|
|
|
case OB_GPENCIL_LEGACY:
|
2023-11-30 19:54:06 -05:00
|
|
|
return DRW_gpencil_material_count_get(static_cast<const bGPdata *>(ob->data));
|
2020-01-28 16:39:33 +01:00
|
|
|
default:
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch **DRW_cache_object_surface_material_get(Object *ob,
|
|
|
|
|
GPUMaterial **gpumat_array,
|
|
|
|
|
uint gpumat_array_len)
|
2017-04-25 18:46:59 +02:00
|
|
|
{
|
|
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2020-01-17 16:05:19 +01:00
|
|
|
return DRW_cache_mesh_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
2017-04-25 18:46:59 +02:00
|
|
|
default:
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2017-04-25 18:46:59 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 02:18:14 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Empties
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_plain_axes_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_plain_axes) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 6);
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, -1.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 1.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, -1.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, flag});
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_plain_axes = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_plain_axes;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_cube_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_empty_cube) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, ARRAY_SIZE(bone_box_wire));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(bone_box_wire); i++) {
|
|
|
|
|
float x = bone_box_verts[bone_box_wire[i]][0];
|
|
|
|
|
float y = bone_box_verts[bone_box_wire[i]][1] * 2.0 - 1.0f;
|
|
|
|
|
float z = bone_box_verts[bone_box_wire[i]][2];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, VCLASS_EMPTY_SCALED});
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_empty_cube = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cube;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_single_arrow_get()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_single_arrow) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 4 * 2 * 2 + 2);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
|
|
|
|
float p[3][3] = {{0}};
|
|
|
|
|
p[0][2] = 1.0f;
|
|
|
|
|
p[1][0] = 0.035f;
|
|
|
|
|
p[1][1] = 0.035f;
|
|
|
|
|
p[2][0] = -0.035f;
|
|
|
|
|
p[2][1] = 0.035f;
|
|
|
|
|
p[1][2] = p[2][2] = 0.75f;
|
2017-02-07 11:20:15 +01:00
|
|
|
for (int sides = 0; sides < 4; sides++) {
|
|
|
|
|
if (sides % 2 == 1) {
|
2019-12-02 01:40:58 +01:00
|
|
|
p[1][0] = -p[1][0];
|
|
|
|
|
p[2][1] = -p[2][1];
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2019-12-02 01:40:58 +01:00
|
|
|
p[1][1] = -p[1][1];
|
|
|
|
|
p[2][0] = -p[2][0];
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0, a = 1; i < 2; i++, a++) {
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[i][0], p[i][1], p[i][2]}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[a][0], p[a][1], p[a][2]}, flag});
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.75f}, flag});
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_single_arrow = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_single_arrow;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_sphere_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_empty_sphere) {
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = sphere_wire_vbo(1.0f, VCLASS_EMPTY_SCALED);
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_empty_sphere = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_sphere;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_cone_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
#define NSEGMENTS 8
|
|
|
|
|
if (!SHC.drw_empty_cone) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 4);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
2017-02-07 11:20:15 +01:00
|
|
|
/* a single ring of vertices */
|
|
|
|
|
float p[NSEGMENTS][2];
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
|
2017-02-07 11:20:15 +01:00
|
|
|
p[i][0] = cosf(angle);
|
|
|
|
|
p[i][1] = sinf(angle);
|
|
|
|
|
}
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float cv[2];
|
2017-02-07 11:20:15 +01:00
|
|
|
cv[0] = p[(i) % NSEGMENTS][0];
|
|
|
|
|
cv[1] = p[(i) % NSEGMENTS][1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
/* cone sides */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 2.0f, 0.0f}, flag});
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
/* end ring */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
|
2017-02-22 18:52:07 +01:00
|
|
|
cv[0] = p[(i + 1) % NSEGMENTS][0];
|
|
|
|
|
cv[1] = p[(i + 1) % NSEGMENTS][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], 0.0f, cv[1]}, flag});
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_empty_cone = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cone;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_cylinder_get()
|
2018-07-17 11:36:07 +02:00
|
|
|
{
|
|
|
|
|
#define NSEGMENTS 12
|
|
|
|
|
if (!SHC.drw_empty_cylinder) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, NSEGMENTS * 6);
|
|
|
|
|
|
2018-07-17 11:36:07 +02:00
|
|
|
/* a single ring of vertices */
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SCALED;
|
2018-07-17 11:36:07 +02:00
|
|
|
float p[NSEGMENTS][2];
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
|
2018-07-17 11:36:07 +02:00
|
|
|
p[i][0] = cosf(angle);
|
|
|
|
|
p[i][1] = sinf(angle);
|
|
|
|
|
}
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float cv[2], pv[2];
|
2018-07-17 11:36:07 +02:00
|
|
|
cv[0] = p[(i) % NSEGMENTS][0];
|
|
|
|
|
cv[1] = p[(i) % NSEGMENTS][1];
|
|
|
|
|
pv[0] = p[(i + 1) % NSEGMENTS][0];
|
|
|
|
|
pv[1] = p[(i + 1) % NSEGMENTS][1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-17 11:36:07 +02:00
|
|
|
/* cylinder sides */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], -1.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 1.0f}, flag});
|
2018-07-17 11:36:07 +02:00
|
|
|
/* top ring */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], 1.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{pv[0], pv[1], 1.0f}, flag});
|
2018-07-17 11:36:07 +02:00
|
|
|
/* bottom ring */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{cv[0], cv[1], -1.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{pv[0], pv[1], -1.0f}, flag});
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_empty_cylinder = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cylinder;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_capsule_body_get()
|
2018-07-17 11:36:07 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_empty_capsule_body) {
|
|
|
|
|
const float pos[8][3] = {
|
|
|
|
|
{1.0f, 0.0f, 1.0f},
|
|
|
|
|
{1.0f, 0.0f, 0.0f},
|
|
|
|
|
{0.0f, 1.0f, 1.0f},
|
|
|
|
|
{0.0f, 1.0f, 0.0f},
|
|
|
|
|
{-1.0f, 0.0f, 1.0f},
|
|
|
|
|
{-1.0f, 0.0f, 0.0f},
|
|
|
|
|
{0.0f, -1.0f, 1.0f},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0.0f, -1.0f, 0.0f},
|
2018-07-17 11:36:07 +02:00
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-17 11:36:07 +02:00
|
|
|
/* Position Only 3D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-07-17 11:36:07 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 8);
|
|
|
|
|
GPU_vertbuf_attr_fill(vbo, attr_id.pos, pos);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_empty_capsule_body = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_capsule_body;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_empty_capsule_cap_get()
|
2018-07-17 11:36:07 +02:00
|
|
|
{
|
|
|
|
|
#define NSEGMENTS 24 /* Must be multiple of 2. */
|
|
|
|
|
if (!SHC.drw_empty_capsule_cap) {
|
|
|
|
|
/* a single ring of vertices */
|
|
|
|
|
float p[NSEGMENTS][2];
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = 2 * M_PI * (float(i) / float(NSEGMENTS));
|
2018-07-17 11:36:07 +02:00
|
|
|
p[i][0] = cosf(angle);
|
|
|
|
|
p[i][1] = sinf(angle);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-17 11:36:07 +02:00
|
|
|
/* Position Only 3D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-07-17 11:36:07 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, (NSEGMENTS * 2) * 2);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-17 11:36:07 +02:00
|
|
|
/* Base circle */
|
|
|
|
|
int vidx = 0;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS; i++) {
|
2018-07-17 11:36:07 +02:00
|
|
|
float v[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
copy_v2_v2(v, p[(i) % NSEGMENTS]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-19 16:06:37 +10:00
|
|
|
copy_v2_v2(v, p[(i + 1) % NSEGMENTS]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < NSEGMENTS / 2; i++) {
|
2018-07-17 11:36:07 +02:00
|
|
|
float v[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
|
int ci = i % NSEGMENTS;
|
|
|
|
|
int pi = (i + 1) % NSEGMENTS;
|
|
|
|
|
/* Y half circle */
|
|
|
|
|
copy_v3_fl3(v, p[ci][0], 0.0f, p[ci][1]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-17 11:36:07 +02:00
|
|
|
copy_v3_fl3(v, p[pi][0], 0.0f, p[pi][1]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-17 11:36:07 +02:00
|
|
|
/* X half circle */
|
|
|
|
|
copy_v3_fl3(v, 0.0f, p[ci][0], p[ci][1]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-17 11:36:07 +02:00
|
|
|
copy_v3_fl3(v, 0.0f, p[pi][0], p[pi][1]);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_empty_capsule_cap = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_capsule_cap;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_wind_get()
|
2017-04-10 22:22:37 +02:00
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_wind) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * (CIRCLE_RESOL * 4);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE;
|
2017-04-10 22:22:37 +02:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float z = 0.05f * float(i);
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_wind = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_wind;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_force_get()
|
2017-04-10 22:22:37 +02:00
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_force) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * (CIRCLE_RESOL * 3);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE | VCLASS_SCREENALIGNED;
|
2017-04-10 22:22:37 +02:00
|
|
|
for (int i = 0; i < 3; i++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float radius = 1.0f + 0.5f * i;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_RESOL, radius, 0.0f, flag);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_force = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_force;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_vortex_get()
|
2017-04-10 22:22:37 +02:00
|
|
|
{
|
|
|
|
|
#define SPIRAL_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_vortex) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = SPIRAL_RESOL * 2 + 1;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE;
|
2017-04-10 22:22:37 +02:00
|
|
|
for (int a = SPIRAL_RESOL; a > -1; a--) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float r = a / float(SPIRAL_RESOL);
|
2019-12-02 01:40:58 +01:00
|
|
|
float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * r, cosf(angle) * r, 0.0f}, flag});
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
for (int a = 1; a <= SPIRAL_RESOL; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float r = a / float(SPIRAL_RESOL);
|
2019-12-02 01:40:58 +01:00
|
|
|
float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * -r, cosf(angle) * -r, 0.0f}, flag});
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_vortex = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_vortex;
|
|
|
|
|
#undef SPIRAL_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_curve_get()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_curve) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2 * (CIRCLE_RESOL);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE | VCLASS_SCREENALIGNED;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_RESOL, 1.0f, 0.0f, flag);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_curve = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_curve;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_tube_limit_get()
|
2017-04-10 22:22:37 +02:00
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
2020-01-23 15:38:33 +01:00
|
|
|
#define SIDE_STIPPLE 32
|
2017-04-10 22:22:37 +02:00
|
|
|
if (!SHC.drw_field_tube_limit) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-23 15:38:33 +01:00
|
|
|
int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE;
|
2017-04-10 22:22:37 +02:00
|
|
|
/* Caps */
|
|
|
|
|
for (int i = 0; i < 2; i++) {
|
2020-01-23 15:38:33 +01:00
|
|
|
float z = i * 2.0f - 1.0f;
|
|
|
|
|
circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-04-10 22:22:37 +02:00
|
|
|
/* Side Edges */
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
2020-01-23 15:38:33 +01:00
|
|
|
float angle = (2.0f * M_PI * a) / 4.0f;
|
|
|
|
|
for (int i = 0; i < SIDE_STIPPLE; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float z = (i / float(SIDE_STIPPLE)) * 2.0f - 1.0f;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle), cosf(angle), z}, flag});
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_tube_limit = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_tube_limit;
|
2020-01-23 15:38:33 +01:00
|
|
|
#undef SIDE_STIPPLE
|
2017-04-10 22:22:37 +02:00
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_cone_limit_get()
|
2017-04-10 22:22:37 +02:00
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
2020-01-23 15:38:33 +01:00
|
|
|
#define SIDE_STIPPLE 32
|
2017-04-10 22:22:37 +02:00
|
|
|
if (!SHC.drw_field_cone_limit) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-01-23 15:38:33 +01:00
|
|
|
int v_len = 2 * (CIRCLE_RESOL * 2 + 4 * SIDE_STIPPLE / 2);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE;
|
2017-04-10 22:22:37 +02:00
|
|
|
/* Caps */
|
|
|
|
|
for (int i = 0; i < 2; i++) {
|
2020-01-23 15:38:33 +01:00
|
|
|
float z = i * 2.0f - 1.0f;
|
|
|
|
|
circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, z, flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-04-10 22:22:37 +02:00
|
|
|
/* Side Edges */
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
2020-01-23 15:38:33 +01:00
|
|
|
float angle = (2.0f * M_PI * a) / 4.0f;
|
|
|
|
|
for (int i = 0; i < SIDE_STIPPLE; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float z = (i / float(SIDE_STIPPLE)) * 2.0f - 1.0f;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{sinf(angle) * z, cosf(angle) * z, z}, flag});
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_field_cone_limit = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_cone_limit;
|
2020-01-23 15:38:33 +01:00
|
|
|
#undef SIDE_STIPPLE
|
2017-04-10 22:22:37 +02:00
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_field_sphere_limit_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_sphere_limit) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * CIRCLE_RESOL;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_SIZE | VCLASS_SCREENALIGNED;
|
|
|
|
|
circle_dashed_verts(vbo, &v, CIRCLE_RESOL, 1.0f, 0.0f, flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_field_sphere_limit = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_field_sphere_limit;
|
|
|
|
|
#undef CIRCLE_RESOL
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/** \} */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Lights
|
|
|
|
|
* \{ */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
#define DIAMOND_NSEGMENTS 4
|
|
|
|
|
#define INNER_NSEGMENTS 8
|
|
|
|
|
#define OUTER_NSEGMENTS 10
|
|
|
|
|
#define CIRCLE_NSEGMENTS 32
|
2018-01-21 18:32:40 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static float light_distance_z_get(char axis, const bool start)
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
switch (axis) {
|
|
|
|
|
case 'x': /* - X */
|
|
|
|
|
return start ? 0.4f : 0.3f;
|
|
|
|
|
case 'X': /* + X */
|
|
|
|
|
return start ? 0.6f : 0.7f;
|
|
|
|
|
case 'y': /* - Y */
|
|
|
|
|
return start ? 1.4f : 1.3f;
|
|
|
|
|
case 'Y': /* + Y */
|
|
|
|
|
return start ? 1.6f : 1.7f;
|
|
|
|
|
case 'z': /* - Z */
|
|
|
|
|
return start ? 2.4f : 2.3f;
|
|
|
|
|
case 'Z': /* + Z */
|
|
|
|
|
return start ? 2.6f : 2.7f;
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return 0.0;
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_groundline_get()
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_ground_line) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * (1 + DIAMOND_NSEGMENTS);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
/* Ground Point */
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.35f, 0.0f, 0);
|
|
|
|
|
/* Ground Line */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 1.0}, 0});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, 0});
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_ground_line = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_ground_line;
|
Cycles/Eevee: Implement disk and ellipse shapes for area lamps
The implementation is pretty straightforward.
In Cycles, sampling the shapes is currently done w.r.t. area instead of solid angle.
There is a paper on solid angle sampling for disks [1], but the described algorithm is based on
simply sampling the enclosing square and rejecting samples outside of the disk, which is not exactly
great for Cycles' RNG (we'd need to setup a LCG for the repeated sampling) and for GPU divergence.
Even worse, the algorithm is only defined for disks. For ellipses, the basic idea still works, but a
way to analytically calculate the solid angle is required. This is technically possible [2], but the
calculation is extremely complex and still requires a lookup table for the Heuman Lambda function.
Therefore, I've decided to not implement that for now, we could still look into it later on.
In Eevee, the code uses the existing ltc_evaluate_disk to implement the lighting calculations.
[1]: "Solid Angle Sampling of Disk and Cylinder Lights"
[2]: "Analytical solution for the solid angle subtended at any point by an ellipse via a point source radiation vector potential"
Reviewers: sergey, brecht, fclem
Differential Revision: https://developer.blender.org/D3171
2018-05-24 03:50:16 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_icon_inner_lines_get()
|
Cycles/Eevee: Implement disk and ellipse shapes for area lamps
The implementation is pretty straightforward.
In Cycles, sampling the shapes is currently done w.r.t. area instead of solid angle.
There is a paper on solid angle sampling for disks [1], but the described algorithm is based on
simply sampling the enclosing square and rejecting samples outside of the disk, which is not exactly
great for Cycles' RNG (we'd need to setup a LCG for the repeated sampling) and for GPU divergence.
Even worse, the algorithm is only defined for disks. For ellipses, the basic idea still works, but a
way to analytically calculate the solid angle is required. This is technically possible [2], but the
calculation is extremely complex and still requires a lookup table for the Heuman Lambda function.
Therefore, I've decided to not implement that for now, we could still look into it later on.
In Eevee, the code uses the existing ltc_evaluate_disk to implement the lighting calculations.
[1]: "Solid Angle Sampling of Disk and Cylinder Lights"
[2]: "Analytical solution for the solid angle subtended at any point by an ellipse via a point source radiation vector potential"
Reviewers: sergey, brecht, fclem
Differential Revision: https://developer.blender.org/D3171
2018-05-24 03:50:16 +02:00
|
|
|
{
|
2023-03-07 15:12:35 +01:00
|
|
|
if (!SHC.drw_light_icon_inner_lines) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-07 15:12:35 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const float r = 9.0f;
|
|
|
|
|
int v = 0;
|
2023-03-07 15:12:35 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, r * 0.3f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
circle_dashed_verts(vbo, &v, INNER_NSEGMENTS, r * 1.0f, 0.0f, VCLASS_SCREENSPACE);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-07 15:12:35 +01:00
|
|
|
SHC.drw_light_icon_inner_lines = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
Cycles/Eevee: Implement disk and ellipse shapes for area lamps
The implementation is pretty straightforward.
In Cycles, sampling the shapes is currently done w.r.t. area instead of solid angle.
There is a paper on solid angle sampling for disks [1], but the described algorithm is based on
simply sampling the enclosing square and rejecting samples outside of the disk, which is not exactly
great for Cycles' RNG (we'd need to setup a LCG for the repeated sampling) and for GPU divergence.
Even worse, the algorithm is only defined for disks. For ellipses, the basic idea still works, but a
way to analytically calculate the solid angle is required. This is technically possible [2], but the
calculation is extremely complex and still requires a lookup table for the Heuman Lambda function.
Therefore, I've decided to not implement that for now, we could still look into it later on.
In Eevee, the code uses the existing ltc_evaluate_disk to implement the lighting calculations.
[1]: "Solid Angle Sampling of Disk and Cylinder Lights"
[2]: "Analytical solution for the solid angle subtended at any point by an ellipse via a point source radiation vector potential"
Reviewers: sergey, brecht, fclem
Differential Revision: https://developer.blender.org/D3171
2018-05-24 03:50:16 +02:00
|
|
|
}
|
2023-03-07 15:12:35 +01:00
|
|
|
return SHC.drw_light_icon_inner_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_icon_outer_lines_get()
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2023-03-07 15:12:35 +01:00
|
|
|
if (!SHC.drw_light_icon_outer_lines) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-07 15:12:35 +01:00
|
|
|
int v_len = 2 * OUTER_NSEGMENTS;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
const float r = 9.0f;
|
|
|
|
|
int v = 0;
|
2023-03-07 15:12:35 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
2023-03-07 15:12:35 +01:00
|
|
|
|
|
|
|
|
SHC.drw_light_icon_outer_lines = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2023-03-07 15:12:35 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_light_icon_outer_lines;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_icon_sun_rays_get()
|
2023-03-07 15:12:35 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_light_icon_sun_rays) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
const int num_rays = 8;
|
|
|
|
|
int v_len = 4 * num_rays;
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2023-03-07 15:12:35 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
const float r = 9.0f;
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Sun Rays */
|
2023-03-07 15:12:35 +01:00
|
|
|
for (int a = 0; a < num_rays; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = (2.0f * M_PI * a) / float(num_rays);
|
2019-12-02 01:40:58 +01:00
|
|
|
float s = sinf(angle) * r;
|
|
|
|
|
float c = cosf(angle) * r;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 1.6f, c * 1.6f, 0.0f}, VCLASS_SCREENSPACE});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 1.9f, c * 1.9f, 0.0f}, VCLASS_SCREENSPACE});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 2.2f, c * 2.2f, 0.0f}, VCLASS_SCREENSPACE});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s * 2.5f, c * 2.5f, 0.0f}, VCLASS_SCREENSPACE});
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
2023-03-07 15:12:35 +01:00
|
|
|
|
|
|
|
|
SHC.drw_light_icon_sun_rays = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2023-03-07 15:12:35 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_light_icon_sun_rays;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_point_lines_get()
|
2023-03-07 15:12:35 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_light_point_lines) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2 * CIRCLE_NSEGMENTS;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2023-03-07 15:12:35 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
|
|
|
|
|
/* Light area */
|
|
|
|
|
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_light_point_lines = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2023-03-07 15:12:35 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_light_point_lines;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_sun_lines_get()
|
2023-03-07 15:12:35 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_light_sun_lines) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2023-03-07 15:12:35 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Direction Line */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, 0});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, -20.0}, 0}); /* Good default. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_light_sun_lines = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_light_sun_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_spot_lines_get()
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_light_spot_lines) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-07 15:12:35 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS * 4 + 1);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
2023-03-07 15:12:35 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Light area */
|
|
|
|
|
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
|
|
|
|
/* Cone cap */
|
|
|
|
|
flag = VCLASS_LIGHT_SPOT_SHAPE;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
|
|
|
|
flag = VCLASS_LIGHT_SPOT_SHAPE | VCLASS_LIGHT_SPOT_BLEND;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
|
|
|
|
/* Cone silhouette */
|
|
|
|
|
flag = VCLASS_LIGHT_SPOT_SHAPE | VCLASS_LIGHT_SPOT_CONE;
|
|
|
|
|
for (int a = 0; a < CIRCLE_NSEGMENTS; a++) {
|
|
|
|
|
float angle = (2.0f * M_PI * a) / CIRCLE_NSEGMENTS;
|
|
|
|
|
float s = sinf(angle);
|
|
|
|
|
float c = cosf(angle);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s, c, -1.0f}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
/* Direction Line */
|
|
|
|
|
float zsta = light_distance_z_get('z', true);
|
|
|
|
|
float zend = light_distance_z_get('z', false);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_light_spot_lines = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_light_spot_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_spot_volume_get()
|
2018-08-22 18:44:24 +02:00
|
|
|
{
|
2019-02-27 12:02:02 +11:00
|
|
|
if (!SHC.drw_light_spot_volume) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = CIRCLE_NSEGMENTS + 1 + 1;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
/* Cone apex */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Cone silhouette */
|
|
|
|
|
int flag = VCLASS_LIGHT_SPOT_SHAPE;
|
|
|
|
|
for (int a = 0; a < CIRCLE_NSEGMENTS + 1; a++) {
|
|
|
|
|
float angle = (2.0f * M_PI * a) / CIRCLE_NSEGMENTS;
|
|
|
|
|
float s = sinf(-angle);
|
|
|
|
|
float c = cosf(-angle);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{s, c, -1.0f}, flag});
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_light_spot_volume = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
2019-02-27 12:02:02 +11:00
|
|
|
return SHC.drw_light_spot_volume;
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_area_disk_lines_get()
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_light_area_disk_lines) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-03-05 05:22:40 +01:00
|
|
|
|
2023-03-07 15:12:35 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + CIRCLE_NSEGMENTS + 1);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
2023-03-07 15:12:35 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Light area */
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 0.5f, 0.0f, VCLASS_LIGHT_AREA_SHAPE);
|
|
|
|
|
/* Direction Line */
|
|
|
|
|
float zsta = light_distance_z_get('z', true);
|
|
|
|
|
float zend = light_distance_z_get('z', false);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
|
|
|
|
|
SHC.drw_light_area_disk_lines = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_light_area_disk_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_light_area_square_lines_get()
|
2018-08-22 18:44:24 +02:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_light_area_square_lines) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2018-08-22 18:44:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2023-03-07 15:12:35 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS * 2 + 4 + 1);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
2023-03-07 15:12:35 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Light area */
|
|
|
|
|
int flag = VCLASS_LIGHT_AREA_SHAPE;
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
|
|
|
|
for (int b = 0; b < 2; b++) {
|
2020-08-07 22:36:11 +10:00
|
|
|
const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
|
2019-12-02 01:40:58 +01:00
|
|
|
float x = p[(a + b) % 4][0];
|
|
|
|
|
float y = p[(a + b) % 4][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x * 0.5f, y * 0.5f, 0.0f}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Direction Line */
|
|
|
|
|
float zsta = light_distance_z_get('z', true);
|
|
|
|
|
float zend = light_distance_z_get('z', false);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zsta}, VCLASS_LIGHT_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, zend}, VCLASS_LIGHT_DIST});
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE);
|
2018-08-22 18:44:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_light_area_square_lines = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_light_area_square_lines;
|
2018-08-22 18:44:24 +02:00
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
#undef CIRCLE_NSEGMENTS
|
|
|
|
|
#undef OUTER_NSEGMENTS
|
|
|
|
|
#undef INNER_NSEGMENTS
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Speaker
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_speaker_get()
|
2017-02-15 03:38:21 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_speaker) {
|
|
|
|
|
float v[3];
|
|
|
|
|
const int segments = 16;
|
|
|
|
|
int vidx = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-15 03:38:21 +01:00
|
|
|
/* Position Only 3D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2017-05-17 12:22:22 +10:00
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-02-15 03:38:21 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 3 * segments * 2 + 4 * 4);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-15 03:38:21 +01:00
|
|
|
for (int j = 0; j < 3; j++) {
|
|
|
|
|
float z = 0.25f * j - 0.125f;
|
|
|
|
|
float r = (j == 0 ? 0.5f : 0.25f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-15 03:38:21 +01:00
|
|
|
copy_v3_fl3(v, r, 0.0f, z);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2017-02-15 03:38:21 +01:00
|
|
|
for (int i = 1; i < segments; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float x = cosf(2.0f * float(M_PI) * i / segments) * r;
|
|
|
|
|
float y = sinf(2.0f * float(M_PI) * i / segments) * r;
|
2017-02-15 03:38:21 +01:00
|
|
|
copy_v3_fl3(v, x, y, z);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2017-02-15 03:38:21 +01:00
|
|
|
}
|
|
|
|
|
copy_v3_fl3(v, r, 0.0f, z);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2017-02-15 03:38:21 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-15 03:38:21 +01:00
|
|
|
for (int j = 0; j < 4; j++) {
|
|
|
|
|
float x = (((j + 1) % 2) * (j - 1)) * 0.5f;
|
|
|
|
|
float y = ((j % 2) * (j - 2)) * 0.5f;
|
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
|
|
|
if (i == 1) {
|
|
|
|
|
x *= 0.5f;
|
|
|
|
|
y *= 0.5f;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-15 03:38:21 +01:00
|
|
|
float z = 0.25f * i - 0.125f;
|
|
|
|
|
copy_v3_fl3(v, x, y, z);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2017-02-15 03:38:21 +01:00
|
|
|
if (i == 1) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v);
|
2017-02-15 03:38:21 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_speaker = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-15 03:38:21 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_speaker;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2017-06-07 16:00:10 +02:00
|
|
|
/** \name Probe
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lightprobe_cube_get()
|
2017-06-07 16:00:10 +02:00
|
|
|
{
|
2017-06-27 14:59:53 +02:00
|
|
|
if (!SHC.drw_lightprobe_cube) {
|
2020-01-16 19:47:13 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = (6 + 3 + (1 + 2 * DIAMOND_NSEGMENTS) * 6) * 2;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2020-01-16 19:47:13 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
const float r = 14.0f;
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_SCREENSPACE;
|
|
|
|
|
/* Icon */
|
2017-06-27 14:59:53 +02:00
|
|
|
const float sin_pi_3 = 0.86602540378f;
|
|
|
|
|
const float cos_pi_3 = 0.5f;
|
2020-01-16 19:47:13 +01:00
|
|
|
const float p[7][2] = {
|
|
|
|
|
{0.0f, 1.0f},
|
|
|
|
|
{sin_pi_3, cos_pi_3},
|
|
|
|
|
{sin_pi_3, -cos_pi_3},
|
|
|
|
|
{0.0f, -1.0f},
|
|
|
|
|
{-sin_pi_3, -cos_pi_3},
|
|
|
|
|
{-sin_pi_3, cos_pi_3},
|
|
|
|
|
{0.0f, 0.0f},
|
2017-06-27 14:59:53 +02:00
|
|
|
};
|
2020-01-16 19:47:13 +01:00
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
|
|
float t1[2], t2[2];
|
|
|
|
|
copy_v2_v2(t1, p[i]);
|
|
|
|
|
copy_v2_v2(t2, p[(i + 1) % 6]);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
|
|
|
|
|
}
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[1][0] * r, p[1][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[5][0] * r, p[5][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[3][0] * r, p[3][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
2020-01-16 19:47:13 +01:00
|
|
|
/* Direction Lines */
|
|
|
|
|
flag = VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 6; i++) {
|
2020-01-16 19:47:13 +01:00
|
|
|
char axes[] = "zZyYxX";
|
|
|
|
|
float zsta = light_distance_z_get(axes[i], true);
|
|
|
|
|
float zend = light_distance_z_get(axes[i], false);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zsta}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zend}, flag});
|
2020-01-16 19:47:13 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, flag);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, flag);
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_lightprobe_cube = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_lightprobe_cube;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lightprobe_grid_get()
|
2017-06-27 14:59:53 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_lightprobe_grid) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = (6 * 2 + 3 + (1 + 2 * DIAMOND_NSEGMENTS) * 6) * 2;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const float r = 14.0f;
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_SCREENSPACE;
|
|
|
|
|
/* Icon */
|
|
|
|
|
const float sin_pi_3 = 0.86602540378f;
|
|
|
|
|
const float cos_pi_3 = 0.5f;
|
|
|
|
|
const float p[7][2] = {
|
|
|
|
|
{0.0f, 1.0f},
|
|
|
|
|
{sin_pi_3, cos_pi_3},
|
|
|
|
|
{sin_pi_3, -cos_pi_3},
|
|
|
|
|
{0.0f, -1.0f},
|
|
|
|
|
{-sin_pi_3, -cos_pi_3},
|
|
|
|
|
{-sin_pi_3, cos_pi_3},
|
|
|
|
|
{0.0f, 0.0f},
|
|
|
|
|
};
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 6; i++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float t1[2], t2[2], tr[2];
|
|
|
|
|
copy_v2_v2(t1, p[i]);
|
|
|
|
|
copy_v2_v2(t2, p[(i + 1) % 6]);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
|
2017-06-27 14:59:53 +02:00
|
|
|
/* Internal wires. */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int j = 1; j < 2; j++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
mul_v2_v2fl(tr, p[(i / 2) * 2 + 1], -0.5f * j);
|
|
|
|
|
add_v2_v2v2(t1, p[i], tr);
|
|
|
|
|
add_v2_v2v2(t2, p[(i + 1) % 6], tr);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t1[0] * r, t1[1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{t2[0] * r, t2[1] * r, 0.0f}, flag});
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[1][0] * r, p[1][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[5][0] * r, p[5][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[3][0] * r, p[3][1] * r, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[6][0] * r, p[6][1] * r, 0.0f}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Direction Lines */
|
|
|
|
|
flag = VCLASS_LIGHT_DIST | VCLASS_SCREENSPACE;
|
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
|
|
|
char axes[] = "zZyYxX";
|
|
|
|
|
float zsta = light_distance_z_get(axes[i], true);
|
|
|
|
|
float zend = light_distance_z_get(axes[i], false);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zsta}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, zend}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zsta, flag);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.2f, zend, flag);
|
2017-06-07 16:00:10 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_lightprobe_grid = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_lightprobe_grid;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lightprobe_planar_get()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_lightprobe_planar) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2 * 4;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const float r = 20.0f;
|
|
|
|
|
int v = 0;
|
|
|
|
|
/* Icon */
|
|
|
|
|
const float sin_pi_3 = 0.86602540378f;
|
|
|
|
|
const float p[4][2] = {
|
|
|
|
|
{0.0f, 0.5f},
|
|
|
|
|
{sin_pi_3, 0.0f},
|
|
|
|
|
{0.0f, -0.5f},
|
|
|
|
|
{-sin_pi_3, 0.0f},
|
|
|
|
|
};
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
for (int a = 0; a < 2; a++) {
|
|
|
|
|
float x = p[(i + a) % 4][0] * r;
|
|
|
|
|
float y = p[(i + a) % 4][1] * r;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0}, VCLASS_SCREENSPACE});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_lightprobe_planar = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-06-07 16:00:10 +02:00
|
|
|
}
|
2017-06-27 14:59:53 +02:00
|
|
|
return SHC.drw_lightprobe_planar;
|
2017-06-07 16:00:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \name Armature Bones
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
static const float bone_octahedral_verts[6][3] = {
|
|
|
|
|
{0.0f, 0.0f, 0.0f},
|
|
|
|
|
{0.1f, 0.1f, 0.1f},
|
|
|
|
|
{0.1f, 0.1f, -0.1f},
|
|
|
|
|
{-0.1f, 0.1f, -0.1f},
|
|
|
|
|
{-0.1f, 0.1f, 0.1f},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0.0f, 1.0f, 0.0f},
|
2017-02-22 13:00:15 +01:00
|
|
|
};
|
|
|
|
|
|
2018-04-22 21:55:05 +02:00
|
|
|
static const float bone_octahedral_smooth_normals[6][3] = {
|
|
|
|
|
{0.0f, -1.0f, 0.0f},
|
|
|
|
|
#if 0 /* creates problems for outlines when scaled */
|
2019-04-17 08:24:14 +02:00
|
|
|
{0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
|
|
|
|
|
{0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
|
|
|
|
|
{-0.943608f * M_SQRT1_2, -0.331048f, -0.943608f * M_SQRT1_2},
|
|
|
|
|
{-0.943608f * M_SQRT1_2, -0.331048f, 0.943608f * M_SQRT1_2},
|
2018-04-22 21:55:05 +02:00
|
|
|
#else
|
|
|
|
|
{M_SQRT1_2, 0.0f, M_SQRT1_2},
|
|
|
|
|
{M_SQRT1_2, 0.0f, -M_SQRT1_2},
|
|
|
|
|
{-M_SQRT1_2, 0.0f, -M_SQRT1_2},
|
|
|
|
|
{-M_SQRT1_2, 0.0f, M_SQRT1_2},
|
|
|
|
|
#endif
|
2019-02-03 14:01:45 +11:00
|
|
|
{0.0f, 1.0f, 0.0f},
|
2018-04-22 21:55:05 +02:00
|
|
|
};
|
|
|
|
|
|
2018-05-27 11:06:03 +02:00
|
|
|
#if 0 /* UNUSED */
|
|
|
|
|
|
2018-05-11 07:48:52 +02:00
|
|
|
static const uint bone_octahedral_wire[24] = {
|
2019-04-17 08:24:14 +02:00
|
|
|
0, 1, 1, 5, 5, 3, 3, 0, 0, 4, 4, 5, 5, 2, 2, 0, 1, 2, 2, 3, 3, 4, 4, 1,
|
2017-02-22 13:00:15 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* aligned with bone_octahedral_wire
|
|
|
|
|
* Contains adjacent normal index */
|
2018-05-11 07:48:52 +02:00
|
|
|
static const uint bone_octahedral_wire_adjacent_face[24] = {
|
2019-04-17 08:24:14 +02:00
|
|
|
0, 3, 4, 7, 5, 6, 1, 2, 2, 3, 6, 7, 4, 5, 0, 1, 0, 4, 1, 5, 2, 6, 3, 7,
|
2017-02-22 13:00:15 +01:00
|
|
|
};
|
2018-05-16 19:04:07 +02:00
|
|
|
#endif
|
2017-02-22 13:00:15 +01:00
|
|
|
|
2018-05-11 07:48:52 +02:00
|
|
|
static const uint bone_octahedral_solid_tris[8][3] = {
|
2017-02-22 13:00:15 +01:00
|
|
|
{2, 1, 0}, /* bottom */
|
|
|
|
|
{3, 2, 0},
|
|
|
|
|
{4, 3, 0},
|
|
|
|
|
{1, 4, 0},
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
{5, 1, 2}, /* top */
|
|
|
|
|
{5, 2, 3},
|
|
|
|
|
{5, 3, 4},
|
2019-02-03 14:01:45 +11:00
|
|
|
{5, 4, 1},
|
2017-02-22 13:00:15 +01:00
|
|
|
};
|
|
|
|
|
|
2018-04-22 21:55:05 +02:00
|
|
|
/**
|
|
|
|
|
* Store indices of generated verts from bone_octahedral_solid_tris to define adjacency infos.
|
|
|
|
|
* Example: triangle {2, 1, 0} is adjacent to {3, 2, 0}, {1, 4, 0} and {5, 1, 2}.
|
|
|
|
|
* {2, 1, 0} becomes {0, 1, 2}
|
|
|
|
|
* {3, 2, 0} becomes {3, 4, 5}
|
|
|
|
|
* {1, 4, 0} becomes {9, 10, 11}
|
|
|
|
|
* {5, 1, 2} becomes {12, 13, 14}
|
|
|
|
|
* According to opengl specification it becomes (starting from
|
|
|
|
|
* the first vertex of the first face aka. vertex 2):
|
|
|
|
|
* {0, 12, 1, 10, 2, 3}
|
2019-03-19 15:17:46 +11:00
|
|
|
*/
|
2018-05-20 22:48:35 +02:00
|
|
|
static const uint bone_octahedral_wire_lines_adjacency[12][4] = {
|
2018-05-21 00:15:19 +02:00
|
|
|
{0, 1, 2, 6},
|
|
|
|
|
{0, 12, 1, 6},
|
|
|
|
|
{0, 3, 12, 6},
|
|
|
|
|
{0, 2, 3, 6},
|
|
|
|
|
{1, 6, 2, 3},
|
|
|
|
|
{1, 12, 6, 3},
|
|
|
|
|
{1, 0, 12, 3},
|
|
|
|
|
{1, 2, 0, 3},
|
|
|
|
|
{2, 0, 1, 12},
|
|
|
|
|
{2, 3, 0, 12},
|
|
|
|
|
{2, 6, 3, 12},
|
|
|
|
|
{2, 1, 6, 12},
|
2018-05-20 22:48:35 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if 0 /* UNUSED */
|
2018-05-11 07:48:52 +02:00
|
|
|
static const uint bone_octahedral_solid_tris_adjacency[8][6] = {
|
2019-04-17 08:24:14 +02:00
|
|
|
{0, 12, 1, 10, 2, 3},
|
|
|
|
|
{3, 15, 4, 1, 5, 6},
|
|
|
|
|
{6, 18, 7, 4, 8, 9},
|
|
|
|
|
{9, 21, 10, 7, 11, 0},
|
|
|
|
|
|
|
|
|
|
{12, 22, 13, 2, 14, 17},
|
|
|
|
|
{15, 13, 16, 5, 17, 20},
|
|
|
|
|
{18, 16, 19, 8, 20, 23},
|
|
|
|
|
{21, 19, 22, 11, 23, 14},
|
2018-04-22 21:55:05 +02:00
|
|
|
};
|
2018-05-20 22:48:35 +02:00
|
|
|
#endif
|
2018-04-22 21:55:05 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
/* aligned with bone_octahedral_solid_tris */
|
|
|
|
|
static const float bone_octahedral_solid_normals[8][3] = {
|
|
|
|
|
{M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
|
|
|
|
|
{-0.00000000f, -M_SQRT1_2, -M_SQRT1_2},
|
|
|
|
|
{-M_SQRT1_2, -M_SQRT1_2, 0.00000000f},
|
|
|
|
|
{0.00000000f, -M_SQRT1_2, M_SQRT1_2},
|
|
|
|
|
{0.99388373f, 0.11043154f, -0.00000000f},
|
|
|
|
|
{0.00000000f, 0.11043154f, -0.99388373f},
|
|
|
|
|
{-0.99388373f, 0.11043154f, 0.00000000f},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0.00000000f, 0.11043154f, 0.99388373f},
|
2017-02-22 13:00:15 +01:00
|
|
|
};
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_octahedral_get()
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_octahedral) {
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v_idx = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-04-22 21:55:05 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos, nor, snor;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.snor = GPU_vertformat_attr_add(&format, "snor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
/* Vertices */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 24);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
for (int i = 0; i < 8; i++) {
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int j = 0; j < 3; j++) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_octahedral_solid_normals[i]);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo,
|
|
|
|
|
attr_id.snor,
|
|
|
|
|
v_idx,
|
|
|
|
|
bone_octahedral_smooth_normals[bone_octahedral_solid_tris[i][j]]);
|
|
|
|
|
GPU_vertbuf_attr_set(
|
|
|
|
|
vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][j]]);
|
2018-05-21 00:15:19 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_octahedral = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_octahedral;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_octahedral_wire_get()
|
2018-05-20 22:48:35 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_octahedral_wire) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBufBuilder elb;
|
|
|
|
|
GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, 12, 24);
|
2018-05-20 22:48:35 +02:00
|
|
|
|
|
|
|
|
for (int i = 0; i < 12; i++) {
|
2019-01-04 19:08:09 +11:00
|
|
|
GPU_indexbuf_add_line_adj_verts(&elb,
|
|
|
|
|
bone_octahedral_wire_lines_adjacency[i][0],
|
|
|
|
|
bone_octahedral_wire_lines_adjacency[i][1],
|
|
|
|
|
bone_octahedral_wire_lines_adjacency[i][2],
|
|
|
|
|
bone_octahedral_wire_lines_adjacency[i][3]);
|
2018-05-20 22:48:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* HACK Reuse vertex buffer. */
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *pos_nor_batch = DRW_cache_bone_octahedral_get();
|
2018-05-20 22:48:35 +02:00
|
|
|
|
2019-01-04 19:08:09 +11:00
|
|
|
SHC.drw_bone_octahedral_wire = GPU_batch_create_ex(GPU_PRIM_LINES_ADJ,
|
|
|
|
|
pos_nor_batch->verts[0],
|
|
|
|
|
GPU_indexbuf_build(&elb),
|
|
|
|
|
GPU_BATCH_OWNS_INDEX);
|
2018-05-20 22:48:35 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_octahedral_wire;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_box_get()
|
2017-05-03 08:34:24 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_box) {
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v_idx = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-04-22 21:55:05 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos, nor, snor;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.snor = GPU_vertformat_attr_add(&format, "snor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-05-03 08:34:24 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-03 08:34:24 +02:00
|
|
|
/* Vertices */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 36);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-03 08:34:24 +02:00
|
|
|
for (int i = 0; i < 12; i++) {
|
|
|
|
|
for (int j = 0; j < 3; j++) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.nor, v_idx, bone_box_solid_normals[i]);
|
|
|
|
|
GPU_vertbuf_attr_set(
|
|
|
|
|
vbo, attr_id.snor, v_idx, bone_box_smooth_normals[bone_box_solid_tris[i][j]]);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_box_verts[bone_box_solid_tris[i][j]]);
|
2017-05-03 08:34:24 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_box = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-05-03 08:34:24 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_box;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_box_wire_get()
|
2018-05-20 22:48:35 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_box_wire) {
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBufBuilder elb;
|
|
|
|
|
GPU_indexbuf_init(&elb, GPU_PRIM_LINES_ADJ, 12, 36);
|
2018-05-20 22:48:35 +02:00
|
|
|
|
|
|
|
|
for (int i = 0; i < 12; i++) {
|
2019-01-04 19:08:09 +11:00
|
|
|
GPU_indexbuf_add_line_adj_verts(&elb,
|
|
|
|
|
bone_box_wire_lines_adjacency[i][0],
|
|
|
|
|
bone_box_wire_lines_adjacency[i][1],
|
|
|
|
|
bone_box_wire_lines_adjacency[i][2],
|
|
|
|
|
bone_box_wire_lines_adjacency[i][3]);
|
2018-05-20 22:48:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* HACK Reuse vertex buffer. */
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *pos_nor_batch = DRW_cache_bone_box_get();
|
2018-05-20 22:48:35 +02:00
|
|
|
|
2019-01-04 19:08:09 +11:00
|
|
|
SHC.drw_bone_box_wire = GPU_batch_create_ex(GPU_PRIM_LINES_ADJ,
|
|
|
|
|
pos_nor_batch->verts[0],
|
|
|
|
|
GPU_indexbuf_build(&elb),
|
|
|
|
|
GPU_BATCH_OWNS_INDEX);
|
2018-05-20 22:48:35 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_box_wire;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-18 11:41:59 +02:00
|
|
|
/* Helpers for envelope bone's solid sphere-with-hidden-equatorial-cylinder.
|
|
|
|
|
* Note that here we only encode head/tail in forth component of the vector. */
|
|
|
|
|
static void benv_lat_lon_to_co(const float lat, const float lon, float r_nor[3])
|
|
|
|
|
{
|
|
|
|
|
r_nor[0] = sinf(lat) * cosf(lon);
|
2018-05-02 08:44:24 +02:00
|
|
|
r_nor[1] = sinf(lat) * sinf(lon);
|
|
|
|
|
r_nor[2] = cosf(lat);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_envelope_solid_get()
|
2017-05-18 11:41:59 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_envelope) {
|
2018-04-29 19:39:44 +02:00
|
|
|
const int lon_res = 24;
|
2018-05-02 08:44:24 +02:00
|
|
|
const int lat_res = 24;
|
2018-04-29 19:39:44 +02:00
|
|
|
const float lon_inc = 2.0f * M_PI / lon_res;
|
|
|
|
|
const float lat_inc = M_PI / lat_res;
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v_idx = 0;
|
2017-05-18 11:41:59 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2017-05-18 11:41:59 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Vertices */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, ((lat_res + 1) * 2) * lon_res * 1);
|
2017-05-18 11:41:59 +02:00
|
|
|
|
2018-05-02 08:44:24 +02:00
|
|
|
float lon = 0.0f;
|
2017-05-18 11:41:59 +02:00
|
|
|
for (int i = 0; i < lon_res; i++, lon += lon_inc) {
|
|
|
|
|
float lat = 0.0f;
|
2018-05-02 08:58:29 +02:00
|
|
|
float co1[3], co2[3];
|
2017-05-18 11:41:59 +02:00
|
|
|
|
2021-07-03 23:08:40 +10:00
|
|
|
/* NOTE: the poles are duplicated on purpose, to restart the strip. */
|
2018-05-02 08:44:24 +02:00
|
|
|
|
2018-04-29 19:39:44 +02:00
|
|
|
/* 1st sphere */
|
2017-05-18 11:41:59 +02:00
|
|
|
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
|
2018-04-29 19:39:44 +02:00
|
|
|
benv_lat_lon_to_co(lat, lon, co1);
|
|
|
|
|
benv_lat_lon_to_co(lat, lon + lon_inc, co2);
|
2017-05-18 11:41:59 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
2018-04-29 19:39:44 +02:00
|
|
|
|
2018-05-02 08:44:24 +02:00
|
|
|
/* Closing the loop */
|
|
|
|
|
benv_lat_lon_to_co(M_PI, lon, co1);
|
|
|
|
|
benv_lat_lon_to_co(M_PI, lon + lon_inc, co2);
|
2018-04-29 19:39:44 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, co2);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_envelope = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_TRI_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_envelope;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_envelope_outline_get()
|
2017-05-17 12:34:06 +02:00
|
|
|
{
|
2018-04-30 22:35:30 +02:00
|
|
|
if (!SHC.drw_bone_envelope_outline) {
|
|
|
|
|
#define CIRCLE_RESOL 64
|
|
|
|
|
float v0[2], v1[2], v2[2];
|
|
|
|
|
const float radius = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-30 22:35:30 +02:00
|
|
|
/* Position Only 2D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-04-30 22:35:30 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos0, pos1, pos2;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos0 = GPU_vertformat_attr_add(&format, "pos0", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.pos1 = GPU_vertformat_attr_add(&format, "pos1", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.pos2 = GPU_vertformat_attr_add(&format, "pos2", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2017-05-17 12:34:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-05 16:08:52 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-28 09:38:07 +10:00
|
|
|
v0[0] = radius * sinf((2.0f * M_PI * -2) / float(CIRCLE_RESOL));
|
|
|
|
|
v0[1] = radius * cosf((2.0f * M_PI * -2) / float(CIRCLE_RESOL));
|
|
|
|
|
v1[0] = radius * sinf((2.0f * M_PI * -1) / float(CIRCLE_RESOL));
|
|
|
|
|
v1[1] = radius * cosf((2.0f * M_PI * -1) / float(CIRCLE_RESOL));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-30 22:35:30 +02:00
|
|
|
/* Output 4 verts for each position. See shader for explanation. */
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v = 0;
|
2019-12-05 16:08:52 +01:00
|
|
|
for (int a = 0; a <= CIRCLE_RESOL; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
v2[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
|
|
|
|
v2[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos0, v, v0);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos1, v, v1);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos2, v++, v2);
|
2018-04-30 22:35:30 +02:00
|
|
|
copy_v2_v2(v0, v1);
|
|
|
|
|
copy_v2_v2(v1, v2);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_envelope_outline = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-04-30 22:35:30 +02:00
|
|
|
#undef CIRCLE_RESOL
|
2017-05-17 12:34:06 +02:00
|
|
|
}
|
2018-04-30 22:35:30 +02:00
|
|
|
return SHC.drw_bone_envelope_outline;
|
2017-05-17 12:34:06 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_point_get()
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_point) {
|
2018-04-27 16:27:47 +02:00
|
|
|
#if 0 /* old style geometry sphere */
|
2017-02-22 13:00:15 +01:00
|
|
|
const int lon_res = 16;
|
|
|
|
|
const int lat_res = 8;
|
|
|
|
|
const float rad = 0.05f;
|
|
|
|
|
const float lon_inc = 2 * M_PI / lon_res;
|
|
|
|
|
const float lat_inc = M_PI / lat_res;
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v_idx = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-17 08:24:14 +02:00
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint pos, nor;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
/* Vertices */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, (lat_res - 1) * lon_res * 6);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
float lon = 0.0f;
|
2017-02-22 18:52:07 +01:00
|
|
|
for (int i = 0; i < lon_res; i++, lon += lon_inc) {
|
2017-02-22 13:00:15 +01:00
|
|
|
float lat = 0.0f;
|
2017-02-22 18:52:07 +01:00
|
|
|
for (int j = 0; j < lat_res; j++, lat += lat_inc) {
|
2017-02-22 13:00:15 +01:00
|
|
|
if (j != lat_res - 1) { /* Pole */
|
2019-04-17 08:24:14 +02:00
|
|
|
add_lat_lon_vert(
|
|
|
|
|
vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
|
2017-05-17 12:22:22 +10:00
|
|
|
add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon);
|
2019-04-17 08:24:14 +02:00
|
|
|
add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-02-22 13:00:15 +01:00
|
|
|
if (j != 0) { /* Pole */
|
2019-04-17 08:24:14 +02:00
|
|
|
add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon + lon_inc);
|
|
|
|
|
add_lat_lon_vert(
|
|
|
|
|
vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat + lat_inc, lon + lon_inc);
|
|
|
|
|
add_lat_lon_vert(vbo, attr_id.pos, attr_id.nor, &v_idx, rad, lat, lon);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-04-27 16:27:47 +02:00
|
|
|
#else
|
|
|
|
|
# define CIRCLE_RESOL 64
|
|
|
|
|
float v[2];
|
|
|
|
|
const float radius = 0.05f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-27 16:27:47 +02:00
|
|
|
/* Position Only 2D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-04-27 16:27:47 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2018-04-27 16:27:47 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-27 16:27:47 +02:00
|
|
|
for (int a = 0; a < CIRCLE_RESOL; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
v[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
|
|
|
|
v[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, a, v);
|
2018-04-27 16:27:47 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-04-27 16:27:47 +02:00
|
|
|
# undef CIRCLE_RESOL
|
|
|
|
|
#endif
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_point;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_point_wire_outline_get()
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_point_wire) {
|
2018-04-27 16:27:47 +02:00
|
|
|
#if 0 /* old style geometry sphere */
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = sphere_wire_vbo(0.05f);
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_point_wire = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-04-27 16:27:47 +02:00
|
|
|
#else
|
|
|
|
|
# define CIRCLE_RESOL 64
|
|
|
|
|
const float radius = 0.05f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-04-27 16:27:47 +02:00
|
|
|
/* Position Only 2D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-04-27 16:27:47 +02:00
|
|
|
static struct {
|
2019-12-05 16:08:52 +01:00
|
|
|
uint pos;
|
2018-04-27 16:27:47 +02:00
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2019-12-05 16:08:52 +01:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
2018-04-27 16:27:47 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-05 16:08:52 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v = 0;
|
2019-12-05 16:08:52 +01:00
|
|
|
for (int a = 0; a <= CIRCLE_RESOL; a++) {
|
|
|
|
|
float pos[2];
|
|
|
|
|
pos[0] = radius * sinf((2.0f * M_PI * a) / CIRCLE_RESOL);
|
|
|
|
|
pos[1] = radius * cosf((2.0f * M_PI * a) / CIRCLE_RESOL);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v++, pos);
|
2018-04-27 16:27:47 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_point_wire = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-04-27 16:27:47 +02:00
|
|
|
# undef CIRCLE_RESOL
|
|
|
|
|
#endif
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_point_wire;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-08 12:05:06 +02:00
|
|
|
/* keep in sync with armature_stick_vert.glsl */
|
|
|
|
|
#define COL_WIRE (1 << 0)
|
|
|
|
|
#define COL_HEAD (1 << 1)
|
|
|
|
|
#define COL_TAIL (1 << 2)
|
|
|
|
|
#define COL_BONE (1 << 3)
|
|
|
|
|
|
|
|
|
|
#define POS_HEAD (1 << 4)
|
|
|
|
|
#define POS_TAIL (1 << 5)
|
|
|
|
|
#define POS_BONE (1 << 6)
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_stick_get()
|
2018-05-08 12:05:06 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_stick) {
|
|
|
|
|
#define CIRCLE_RESOL 12
|
2018-05-11 07:48:52 +02:00
|
|
|
uint v = 0;
|
|
|
|
|
uint flag;
|
2018-05-08 12:05:06 +02:00
|
|
|
const float radius = 2.0f; /* head/tail radius */
|
|
|
|
|
float pos[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-08 12:05:06 +02:00
|
|
|
/* Position Only 2D format */
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-05-08 12:05:06 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos, flag;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.flag = GPU_vertformat_attr_add(&format, "flag", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
2018-05-08 12:05:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-11 07:48:52 +02:00
|
|
|
const uint vcount = (CIRCLE_RESOL + 1) * 2 + 6;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, vcount);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBufBuilder elb;
|
2019-05-29 00:08:10 +02:00
|
|
|
GPU_indexbuf_init_ex(&elb, GPU_PRIM_TRI_FAN, (CIRCLE_RESOL + 2) * 2 + 6 + 2, vcount);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-08 12:05:06 +02:00
|
|
|
/* head/tail points */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 2; i++) {
|
2018-05-08 12:05:06 +02:00
|
|
|
/* center vertex */
|
|
|
|
|
copy_v2_fl(pos, 0.0f);
|
|
|
|
|
flag = (i == 0) ? POS_HEAD : POS_TAIL;
|
|
|
|
|
flag |= (i == 0) ? COL_HEAD : COL_TAIL;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 12:05:06 +02:00
|
|
|
/* circle vertices */
|
|
|
|
|
flag |= COL_WIRE;
|
|
|
|
|
for (int a = 0; a < CIRCLE_RESOL; a++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
pos[0] = radius * sinf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
|
|
|
|
pos[1] = radius * cosf((2.0f * M_PI * a) / float(CIRCLE_RESOL));
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 12:05:06 +02:00
|
|
|
}
|
|
|
|
|
/* Close the circle */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v - CIRCLE_RESOL);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2018-05-08 12:05:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-05-08 12:05:06 +02:00
|
|
|
/* Bone rectangle */
|
|
|
|
|
pos[0] = 0.0f;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < 6; i++) {
|
2021-10-20 10:45:59 +11:00
|
|
|
pos[1] = ELEM(i, 0, 3) ? 0.0f : ((i < 3) ? 1.0f : -1.0f);
|
|
|
|
|
flag = ((i < 2 || i > 4) ? POS_HEAD : POS_TAIL) | (ELEM(i, 0, 3) ? 0 : COL_WIRE) | COL_BONE |
|
|
|
|
|
POS_BONE;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.flag, v, &flag);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 12:05:06 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-04 19:08:09 +11:00
|
|
|
SHC.drw_bone_stick = GPU_batch_create_ex(GPU_PRIM_TRI_FAN,
|
|
|
|
|
vbo,
|
|
|
|
|
GPU_indexbuf_build(&elb),
|
|
|
|
|
GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
|
2018-05-08 12:05:06 +02:00
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_stick;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-06 16:09:25 +02:00
|
|
|
#define S_X 0.0215f
|
|
|
|
|
#define S_Y 0.025f
|
|
|
|
|
static float x_axis_name[4][2] = {
|
|
|
|
|
{0.9f * S_X, 1.0f * S_Y},
|
|
|
|
|
{-1.0f * S_X, -1.0f * S_Y},
|
2019-02-03 14:01:45 +11:00
|
|
|
{-0.9f * S_X, 1.0f * S_Y},
|
|
|
|
|
{1.0f * S_X, -1.0f * S_Y},
|
2018-05-06 16:09:25 +02:00
|
|
|
};
|
2023-07-06 10:29:02 +10:00
|
|
|
#define X_LEN ARRAY_SIZE(x_axis_name)
|
2018-05-06 16:09:25 +02:00
|
|
|
#undef S_X
|
|
|
|
|
#undef S_Y
|
|
|
|
|
|
|
|
|
|
#define S_X 0.0175f
|
|
|
|
|
#define S_Y 0.025f
|
|
|
|
|
static float y_axis_name[6][2] = {
|
|
|
|
|
{-1.0f * S_X, 1.0f * S_Y},
|
|
|
|
|
{0.0f * S_X, -0.1f * S_Y},
|
|
|
|
|
{1.0f * S_X, 1.0f * S_Y},
|
|
|
|
|
{0.0f * S_X, -0.1f * S_Y},
|
2019-02-03 14:01:45 +11:00
|
|
|
{0.0f * S_X, -0.1f * S_Y},
|
|
|
|
|
{0.0f * S_X, -1.0f * S_Y},
|
2018-05-06 16:09:25 +02:00
|
|
|
};
|
2023-07-06 10:29:02 +10:00
|
|
|
#define Y_LEN ARRAY_SIZE(y_axis_name)
|
2018-05-06 16:09:25 +02:00
|
|
|
#undef S_X
|
|
|
|
|
#undef S_Y
|
|
|
|
|
|
|
|
|
|
#define S_X 0.02f
|
|
|
|
|
#define S_Y 0.025f
|
|
|
|
|
static float z_axis_name[10][2] = {
|
|
|
|
|
{-0.95f * S_X, 1.00f * S_Y},
|
|
|
|
|
{0.95f * S_X, 1.00f * S_Y},
|
|
|
|
|
{0.95f * S_X, 1.00f * S_Y},
|
|
|
|
|
{0.95f * S_X, 0.90f * S_Y},
|
|
|
|
|
{0.95f * S_X, 0.90f * S_Y},
|
|
|
|
|
{-1.00f * S_X, -0.90f * S_Y},
|
|
|
|
|
{-1.00f * S_X, -0.90f * S_Y},
|
|
|
|
|
{-1.00f * S_X, -1.00f * S_Y},
|
2019-02-03 14:01:45 +11:00
|
|
|
{-1.00f * S_X, -1.00f * S_Y},
|
|
|
|
|
{1.00f * S_X, -1.00f * S_Y},
|
2018-05-06 16:09:25 +02:00
|
|
|
};
|
2023-07-06 10:29:02 +10:00
|
|
|
#define Z_LEN ARRAY_SIZE(z_axis_name)
|
2018-05-06 16:09:25 +02:00
|
|
|
#undef S_X
|
|
|
|
|
#undef S_Y
|
|
|
|
|
|
|
|
|
|
#define S_X 0.007f
|
|
|
|
|
#define S_Y 0.007f
|
|
|
|
|
static float axis_marker[8][2] = {
|
|
|
|
|
#if 0 /* square */
|
2019-04-17 08:24:14 +02:00
|
|
|
{-1.0f * S_X, 1.0f * S_Y},
|
|
|
|
|
{1.0f * S_X, 1.0f * S_Y},
|
|
|
|
|
{1.0f * S_X, 1.0f * S_Y},
|
|
|
|
|
{1.0f * S_X, -1.0f * S_Y},
|
|
|
|
|
{1.0f * S_X, -1.0f * S_Y},
|
|
|
|
|
{-1.0f * S_X, -1.0f * S_Y},
|
|
|
|
|
{-1.0f * S_X, -1.0f * S_Y},
|
|
|
|
|
{-1.0f * S_X, 1.0f * S_Y}
|
2018-05-06 16:09:25 +02:00
|
|
|
#else /* diamond */
|
2020-11-06 11:25:27 +11:00
|
|
|
{-S_X, 0.0f},
|
|
|
|
|
{0.0f, S_Y},
|
|
|
|
|
{0.0f, S_Y},
|
|
|
|
|
{S_X, 0.0f},
|
|
|
|
|
{S_X, 0.0f},
|
|
|
|
|
{0.0f, -S_Y},
|
|
|
|
|
{0.0f, -S_Y},
|
|
|
|
|
{-S_X, 0.0f}
|
2018-05-06 16:09:25 +02:00
|
|
|
#endif
|
|
|
|
|
};
|
2023-07-06 10:29:02 +10:00
|
|
|
#define MARKER_LEN ARRAY_SIZE(axis_marker)
|
2018-05-06 16:09:25 +02:00
|
|
|
#define MARKER_FILL_LAYER 6
|
|
|
|
|
#undef S_X
|
|
|
|
|
#undef S_Y
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_arrows_get()
|
2017-02-22 13:00:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_arrows) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = (2 + MARKER_LEN * MARKER_FILL_LAYER) * 3 + (X_LEN + Y_LEN + Z_LEN);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
2018-05-06 16:09:25 +02:00
|
|
|
for (int axis = 0; axis < 3; axis++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
int flag = VCLASS_EMPTY_AXES | VCLASS_SCREENALIGNED;
|
|
|
|
|
/* Vertex layout is XY screen position and axis in Z.
|
2021-06-26 21:35:18 +10:00
|
|
|
* Fractional part of Z is a positive offset at axis unit position. */
|
2023-07-27 14:16:58 +02:00
|
|
|
float p[3] = {0.0f, 0.0f, float(axis)};
|
2018-05-06 16:09:25 +02:00
|
|
|
/* center to axis line */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0f}, 0});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
|
2018-05-06 16:09:25 +02:00
|
|
|
/* Axis end marker */
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int j = 1; j < MARKER_FILL_LAYER + 1; j++) {
|
|
|
|
|
for (int i = 0; i < MARKER_LEN; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
mul_v2_v2fl(p, axis_marker[i], 4.0f * j / float(MARKER_FILL_LAYER));
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
|
2018-05-06 16:09:25 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2018-05-06 16:09:25 +02:00
|
|
|
/* Axis name */
|
2019-12-02 01:40:58 +01:00
|
|
|
flag = VCLASS_EMPTY_AXES | VCLASS_EMPTY_AXES_NAME | VCLASS_SCREENALIGNED;
|
|
|
|
|
int axis_v_len[] = {X_LEN, Y_LEN, Z_LEN};
|
|
|
|
|
float(*axis_v)[2] = (axis == 0) ? x_axis_name : ((axis == 1) ? y_axis_name : z_axis_name);
|
|
|
|
|
p[2] = axis + 0.25f;
|
|
|
|
|
for (int i = 0; i < axis_v_len[axis]; i++) {
|
|
|
|
|
mul_v2_v2fl(p, axis_v[i], 4.0f);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{p[0], p[1], p[2]}, flag});
|
2018-05-06 16:09:25 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_arrows = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_arrows;
|
|
|
|
|
}
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2018-12-30 15:14:00 +11:00
|
|
|
static const float staticSine[16] = {
|
2018-10-03 15:42:05 +02:00
|
|
|
0.0f,
|
|
|
|
|
0.104528463268f,
|
|
|
|
|
0.207911690818f,
|
|
|
|
|
0.309016994375f,
|
|
|
|
|
0.406736643076f,
|
|
|
|
|
0.5f,
|
|
|
|
|
0.587785252292f,
|
|
|
|
|
0.669130606359f,
|
|
|
|
|
0.743144825477f,
|
|
|
|
|
0.809016994375f,
|
|
|
|
|
0.866025403784f,
|
|
|
|
|
0.913545457643f,
|
|
|
|
|
0.951056516295f,
|
|
|
|
|
0.978147600734f,
|
2019-02-03 14:01:45 +11:00
|
|
|
0.994521895368f,
|
|
|
|
|
1.0f,
|
2018-10-03 15:42:05 +02:00
|
|
|
};
|
|
|
|
|
|
2019-04-02 17:54:04 +11:00
|
|
|
#define set_vert(a, b, quarter) \
|
|
|
|
|
{ \
|
|
|
|
|
copy_v2_fl2(pos, (quarter % 2 == 0) ? -(a) : (a), (quarter < 2) ? -(b) : (b)); \
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v++, pos); \
|
|
|
|
|
} \
|
|
|
|
|
((void)0)
|
2018-10-03 15:42:05 +02:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_dof_sphere_get()
|
2018-10-03 15:42:05 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_dof_sphere) {
|
|
|
|
|
int i, j, q, n = ARRAY_SIZE(staticSine);
|
|
|
|
|
float x, z, px, pz, pos[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-03 15:42:05 +02:00
|
|
|
/* Position Only 3D format */
|
|
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-10-03 15:42:05 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, n * n * 6 * 4);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-03 15:42:05 +02:00
|
|
|
uint v = 0;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (q = 0; q < 4; q++) {
|
2018-10-03 15:42:05 +02:00
|
|
|
pz = 0.0f;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (i = 1; i < n; i++) {
|
2018-10-03 15:42:05 +02:00
|
|
|
z = staticSine[i];
|
|
|
|
|
px = 0.0f;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (j = 1; j <= (n - i); j++) {
|
2018-10-03 15:42:05 +02:00
|
|
|
x = staticSine[j];
|
|
|
|
|
if (j == n - i) {
|
|
|
|
|
set_vert(px, z, q);
|
|
|
|
|
set_vert(px, pz, q);
|
|
|
|
|
set_vert(x, pz, q);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
set_vert(x, z, q);
|
|
|
|
|
set_vert(x, pz, q);
|
|
|
|
|
set_vert(px, z, q);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-10-03 15:42:05 +02:00
|
|
|
set_vert(x, pz, q);
|
|
|
|
|
set_vert(px, pz, q);
|
|
|
|
|
set_vert(px, z, q);
|
|
|
|
|
}
|
|
|
|
|
px = x;
|
|
|
|
|
}
|
|
|
|
|
pz = z;
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-07-03 23:08:40 +10:00
|
|
|
/* TODO: allocate right count from the beginning. */
|
2018-10-03 15:42:05 +02:00
|
|
|
GPU_vertbuf_data_resize(vbo, v);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_bone_dof_sphere = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-10-03 15:42:05 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_dof_sphere;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_bone_dof_lines_get()
|
2018-10-03 15:42:05 +02:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_bone_dof_lines) {
|
|
|
|
|
int i, n = ARRAY_SIZE(staticSine);
|
|
|
|
|
float pos[2];
|
|
|
|
|
|
|
|
|
|
/* Position Only 3D format */
|
|
|
|
|
static GPUVertFormat format = {0};
|
|
|
|
|
static struct {
|
|
|
|
|
uint pos;
|
|
|
|
|
} attr_id;
|
|
|
|
|
if (format.attr_len == 0) {
|
|
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-10-03 15:42:05 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, n * 4);
|
|
|
|
|
|
|
|
|
|
uint v = 0;
|
|
|
|
|
for (i = 0; i < n * 4; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float a = (1.0f - (i / float(n * 4))) * 2.0f * M_PI;
|
2018-10-03 15:42:05 +02:00
|
|
|
float x = cosf(a);
|
|
|
|
|
float y = sinf(a);
|
|
|
|
|
set_vert(x, y, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SHC.drw_bone_dof_lines = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINE_LOOP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-10-03 15:42:05 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_dof_lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef set_vert
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Camera
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_frame_get()
|
2019-12-02 01:40:58 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_camera_frame) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = 2 * (4 + 4);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
2020-08-07 22:36:11 +10:00
|
|
|
const float p[4][2] = {{-1.0f, -1.0f}, {-1.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}};
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Frame */
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
|
|
|
|
for (int b = 0; b < 2; b++) {
|
|
|
|
|
float x = p[(a + b) % 4][0];
|
|
|
|
|
float y = p[(a + b) % 4][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Wires to origin. */
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
|
|
|
|
float x = p[a][0];
|
|
|
|
|
float y = p[a][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0f}, VCLASS_CAMERA_FRAME});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_camera_frame = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-01-22 11:26:32 +11:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_camera_frame;
|
2018-01-22 11:26:32 +11:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_volume_get()
|
2018-01-22 11:26:32 +11:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_camera_volume) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = ARRAY_SIZE(bone_box_solid_tris) * 3;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_CAMERA_FRAME | VCLASS_CAMERA_VOLUME;
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(bone_box_solid_tris); i++) {
|
|
|
|
|
for (int a = 0; a < 3; a++) {
|
|
|
|
|
float x = bone_box_verts[bone_box_solid_tris[i][a]][2];
|
|
|
|
|
float y = bone_box_verts[bone_box_solid_tris[i][a]][0];
|
|
|
|
|
float z = bone_box_verts[bone_box_solid_tris[i][a]][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_camera_volume = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-01-22 11:26:32 +11:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_camera_volume;
|
2018-01-22 11:26:32 +11:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_volume_wire_get()
|
2017-03-04 00:09:22 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_camera_volume_wire) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-03-04 00:09:22 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = ARRAY_SIZE(bone_box_wire);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2017-03-04 00:09:22 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_CAMERA_FRAME | VCLASS_CAMERA_VOLUME;
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(bone_box_wire); i++) {
|
|
|
|
|
float x = bone_box_verts[bone_box_wire[i]][2];
|
|
|
|
|
float y = bone_box_verts[bone_box_wire[i]][0];
|
|
|
|
|
float z = bone_box_verts[bone_box_wire[i]][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, z}, flag});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
2017-03-04 00:09:22 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_camera_volume_wire = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-04 00:09:22 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_camera_volume_wire;
|
2017-03-04 00:09:22 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_tria_wire_get()
|
2018-01-22 00:14:28 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_camera_tria_wire) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2018-01-22 00:14:28 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = 2 * 3;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
2020-08-07 22:36:11 +10:00
|
|
|
const float p[3][2] = {{-1.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}};
|
2019-12-02 01:40:58 +01:00
|
|
|
for (int a = 0; a < 3; a++) {
|
|
|
|
|
for (int b = 0; b < 2; b++) {
|
|
|
|
|
float x = p[(a + b) % 3][0];
|
|
|
|
|
float y = p[(a + b) % 3][1];
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
|
2019-12-02 01:40:58 +01:00
|
|
|
}
|
|
|
|
|
}
|
2018-01-22 00:14:28 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_camera_tria_wire = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2018-01-22 00:14:28 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_camera_tria_wire;
|
2018-01-22 00:14:28 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_tria_get()
|
2017-03-04 00:09:22 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_camera_tria) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-03-04 00:09:22 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = 3;
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
/* Use camera frame position */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 1.0f, 1.0f}, VCLASS_CAMERA_FRAME});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 1.0f, 1.0f}, VCLASS_CAMERA_FRAME});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, VCLASS_CAMERA_FRAME});
|
2017-03-04 00:09:22 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_camera_tria = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-03-04 00:09:22 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_camera_tria;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_camera_distances_get()
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_camera_distances) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
const int v_len = 2 * (1 + DIAMOND_NSEGMENTS * 2 + 2);
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
/* Direction Line */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 0.0}, VCLASS_CAMERA_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 0.0, 1.0}, VCLASS_CAMERA_DIST});
|
2019-12-02 01:40:58 +01:00
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.5f, 0.0f, VCLASS_CAMERA_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
circle_verts(vbo, &v, DIAMOND_NSEGMENTS, 1.5f, 1.0f, VCLASS_CAMERA_DIST | VCLASS_SCREENSPACE);
|
|
|
|
|
/* Focus cross */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0, 0.0, 2.0}, VCLASS_CAMERA_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0, 0.0, 2.0}, VCLASS_CAMERA_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, 1.0, 2.0}, VCLASS_CAMERA_DIST});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0, -1.0, 2.0}, VCLASS_CAMERA_DIST});
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
SHC.drw_camera_distances = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_camera_distances;
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Meshes
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_all_verts_get(Object *ob)
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-02-07 11:20:15 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_all_verts(static_cast<Mesh *>(ob->data));
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_all_edges_get(Object *ob)
|
2018-12-17 17:01:06 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-12-17 17:01:06 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_all_edges(static_cast<Mesh *>(ob->data));
|
2018-12-17 17:01:06 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_loose_edges_get(Object *ob)
|
2018-11-23 16:44:16 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-11-23 16:44:16 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_loose_edges(static_cast<Mesh *>(ob->data));
|
2018-11-23 16:44:16 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
|
2018-06-01 11:35:51 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-06-01 11:35:51 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_edge_detection(static_cast<Mesh *>(ob->data), r_is_manifold);
|
2018-06-01 11:35:51 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_get(Object *ob)
|
2017-05-03 18:55:40 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-05-03 18:55:40 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface(static_cast<Mesh *>(ob->data));
|
2017-05-03 18:55:40 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_edges_get(Object *ob)
|
2017-05-04 19:59:27 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-05-04 19:59:27 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_edges(ob, static_cast<Mesh *>(ob->data));
|
2017-05-04 19:59:27 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch **DRW_cache_mesh_surface_shaded_get(Object *ob,
|
|
|
|
|
GPUMaterial **gpumat_array,
|
|
|
|
|
uint gpumat_array_len)
|
2017-04-25 18:46:59 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-25 18:46:59 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_shaded(
|
|
|
|
|
ob, static_cast<Mesh *>(ob->data), gpumat_array, gpumat_array_len);
|
2017-04-25 18:46:59 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch **DRW_cache_mesh_surface_texpaint_get(Object *ob)
|
2017-05-22 23:31:46 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-05-22 23:31:46 +10:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_texpaint(ob, static_cast<Mesh *>(ob->data));
|
2017-05-22 23:31:46 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
|
2017-05-22 23:31:46 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-05-22 23:31:46 +10:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_texpaint_single(ob, static_cast<Mesh *>(ob->data));
|
2017-05-22 23:31:46 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_vertpaint_get(Object *ob)
|
2017-03-09 01:29:58 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-03-09 01:29:58 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_vertpaint(ob, static_cast<Mesh *>(ob->data));
|
2017-03-09 01:29:58 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_sculpt(ob, static_cast<Mesh *>(ob->data));
|
Sculpt Vertex Colors: Initial implementation
Sculpt Vertex Colors is a painting system that runs inside sculpt mode, reusing all its tools and optimizations. This provides much better performance, easier to maintain code and more advanced features (new brush engine, filters, symmetry options, masks and face sets compatibility...). This is also the initial step for future features like vertex painting in Multires and brushes that can sculpt and paint at the same time.
This commit includes:
- SCULPT_UNDO_COLOR for undo support in sculpt mode
- SCULPT_UPDATE_COLOR and PBVH flags and rendering
- Sculpt Color API functions
- Sculpt capability for sculpt tools (only enabled in the Paint Brush for now)
- Rendering support in workbench (default to Sculpt Vertex Colors except in Vertex Paint)
- Conversion operator between MPropCol (Sculpt Vertex Colors) and MLoopCol (Vertex Paint)
- Remesher reprojection in the Voxel Remehser
- Paint Brush and Smear Brush with color smoothing in alt-smooth mode
- Parameters for the new brush engine (density, opacity, flow, wet paint mixing, tip scale) implemented in Sculpt Vertex Colors
- Color Filter
- Color picker (uses S shortcut, replaces smooth)
- Color selector in the top bar
Reviewed By: brecht
Maniphest Tasks: T72866
Differential Revision: https://developer.blender.org/D5975
2020-06-22 20:05:28 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_weights_get(Object *ob)
|
2017-04-28 22:30:21 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-28 22:30:21 +10:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_weights(static_cast<Mesh *>(ob->data));
|
2017-04-28 22:30:21 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_face_wireframe_get(Object *ob)
|
2017-03-09 01:29:58 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-03-09 01:29:58 +01:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_wireframes_face(static_cast<Mesh *>(ob->data));
|
2017-03-09 01:29:58 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
|
2019-04-18 08:00:59 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2019-04-18 08:00:59 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_edit_mesh_analysis(static_cast<Mesh *>(ob->data));
|
2019-04-18 08:00:59 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_mesh_surface_viewer_attribute_get(Object *ob)
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_mesh_batch_cache_get_surface_viewer_attribute(static_cast<Mesh *>(ob->data));
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
}
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2017-04-15 16:46:17 +10:00
|
|
|
/** \name Curve
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_wire_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2020-08-07 11:49:59 +02:00
|
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
2017-04-15 16:46:17 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_wire_viewer_attribute_get(Object *ob)
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
Geometry Nodes: viewport preview
This adds support for showing geometry passed to the Viewer in the 3d
viewport (instead of just in the spreadsheet). The "viewer geometry"
bypasses the group output. So it is not necessary to change the final
output of the node group to be able to see the intermediate geometry.
**Activation and deactivation of a viewer node**
* A viewer node is activated by clicking on it.
* Ctrl+shift+click on any node/socket connects it to the viewer and
makes it active.
* Ctrl+shift+click in empty space deactivates the active viewer.
* When the active viewer is not visible anymore (e.g. another object
is selected, or the current node group is exit), it is deactivated.
* Clicking on the icon in the header of the Viewer node toggles whether
its active or not.
**Pinning**
* The spreadsheet still allows pinning the active viewer as before.
When pinned, the spreadsheet still references the viewer node even
when it becomes inactive.
* The viewport does not support pinning at the moment. It always shows
the active viewer.
**Attribute**
* When a field is linked to the second input of the viewer node it is
displayed as an overlay in the viewport.
* When possible the correct domain for the attribute is determined
automatically. This does not work in all cases. It falls back to the
face corner domain on meshes and the point domain on curves. When
necessary, the domain can be picked manually.
* The spreadsheet now only shows the "Viewer" column for the domain
that is selected in the Viewer node.
* Instance attributes are visualized as a constant color per instance.
**Viewport Options**
* The attribute overlay opacity can be controlled with the "Viewer Node"
setting in the overlays popover.
* A viewport can be configured not to show intermediate viewer-geometry
by disabling the "Viewer Node" option in the "View" menu.
**Implementation Details**
* The "spreadsheet context path" was generalized to a "viewer path" that
is used in more places now.
* The viewer node itself determines the attribute domain, evaluates the
field and stores the result in a `.viewer` attribute.
* A new "viewer attribute' overlay displays the data from the `.viewer`
attribute.
* The ground truth for the active viewer node is stored in the workspace
now. Node editors, spreadsheets and viewports retrieve the active
viewer from there unless they are pinned.
* The depsgraph object iterator has a new "viewer path" setting. When set,
the viewed geometry of the corresponding object is part of the iterator
instead of the final evaluated geometry.
* To support the instance attribute overlay `DupliObject` was extended
to contain the information necessary for drawing the overlay.
* The ctrl+shift+click operator has been refactored so that it can make
existing links to viewers active again.
* The auto-domain-detection in the Viewer node works by checking the
"preferred domain" for every field input. If there is not exactly one
preferred domain, the fallback is used.
Known limitations:
* Loose edges of meshes don't have the attribute overlay. This could be
added separately if necessary.
* Some attributes are hard to visualize as a color directly. For example,
the values might have to be normalized or some should be drawn as arrays.
For now, we encourage users to build node groups that generate appropriate
viewer-geometry. We might include some of that functionality in future versions.
Support for displaying attribute values as text in the viewport is planned as well.
* There seems to be an issue with the attribute overlay for pointclouds on
nvidia gpus, to be investigated.
Differential Revision: https://developer.blender.org/D15954
2022-09-28 17:54:59 +02:00
|
|
|
return DRW_curve_batch_cache_get_wire_edge_viewer_attribute(cu);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_normal_get(Object *ob)
|
2017-04-20 05:23:48 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2018-12-13 01:26:07 +01:00
|
|
|
return DRW_curve_batch_cache_get_normal_edge(cu);
|
2017-04-20 05:23:48 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_curve_edge_overlay_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF));
|
2017-04-15 16:46:17 +10:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2018-12-10 15:29:04 +01:00
|
|
|
return DRW_curve_batch_cache_get_edit_edges(cu);
|
2017-04-15 16:46:17 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_curve_vert_overlay_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ELEM(ob->type, OB_CURVES_LEGACY, OB_SURF));
|
2017-04-15 16:46:17 +10:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2020-05-13 21:20:18 +02:00
|
|
|
return DRW_curve_batch_cache_get_edit_verts(cu);
|
2017-04-15 16:46:17 +10:00
|
|
|
}
|
|
|
|
|
|
2017-04-21 02:18:14 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-11-16 15:12:32 -02:00
|
|
|
/* -------------------------------------------------------------------- */
|
2017-04-21 02:18:14 +10:00
|
|
|
/** \name Font
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_text_edge_wire_get(Object *ob)
|
2017-04-21 02:18:14 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-21 02:18:14 +10:00
|
|
|
BLI_assert(ob->type == OB_FONT);
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2020-08-07 11:49:59 +02:00
|
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
2017-04-21 02:18:14 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Surface
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_surf_edge_wire_get(Object *ob)
|
2018-12-14 15:23:13 +01:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-12-14 15:23:13 +01:00
|
|
|
BLI_assert(ob->type == OB_SURF);
|
2023-07-27 14:16:58 +02:00
|
|
|
Curve *cu = static_cast<Curve *>(ob->data);
|
2020-08-07 11:49:59 +02:00
|
|
|
return DRW_curve_batch_cache_get_wire_edge(cu);
|
2017-04-21 02:18:14 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
2017-04-15 16:46:17 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \name Lattice
|
|
|
|
|
* \{ */
|
2017-04-13 22:09:59 +10:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lattice_verts_get(Object *ob)
|
2017-04-13 22:09:59 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-13 22:09:59 +10:00
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
2017-04-21 21:14:11 +10:00
|
|
|
return DRW_lattice_batch_cache_get_all_verts(lt);
|
2017-04-13 22:09:59 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
|
2017-04-13 22:09:59 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-13 22:09:59 +10:00
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
2017-06-27 15:59:13 +02:00
|
|
|
int actdef = -1;
|
|
|
|
|
|
2021-07-13 12:10:34 -04:00
|
|
|
if (use_weight && !BLI_listbase_is_empty(<->vertex_group_names) && lt->editlatt->latt->dvert) {
|
|
|
|
|
actdef = lt->vertex_group_active_index - 1;
|
2017-06-27 15:59:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return DRW_lattice_batch_cache_get_all_edges(lt, use_weight, actdef);
|
2017-04-13 22:09:59 +10:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_lattice_vert_overlay_get(Object *ob)
|
2017-04-13 23:29:45 +10:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2017-04-13 23:29:45 +10:00
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
Lattice *lt = static_cast<Lattice *>(ob->data);
|
2018-12-10 15:29:04 +01:00
|
|
|
return DRW_lattice_batch_cache_get_edit_verts(lt);
|
2017-04-13 23:29:45 +10:00
|
|
|
}
|
|
|
|
|
|
2017-05-03 08:34:24 +02:00
|
|
|
/** \} */
|
2017-05-09 16:23:47 +02:00
|
|
|
|
2020-03-17 16:27:08 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name PointCloud
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-03-17 16:27:08 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Volume
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-01-05 12:20:30 -05:00
|
|
|
namespace blender::draw {
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_volume_face_wireframe_get(Object *ob)
|
2020-03-17 16:27:08 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_VOLUME);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_volume_batch_cache_get_wireframes_face(static_cast<Volume *>(ob->data));
|
2020-03-17 16:27:08 +01:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_volume_selection_surface_get(Object *ob)
|
2020-09-29 12:39:41 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_VOLUME);
|
2023-07-27 14:16:58 +02:00
|
|
|
return DRW_volume_batch_cache_get_selection_surface(static_cast<Volume *>(ob->data));
|
2020-09-29 12:39:41 +02:00
|
|
|
}
|
|
|
|
|
|
2024-01-05 12:20:30 -05:00
|
|
|
} // namespace blender::draw
|
|
|
|
|
|
2020-03-17 16:27:08 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-05-09 16:23:47 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Particles
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_hair(Object *object,
|
|
|
|
|
ParticleSystem *psys,
|
|
|
|
|
ModifierData *md)
|
2017-05-09 16:23:47 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-05-15 12:38:49 +02:00
|
|
|
return DRW_particles_batch_cache_get_hair(object, psys, md);
|
2017-05-09 16:23:47 +02:00
|
|
|
}
|
2017-05-19 17:13:48 +02:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
|
2017-05-19 17:13:48 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-03-29 12:30:20 +02:00
|
|
|
return DRW_particles_batch_cache_get_dots(object, psys);
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_strands(Object *object,
|
|
|
|
|
ParticleSystem *psys,
|
|
|
|
|
PTCacheEdit *edit,
|
|
|
|
|
bool use_weight)
|
2018-05-09 11:14:27 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-11-27 13:49:00 +01:00
|
|
|
return DRW_particles_batch_cache_get_edit_strands(object, psys, edit, use_weight);
|
2018-05-09 11:14:27 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_inner_points(Object *object,
|
|
|
|
|
ParticleSystem *psys,
|
|
|
|
|
PTCacheEdit *edit)
|
2018-05-09 14:08:44 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-05-11 14:54:50 +02:00
|
|
|
return DRW_particles_batch_cache_get_edit_inner_points(object, psys, edit);
|
2018-05-09 14:59:29 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_edit_tip_points(Object *object,
|
|
|
|
|
ParticleSystem *psys,
|
|
|
|
|
PTCacheEdit *edit)
|
2018-05-09 14:59:29 +02:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-05-11 14:54:50 +02:00
|
|
|
return DRW_particles_batch_cache_get_edit_tip_points(object, psys, edit);
|
2018-05-09 14:08:44 +02:00
|
|
|
}
|
|
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_particles_get_prim(int type)
|
2017-05-19 17:13:48 +02:00
|
|
|
{
|
|
|
|
|
switch (type) {
|
|
|
|
|
case PART_DRAW_CROSS:
|
|
|
|
|
if (!SHC.drw_particle_cross) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 6);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = 0;
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, -1.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 1.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{-1.0f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{1.0f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, -1.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 1.0f}, flag});
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_particle_cross = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-19 17:13:48 +02:00
|
|
|
return SHC.drw_particle_cross;
|
|
|
|
|
case PART_DRAW_AXIS:
|
|
|
|
|
if (!SHC.drw_particle_axis) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, 6);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_EMPTY_AXES;
|
2021-02-05 16:23:34 +11:00
|
|
|
/* Set minimum to 0.001f so we can easily normalize to get the color. */
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0001f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 2.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0001f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{2.0f, 0.0f, 0.0f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 0.0001f}, flag});
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{0.0f, 0.0f, 2.0f}, flag});
|
|
|
|
|
|
|
|
|
|
SHC.drw_particle_axis = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINES, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-19 17:13:48 +02:00
|
|
|
return SHC.drw_particle_axis;
|
|
|
|
|
case PART_DRAW_CIRC:
|
|
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_particle_circle) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertFormat format = extra_vert_format();
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_data_alloc(vbo, CIRCLE_RESOL + 1);
|
|
|
|
|
|
|
|
|
|
int v = 0;
|
|
|
|
|
int flag = VCLASS_SCREENALIGNED;
|
|
|
|
|
for (int a = 0; a <= CIRCLE_RESOL; a++) {
|
|
|
|
|
float angle = (2.0f * M_PI * a) / CIRCLE_RESOL;
|
|
|
|
|
float x = sinf(angle);
|
|
|
|
|
float y = cosf(angle);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, Vert{{x, y, 0.0f}, flag});
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_particle_circle = GPU_batch_create_ex(
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, nullptr, GPU_BATCH_OWNS_VBO);
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-05-19 17:13:48 +02:00
|
|
|
return SHC.drw_particle_circle;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
default:
|
|
|
|
|
BLI_assert(false);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
return nullptr;
|
2017-05-19 17:13:48 +02:00
|
|
|
}
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch *DRW_cache_cursor_get(bool crosshair_lines)
|
2018-03-27 23:50:26 +02:00
|
|
|
{
|
2024-03-26 03:06:25 +01:00
|
|
|
blender::gpu::Batch **drw_cursor = crosshair_lines ? &SHC.drw_cursor :
|
|
|
|
|
&SHC.drw_cursor_only_circle;
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
if (*drw_cursor == nullptr) {
|
2018-03-27 23:50:26 +02:00
|
|
|
const float f5 = 0.25f;
|
|
|
|
|
const float f10 = 0.5f;
|
|
|
|
|
const float f20 = 1.0f;
|
|
|
|
|
|
|
|
|
|
const int segments = 16;
|
2018-07-08 12:45:53 +02:00
|
|
|
const int vert_len = segments + 8;
|
|
|
|
|
const int index_len = vert_len + 5;
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2020-08-07 22:36:11 +10:00
|
|
|
const uchar red[3] = {255, 0, 0};
|
|
|
|
|
const uchar white[3] = {255, 255, 255};
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertFormat format = {0};
|
2018-03-27 23:50:26 +02:00
|
|
|
static struct {
|
|
|
|
|
uint pos, color;
|
|
|
|
|
} attr_id;
|
2018-07-08 13:05:41 +02:00
|
|
|
if (format.attr_len == 0) {
|
2018-07-18 00:12:21 +02:00
|
|
|
attr_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
|
|
|
|
attr_id.color = GPU_vertformat_attr_add(
|
|
|
|
|
&format, "color", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
2018-03-27 23:50:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBufBuilder elb;
|
2019-05-29 00:08:10 +02:00
|
|
|
GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len);
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::VertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_data_alloc(vbo, vert_len);
|
2018-03-27 23:50:26 +02:00
|
|
|
|
|
|
|
|
int v = 0;
|
2019-09-08 00:12:26 +10:00
|
|
|
for (int i = 0; i < segments; i++) {
|
2023-07-28 09:38:07 +10:00
|
|
|
float angle = float(2 * M_PI) * (float(i) / float(segments));
|
2018-03-27 23:50:26 +02:00
|
|
|
float x = f10 * cosf(angle);
|
|
|
|
|
float y = f10 * sinf(angle);
|
|
|
|
|
|
2019-01-25 07:10:13 +11:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, (i % 2 == 0) ? red : white);
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{x, y});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-03-27 23:50:26 +02:00
|
|
|
}
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_generic_vert(&elb, 0);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
|
|
|
|
if (crosshair_lines) {
|
2018-07-08 12:47:13 +02:00
|
|
|
uchar crosshair_color[3];
|
2018-05-08 14:18:09 +02:00
|
|
|
UI_GetThemeColor3ubv(TH_VIEW_OVERLAY, crosshair_color);
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{-f20, 0});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{-f5, 0});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{+f5, 0});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{+f20, 0});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, -f20});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, -f5});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_indexbuf_add_primitive_restart(&elb);
|
2018-05-08 14:18:09 +02:00
|
|
|
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, +f5});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2023-07-27 14:16:58 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, blender::float2{0, +f20});
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
2018-05-08 14:18:09 +02:00
|
|
|
}
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2024-03-24 16:38:30 +01:00
|
|
|
blender::gpu::IndexBuf *ibo = GPU_indexbuf_build(&elb);
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
*drw_cursor = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINE_STRIP, vbo, ibo, GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
|
2018-03-27 23:50:26 +02:00
|
|
|
}
|
2018-05-08 14:18:09 +02:00
|
|
|
return *drw_cursor;
|
2018-04-22 08:44:23 +02:00
|
|
|
}
|
2018-12-08 20:10:20 +01:00
|
|
|
|
|
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2019-08-17 00:54:22 +10:00
|
|
|
/** \name Batch Cache Implementation (common)
|
2018-12-08 20:10:20 +01:00
|
|
|
* \{ */
|
|
|
|
|
|
2019-05-07 23:21:16 +02:00
|
|
|
void drw_batch_cache_validate(Object *ob)
|
|
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2019-05-07 23:21:16 +02:00
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2022-01-11 15:42:07 +01:00
|
|
|
DRW_mesh_batch_cache_validate(ob, (Mesh *)ob->data);
|
2019-05-07 23:21:16 +02:00
|
|
|
break;
|
2022-02-18 09:50:29 -06:00
|
|
|
case OB_CURVES_LEGACY:
|
2019-05-07 23:21:16 +02:00
|
|
|
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;
|
Curves: Rename "Hair" types, variables, and functions to "Curves"
Based on discussions from T95355 and T94193, the plan is to use
the name "Curves" to describe the data-block container for multiple
curves. Eventually this will replace the existing "Curve" data-block.
However, it will be a while before the curve data-block can be replaced
so in order to distinguish the two curve types in the UI, "Hair Curves"
will be used, but eventually changed back to "Curves".
This patch renames "hair-related" files, functions, types, and variable
names to this convention. A deep rename is preferred to keep code
consistent and to avoid any "hair" terminology from leaking, since the
new data-block is meant for all curve types, not just hair use cases.
The downside of this naming is that the difference between "Curve"
and "Curves" has become important. That was considered during
design discussons and deemed acceptable, especially given the
non-permanent nature of the somewhat common conflict.
Some points of interest:
- All DNA compatibility is lost, just like rBf59767ff9729.
- I renamed `ID_HA` to `ID_CV` so there is no complete mismatch.
- `hair_curves` is used where necessary to distinguish from the
existing "curves" plural.
- I didn't rename any of the cycles/rendering code function names,
since that is also used by the old hair particle system.
Differential Revision: https://developer.blender.org/D14007
2022-02-07 11:55:54 -06:00
|
|
|
case OB_CURVES:
|
|
|
|
|
DRW_curves_batch_cache_validate((Curves *)ob->data);
|
2020-03-17 16:27:08 +01:00
|
|
|
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;
|
2023-05-30 11:14:16 +02:00
|
|
|
case OB_GREASE_PENCIL:
|
|
|
|
|
DRW_grease_pencil_batch_cache_validate((GreasePencil *)ob->data);
|
2019-05-07 23:21:16 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-08 20:10:20 +01:00
|
|
|
void drw_batch_cache_generate_requested(Object *ob)
|
|
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2018-12-22 21:00:23 +01:00
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_get();
|
2019-07-14 16:49:44 +02:00
|
|
|
const Scene *scene = draw_ctx->scene;
|
2019-03-19 13:42:54 +11:00
|
|
|
const enum eContextObjectMode mode = CTX_data_mode_enum_ex(
|
|
|
|
|
draw_ctx->object_edit, draw_ctx->obact, draw_ctx->object_mode);
|
2018-12-22 21:00:23 +01:00
|
|
|
const bool is_paint_mode = ELEM(
|
2019-07-10 13:23:47 +02:00
|
|
|
mode, CTX_MODE_SCULPT, CTX_MODE_PAINT_TEXTURE, CTX_MODE_PAINT_VERTEX, CTX_MODE_PAINT_WEIGHT);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-23 08:46:26 +11:00
|
|
|
const bool use_hide = ((ob->type == OB_MESH) &&
|
|
|
|
|
((is_paint_mode && (ob == draw_ctx->obact) &&
|
2019-04-10 09:49:02 +02:00
|
|
|
DRW_object_use_hide_faces(ob)) ||
|
2020-02-03 08:16:38 +01:00
|
|
|
((mode == CTX_MODE_EDIT_MESH) && DRW_object_is_in_edit_mode(ob))));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-12-08 20:10:20 +01:00
|
|
|
switch (ob->type) {
|
|
|
|
|
case OB_MESH:
|
2020-06-02 15:07:17 +02:00
|
|
|
DRW_mesh_batch_cache_create_requested(
|
|
|
|
|
DST.task_graph, ob, (Mesh *)ob->data, scene, is_paint_mode, use_hide);
|
2018-12-08 20:10:20 +01:00
|
|
|
break;
|
2022-02-18 09:50:29 -06:00
|
|
|
case OB_CURVES_LEGACY:
|
2018-12-13 01:26:07 +01:00
|
|
|
case OB_FONT:
|
|
|
|
|
case OB_SURF:
|
2020-12-18 16:06:26 +01:00
|
|
|
DRW_curve_batch_cache_create_requested(ob, scene);
|
2018-12-13 01:26:07 +01:00
|
|
|
break;
|
2022-04-08 18:23:40 +02:00
|
|
|
case OB_CURVES:
|
|
|
|
|
DRW_curves_batch_cache_create_requested(ob);
|
|
|
|
|
break;
|
2022-10-25 10:43:47 +02:00
|
|
|
case OB_POINTCLOUD:
|
|
|
|
|
DRW_pointcloud_batch_cache_create_requested(ob);
|
|
|
|
|
break;
|
2021-07-03 23:08:40 +10:00
|
|
|
/* TODO: all cases. */
|
2018-12-08 20:10:20 +01:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-29 18:20:54 +02:00
|
|
|
void drw_batch_cache_generate_requested_evaluated_mesh_or_curve(Object *ob)
|
2021-12-01 21:16:18 -05:00
|
|
|
{
|
2024-01-05 12:20:30 -05:00
|
|
|
using namespace blender::draw;
|
2021-12-08 20:29:39 +11:00
|
|
|
/* NOTE: Logic here is duplicated from #drw_batch_cache_generate_requested. */
|
|
|
|
|
|
2021-12-01 21:16:18 -05:00
|
|
|
const DRWContextState *draw_ctx = DRW_context_state_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) && DRW_object_is_in_edit_mode(ob))));
|
|
|
|
|
|
OpenSubDiv: add support for an OpenGL evaluator
This evaluator is used in order to evaluate subdivision at render time, allowing for
faster renders of meshes with a subdivision surface modifier placed at the last
position in the modifier list.
When evaluating the subsurf modifier, we detect whether we can delegate evaluation
to the draw code. If so, the subdivision is first evaluated on the GPU using our own
custom evaluator (only the coarse data needs to be initially sent to the GPU), then,
buffers for the final `MeshBufferCache` are filled on the GPU using a set of
compute shaders. However, some buffers are still filled on the CPU side, if doing so
on the GPU is impractical (e.g. the line adjacency buffer used for x-ray, whose
logic is hardly GPU compatible).
This is done at the mesh buffer extraction level so that the result can be readily used
in the various OpenGL engines, without having to write custom geometry or tesselation
shaders.
We use our own subdivision evaluation shaders, instead of OpenSubDiv's vanilla one, in
order to control the data layout, and interpolation. For example, we store vertex colors
as compressed 16-bit integers, while OpenSubDiv's default evaluator only work for float
types.
In order to still access the modified geometry on the CPU side, for use in modifiers
or transform operators, a dedicated wrapper type is added `MESH_WRAPPER_TYPE_SUBD`.
Subdivision will be lazily evaluated via `BKE_object_get_evaluated_mesh` which will
create such a wrapper if possible. If the final subdivision surface is not needed on
the CPU side, `BKE_object_get_evaluated_mesh_no_subsurf` should be used.
Enabling or disabling GPU subdivision can be done through the user preferences (under
Viewport -> Subdivision).
See patch description for benchmarks.
Reviewed By: campbellbarton, jbakker, fclem, brecht, #eevee_viewport
Differential Revision: https://developer.blender.org/D12406
2021-12-27 16:34:47 +01:00
|
|
|
Mesh *mesh = BKE_object_get_evaluated_mesh_no_subsurf(ob);
|
2022-04-29 18:20:54 +02:00
|
|
|
/* 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.
|
|
|
|
|
*/
|
2023-07-27 14:16:58 +02:00
|
|
|
if (mesh != nullptr) {
|
2022-04-29 18:20:54 +02:00
|
|
|
DRW_mesh_batch_cache_create_requested(
|
|
|
|
|
DST.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);
|
|
|
|
|
}
|
2021-12-01 21:16:18 -05:00
|
|
|
}
|
|
|
|
|
|
2020-06-15 15:22:40 +02:00
|
|
|
void drw_batch_cache_generate_requested_delayed(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_gset_add(DST.delayed_extraction, ob);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-05 12:20:30 -05:00
|
|
|
namespace blender::draw {
|
2019-04-19 02:22:22 +02:00
|
|
|
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;
|
EEVEE: support Curves attributes rendering
This adds support to render Curves attributes in EEVEE.
Each attribute is stored in a texture derived from a VBO. As the
shading group needs the textures to be valid upon creation, the
attributes are created and setup during its very creation, instead
of doing it lazily via create_requested which we cannot rely on
anyway as contrary to the mesh batch, we do cannot really tell if
attributes need to be updated or else via some `DRW_batch_requested`.
Since point attributes need refinement, and since attributes are all
cast to vec4/float4 to account for differences in type conversions
between Blender and OpenGL, the refinement shader for points is
used as is. The point attributes are stored for each subdivision level
in CurvesEvalFinalCache. Each subdivision level also keeps track of the
attributes already in use so they are properly updated when needed.
Some basic garbage collection was added similar to what is done
for meshes: if the attributes used over time have been different
from the currently used attributes for too long, then the buffers
are freed, ensuring that stale attributesare removed.
This adds `CurvesInfos` to the shader creation info, which stores
the scope in which the attributes are defined. Scopes are stored
as booleans, in an array indexed by attribute loading order which
is also the order in which the attributes were added to the material.
A mapping is necessary between the indices used for the scoping, and
the ones used in the Curves cache, as this may contain stale
attributes which have not been garbage collected yet.
Common utilities with the mesh code for handling requested
attributes were moved to a separate file.
Differential Revision: https://developer.blender.org/D14916
2022-05-24 05:02:57 +02:00
|
|
|
case OB_CURVES:
|
|
|
|
|
DRW_curves_batch_cache_free_old((Curves *)ob->data, ctime);
|
|
|
|
|
break;
|
2022-10-25 10:43:47 +02:00
|
|
|
case OB_POINTCLOUD:
|
|
|
|
|
DRW_pointcloud_batch_cache_free_old((PointCloud *)ob->data, ctime);
|
|
|
|
|
break;
|
2019-04-19 02:22:22 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-05 12:20:30 -05:00
|
|
|
} // namespace blender::draw
|
2019-04-19 02:22:22 +02:00
|
|
|
|
2018-12-08 20:10:20 +01:00
|
|
|
/** \} */
|
2022-06-08 12:30:01 -07:00
|
|
|
|
|
|
|
|
void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format,
|
2022-06-09 09:48:37 +10:00
|
|
|
const char *base_name,
|
2023-11-30 23:24:03 -05:00
|
|
|
const int data_type,
|
|
|
|
|
const char *layer_name,
|
2022-06-08 12:30:01 -07:00
|
|
|
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. */
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(attr_name, "%s%s", base_name, attr_safe_name);
|
2022-06-08 12:30:01 -07:00
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
|
|
|
|
|
/* Auto layer name. */
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(attr_name, "a%s", attr_safe_name);
|
2022-06-08 12:30:01 -07:00
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
|
|
|
|
|
/* Active render layer name. */
|
|
|
|
|
if (is_active_render) {
|
2023-11-30 23:24:03 -05:00
|
|
|
GPU_vertformat_alias_add(format, data_type == CD_PROP_FLOAT2 ? "a" : base_name);
|
2022-06-08 12:30:01 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Active display layer name. */
|
|
|
|
|
if (is_active_layer) {
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(attr_name, "a%s", base_name);
|
2022-06-08 12:30:01 -07:00
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
}
|
|
|
|
|
}
|