2022-02-11 09:07:11 +11: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"
|
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
|
|
|
|
2018-03-27 23:50:26 +02:00
|
|
|
#include "UI_resources.h"
|
|
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
#include "BLI_math.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2018-09-23 20:41:10 +03:00
|
|
|
|
2018-12-04 15:39:30 +01:00
|
|
|
#include "BKE_object.h"
|
2019-01-23 08:46:26 +11:00
|
|
|
#include "BKE_paint.h"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
|
|
|
|
#include "GPU_batch.h"
|
2018-07-15 10:34:31 +02:00
|
|
|
#include "GPU_batch_utils.h"
|
2022-03-30 20:24:39 +02:00
|
|
|
#include "GPU_capabilities.h"
|
2017-02-07 11:20:15 +01:00
|
|
|
|
2018-09-23 20:41:10 +03:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2017-02-07 11:20:15 +01:00
|
|
|
#include "draw_cache.h"
|
2017-04-21 21:14:11 +10:00
|
|
|
#include "draw_cache_impl.h"
|
2018-12-08 20:10:20 +01:00
|
|
|
#include "draw_manager.h"
|
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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
typedef struct Vert {
|
|
|
|
|
float pos[3];
|
|
|
|
|
int class;
|
|
|
|
|
} Vert;
|
|
|
|
|
|
2019-12-11 13:35:53 +01:00
|
|
|
typedef struct VertShaded {
|
|
|
|
|
float pos[3];
|
|
|
|
|
int class;
|
|
|
|
|
float nor[3];
|
|
|
|
|
} VertShaded;
|
|
|
|
|
|
2017-08-16 19:50:27 +10:00
|
|
|
/* Batch's only (free'd as an array) */
|
2017-02-22 18:52:07 +01:00
|
|
|
static struct DRWShapeCache {
|
2019-05-11 17:45:20 +02:00
|
|
|
GPUBatch *drw_procedural_verts;
|
|
|
|
|
GPUBatch *drw_procedural_lines;
|
|
|
|
|
GPUBatch *drw_procedural_tris;
|
2022-08-02 20:35:35 +02:00
|
|
|
GPUBatch *drw_procedural_tri_strips;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_cursor;
|
|
|
|
|
GPUBatch *drw_cursor_only_circle;
|
|
|
|
|
GPUBatch *drw_fullscreen_quad;
|
|
|
|
|
GPUBatch *drw_quad;
|
2019-03-06 12:39:07 -03:00
|
|
|
GPUBatch *drw_quad_wires;
|
2018-08-23 13:35:10 +02:00
|
|
|
GPUBatch *drw_grid;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_plain_axes;
|
|
|
|
|
GPUBatch *drw_single_arrow;
|
|
|
|
|
GPUBatch *drw_cube;
|
|
|
|
|
GPUBatch *drw_circle;
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *drw_normal_arrow;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_empty_cube;
|
|
|
|
|
GPUBatch *drw_empty_sphere;
|
|
|
|
|
GPUBatch *drw_empty_cylinder;
|
|
|
|
|
GPUBatch *drw_empty_capsule_body;
|
|
|
|
|
GPUBatch *drw_empty_capsule_cap;
|
|
|
|
|
GPUBatch *drw_empty_cone;
|
|
|
|
|
GPUBatch *drw_field_wind;
|
|
|
|
|
GPUBatch *drw_field_force;
|
|
|
|
|
GPUBatch *drw_field_vortex;
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *drw_field_curve;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_field_tube_limit;
|
|
|
|
|
GPUBatch *drw_field_cone_limit;
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *drw_field_sphere_limit;
|
|
|
|
|
GPUBatch *drw_ground_line;
|
|
|
|
|
GPUBatch *drw_light_point_lines;
|
|
|
|
|
GPUBatch *drw_light_sun_lines;
|
|
|
|
|
GPUBatch *drw_light_spot_lines;
|
2019-02-27 12:02:02 +11:00
|
|
|
GPUBatch *drw_light_spot_volume;
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *drw_light_area_disk_lines;
|
|
|
|
|
GPUBatch *drw_light_area_square_lines;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_speaker;
|
|
|
|
|
GPUBatch *drw_lightprobe_cube;
|
|
|
|
|
GPUBatch *drw_lightprobe_planar;
|
|
|
|
|
GPUBatch *drw_lightprobe_grid;
|
|
|
|
|
GPUBatch *drw_bone_octahedral;
|
|
|
|
|
GPUBatch *drw_bone_octahedral_wire;
|
|
|
|
|
GPUBatch *drw_bone_box;
|
|
|
|
|
GPUBatch *drw_bone_box_wire;
|
|
|
|
|
GPUBatch *drw_bone_envelope;
|
|
|
|
|
GPUBatch *drw_bone_envelope_outline;
|
|
|
|
|
GPUBatch *drw_bone_point;
|
|
|
|
|
GPUBatch *drw_bone_point_wire;
|
|
|
|
|
GPUBatch *drw_bone_stick;
|
|
|
|
|
GPUBatch *drw_bone_arrows;
|
2018-10-03 15:42:05 +02:00
|
|
|
GPUBatch *drw_bone_dof_sphere;
|
|
|
|
|
GPUBatch *drw_bone_dof_lines;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_camera_frame;
|
|
|
|
|
GPUBatch *drw_camera_tria;
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *drw_camera_tria_wire;
|
|
|
|
|
GPUBatch *drw_camera_distances;
|
|
|
|
|
GPUBatch *drw_camera_volume;
|
|
|
|
|
GPUBatch *drw_camera_volume_wire;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *drw_particle_cross;
|
|
|
|
|
GPUBatch *drw_particle_circle;
|
|
|
|
|
GPUBatch *drw_particle_axis;
|
2020-03-09 16:27:24 +01:00
|
|
|
GPUBatch *drw_gpencil_dummy_quad;
|
2020-11-13 08:24:52 +01:00
|
|
|
GPUBatch *drw_sphere_lod[DRW_LOD_MAX];
|
2017-02-07 11:20:15 +01:00
|
|
|
} SHC = {NULL};
|
|
|
|
|
|
|
|
|
|
void DRW_shape_cache_free(void)
|
|
|
|
|
{
|
2018-07-18 00:12:21 +02:00
|
|
|
uint i = sizeof(SHC) / sizeof(GPUBatch *);
|
|
|
|
|
GPUBatch **batch = (GPUBatch **)&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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GPUBatch *drw_cache_procedural_points_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
SHC.drw_procedural_verts = GPU_batch_create_ex(GPU_PRIM_POINTS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_verts;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPUBatch *drw_cache_procedural_lines_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
SHC.drw_procedural_lines = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPUBatch *drw_cache_procedural_triangles_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
SHC.drw_procedural_tris = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_procedural_tris;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-02 20:35:35 +02:00
|
|
|
GPUBatch *drw_cache_procedural_triangle_strips_get()
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 1);
|
|
|
|
|
|
|
|
|
|
SHC.drw_procedural_tri_strips = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static GPUVertFormat extra_vert_format(void)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-16 19:04:07 +02:00
|
|
|
static void UNUSED_FUNCTION(add_fancy_edge)(GPUVertBuf *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 */
|
2019-04-17 08:24:14 +02:00
|
|
|
static void add_lat_lon_vert(GPUVertBuf *vbo,
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
static GPUVertBuf *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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
static GPUVertBuf *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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2017-02-22 13:00:15 +01:00
|
|
|
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
|
|
|
|
|
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) {
|
2019-12-02 01:40:58 +01: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) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{cv[0], 0.0f, cv[1]}, flag});
|
2018-07-31 20:44:49 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2019-12-02 01:40:58 +01: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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_fullscreen_quad_get(void)
|
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");
|
2019-09-24 18:05:14 +02:00
|
|
|
GPU_vertformat_alias_add(&format, "orco"); /* Fix driver bug (see T70004) */
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_fullscreen_quad = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_fullscreen_quad;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_quad_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{p[a][0], p[a][1], 0.0f}, flag});
|
2017-09-30 18:54:28 +02:00
|
|
|
}
|
|
|
|
|
|
2022-03-30 20:24:39 +02:00
|
|
|
SHC.drw_quad = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-09-30 18:54:28 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_quad;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-06 12:39:07 -03:00
|
|
|
GPUBatch *DRW_cache_quad_wires_get(void)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
|
|
|
GPUVertBuf *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++) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_quad_wires = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2019-03-06 12:39:07 -03:00
|
|
|
}
|
|
|
|
|
return SHC.drw_quad_wires;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
GPUBatch *DRW_cache_grid_get(void)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2018-08-23 13:35:10 +02:00
|
|
|
float pos0[2] = {(float)i / 8.0f, (float)j / 8.0f};
|
2018-08-24 10:26:59 +10:00
|
|
|
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
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
madd_v2_v2v2fl(pos0, (float[2]){-1.0f, -1.0f}, pos0, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos1, (float[2]){-1.0f, -1.0f}, pos1, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos2, (float[2]){-1.0f, -1.0f}, pos2, 2.0f);
|
|
|
|
|
madd_v2_v2v2fl(pos3, (float[2]){-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
|
|
|
|
2018-08-23 13:35:10 +02:00
|
|
|
SHC.drw_grid = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_grid;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-14 13:45:54 +02:00
|
|
|
/* Sphere */
|
2019-12-02 01:40:58 +01:00
|
|
|
static void sphere_lat_lon_vert(GPUVertBuf *vbo, int *v_ofs, float lat, float lon)
|
|
|
|
|
{
|
|
|
|
|
float x = sinf(lat) * cosf(lon);
|
|
|
|
|
float y = cosf(lat);
|
|
|
|
|
float z = sinf(lat) * sinf(lon);
|
2019-12-11 13:35:53 +01: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)++;
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-13 08:24:52 +01:00
|
|
|
GPUBatch *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:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
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);
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_TRIS, vbo, NULL, 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(
|
|
|
|
|
GPUVertBuf *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;
|
|
|
|
|
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(
|
|
|
|
|
GPUVertBuf *vbo, int *vert_idx, int segments, float radius, float z, int flag)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
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},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_cube_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertBuf *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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, VCLASS_EMPTY_SCALED});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_circle_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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++) {
|
|
|
|
|
float x = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
|
|
|
|
|
float z = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL));
|
|
|
|
|
float y = 0.0f;
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_circle = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_circle;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_normal_arrow_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_normal_arrow = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2022-08-17 10:20:25 -04:00
|
|
|
void DRW_vertbuf_create_wiredata(GPUVertBuf *vbo, const int vert_len)
|
|
|
|
|
{
|
|
|
|
|
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) {
|
|
|
|
|
memset(GPU_vertbuf_get_data(vbo), 0xFF, (size_t)vert_len);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
GPUVertBufRaw wd_step;
|
|
|
|
|
GPU_vertbuf_attr_get_raw_data(vbo, attr_id.wd, &wd_step);
|
|
|
|
|
for (int i = 0; i < vert_len; i++) {
|
|
|
|
|
*((float *)GPU_vertbuf_raw_step(&wd_step)) = 1.0f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
*
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_gpencil_dummy_buffer_get(void)
|
|
|
|
|
{
|
|
|
|
|
if (SHC.drw_gpencil_dummy_quad == NULL) {
|
|
|
|
|
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);
|
2020-03-09 16:27:24 +01:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, 4);
|
|
|
|
|
|
|
|
|
|
SHC.drw_gpencil_dummy_quad = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_TRI_FAN, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
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
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GPUBatch *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:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *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:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-07 05:03:01 +01:00
|
|
|
GPUBatch *DRW_cache_object_face_wireframe_get(Object *ob)
|
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);
|
2022-08-17 13:02:27 -04:00
|
|
|
case OB_GPENCIL:
|
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:
|
|
|
|
|
return NULL;
|
2018-05-31 18:43:19 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_object_loose_edges_get(struct 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:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-31 18:43:19 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *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);
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_POINTCLOUD:
|
2020-07-15 20:10:45 +02:00
|
|
|
return DRW_cache_pointcloud_surface_get(ob);
|
2017-04-21 02:18:14 +10:00
|
|
|
default:
|
|
|
|
|
return NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2017-04-21 02:18:14 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-06-19 17:02:55 +02:00
|
|
|
GPUVertBuf *DRW_cache_object_pos_vertbuf_get(Object *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 *me = BKE_object_get_evaluated_mesh_no_subsurf(ob);
|
2020-06-19 17:02:55 +02:00
|
|
|
short type = (me != NULL) ? OB_MESH : ob->type;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case OB_MESH:
|
|
|
|
|
return DRW_mesh_batch_cache_pos_vertbuf_get((me != NULL) ? me : ob->data);
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 16:39:33 +01:00
|
|
|
int DRW_cache_object_material_count_get(struct Object *ob)
|
|
|
|
|
{
|
2021-03-04 15:27:33 +01:00
|
|
|
short type = ob->type;
|
|
|
|
|
|
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 *me = BKE_object_get_evaluated_mesh_no_subsurf(ob);
|
2021-03-04 15:27:33 +01:00
|
|
|
if (me != NULL && 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:
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_material_count_get(ob, (me != NULL) ? me : 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:
|
|
|
|
|
return DRW_curve_material_count_get(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:
|
|
|
|
|
return DRW_curves_material_count_get(ob->data);
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_POINTCLOUD:
|
|
|
|
|
return DRW_pointcloud_material_count_get(ob->data);
|
|
|
|
|
case OB_VOLUME:
|
|
|
|
|
return DRW_volume_material_count_get(ob->data);
|
2022-05-02 09:22:14 +02:00
|
|
|
case OB_GPENCIL:
|
|
|
|
|
return DRW_gpencil_material_count_get(ob->data);
|
2020-01-28 16:39:33 +01:00
|
|
|
default:
|
|
|
|
|
BLI_assert(0);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch **DRW_cache_object_surface_material_get(struct Object *ob,
|
2018-12-16 15:17:31 +01:00
|
|
|
struct GPUMaterial **gpumat_array,
|
2020-01-17 16:05:19 +01:00
|
|
|
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);
|
2020-03-17 16:27:08 +01:00
|
|
|
case OB_POINTCLOUD:
|
2020-07-15 20:10:45 +02:00
|
|
|
return DRW_cache_pointcloud_surface_shaded_get(ob, gpumat_array, gpumat_array_len);
|
2017-04-25 18:46:59 +02:00
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-21 02:18:14 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Empties
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_plain_axes_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_plain_axes = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_plain_axes;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_empty_cube_get(void)
|
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();
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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];
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_empty_cube = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cube;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_single_arrow_get(void)
|
|
|
|
|
{
|
|
|
|
|
if (!SHC.drw_single_arrow) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
2019-12-02 01:40:58 +01: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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_single_arrow = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_single_arrow;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_empty_sphere_get(void)
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
if (!SHC.drw_empty_sphere) {
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUVertBuf *vbo = sphere_wire_vbo(1.0f, VCLASS_EMPTY_SCALED);
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_empty_sphere = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_sphere;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_empty_cone_get(void)
|
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();
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2017-02-07 11:20:15 +01:00
|
|
|
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
|
|
|
|
|
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 */
|
2019-12-02 01:40:58 +01: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 */
|
2019-12-02 01:40:58 +01: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];
|
2019-12-02 01:40:58 +01: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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_empty_cone = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cone;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_empty_cylinder_get(void)
|
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();
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2018-07-17 11:36:07 +02:00
|
|
|
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
|
|
|
|
|
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 */
|
2019-12-02 01:40:58 +01: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 */
|
2019-12-02 01:40:58 +01: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 */
|
2019-12-02 01:40:58 +01: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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_empty_cylinder = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_cylinder;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_empty_capsule_body_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_capsule_body;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_empty_capsule_cap_get(void)
|
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++) {
|
2018-07-17 11:36:07 +02:00
|
|
|
float angle = 2 * M_PI * ((float)i / (float)NSEGMENTS);
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_empty_capsule_cap = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2018-07-17 11:36:07 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_empty_capsule_cap;
|
|
|
|
|
#undef NSEGMENTS
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_field_wind_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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++) {
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_field_wind = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_wind;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_field_force_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_field_force = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_force;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_field_vortex_get(void)
|
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;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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--) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float r = a / (float)SPIRAL_RESOL;
|
|
|
|
|
float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
|
|
|
|
|
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++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
float r = a / (float)SPIRAL_RESOL;
|
|
|
|
|
float angle = (2.0f * M_PI * a) / SPIRAL_RESOL;
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_field_vortex = GPU_batch_create_ex(GPU_PRIM_LINE_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-04-10 22:22:37 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_field_vortex;
|
|
|
|
|
#undef SPIRAL_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_field_curve_get(void)
|
|
|
|
|
{
|
|
|
|
|
#define CIRCLE_RESOL 32
|
|
|
|
|
if (!SHC.drw_field_curve) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2 * (CIRCLE_RESOL);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
SHC.drw_field_curve = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_field_curve;
|
|
|
|
|
#undef CIRCLE_RESOL
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_field_tube_limit_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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++) {
|
|
|
|
|
float z = (i / (float)SIDE_STIPPLE) * 2.0f - 1.0f;
|
2019-12-02 01:40:58 +01: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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_field_tube_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_field_cone_limit_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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++) {
|
|
|
|
|
float z = (i / (float)SIDE_STIPPLE) * 2.0f - 1.0f;
|
2019-12-02 01:40:58 +01: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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_field_cone_limit = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_field_sphere_limit_get(void)
|
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;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_groundline_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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 */
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_ground_line = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_light_point_lines_get(void)
|
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
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_light_point_lines) {
|
|
|
|
|
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 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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;
|
|
|
|
|
/* Light Icon */
|
|
|
|
|
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);
|
|
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
/* Light area */
|
|
|
|
|
int flag = VCLASS_SCREENALIGNED | VCLASS_LIGHT_AREA_SHAPE;
|
|
|
|
|
circle_verts(vbo, &v, CIRCLE_NSEGMENTS, 1.0f, 0.0f, flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_light_point_lines = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
return SHC.drw_light_point_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_light_sun_lines_get(void)
|
2017-03-05 05:22:40 +01:00
|
|
|
{
|
2019-12-02 01:40:58 +01:00
|
|
|
if (!SHC.drw_light_sun_lines) {
|
|
|
|
|
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 * (DIAMOND_NSEGMENTS + INNER_NSEGMENTS + OUTER_NSEGMENTS + 8 * 2 + 1);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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;
|
|
|
|
|
/* Light Icon */
|
|
|
|
|
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);
|
|
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
/* Sun Rays */
|
|
|
|
|
for (int a = 0; a < 8; a++) {
|
|
|
|
|
float angle = (2.0f * M_PI * a) / 8.0f;
|
|
|
|
|
float s = sinf(angle) * r;
|
|
|
|
|
float c = cosf(angle) * r;
|
|
|
|
|
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
|
|
|
}
|
2019-12-02 01:40:58 +01:00
|
|
|
/* Direction Line */
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_light_sun_lines = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_light_spot_lines_get(void)
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS +
|
|
|
|
|
CIRCLE_NSEGMENTS * 4 + 1);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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;
|
|
|
|
|
/* Light Icon */
|
|
|
|
|
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);
|
|
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
/* 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);
|
|
|
|
|
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});
|
|
|
|
|
}
|
|
|
|
|
/* Direction Line */
|
|
|
|
|
float zsta = light_distance_z_get('z', true);
|
|
|
|
|
float zend = light_distance_z_get('z', false);
|
|
|
|
|
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});
|
|
|
|
|
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_spot_lines = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_light_spot_lines;
|
2017-03-05 05:22:40 +01:00
|
|
|
}
|
|
|
|
|
|
2019-02-27 12:02:02 +11:00
|
|
|
GPUBatch *DRW_cache_light_spot_volume_get(void)
|
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;
|
2018-08-22 18:44:24 +02:00
|
|
|
GPUVertBuf *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 */
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{0.0f, 0.0f, 0.0f}, 0});
|
|
|
|
|
/* 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);
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_TRI_FAN, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_light_area_disk_lines_get(void)
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 *
|
|
|
|
|
(DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + CIRCLE_NSEGMENTS + 1);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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;
|
|
|
|
|
/* Light Icon */
|
|
|
|
|
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);
|
|
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
/* 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);
|
|
|
|
|
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});
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_light_area_square_lines_get(void)
|
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
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
2019-12-02 01:40:58 +01:00
|
|
|
int v_len = 2 * (DIAMOND_NSEGMENTS * 3 + INNER_NSEGMENTS + OUTER_NSEGMENTS + 4 + 1);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, v_len);
|
|
|
|
|
|
|
|
|
|
const float r = 9.0f;
|
|
|
|
|
int v = 0;
|
|
|
|
|
/* Light Icon */
|
|
|
|
|
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);
|
|
|
|
|
circle_dashed_verts(vbo, &v, OUTER_NSEGMENTS, r * 1.33f, 0.0f, VCLASS_SCREENSPACE);
|
|
|
|
|
/* 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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x * 0.5f, y * 0.5f, 0.0f}, flag});
|
|
|
|
|
}
|
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);
|
|
|
|
|
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});
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_speaker_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2020-11-06 11:25:27 +11: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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_speaker = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_lightprobe_cube_get(void)
|
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;
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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]);
|
|
|
|
|
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-07 16:00:10 +02:00
|
|
|
}
|
2020-01-16 19:47:13 +01: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});
|
|
|
|
|
/* 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);
|
|
|
|
|
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});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_lightprobe_cube = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_lightprobe_cube;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_lightprobe_grid_get(void)
|
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;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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]);
|
|
|
|
|
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);
|
|
|
|
|
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
|
|
|
}
|
2019-12-02 01:40:58 +01: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});
|
|
|
|
|
/* 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);
|
|
|
|
|
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});
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_lightprobe_grid = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_lightprobe_grid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_lightprobe_planar_get(void)
|
|
|
|
|
{
|
|
|
|
|
if (!SHC.drw_lightprobe_planar) {
|
|
|
|
|
GPUVertFormat format = extra_vert_format();
|
|
|
|
|
|
|
|
|
|
int v_len = 2 * 4;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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;
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, 0.0}, VCLASS_SCREENSPACE});
|
|
|
|
|
}
|
2017-06-27 14:59:53 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_lightprobe_planar = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
};
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_octahedral_get(void)
|
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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2019-01-04 19:08:09 +11:00
|
|
|
SHC.drw_bone_octahedral = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-02-22 13:00:15 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_octahedral;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_octahedral_wire_get(void)
|
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. */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_box_get(void)
|
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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2019-01-04 19:08:09 +11:00
|
|
|
SHC.drw_bone_box = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-05-03 08:34:24 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_box;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_box_wire_get(void)
|
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. */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_envelope_solid_get(void)
|
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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_envelope = GPU_batch_create_ex(GPU_PRIM_TRI_STRIP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-05-18 11:41:59 +02:00
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_envelope;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_envelope_outline_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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-04-30 22:35:30 +02: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++) {
|
2018-04-30 22:35:30 +02: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(
|
2019-12-05 16:08:52 +01:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_point_get(void)
|
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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, 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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_point = GPU_batch_create_ex(GPU_PRIM_TRI_FAN, vbo, NULL, 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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_point_wire_outline_get(void)
|
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 */
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = sphere_wire_vbo(0.05f);
|
|
|
|
|
SHC.drw_bone_point_wire = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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(
|
2019-12-05 16:08:52 +01:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, NULL, 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)
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_stick_get(void)
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
|
|
|
|
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
|
|
|
};
|
2020-08-08 13:29:21 +10:00
|
|
|
#define X_LEN (sizeof(x_axis_name) / (sizeof(float[2])))
|
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
|
|
|
};
|
2020-08-08 13:29:21 +10:00
|
|
|
#define Y_LEN (sizeof(y_axis_name) / (sizeof(float[2])))
|
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
|
|
|
};
|
2020-08-08 13:29:21 +10:00
|
|
|
#define Z_LEN (sizeof(z_axis_name) / (sizeof(float[2])))
|
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
|
|
|
|
|
};
|
2020-08-08 13:29:21 +10:00
|
|
|
#define MARKER_LEN (sizeof(axis_marker) / (sizeof(float[2])))
|
2018-05-06 16:09:25 +02:00
|
|
|
#define MARKER_FILL_LAYER 6
|
|
|
|
|
#undef S_X
|
|
|
|
|
#undef S_Y
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_bone_arrows_get(void)
|
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();
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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. */
|
2019-12-02 01:40:58 +01:00
|
|
|
float p[3] = {0.0f, 0.0f, axis};
|
2018-05-06 16:09:25 +02:00
|
|
|
/* center to axis line */
|
2019-12-02 01:40:58 +01: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++) {
|
2019-12-02 01:40:58 +01:00
|
|
|
mul_v2_v2fl(p, axis_marker[i], 4.0f * j / (float)MARKER_FILL_LAYER);
|
|
|
|
|
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);
|
|
|
|
|
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-07-18 00:12:21 +02:00
|
|
|
SHC.drw_bone_arrows = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_bone_dof_sphere_get(void)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
2018-10-03 15:42:05 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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
|
|
|
|
2018-10-03 15:42:05 +02:00
|
|
|
SHC.drw_bone_dof_sphere = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_dof_sphere;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_bone_dof_lines_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
GPU_vertbuf_data_alloc(vbo, n * 4);
|
|
|
|
|
|
|
|
|
|
uint v = 0;
|
|
|
|
|
for (i = 0; i < n * 4; i++) {
|
|
|
|
|
float a = (1.0f - (i / (float)(n * 4))) * 2.0f * M_PI;
|
|
|
|
|
float x = cosf(a);
|
|
|
|
|
float y = sinf(a);
|
|
|
|
|
set_vert(x, y, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SHC.drw_bone_dof_lines = GPU_batch_create_ex(
|
|
|
|
|
GPU_PRIM_LINE_LOOP, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
|
|
|
|
}
|
|
|
|
|
return SHC.drw_bone_dof_lines;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef set_vert
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Camera
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_camera_frame_get(void)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Wires to origin. */
|
|
|
|
|
for (int a = 0; a < 4; a++) {
|
|
|
|
|
float x = p[a][0];
|
|
|
|
|
float y = p[a][1];
|
|
|
|
|
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});
|
|
|
|
|
}
|
2018-01-22 11:26:32 +11:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_camera_frame = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_camera_volume_get(void)
|
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;
|
|
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, flag});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SHC.drw_camera_volume = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_camera_volume_wire_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, z}, flag});
|
|
|
|
|
}
|
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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_camera_tria_wire_get(void)
|
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;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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];
|
|
|
|
|
GPU_vertbuf_vert_set(vbo, v++, &(Vert){{x, y, 1.0f}, VCLASS_CAMERA_FRAME});
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-22 00:14:28 +01:00
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_camera_tria_wire = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_camera_tria_get(void)
|
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;
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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 */
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_camera_tria = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
2017-03-04 00:09:22 +01:00
|
|
|
}
|
|
|
|
|
return SHC.drw_camera_tria;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
GPUBatch *DRW_cache_camera_distances_get(void)
|
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);
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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 */
|
|
|
|
|
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});
|
|
|
|
|
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 */
|
|
|
|
|
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
|
|
|
|
2019-12-02 01:40:58 +01:00
|
|
|
SHC.drw_camera_distances = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_all_verts_get(Object *ob)
|
2017-02-07 11:20:15 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_all_verts(ob->data);
|
2017-02-07 11:20:15 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_all_edges_get(Object *ob)
|
2018-12-17 17:01:06 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_all_edges(ob->data);
|
2018-12-17 17:01:06 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob)
|
2018-11-23 16:44:16 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_loose_edges(ob->data);
|
2018-11-23 16:44:16 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_edge_detection_get(Object *ob, bool *r_is_manifold)
|
2018-06-01 11:35:51 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_edge_detection(ob->data, r_is_manifold);
|
2018-06-01 11:35:51 +02:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_get(Object *ob)
|
2017-05-03 18:55:40 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface(ob->data);
|
2017-05-03 18:55:40 +02:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_edges_get(Object *ob)
|
2017-05-04 19:59:27 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_edges(ob, ob->data);
|
2017-05-04 19:59:27 +02:00
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch **DRW_cache_mesh_surface_shaded_get(Object *ob,
|
2018-12-16 15:17:31 +01:00
|
|
|
struct GPUMaterial **gpumat_array,
|
2020-01-17 16:05:19 +01:00
|
|
|
uint gpumat_array_len)
|
2017-04-25 18:46:59 +02:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_shaded(ob, ob->data, gpumat_array, gpumat_array_len);
|
2017-04-25 18:46:59 +02:00
|
|
|
}
|
|
|
|
|
|
2018-12-16 15:17:31 +01:00
|
|
|
GPUBatch **DRW_cache_mesh_surface_texpaint_get(Object *ob)
|
2017-05-22 23:31:46 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_texpaint(ob, ob->data);
|
2017-05-22 23:31:46 +10:00
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(Object *ob)
|
2017-05-22 23:31:46 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_texpaint_single(ob, ob->data);
|
2017-05-22 23:31:46 +10:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_vertpaint_get(Object *ob)
|
2017-03-09 01:29:58 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_vertpaint(ob, ob->data);
|
2017-03-09 01:29:58 +01:00
|
|
|
}
|
|
|
|
|
|
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
|
|
|
GPUBatch *DRW_cache_mesh_surface_sculptcolors_get(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2022-01-11 15:42:07 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_sculpt(ob, 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
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_weights_get(Object *ob)
|
2017-04-28 22:30:21 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_surface_weights(ob->data);
|
2017-04-28 22:30:21 +10:00
|
|
|
}
|
|
|
|
|
|
2018-12-18 17:10:38 +01:00
|
|
|
GPUBatch *DRW_cache_mesh_face_wireframe_get(Object *ob)
|
2017-03-09 01:29:58 +01:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
2018-12-18 17:10:38 +01:00
|
|
|
return DRW_mesh_batch_cache_get_wireframes_face(ob->data);
|
2017-03-09 01:29:58 +01:00
|
|
|
}
|
|
|
|
|
|
2019-04-18 08:00:59 +02:00
|
|
|
GPUBatch *DRW_cache_mesh_surface_mesh_analysis_get(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_MESH);
|
|
|
|
|
return DRW_mesh_batch_cache_get_edit_mesh_analysis(ob->data);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-15 14:24:30 +10:00
|
|
|
/** \} */
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2017-04-15 16:46:17 +10:00
|
|
|
/** \name Curve
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_curve_edge_wire_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
2017-04-15 16:46:17 +10:00
|
|
|
struct Curve *cu = 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
|
|
|
}
|
|
|
|
|
|
2018-12-13 01:26:07 +01:00
|
|
|
GPUBatch *DRW_cache_curve_edge_normal_get(Object *ob)
|
2017-04-20 05:23:48 +10:00
|
|
|
{
|
2022-02-18 09:50:29 -06:00
|
|
|
BLI_assert(ob->type == OB_CURVES_LEGACY);
|
2017-04-20 05:23:48 +10:00
|
|
|
struct Curve *cu = 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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_curve_edge_overlay_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
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
|
|
|
|
|
|
|
|
struct Curve *cu = 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
|
|
|
}
|
|
|
|
|
|
2020-05-13 21:20:18 +02:00
|
|
|
GPUBatch *DRW_cache_curve_vert_overlay_get(Object *ob)
|
2017-04-15 16:46:17 +10:00
|
|
|
{
|
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
|
|
|
|
|
|
|
|
struct Curve *cu = 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_text_edge_wire_get(Object *ob)
|
2017-04-21 02:18:14 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_FONT);
|
|
|
|
|
struct Curve *cu = 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-12-14 15:23:13 +01:00
|
|
|
GPUBatch *DRW_cache_surf_edge_wire_get(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_SURF);
|
|
|
|
|
struct Curve *cu = 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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_lattice_verts_get(Object *ob)
|
2017-04-13 22:09:59 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
|
|
|
|
struct Lattice *lt = 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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
|
2017-04-13 22:09:59 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
2017-06-27 15:59:13 +02:00
|
|
|
Lattice *lt = ob->data;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_lattice_vert_overlay_get(Object *ob)
|
2017-04-13 23:29:45 +10:00
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_LATTICE);
|
|
|
|
|
|
|
|
|
|
struct Lattice *lt = 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
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_pointcloud_get_dots(Object *object)
|
|
|
|
|
{
|
2020-07-15 20:10:45 +02:00
|
|
|
BLI_assert(object->type == OB_POINTCLOUD);
|
2020-03-17 16:27:08 +01:00
|
|
|
return DRW_pointcloud_batch_cache_get_dots(object);
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-15 20:10:45 +02:00
|
|
|
GPUBatch *DRW_cache_pointcloud_surface_get(Object *object)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(object->type == OB_POINTCLOUD);
|
|
|
|
|
return DRW_pointcloud_batch_cache_get_surface(object);
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 15:49:31 +11:00
|
|
|
/** \} */
|
|
|
|
|
|
2020-03-17 16:27:08 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Volume
|
|
|
|
|
* \{ */
|
|
|
|
|
|
|
|
|
|
GPUBatch *DRW_cache_volume_face_wireframe_get(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_VOLUME);
|
|
|
|
|
return DRW_volume_batch_cache_get_wireframes_face(ob->data);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-29 12:39:41 +02:00
|
|
|
GPUBatch *DRW_cache_volume_selection_surface_get(Object *ob)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(ob->type == OB_VOLUME);
|
|
|
|
|
return DRW_volume_batch_cache_get_selection_surface(ob->data);
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-17 16:27:08 +01:00
|
|
|
/** \} */
|
|
|
|
|
|
2017-05-09 16:23:47 +02:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
/** \name Particles
|
|
|
|
|
* \{ */
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_particles_get_hair(Object *object, ParticleSystem *psys, ModifierData *md)
|
2017-05-09 16:23:47 +02:00
|
|
|
{
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_particles_get_dots(Object *object, ParticleSystem *psys)
|
2017-05-19 17:13:48 +02:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_particles_get_edit_strands(Object *object,
|
2018-05-11 14:54:50 +02:00
|
|
|
ParticleSystem *psys,
|
2018-11-27 13:49:00 +01:00
|
|
|
struct PTCacheEdit *edit,
|
|
|
|
|
bool use_weight)
|
2018-05-09 11:14:27 +02:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_particles_get_edit_inner_points(Object *object,
|
2018-05-11 14:54:50 +02:00
|
|
|
ParticleSystem *psys,
|
|
|
|
|
struct PTCacheEdit *edit)
|
2018-05-09 14:08:44 +02:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_particles_get_edit_tip_points(Object *object,
|
2018-05-11 14:54:50 +02:00
|
|
|
ParticleSystem *psys,
|
|
|
|
|
struct PTCacheEdit *edit)
|
2018-05-09 14:59:29 +02:00
|
|
|
{
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *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();
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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;
|
|
|
|
|
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(
|
|
|
|
|
GPU_PRIM_LINES, vbo, NULL, 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();
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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. */
|
2019-12-02 01:40:58 +01: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});
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
SHC.drw_particle_axis = GPU_batch_create_ex(GPU_PRIM_LINES, vbo, NULL, 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();
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *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);
|
|
|
|
|
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(
|
2019-12-02 01:40:58 +01:00
|
|
|
GPU_PRIM_LINE_STRIP, vbo, NULL, 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2018-03-27 23:50:26 +02:00
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch *DRW_cache_cursor_get(bool crosshair_lines)
|
2018-03-27 23:50:26 +02:00
|
|
|
{
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUBatch **drw_cursor = crosshair_lines ? &SHC.drw_cursor : &SHC.drw_cursor_only_circle;
|
2018-05-08 14:18:09 +02:00
|
|
|
|
|
|
|
|
if (*drw_cursor == NULL) {
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
|
|
|
|
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++) {
|
2018-03-27 23:50:26 +02:00
|
|
|
float angle = (float)(2 * M_PI) * ((float)i / (float)segments);
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){x, y});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f20, 0});
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){-f5, 0});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f5, 0});
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){+f20, 0});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f20});
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, -f5});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f5});
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.color, v, crosshair_color);
|
|
|
|
|
GPU_indexbuf_add_generic_vert(&elb, v++);
|
|
|
|
|
GPU_vertbuf_attr_set(vbo, attr_id.pos, v, (const float[2]){0, +f20});
|
|
|
|
|
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
|
|
|
|
2018-07-18 00:12:21 +02:00
|
|
|
GPUIndexBuf *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)
|
|
|
|
|
{
|
|
|
|
|
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;
|
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)
|
|
|
|
|
{
|
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;
|
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
|
|
|
{
|
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.
|
|
|
|
|
*/
|
|
|
|
|
if (mesh != NULL) {
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2021-07-03 23:08:40 +10:00
|
|
|
/* TODO: all cases. */
|
2019-04-19 02:22:22 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
|
|
const CustomData *UNUSED(data),
|
2022-06-08 12:30:01 -07:00
|
|
|
const CustomDataLayer *cl,
|
|
|
|
|
bool is_active_render,
|
|
|
|
|
bool is_active_layer)
|
|
|
|
|
{
|
|
|
|
|
char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME];
|
|
|
|
|
const char *layer_name = cl->name;
|
|
|
|
|
|
|
|
|
|
GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME);
|
|
|
|
|
|
|
|
|
|
/* Attribute layer name. */
|
|
|
|
|
BLI_snprintf(attr_name, sizeof(attr_name), "%s%s", base_name, attr_safe_name);
|
|
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
|
|
|
|
|
/* Auto layer name. */
|
|
|
|
|
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name);
|
|
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
|
|
|
|
|
/* Active render layer name. */
|
|
|
|
|
if (is_active_render) {
|
|
|
|
|
GPU_vertformat_alias_add(format, base_name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Active display layer name. */
|
|
|
|
|
if (is_active_layer) {
|
|
|
|
|
BLI_snprintf(attr_name, sizeof(attr_name), "a%s", base_name);
|
|
|
|
|
GPU_vertformat_alias_add(format, attr_name);
|
|
|
|
|
}
|
|
|
|
|
}
|