Fix T61801: Wireframes on curves not working

This commit is contained in:
Clément Foucault 2019-02-25 19:37:08 +01:00
parent a7acd4690c
commit 753e73009f
4 changed files with 62 additions and 91 deletions

View File

@ -81,12 +81,12 @@ struct GPUBatch **DRW_metaball_batch_cache_get_surface_shaded(
struct GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(struct Object *ob);
/* DispList */
void DRW_displist_vertbuf_create_pos_and_nor(struct ListBase *lb, struct GPUVertBuf *vbo);
void DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(
void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(struct ListBase *lb, struct GPUVertBuf *vbo);
void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(
struct ListBase *lb, struct GPUVertBuf *vbo_pos_nor, struct GPUVertBuf *vbo_uv);
void DRW_displist_vertbuf_create_wireframe_data_tess(struct ListBase *lb, struct GPUVertBuf *vbo);
void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *vbo);
void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
void DRW_displist_indexbuf_create_lines_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
void DRW_displist_indexbuf_create_triangles_in_order(struct ListBase *lb, struct GPUIndexBuf *ibo);
void DRW_displist_indexbuf_create_triangles_loop_split_by_material(
struct ListBase *lb, struct GPUIndexBuf **ibo_mat, uint mat_len);
/* Lattice */

View File

@ -347,15 +347,11 @@ typedef struct CurveBatchCache {
struct {
GPUVertBuf *pos_nor;
GPUVertBuf *curves_pos;
GPUVertBuf *loop_pos_nor;
GPUVertBuf *loop_uv;
} ordered;
struct {
GPUVertBuf *pos_nor;
GPUVertBuf *uv;
GPUVertBuf *wireframe_data;
} tess;
struct {
/* Curve points. Aligned with ordered.pos_nor */
GPUVertBuf *curves_nor;
@ -367,6 +363,7 @@ typedef struct CurveBatchCache {
struct {
GPUIndexBuf *surfaces_tris;
GPUIndexBuf *surfaces_lines;
GPUIndexBuf *curves_lines;
/* Edit mode */
GPUIndexBuf *edit_verts_points; /* Only control points. Not handles. */
@ -375,14 +372,13 @@ typedef struct CurveBatchCache {
struct {
GPUBatch *surfaces;
GPUBatch *surfaces_edges;
GPUBatch *curves;
/* control handles and vertices */
GPUBatch *edit_edges;
GPUBatch *edit_verts;
GPUBatch *edit_handles_verts;
GPUBatch *edit_normals;
/* Triangles for object mode wireframe. */
GPUBatch *wire_triangles;
} batch;
GPUIndexBuf **surf_per_mat_tris;
@ -506,10 +502,6 @@ static void curve_batch_cache_clear(Curve *cu)
GPUVertBuf **vbo = (GPUVertBuf **)&cache->ordered;
GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
}
for (int i = 0; i < sizeof(cache->tess) / sizeof(void *); ++i) {
GPUVertBuf **vbo = (GPUVertBuf **)&cache->tess;
GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
}
for (int i = 0; i < sizeof(cache->edit) / sizeof(void *); ++i) {
GPUVertBuf **vbo = (GPUVertBuf **)&cache->edit;
GPU_VERTBUF_DISCARD_SAFE(vbo[i]);
@ -884,7 +876,7 @@ GPUBatch **DRW_curve_batch_cache_get_surface_shaded(
GPUBatch *DRW_curve_batch_cache_get_wireframes_face(Curve *cu)
{
CurveBatchCache *cache = curve_batch_cache_get(cu);
return DRW_batch_request(&cache->batch.wire_triangles);
return DRW_batch_request(&cache->batch.surfaces_edges);
}
/** \} */
@ -920,14 +912,14 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
DRW_ibo_request(cache->batch.surfaces, &cache->ibo.surfaces_tris);
DRW_vbo_request(cache->batch.surfaces, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.surfaces_edges, GPU_PRIM_LINES)) {
DRW_ibo_request(cache->batch.surfaces_edges, &cache->ibo.surfaces_lines);
DRW_vbo_request(cache->batch.surfaces_edges, &cache->ordered.pos_nor);
}
if (DRW_batch_requested(cache->batch.curves, GPU_PRIM_LINE_STRIP)) {
DRW_ibo_request(cache->batch.curves, &cache->ibo.curves_lines);
DRW_vbo_request(cache->batch.curves, &cache->ordered.curves_pos);
}
if (DRW_batch_requested(cache->batch.wire_triangles, GPU_PRIM_TRIS)) {
DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.pos_nor);
DRW_vbo_request(cache->batch.wire_triangles, &cache->tess.wireframe_data);
}
/* Edit mode */
if (DRW_batch_requested(cache->batch.edit_edges, GPU_PRIM_LINES)) {
@ -953,9 +945,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
DRW_ibo_request(cache->surf_per_mat[i], &cache->surf_per_mat_tris[i]);
}
if (cache->cd_used & CD_MLOOPUV) {
DRW_vbo_request(cache->surf_per_mat[i], &cache->tess.uv);
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_uv);
}
DRW_vbo_request(cache->surf_per_mat[i], &cache->tess.pos_nor);
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_pos_nor);
}
}
@ -963,10 +955,10 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
int mr_flag = 0;
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.pos_nor, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.curves_pos, CU_DATATYPE_WIRE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.pos_nor, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.uv, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->tess.wireframe_data, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_tris, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surfaces_lines, CU_DATATYPE_SURFACE);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.curves_lines, CU_DATATYPE_WIRE);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->edit.pos, CU_DATATYPE_OVERLAY);
@ -987,23 +979,20 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
/* Generate VBOs */
if (DRW_vbo_requested(cache->ordered.pos_nor)) {
DRW_displist_vertbuf_create_pos_and_nor(lb, cache->ordered.pos_nor);
DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->ordered.pos_nor);
}
if (DRW_vbo_requested(cache->ordered.curves_pos)) {
curve_create_curves_pos(rdata, cache->ordered.curves_pos);
}
if (DRW_vbo_requested(cache->tess.pos_nor) ||
DRW_vbo_requested(cache->tess.uv))
if (DRW_vbo_requested(cache->ordered.loop_pos_nor) ||
DRW_vbo_requested(cache->ordered.loop_uv))
{
DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(lb, cache->tess.pos_nor, cache->tess.uv);
}
if (DRW_vbo_requested(cache->tess.wireframe_data)) {
DRW_displist_vertbuf_create_wireframe_data_tess(lb, cache->tess.wireframe_data);
DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(lb, cache->ordered.loop_pos_nor, cache->ordered.loop_uv);
}
if (DRW_ibo_requested(cache->surf_per_mat_tris[0])) {
DRW_displist_indexbuf_create_triangles_tess_split_by_material(lb, cache->surf_per_mat_tris, cache->mat_len);
DRW_displist_indexbuf_create_triangles_loop_split_by_material(lb, cache->surf_per_mat_tris, cache->mat_len);
}
if (DRW_ibo_requested(cache->ibo.curves_lines)) {
@ -1012,6 +1001,9 @@ void DRW_curve_batch_cache_create_requested(Object *ob)
if (DRW_ibo_requested(cache->ibo.surfaces_tris)) {
DRW_displist_indexbuf_create_triangles_in_order(lb, cache->ibo.surfaces_tris);
}
if (DRW_ibo_requested(cache->ibo.surfaces_lines)) {
DRW_displist_indexbuf_create_lines_in_order(lb, cache->ibo.surfaces_lines);
}
if (DRW_vbo_requested(cache->edit.pos) ||
DRW_vbo_requested(cache->edit.data) ||

View File

@ -165,14 +165,15 @@ static int displist_indexbufbuilder_tess_set(
return v_idx;
}
void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo)
void DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(ListBase *lb, GPUVertBuf *vbo)
{
static GPUVertFormat format = { 0 };
static struct { uint pos, nor; } attr_id;
static struct { uint pos, nor, wd; } attr_id;
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_I16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
attr_id.wd = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
}
GPU_vertbuf_init_with_format(vbo, &format);
@ -188,6 +189,8 @@ void DRW_displist_vertbuf_create_pos_and_nor(ListBase *lb, GPUVertBuf *vbo)
const float *fp_no = dl->nors;
const int vbo_end = vbo_len_used + dl_vert_len(dl);
while (vbo_len_used < vbo_end) {
uchar sharpness = 0xFF;
GPU_vertbuf_attr_set(vbo, attr_id.wd, vbo_len_used, &sharpness);
GPU_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used, fp_co);
if (fp_no) {
static short short_no[4];
@ -224,7 +227,7 @@ void DRW_displist_indexbuf_create_triangles_in_order(ListBase *lb, GPUIndexBuf *
GPU_indexbuf_build_in_place(&elb, ibo);
}
void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
void DRW_displist_indexbuf_create_triangles_loop_split_by_material(
ListBase *lb,
GPUIndexBuf **ibo_mats, uint mat_len)
{
@ -252,65 +255,39 @@ void DRW_displist_indexbuf_create_triangles_tess_split_by_material(
}
}
typedef struct DRWDisplistWireThunk {
uint wd_id, ofs;
const DispList *dl;
GPUVertBuf *vbo;
} DRWDisplistWireThunk;
static void set_overlay_wires_tri_indices(void *thunk, uint v1, uint v2, uint v3)
{
DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
uint indices[3] = {v1, v2, v3};
for (int i = 0; i < 3; ++i) {
/* TODO: Compute sharpness. For now, only tag real egdes. */
uchar sharpness = 0xFF;
GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, indices[i], &sharpness);
}
GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk;
GPU_indexbuf_add_line_verts(eld, v1, v2);
GPU_indexbuf_add_line_verts(eld, v2, v3);
GPU_indexbuf_add_line_verts(eld, v3, v1);
}
static void set_overlay_wires_quad_tri_indices(void *thunk, uint v1, uint v2, uint v3)
{
DRWDisplistWireThunk *dwt = (DRWDisplistWireThunk *)thunk;
uint indices[3] = {v1, v2, v3};
for (int i = 0; i < 3; ++i) {
/* TODO: Compute sharpness. For now, only tag real egdes. */
uchar sharpness = (i == 0) ? 0x00 : 0xFF;
GPU_vertbuf_attr_set(dwt->vbo, dwt->wd_id, indices[i], &sharpness);
}
GPUIndexBufBuilder *eld = (GPUIndexBufBuilder *)thunk;
GPU_indexbuf_add_line_verts(eld, v1, v3);
GPU_indexbuf_add_line_verts(eld, v3, v2);
}
/* TODO reuse the position and normals from other tesselation vertbuf. */
void DRW_displist_vertbuf_create_wireframe_data_tess(ListBase *lb, GPUVertBuf *vbo)
void DRW_displist_indexbuf_create_lines_in_order(ListBase *lb, GPUIndexBuf *ibo)
{
static DRWDisplistWireThunk thunk;
static GPUVertFormat format = {0};
if (format.attr_len == 0) {
thunk.wd_id = GPU_vertformat_attr_add(&format, "wd", GPU_COMP_U8, 1, GPU_FETCH_INT_TO_FLOAT_UNIT);
GPU_vertformat_triple_load(&format);
}
const int tri_len = curve_render_surface_tri_len_get(lb);
const int vert_len = curve_render_surface_vert_len_get(lb);
GPU_vertbuf_init_with_format(vbo, &format);
thunk.vbo = vbo;
GPUIndexBufBuilder elb;
GPU_indexbuf_init(&elb, GPU_PRIM_LINES, tri_len * 3, vert_len);
int vert_len = curve_render_surface_tri_len_get(lb) * 3;
GPU_vertbuf_data_alloc(thunk.vbo, vert_len);
thunk.ofs = 0;
int ofs = 0;
for (const DispList *dl = lb->first; dl; dl = dl->next) {
thunk.dl = dl;
/* TODO consider non-manifold edges correctly. */
thunk.ofs = displist_indexbufbuilder_tess_set(
set_overlay_wires_tri_indices,
set_overlay_wires_quad_tri_indices,
&thunk, dl, thunk.ofs);
displist_indexbufbuilder_set(
(SetTriIndicesFn *)set_overlay_wires_tri_indices,
(SetTriIndicesFn *)set_overlay_wires_quad_tri_indices,
&elb, dl, ofs);
ofs += dl_vert_len(dl);
}
if (thunk.ofs < vert_len) {
GPU_vertbuf_data_resize(thunk.vbo, thunk.ofs);
}
GPU_indexbuf_build_in_place(&elb, ibo);
}
static void surf_uv_quad(const DispList *dl, const uint quad[4], float r_uv[4][2])
@ -364,7 +341,7 @@ static void displist_vertbuf_attr_set_tri_pos_nor_uv(
}
}
void DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(
void DRW_displist_vertbuf_create_loop_pos_and_nor_and_uv(
ListBase *lb,
GPUVertBuf *vbo_pos_nor, GPUVertBuf *vbo_uv)
{

View File

@ -139,7 +139,7 @@ static GPUVertBuf *mball_batch_cache_get_pos_and_normals(Object *ob, MetaBallBat
if (cache->pos_nor_in_order == NULL) {
ListBase *lb = &ob->runtime.curve_cache->disp;
cache->pos_nor_in_order = MEM_callocN(sizeof(GPUVertBuf), __func__);
DRW_displist_vertbuf_create_pos_and_nor(lb, cache->pos_nor_in_order);
DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, cache->pos_nor_in_order);
}
return cache->pos_nor_in_order;
}
@ -203,13 +203,15 @@ GPUBatch *DRW_metaball_batch_cache_get_wireframes_face(Object *ob)
ListBase *lb = &ob->runtime.curve_cache->disp;
GPUVertBuf *vbo_pos_nor = MEM_callocN(sizeof(GPUVertBuf), __func__);
GPUVertBuf *vbo_wireframe_data = MEM_callocN(sizeof(GPUVertBuf), __func__);
DRW_displist_vertbuf_create_pos_and_nor_and_wiredata(lb, vbo_pos_nor);
DRW_displist_vertbuf_create_pos_and_nor_and_uv_tess(lb, vbo_pos_nor, NULL);
DRW_displist_vertbuf_create_wireframe_data_tess(lb, vbo_wireframe_data);
GPUIndexBuf *ibo = MEM_callocN(sizeof(GPUIndexBuf), __func__);
DRW_displist_indexbuf_create_lines_in_order(lb, ibo);
cache->face_wire.batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo_pos_nor, NULL, GPU_BATCH_OWNS_VBO);
GPU_batch_vertbuf_add_ex(cache->face_wire.batch, vbo_wireframe_data, true);
cache->face_wire.batch = GPU_batch_create_ex(GPU_PRIM_LINES,
vbo_pos_nor,
ibo,
GPU_BATCH_OWNS_VBO | GPU_BATCH_OWNS_INDEX);
}
return cache->face_wire.batch;