DRW: Support Wireframe for cruve/surface/text objects
This commit is contained in:
parent
1cc7bcd8d8
commit
1ec21ed41a
|
@ -698,9 +698,18 @@ void DRW_cache_object_face_wireframe_get(
|
|||
{
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
DRW_mesh_batch_cache_get_wireframes_face_texbuf(ob->data, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
|
||||
/* TODO, should match 'DRW_cache_object_surface_get' */
|
||||
DRW_cache_mesh_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
DRW_cache_curve_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
break;
|
||||
case OB_SURF:
|
||||
DRW_cache_surf_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
break;
|
||||
case OB_FONT:
|
||||
DRW_cache_text_face_wireframe_get(ob, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
break;
|
||||
/* TODO, metaballs' */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3046,6 +3055,15 @@ GPUBatch *DRW_cache_mesh_surface_get(Object *ob)
|
|||
return DRW_mesh_batch_cache_get_triangles_with_normals(me);
|
||||
}
|
||||
|
||||
void DRW_cache_mesh_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
|
||||
Mesh *me = ob->data;
|
||||
DRW_mesh_batch_cache_get_wireframes_face_texbuf(me, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
}
|
||||
|
||||
GPUBatch *DRW_cache_mesh_loose_edges_get(Object *ob)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MESH);
|
||||
|
@ -3237,6 +3255,15 @@ GPUBatch *DRW_cache_curve_surface_get(Object *ob)
|
|||
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
|
||||
}
|
||||
|
||||
void DRW_cache_curve_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count)
|
||||
{
|
||||
BLI_assert(ob->type == OB_CURVE);
|
||||
|
||||
struct Curve *cu = ob->data;
|
||||
DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
}
|
||||
|
||||
/* Return list of batches */
|
||||
GPUBatch **DRW_cache_curve_surface_shaded_get(
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
|
||||
|
@ -3293,6 +3320,21 @@ GPUBatch *DRW_cache_text_surface_get(Object *ob)
|
|||
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
|
||||
}
|
||||
|
||||
void DRW_cache_text_face_wireframe_get(
|
||||
Object *ob,
|
||||
struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count)
|
||||
{
|
||||
BLI_assert(ob->type == OB_FONT);
|
||||
struct Curve *cu = ob->data;
|
||||
if (cu->editfont && (cu->flag & CU_FAST)) {
|
||||
*r_vert_tx = NULL;
|
||||
*r_faceid_tx = NULL;
|
||||
*r_tri_count = 0;
|
||||
return;
|
||||
}
|
||||
DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
}
|
||||
|
||||
GPUBatch **DRW_cache_text_surface_shaded_get(
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
|
||||
{
|
||||
|
@ -3333,6 +3375,15 @@ GPUBatch *DRW_cache_surf_surface_get(Object *ob)
|
|||
return DRW_curve_batch_cache_get_triangles_with_normals(cu, ob->runtime.curve_cache);
|
||||
}
|
||||
|
||||
void DRW_cache_surf_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count)
|
||||
{
|
||||
BLI_assert(ob->type == OB_SURF);
|
||||
|
||||
struct Curve *cu = ob->data;
|
||||
DRW_curve_batch_cache_get_wireframes_face_texbuf(cu, ob->runtime.curve_cache, r_vert_tx, r_faceid_tx, r_tri_count);
|
||||
}
|
||||
|
||||
/* Return list of batches */
|
||||
GPUBatch **DRW_cache_surf_surface_shaded_get(
|
||||
Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len)
|
||||
|
|
|
@ -152,6 +152,8 @@ struct GPUBatch **DRW_cache_mesh_surface_shaded_get(
|
|||
char **auto_layer_names, int **auto_layer_is_srgb, int *auto_layer_count);
|
||||
struct GPUBatch **DRW_cache_mesh_surface_texpaint_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_mesh_surface_texpaint_single_get(struct Object *ob);
|
||||
void DRW_cache_mesh_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count);
|
||||
|
||||
void DRW_cache_mesh_sculpt_coords_ensure(struct Object *ob);
|
||||
|
||||
|
@ -161,6 +163,8 @@ struct GPUBatch **DRW_cache_curve_surface_shaded_get(
|
|||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
struct GPUBatch *DRW_cache_curve_surface_verts_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_curve_edge_wire_get(struct Object *ob);
|
||||
void DRW_cache_curve_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count);
|
||||
/* edit-mode */
|
||||
struct GPUBatch *DRW_cache_curve_edge_normal_get(struct Object *ob, float normal_size);
|
||||
struct GPUBatch *DRW_cache_curve_edge_overlay_get(struct Object *ob);
|
||||
|
@ -171,6 +175,8 @@ struct GPUBatch *DRW_cache_text_edge_wire_get(struct Object *ob);
|
|||
struct GPUBatch *DRW_cache_text_surface_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_text_surface_shaded_get(
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
void DRW_cache_text_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count);
|
||||
/* edit-mode */
|
||||
struct GPUBatch *DRW_cache_text_cursor_overlay_get(struct Object *ob);
|
||||
struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob);
|
||||
|
@ -179,6 +185,8 @@ struct GPUBatch *DRW_cache_text_select_overlay_get(struct Object *ob);
|
|||
struct GPUBatch *DRW_cache_surf_surface_get(struct Object *ob);
|
||||
struct GPUBatch **DRW_cache_surf_surface_shaded_get(
|
||||
struct Object *ob, struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
void DRW_cache_surf_face_wireframe_get(
|
||||
Object *ob, struct GPUTexture **r_vert_tx, struct GPUTexture **r_faceid_tx, int *r_tri_count);
|
||||
|
||||
/* Lattice */
|
||||
struct GPUBatch *DRW_cache_lattice_verts_get(struct Object *ob);
|
||||
|
|
|
@ -75,6 +75,9 @@ struct GPUBatch *DRW_curve_batch_cache_get_triangles_with_normals(
|
|||
struct GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
|
||||
struct Curve *cu, struct CurveCache *ob_curve_cache,
|
||||
struct GPUMaterial **gpumat_array, uint gpumat_array_len);
|
||||
void DRW_curve_batch_cache_get_wireframes_face_texbuf(
|
||||
struct Curve *cu, struct CurveCache *ob_curve_cache,
|
||||
struct GPUTexture **verts_data, struct GPUTexture **face_indices, int *tri_count);
|
||||
|
||||
/* Metaball */
|
||||
struct GPUBatch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob);
|
||||
|
@ -91,6 +94,7 @@ struct GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_mate
|
|||
struct ListBase *lb, uint gpumat_array_len);
|
||||
struct GPUBatch **DRW_displist_batch_calc_tri_pos_normals_and_uv_split_by_material(
|
||||
struct ListBase *lb, uint gpumat_array_len);
|
||||
struct GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb);
|
||||
|
||||
/* Lattice */
|
||||
struct GPUBatch *DRW_lattice_batch_cache_get_all_edges(struct Lattice *lt, bool use_weight, const int actdef);
|
||||
|
|
|
@ -39,9 +39,12 @@
|
|||
#include "BKE_font.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_texture.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "draw_cache_impl.h" /* own include */
|
||||
|
||||
#define SELECT 1
|
||||
|
@ -320,6 +323,14 @@ typedef struct CurveBatchCache {
|
|||
int mat_len;
|
||||
} surface;
|
||||
|
||||
/* Wireframes */
|
||||
struct {
|
||||
GPUVertBuf *elem_vbo;
|
||||
GPUTexture *elem_tx;
|
||||
GPUTexture *verts_tx;
|
||||
uint tri_count;
|
||||
} face_wire;
|
||||
|
||||
/* 3d text */
|
||||
struct {
|
||||
GPUBatch *select;
|
||||
|
@ -439,6 +450,11 @@ static void curve_batch_cache_clear(Curve *cu)
|
|||
GPU_BATCH_DISCARD_ARRAY_SAFE(cache->surface.shaded_triangles, cache->surface.mat_len);
|
||||
GPU_BATCH_DISCARD_SAFE(cache->surface.batch);
|
||||
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->face_wire.elem_vbo);
|
||||
DRW_TEXTURE_FREE_SAFE(cache->face_wire.elem_tx);
|
||||
DRW_TEXTURE_FREE_SAFE(cache->face_wire.verts_tx);
|
||||
cache->face_wire.tri_count = 0;
|
||||
|
||||
/* don't own vbo & elems */
|
||||
GPU_BATCH_DISCARD_SAFE(cache->wire.batch);
|
||||
GPU_VERTBUF_DISCARD_SAFE(cache->wire.verts);
|
||||
|
@ -785,6 +801,40 @@ static GPUBatch *curve_batch_cache_get_pos_and_normals(CurveRenderData *rdata, C
|
|||
return cache->surface.batch;
|
||||
}
|
||||
|
||||
static GPUTexture *curve_batch_cache_get_edges_overlay_texture_buf(CurveRenderData *rdata, CurveBatchCache *cache)
|
||||
{
|
||||
BLI_assert(rdata->types & CU_DATATYPE_SURFACE);
|
||||
|
||||
if (cache->face_wire.elem_tx != NULL) {
|
||||
return cache->face_wire.elem_tx;
|
||||
}
|
||||
|
||||
ListBase *lb = &rdata->ob_curve_cache->disp;
|
||||
|
||||
/* We need a special index buffer. */
|
||||
GPUVertBuf *vbo = cache->face_wire.elem_vbo = DRW_displist_create_edges_overlay_texture_buf(lb);
|
||||
|
||||
/* Upload data early because we need to create the texture for it. */
|
||||
GPU_vertbuf_use(vbo);
|
||||
cache->face_wire.elem_tx = GPU_texture_create_from_vertbuf(vbo);
|
||||
cache->face_wire.tri_count = vbo->vertex_alloc / 3;
|
||||
|
||||
return cache->face_wire.elem_tx;
|
||||
}
|
||||
|
||||
static GPUTexture *curve_batch_cache_get_vert_pos_and_nor_in_order_buf(CurveRenderData *rdata, CurveBatchCache *cache)
|
||||
{
|
||||
BLI_assert(rdata->types & CU_DATATYPE_SURFACE);
|
||||
|
||||
if (cache->face_wire.verts_tx == NULL) {
|
||||
curve_batch_cache_get_pos_and_normals(rdata, cache);
|
||||
GPU_vertbuf_use(cache->surface.verts); /* Upload early for buffer texture creation. */
|
||||
cache->face_wire.verts_tx = GPU_texture_create_buffer(GPU_R32F, cache->surface.verts->vbo_id);
|
||||
}
|
||||
|
||||
return cache->face_wire.verts_tx;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
|
||||
|
@ -1024,6 +1074,25 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
|
|||
return cache->surface.shaded_triangles;
|
||||
}
|
||||
|
||||
void DRW_curve_batch_cache_get_wireframes_face_texbuf(
|
||||
Curve *cu, CurveCache *ob_curve_cache,
|
||||
GPUTexture **verts_data, GPUTexture **face_indices, int *tri_count)
|
||||
{
|
||||
CurveBatchCache *cache = curve_batch_cache_get(cu);
|
||||
|
||||
if (cache->face_wire.elem_tx == NULL || cache->face_wire.verts_tx == NULL) {
|
||||
CurveRenderData *rdata = curve_render_data_create(cu, ob_curve_cache, CU_DATATYPE_SURFACE);
|
||||
|
||||
curve_batch_cache_get_edges_overlay_texture_buf(rdata, cache);
|
||||
curve_batch_cache_get_vert_pos_and_nor_in_order_buf(rdata, cache);
|
||||
|
||||
curve_render_data_free(rdata);
|
||||
}
|
||||
|
||||
*tri_count = cache->face_wire.tri_count;
|
||||
*face_indices = cache->face_wire.elem_tx;
|
||||
*verts_data = cache->face_wire.verts_tx;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
|
|
@ -87,31 +87,35 @@ static int curve_render_surface_tri_len_get(const ListBase *lb)
|
|||
return tri_len;
|
||||
}
|
||||
|
||||
static void displist_indexbufbuilder_set(GPUIndexBufBuilder *elb, const DispList *dl, const int ofs)
|
||||
typedef void (setTriIndicesFn)(void *thunk, uint v1, uint v2, uint v3);
|
||||
|
||||
static void displist_indexbufbuilder_set(
|
||||
setTriIndicesFn *set_tri_indices,
|
||||
void *thunk, const DispList *dl, const int ofs)
|
||||
{
|
||||
if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
|
||||
const int *idx = dl->index;
|
||||
if (dl->type == DL_INDEX3) {
|
||||
const int i_end = dl->parts;
|
||||
for (int i = 0; i < i_end; i++, idx += 3) {
|
||||
GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs);
|
||||
set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs);
|
||||
}
|
||||
}
|
||||
else if (dl->type == DL_SURF) {
|
||||
const int i_end = dl->totindex;
|
||||
for (int i = 0; i < i_end; i++, idx += 4) {
|
||||
GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs);
|
||||
GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[3] + ofs, idx[2] + ofs);
|
||||
set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[1] + ofs);
|
||||
set_tri_indices(thunk, idx[2] + ofs, idx[0] + ofs, idx[3] + ofs);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(dl->type == DL_INDEX4);
|
||||
const int i_end = dl->parts;
|
||||
for (int i = 0; i < i_end; i++, idx += 4) {
|
||||
GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
|
||||
set_tri_indices(thunk, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
|
||||
|
||||
if (idx[2] != idx[3]) {
|
||||
GPU_indexbuf_add_tri_verts(elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
|
||||
set_tri_indices(thunk, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +129,7 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb)
|
|||
if (format.attr_len == 0) {
|
||||
/* initialize vertex format */
|
||||
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.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
|
||||
}
|
||||
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
|
@ -143,7 +147,9 @@ GPUVertBuf *DRW_displist_vertbuf_calc_pos_with_normals(ListBase *lb)
|
|||
while (vbo_len_used < vbo_end) {
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co);
|
||||
if (fp_no) {
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, fp_no);
|
||||
static short short_no[4];
|
||||
normal_float_to_short_v3(short_no, fp_no);
|
||||
GPU_vertbuf_attr_set(vbo, attr_id.nor, vbo_len_used, short_no);
|
||||
if (ndata_is_single == false) {
|
||||
fp_no += 3;
|
||||
}
|
||||
|
@ -167,7 +173,7 @@ GPUIndexBuf *DRW_displist_indexbuf_calc_triangles_in_order(ListBase *lb)
|
|||
|
||||
int ofs = 0;
|
||||
for (const DispList *dl = lb->first; dl; dl = dl->next) {
|
||||
displist_indexbufbuilder_set(&elb, dl, ofs);
|
||||
displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb, dl, ofs);
|
||||
ofs += dl_vert_len(dl);
|
||||
}
|
||||
|
||||
|
@ -192,7 +198,7 @@ GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(Li
|
|||
/* calc each index buffer builder */
|
||||
int ofs = 0;
|
||||
for (const DispList *dl = lb->first; dl; dl = dl->next) {
|
||||
displist_indexbufbuilder_set(&elb[dl->col], dl, ofs);
|
||||
displist_indexbufbuilder_set((setTriIndicesFn *)GPU_indexbuf_add_tri_verts, &elb[dl->col], dl, ofs);
|
||||
ofs += dl_vert_len(dl);
|
||||
}
|
||||
|
||||
|
@ -204,6 +210,53 @@ GPUIndexBuf **DRW_displist_indexbuf_calc_triangles_in_order_split_by_material(Li
|
|||
return shaded_triangles_in_order;
|
||||
}
|
||||
|
||||
typedef struct DRWDisplistWireThunk {
|
||||
uint index_id, vidx;
|
||||
short dl_type;
|
||||
GPUVertBuf *vbo;
|
||||
} DRWDisplistWireThunk;
|
||||
|
||||
static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3)
|
||||
{
|
||||
DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
|
||||
/* TODO consider non-manifold edges correctly. */
|
||||
if (dwt->dl_type == DL_SURF) {
|
||||
/* Tag real edges. */
|
||||
v2 |= (1 << 30);
|
||||
v3 |= (1 << 30);
|
||||
}
|
||||
else {
|
||||
/* Tag real edges. */
|
||||
v1 |= (1 << 30);
|
||||
v2 |= (1 << 30);
|
||||
v3 |= (1 << 30);
|
||||
}
|
||||
GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v1);
|
||||
GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v2);
|
||||
GPU_vertbuf_attr_set(dwt->vbo, dwt->index_id, dwt->vidx++, &v3);
|
||||
}
|
||||
|
||||
GPUVertBuf *DRW_displist_create_edges_overlay_texture_buf(ListBase *lb)
|
||||
{
|
||||
GPUVertFormat format = {0};
|
||||
uint index_id = GPU_vertformat_attr_add(&format, "index", GPU_COMP_U32, 1, GPU_FETCH_INT);
|
||||
GPUVertBuf *vbo = GPU_vertbuf_create_with_format(&format);
|
||||
|
||||
GPU_vertbuf_data_alloc(vbo, curve_render_surface_tri_len_get(lb) * 3);
|
||||
|
||||
DRWDisplistWireThunk thunk = {.index_id = index_id, .vbo = vbo, .vidx = 0};
|
||||
|
||||
int ofs = 0;
|
||||
for (const DispList *dl = lb->first; dl; dl = dl->next) {
|
||||
thunk.dl_type = dl->type;
|
||||
displist_indexbufbuilder_set(set_overlay_wires_tri_indices, &thunk, dl, ofs);
|
||||
ofs += dl_vert_len(dl);
|
||||
}
|
||||
|
||||
return vbo;
|
||||
}
|
||||
|
||||
|
||||
static void displist_vertbuf_attr_set_tri_pos_normals_and_uv(
|
||||
GPUVertBufRaw *pos_step, GPUVertBufRaw *nor_step, GPUVertBufRaw *uv_step,
|
||||
const float v1[3], const float v2[3], const float v3[3],
|
||||
|
|
Loading…
Reference in New Issue