Use mesh draw cache for back-buffer selection
Vertex/weight paint now work with core profile, resolves T51380.
This commit is contained in:
parent
9869436b89
commit
4bd2429f35
Notes:
blender-bot
2023-02-14 09:03:55 +01:00
Referenced by issue #51380, Vertex & Weight Painting not working in core profile
|
@ -76,6 +76,7 @@ struct Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
|
|||
struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
|
||||
struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup);
|
||||
struct Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
|
||||
struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide);
|
||||
struct Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
|
||||
struct Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
|
||||
struct Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "bmesh.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
#include "GPU_draw.h"
|
||||
|
||||
#include "UI_resources.h"
|
||||
|
||||
|
@ -1274,6 +1275,58 @@ static bool mesh_render_data_looptri_cos_vert_colors_get(
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool mesh_render_data_looptri_cos_select_id_get(
|
||||
MeshRenderData *rdata, const int tri_idx, const bool use_hide,
|
||||
float *(*r_vert_cos)[3],
|
||||
short **r_tri_nor, int *r_select_id)
|
||||
{
|
||||
BLI_assert(
|
||||
rdata->types &
|
||||
(MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT));
|
||||
|
||||
if (rdata->edit_bmesh) {
|
||||
const BMLoop **bm_looptri = (const BMLoop **)rdata->edit_bmesh->looptris[tri_idx];
|
||||
const int poly_index = BM_elem_index_get(bm_looptri[0]->f);
|
||||
|
||||
if (use_hide && BM_elem_flag_test(bm_looptri[0]->f, BM_ELEM_HIDDEN)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh_render_data_ensure_poly_normals_short(rdata);
|
||||
|
||||
short (*pnors_short)[3] = rdata->poly_normals_short;
|
||||
|
||||
|
||||
(*r_vert_cos)[0] = bm_looptri[0]->v->co;
|
||||
(*r_vert_cos)[1] = bm_looptri[1]->v->co;
|
||||
(*r_vert_cos)[2] = bm_looptri[2]->v->co;
|
||||
*r_tri_nor = pnors_short[poly_index];
|
||||
|
||||
GPU_select_index_get(poly_index + 1, r_select_id);
|
||||
}
|
||||
else {
|
||||
const MLoopTri *mlt = &rdata->mlooptri[tri_idx];
|
||||
const int poly_index = mlt->poly;
|
||||
|
||||
if (use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mesh_render_data_ensure_poly_normals_short(rdata);
|
||||
|
||||
short (*pnors_short)[3] = rdata->poly_normals_short;
|
||||
|
||||
(*r_vert_cos)[0] = rdata->mvert[rdata->mloop[mlt->tri[0]].v].co;
|
||||
(*r_vert_cos)[1] = rdata->mvert[rdata->mloop[mlt->tri[1]].v].co;
|
||||
(*r_vert_cos)[2] = rdata->mvert[rdata->mloop[mlt->tri[2]].v].co;
|
||||
*r_tri_nor = pnors_short[poly_index];
|
||||
|
||||
GPU_select_index_get(poly_index + 1, r_select_id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mesh_render_data_edge_cos_sel_get(
|
||||
MeshRenderData *rdata, const int edge_idx,
|
||||
float r_vert_cos[2][3], float r_vert_col[3],
|
||||
|
@ -1587,9 +1640,11 @@ typedef struct MeshBatchCache {
|
|||
VertexBuffer *edge_pos_with_sel;
|
||||
VertexBuffer *tri_pos_with_sel;
|
||||
VertexBuffer *pos_with_sel;
|
||||
VertexBuffer *pos_with_sel_id;
|
||||
Batch *triangles_with_normals;
|
||||
Batch *triangles_with_weights;
|
||||
Batch *triangles_with_vert_colors;
|
||||
Batch *triangles_with_select_id;
|
||||
Batch *points_with_normals;
|
||||
Batch *fancy_edges; /* owns its vertex buffer (not shared) */
|
||||
|
||||
|
@ -1754,6 +1809,8 @@ static void mesh_batch_cache_clear(Mesh *me)
|
|||
VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_normals);
|
||||
BATCH_DISCARD_ALL_SAFE(cache->triangles_with_weights);
|
||||
BATCH_DISCARD_ALL_SAFE(cache->triangles_with_vert_colors);
|
||||
VERTEXBUFFER_DISCARD_SAFE(cache->pos_with_sel_id);
|
||||
BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
|
||||
|
||||
BATCH_DISCARD_ALL_SAFE(cache->fancy_edges);
|
||||
|
||||
|
@ -2135,6 +2192,66 @@ static VertexBuffer *mesh_batch_cache_get_pos_normals_and_vert_colors(
|
|||
return cache->pos_with_vert_colors;
|
||||
}
|
||||
|
||||
static VertexBuffer *mesh_batch_cache_get_pos_normals_and_select_id(
|
||||
MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
|
||||
{
|
||||
BLI_assert(
|
||||
rdata->types &
|
||||
(MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
|
||||
|
||||
if (cache->pos_with_sel_id == NULL) {
|
||||
unsigned int vidx = 0, cidx = 0, nidx = 0;
|
||||
|
||||
static VertexFormat format = { 0 };
|
||||
static unsigned int pos_id, col_id, nor_id;
|
||||
if (format.attrib_ct == 0) {
|
||||
/* initialize vertex format */
|
||||
pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT);
|
||||
nor_id = VertexFormat_add_attrib(&format, "nor", COMP_I16, 3, NORMALIZE_INT_TO_FLOAT);
|
||||
col_id = VertexFormat_add_attrib(&format, "color", COMP_I32, 1, KEEP_INT);
|
||||
}
|
||||
|
||||
const int tri_len = mesh_render_data_looptri_len_get(rdata);
|
||||
|
||||
VertexBuffer *vbo = cache->pos_with_sel_id = VertexBuffer_create_with_format(&format);
|
||||
|
||||
const int vbo_len_capacity = tri_len * 3;
|
||||
int vbo_len_used = 0;
|
||||
VertexBuffer_allocate_data(vbo, vbo_len_capacity);
|
||||
|
||||
for (int i = 0; i < tri_len; i++) {
|
||||
float *tri_vert_cos[3];
|
||||
short *tri_nor;
|
||||
int select_id;
|
||||
|
||||
if (mesh_render_data_looptri_cos_select_id_get(
|
||||
rdata, i, use_hide, &tri_vert_cos, &tri_nor, &select_id))
|
||||
{
|
||||
/* TODO, one elem per tri */
|
||||
VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id);
|
||||
VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id);
|
||||
VertexBuffer_set_attrib(vbo, col_id, cidx++, &select_id);
|
||||
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[0]);
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[1]);
|
||||
VertexBuffer_set_attrib(vbo, pos_id, vidx++, tri_vert_cos[2]);
|
||||
|
||||
/* TODO, one elem per tri */
|
||||
VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
|
||||
VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
|
||||
VertexBuffer_set_attrib(vbo, nor_id, nidx++, tri_nor);
|
||||
}
|
||||
}
|
||||
vbo_len_used = vidx;
|
||||
|
||||
if (vbo_len_capacity != vbo_len_used) {
|
||||
VertexBuffer_resize_data(vbo, vbo_len_used);
|
||||
}
|
||||
}
|
||||
|
||||
return cache->pos_with_sel_id;
|
||||
}
|
||||
|
||||
static VertexBuffer *mesh_batch_cache_get_pos_and_nor_in_order(MeshRenderData *rdata, MeshBatchCache *cache)
|
||||
{
|
||||
BLI_assert(rdata->types & MR_DATATYPE_VERT);
|
||||
|
@ -2493,6 +2610,25 @@ Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh *me)
|
|||
return cache->triangles_with_vert_colors;
|
||||
}
|
||||
|
||||
|
||||
struct Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide)
|
||||
{
|
||||
MeshBatchCache *cache = mesh_batch_cache_get(me);
|
||||
|
||||
if (cache->triangles_with_select_id == NULL) {
|
||||
const int datatype =
|
||||
MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
|
||||
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
|
||||
|
||||
cache->triangles_with_select_id = Batch_create(
|
||||
PRIM_TRIANGLES, mesh_batch_cache_get_pos_normals_and_select_id(rdata, cache, use_hide), NULL);
|
||||
|
||||
mesh_render_data_free(rdata);
|
||||
}
|
||||
|
||||
return cache->triangles_with_select_id;
|
||||
}
|
||||
|
||||
Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
|
||||
{
|
||||
MeshBatchCache *cache = mesh_batch_cache_get(me);
|
||||
|
|
|
@ -9542,8 +9542,9 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
|
|||
|
||||
static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
|
||||
{
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
|
||||
Mesh *me = ob->data;
|
||||
#if defined(WITH_LEGACY_OPENGL)
|
||||
DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask);
|
||||
|
||||
DM_update_materials(dm, ob);
|
||||
|
||||
|
@ -9553,6 +9554,19 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
|
|||
dm->drawMappedFaces(dm, bbs_mesh_solid__setDrawOpts, NULL, NULL, me, 0);
|
||||
|
||||
dm->release(dm);
|
||||
#else
|
||||
UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts);
|
||||
Batch *batch;
|
||||
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
|
||||
batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true);
|
||||
}
|
||||
else {
|
||||
batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false);
|
||||
}
|
||||
Batch_set_builtin_program(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
|
||||
Batch_draw(batch);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
|
||||
|
|
|
@ -119,6 +119,7 @@ typedef enum GPUBuiltinShader {
|
|||
GPU_SHADER_3D_UNIFORM_COLOR,
|
||||
GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
|
||||
GPU_SHADER_3D_FLAT_COLOR,
|
||||
GPU_SHADER_3D_FLAT_COLOR_U32, /* use for select-id's */
|
||||
GPU_SHADER_3D_SMOOTH_COLOR,
|
||||
GPU_SHADER_3D_DEPTH_ONLY,
|
||||
GPU_SHADER_3D_CLIPPED_UNIFORM_COLOR,
|
||||
|
|
|
@ -702,6 +702,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
|
|||
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
|
||||
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
|
||||
datatoc_gpu_shader_flat_color_frag_glsl },
|
||||
[GPU_SHADER_3D_FLAT_COLOR_U32] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
|
||||
datatoc_gpu_shader_flat_color_frag_glsl },
|
||||
[GPU_SHADER_3D_SMOOTH_COLOR] = { datatoc_gpu_shader_3D_smooth_color_vert_glsl,
|
||||
datatoc_gpu_shader_3D_smooth_color_frag_glsl },
|
||||
[GPU_SHADER_3D_DEPTH_ONLY] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_depth_only_frag_glsl },
|
||||
|
@ -781,10 +783,26 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
|
|||
|
||||
if (builtin_shaders[shader] == NULL) {
|
||||
/* just a few special cases */
|
||||
const char *defines = (shader == GPU_SHADER_SMOKE_COBA) ? "#define USE_COBA;\n" :
|
||||
(shader == GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE) ? "#define UNIFORM_SCALE;\n" :
|
||||
(shader == GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS) ? "#define AXIS_NAME;\n" :
|
||||
(shader == GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR) ? "#define USE_INSTANCE_COLOR;\n" : NULL;
|
||||
const char *defines = NULL;
|
||||
switch (shader) {
|
||||
case GPU_SHADER_SMOKE_COBA:
|
||||
defines = "#define USE_COBA;\n";
|
||||
break;
|
||||
case GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE:
|
||||
defines = "#define UNIFORM_SCALE;\n";
|
||||
break;
|
||||
case GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS:
|
||||
defines = "#define AXIS_NAME;\n";
|
||||
break;
|
||||
case GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR:
|
||||
defines = "#define USE_INSTANCE_COLOR;\n";
|
||||
break;
|
||||
case GPU_SHADER_3D_FLAT_COLOR_U32:
|
||||
defines = "#define USE_COLOR_U32;\n";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const GPUShaderStages *stages = builtin_shader_stages + shader;
|
||||
|
||||
|
|
|
@ -3,12 +3,20 @@ uniform mat4 ModelViewProjectionMatrix;
|
|||
|
||||
#if __VERSION__ == 120
|
||||
attribute vec3 pos;
|
||||
#if defined(USE_COLOR_U32)
|
||||
attribute int color;
|
||||
#else
|
||||
attribute vec4 color;
|
||||
#endif
|
||||
|
||||
flat varying vec4 finalColor;
|
||||
#else
|
||||
in vec3 pos;
|
||||
#if defined(USE_COLOR_U32)
|
||||
in int color;
|
||||
#else
|
||||
in vec4 color;
|
||||
#endif
|
||||
|
||||
flat out vec4 finalColor;
|
||||
#endif
|
||||
|
@ -16,5 +24,14 @@ uniform mat4 ModelViewProjectionMatrix;
|
|||
void main()
|
||||
{
|
||||
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
|
||||
|
||||
#if defined(USE_COLOR_U32)
|
||||
finalColor = vec4(
|
||||
((color ) & 0xFF) * (1.0f / 255.0f),
|
||||
((color >> 8) & 0xFF) * (1.0f / 255.0f),
|
||||
((color >> 16) & 0xFF) * (1.0f / 255.0f),
|
||||
((color >> 24) ) * (1.0f / 255.0f));
|
||||
#else
|
||||
finalColor = color;
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue