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:
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_draw.c')
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c234
1 files changed, 102 insertions, 132 deletions
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index ee3afdd5772..d9805214964 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -79,7 +79,52 @@
#include "uvedit_intern.h"
-static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos);
+static int draw_uvs_face_check(Scene *scene)
+{
+ ToolSettings *ts = scene->toolsettings;
+
+ /* checks if we are selecting only faces */
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ if (ts->selectmode == SCE_SELECT_FACE)
+ return 2;
+ else if (ts->selectmode & SCE_SELECT_FACE)
+ return 1;
+ else
+ return 0;
+ }
+ else
+ return (ts->uv_selectmode == UV_SELECT_FACE);
+}
+
+static uchar get_state(SpaceImage *sima, Scene *scene)
+{
+ ToolSettings *ts = scene->toolsettings;
+ int drawfaces = draw_uvs_face_check(scene);
+ const bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
+ uchar state = UVEDIT_EDGES | UVEDIT_DATA;
+
+ if (drawfaces) {
+ state |= UVEDIT_FACEDOTS;
+ }
+ if (draw_stretch || !(sima->flag & SI_NO_DRAWFACES)) {
+ state |= UVEDIT_FACES;
+
+ if (draw_stretch) {
+ if (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) {
+ state |= UVEDIT_STRETCH_AREA;
+ }
+ else {
+ state |= UVEDIT_STRETCH_ANGLE;
+ }
+ }
+ }
+ if (ts->uv_flag & UV_SYNC_SELECTION) {
+ state |= UVEDIT_SYNC_SEL;
+ }
+ return state;
+}
+
+/* ------------------------- */
void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
{
@@ -147,150 +192,75 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2])
GPU_matrix_translate_2f(-cursor[0], -cursor[1]);
}
-static int draw_uvs_face_check(Scene *scene)
+static void draw_uvs_shadow(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *depsgraph)
{
- ToolSettings *ts = scene->toolsettings;
-
- /* checks if we are selecting only faces */
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- if (ts->selectmode == SCE_SELECT_FACE)
- return 2;
- else if (ts->selectmode & SCE_SELECT_FACE)
- return 1;
- else
- return 0;
- }
- else
- return (ts->uv_selectmode == UV_SELECT_FACE);
-}
+ Object *eval_ob = DEG_get_evaluated_object(depsgraph, obedit);
+ GPUBatch *faces, *edges, *verts, *facedots;
+ uchar state = UVEDIT_EDGES | UVEDIT_DATA;
+ float col[4];
+ UI_GetThemeColor4fv(TH_UV_SHADOW, col);
-static void draw_uvs_shadow(Object *obedit)
-{
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
+ DRW_mesh_cache_uvedit(
+ eval_ob, sima, scene, state,
+ &faces, &edges, &verts, &facedots);
- if (bm->totloop == 0) {
- return;
+ if (edges) {
+ GPU_batch_program_set_builtin(edges, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(edges, "color", col);
+ GPU_batch_draw(edges);
}
-
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* draws the mesh when painting */
- immUniformThemeColor(TH_UV_SHADOW);
-
- draw_uvs_lineloop_bmfaces(bm, cd_loop_uv_offset, pos);
-
- immUnbindProgram();
}
-static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos)
+static void draw_uvs_texpaint(Scene *scene, Object *ob, Depsgraph *depsgraph)
{
- BMIter iter, liter;
- BMFace *efa;
- BMLoop *l;
- MLoopUV *luv;
-
- /* For more efficiency first transfer the entire buffer to vram. */
- GPUBatch *loop_batch = immBeginBatchAtMost(GPU_PRIM_LINE_LOOP, bm->totloop);
-
- BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
- continue;
-
- BM_ITER_ELEM(l, &liter, efa, BM_LOOPS_OF_FACE) {
- luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- immVertex2fv(shdr_pos, luv->uv);
- }
- }
- immEnd();
-
- /* Then draw each face contour separately. */
- GPU_batch_program_use_begin(loop_batch);
- unsigned int index = 0;
- BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
- continue;
-
- GPU_batch_draw_range_ex(loop_batch, index, efa->len, false);
- index += efa->len;
- }
- GPU_batch_program_use_end(loop_batch);
- GPU_batch_discard(loop_batch);
-}
+ Object *eval_ob = DEG_get_evaluated_object(depsgraph, ob);
+ Mesh *me = eval_ob->data;
+ ToolSettings *ts = scene->toolsettings;
+ GPUBatch *geom = DRW_mesh_batch_cache_get_texpaint_loop_wire(me);
+ float col[4];
+ UI_GetThemeColor4fv(TH_UV_SHADOW, col);
-static void draw_uvs_texpaint(Scene *scene, Object *ob)
-{
- Mesh *me = ob->data;
- Material *ma;
+ if (!geom)
+ return;
- ma = give_current_material(ob, ob->actcol);
+ GPU_batch_program_set_builtin(geom, GPU_SHADER_2D_UNIFORM_COLOR);
+ GPU_batch_uniform_4fv(geom, "color", col);
- if (me->mloopuv) {
+ const bool do_material_masking = (ts->uv_flag & UV_SHOW_SAME_IMAGE);
+ if (do_material_masking && me->mloopuv) {
+ /* Render loops that have the active material. Minize draw calls. */
MPoly *mpoly = me->mpoly;
- MLoopUV *mloopuv, *mloopuv_base;
- int a, b;
- if (!(ma && ma->texpaintslot && ma->texpaintslot[ma->paint_active_slot].uvname &&
- (mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ma->texpaintslot[ma->paint_active_slot].uvname))))
- {
- mloopuv = me->mloopuv;
- }
-
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- immUniformThemeColor(TH_UV_SHADOW);
-
- mloopuv_base = mloopuv;
-
- for (a = me->totpoly; a > 0; a--, mpoly++) {
- if ((scene->toolsettings->uv_flag & UV_SHOW_SAME_IMAGE) && mpoly->mat_nr != ob->actcol - 1)
- continue;
-
- immBegin(GPU_PRIM_LINE_LOOP, mpoly->totloop);
-
- mloopuv = mloopuv_base + mpoly->loopstart;
- for (b = 0; b < mpoly->totloop; b++, mloopuv++) {
- immVertex2fv(pos, mloopuv->uv);
+ uint draw_start = 0;
+ uint idx = 0;
+ bool prev_ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1));
+
+ GPU_matrix_bind(geom->interface);
+
+ /* TODO(fclem): If drawcall count becomes a problem in the future
+ * we can use multi draw indirect drawcalls for this.
+ * (not implemented in GPU module at the time of writing). */
+ for (int a = 0; a < me->totpoly; a++, mpoly++) {
+ bool ma_match = (mpoly->mat_nr == (eval_ob->actcol - 1));
+ if (ma_match != prev_ma_match) {
+ if (ma_match == false) {
+ GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false);
+ }
+ else {
+ draw_start = idx;
+ }
}
-
- immEnd();
+ idx += mpoly->totloop + 1;
+ prev_ma_match = ma_match;
}
-
- immUnbindProgram();
- }
-}
-
-static uchar get_state(SpaceImage *sima, Scene *scene)
-{
- ToolSettings *ts = scene->toolsettings;
- int drawfaces = draw_uvs_face_check(scene);
- const bool draw_stretch = (sima->flag & SI_DRAW_STRETCH) != 0;
- uchar state = UVEDIT_EDGES | UVEDIT_DATA;
-
- if (drawfaces) {
- state |= UVEDIT_FACEDOTS;
- }
- if (draw_stretch || !(sima->flag & SI_NO_DRAWFACES)) {
- state |= UVEDIT_FACES;
-
- if (draw_stretch) {
- if (sima->dt_uvstretch == SI_UVDT_STRETCH_AREA) {
- state |= UVEDIT_STRETCH_AREA;
- }
- else {
- state |= UVEDIT_STRETCH_ANGLE;
- }
+ if (prev_ma_match == true) {
+ GPU_batch_draw_range_ex(geom, draw_start, idx - draw_start, false);
}
+
+ GPU_batch_program_use_end(geom);
}
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- state |= UVEDIT_SYNC_SEL;
+ else {
+ GPU_batch_draw(geom);
}
- return state;
}
/* draws uv's in the image space */
@@ -308,7 +278,7 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit, Depsgraph *
/* When sync selection is enabled, all faces are drawn (except for hidden)
* so if cage is the same as the final, there is no point in drawing this. */
if (!((ts->uv_flag & UV_SYNC_SELECTION) && is_cage_like_final_meshes)) {
- draw_uvs_shadow(eval_ob);
+ draw_uvs_shadow(sima, scene, obedit, depsgraph);
}
}
@@ -507,7 +477,7 @@ void ED_uvedit_draw_main(
if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) {
if (show_uvshadow) {
- draw_uvs_shadow(obedit);
+ draw_uvs_shadow(sima, scene, obedit, depsgraph);
}
else if (show_uvedit) {
uint objects_len = 0;
@@ -519,7 +489,7 @@ void ED_uvedit_draw_main(
MEM_freeN(objects);
}
else {
- draw_uvs_texpaint(scene, obact);
+ draw_uvs_texpaint(scene, obact, depsgraph);
}
if (show_uvedit && !(toolsettings->use_uv_sculpt))