Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c68
-rw-r--r--source/blender/gpu/GPU_batch.h2
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c8
3 files changed, 68 insertions, 10 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index a50951c98d8..bc5c4f8aeb0 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -1822,6 +1822,7 @@ typedef struct MeshBatchCache {
GPUVertBuf *loop_uv_tan;
GPUVertBuf *loop_vcol;
GPUVertBuf *loop_edge_fac;
+ GPUVertBuf *loop_orco;
} ordered;
/* Edit Mesh Data:
@@ -2033,8 +2034,7 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_pos_nor);
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_uv_tan);
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
- /* TODO */
- // GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
+ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
if (cache->surf_per_mat_tris) {
for (int i = 0; i < cache->mat_len; i++) {
@@ -2966,6 +2966,46 @@ static void mesh_create_loop_pos_and_nor(MeshRenderData *rdata, GPUVertBuf *vbo)
}
}
+static void mesh_create_loop_orco(MeshRenderData *rdata, GPUVertBuf *vbo)
+{
+ const uint loops_len = mesh_render_data_loops_len_get(rdata);
+
+ /* initialize vertex format */
+ GPUVertFormat format = { 0 };
+ GPUVertBufRaw vbo_step;
+
+ /* FIXME(fclem): We use the last component as a way to differentiate from generic vertex attribs.
+ * This is a substential waste of Vram and should be done another way. Unfortunately,
+ * at the time of writting, I did not found any other "non disruptive" alternative. */
+ uint attr_id = GPU_vertformat_attr_add(&format, "orco", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+
+ GPU_vertbuf_init_with_format(vbo, &format);
+ GPU_vertbuf_data_alloc(vbo, loops_len);
+ GPU_vertbuf_attr_get_raw_data(vbo, attr_id, &vbo_step);
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter_efa, iter_loop;
+ BMFace *efa;
+ BMLoop *loop;
+
+ BM_ITER_MESH (efa, &iter_efa, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (loop, &iter_loop, efa, BM_LOOPS_OF_FACE) {
+ float *data = (float *)GPU_vertbuf_raw_step(&vbo_step);
+ copy_v3_v3(data, rdata->orco[BM_elem_index_get(loop->v)]);
+ data[3] = 0.0; /* Tag as not a generic attrib */
+ }
+ }
+ }
+ else {
+ for (uint l = 0; l < loops_len; l++) {
+ float *data = (float *)GPU_vertbuf_raw_step(&vbo_step);
+ copy_v3_v3(data, rdata->orco[rdata->mloop[l].v]);
+ data[3] = 0.0; /* Tag as not a generic attrib */
+ }
+ }
+}
+
static void mesh_create_loop_uv_and_tan(MeshRenderData *rdata, GPUVertBuf *vbo)
{
const uint loops_len = mesh_render_data_loops_len_get(rdata);
@@ -4593,8 +4633,7 @@ void DRW_mesh_batch_cache_create_requested(
GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_vcol);
break;
case CD_ORCO:
- /* TODO */
- // GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
+ GPU_VERTBUF_DISCARD_SAFE(cache->ordered.loop_orco);
break;
}
}
@@ -4784,10 +4823,19 @@ void DRW_mesh_batch_cache_create_requested(
if (cache->cd_lused[CD_MLOOPCOL] != 0) {
DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_vcol);
}
- /* TODO */
- // if (cache->cd_vused[CD_ORCO] != 0) {
- // DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_orco);
- // }
+ if (cache->cd_vused[CD_ORCO] != 0) {
+ /* OPTI : Only do that if there is modifiers that modify orcos. */
+ CustomData *cd_vdata = (me->edit_mesh) ? &me->edit_mesh->bm->vdata : &me->vdata;
+ if (CustomData_get_layer(cd_vdata, CD_ORCO) != NULL &&
+ ob->modifiers.first != NULL)
+ {
+ DRW_vbo_request(cache->surf_per_mat[i], &cache->ordered.loop_orco);
+ }
+ else if ((cache->cd_lused[CD_TANGENT] & DM_TANGENT_MASK_ORCO) == 0) {
+ /* Skip orco calculation if not needed by tangent generation. */
+ cache->cd_vused[CD_ORCO] = 0;
+ }
+ }
}
}
@@ -4797,6 +4845,7 @@ void DRW_mesh_batch_cache_create_requested(
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.weights, MR_DATATYPE_VERT | MR_DATATYPE_DVERT);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_pos_nor, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_uv_tan, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
+ DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_orco, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_vcol, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_SHADING);
DRW_ADD_FLAG_FROM_VBO_REQUEST(mr_flag, cache->ordered.loop_edge_fac, MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP);
DRW_ADD_FLAG_FROM_IBO_REQUEST(mr_flag, cache->ibo.surf_tris, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPTRI);
@@ -4863,6 +4912,9 @@ void DRW_mesh_batch_cache_create_requested(
if (DRW_vbo_requested(cache->ordered.loop_uv_tan)) {
mesh_create_loop_uv_and_tan(rdata, cache->ordered.loop_uv_tan);
}
+ if (DRW_vbo_requested(cache->ordered.loop_orco)) {
+ mesh_create_loop_orco(rdata, cache->ordered.loop_orco);
+ }
if (DRW_vbo_requested(cache->ordered.loop_vcol)) {
mesh_create_loop_vcol(rdata, cache->ordered.loop_vcol);
}
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index 95eb59a57ae..3d013eb8af4 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -39,7 +39,7 @@ typedef enum {
GPU_BATCH_READY_TO_DRAW
} GPUBatchPhase;
-#define GPU_BATCH_VBO_MAX_LEN 3
+#define GPU_BATCH_VBO_MAX_LEN 4
#define GPU_BATCH_VAO_STATIC_LEN 3
#define GPU_BATCH_VAO_DYN_ALLOC_COUNT 16
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index cf770599fc7..b1d94d22f35 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -872,8 +872,9 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
/* XXX FIXME : see notes in mesh_render_data_create() */
/* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */
if (input->attr_type == CD_ORCO) {
- /* orco is computed from local positions, see below */
+ /* OPTI : orco is computed from local positions, but only if no modifier is present. */
BLI_dynstr_append(ds, "uniform vec3 OrcoTexCoFactors[2];\n");
+ BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n");
}
else if (input->attr_name[0] == '\0') {
BLI_dynstr_appendf(ds, "DEFINE_ATTR(%s, %s);\n", GPU_DATATYPE_STR[input->type], attr_prefix_get(input->attr_type));
@@ -976,6 +977,7 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_appendf(
ds, "\tvar%d%s = OrcoTexCoFactors[0] + (ModelMatrixInverse * vec4(hair_get_strand_pos(), 1.0)).xyz * OrcoTexCoFactors[1];\n",
input->attr_id, use_geom ? "g" : "");
+ /* TODO: fix ORCO with modifiers. */
}
else {
BLI_dynstr_appendf(
@@ -1018,6 +1020,10 @@ static char *code_generate_vertex(ListBase *nodes, const char *vert_code, bool u
BLI_dynstr_appendf(
ds, "\tvar%d%s = OrcoTexCoFactors[0] + position * OrcoTexCoFactors[1];\n",
input->attr_id, use_geom ? "g" : "");
+ /* See mesh_create_loop_orco() for explanation. */
+ BLI_dynstr_appendf(
+ ds, "\tif (orco.w == 0.0) { var%d%s = orco.xyz * 0.5 + 0.5; }\n",
+ input->attr_id, use_geom ? "g" : "");
}
else if (input->attr_type == CD_MCOL) {
BLI_dynstr_appendf(