diff options
Diffstat (limited to 'source/blender/editors/uvedit/uvedit_draw.c')
-rw-r--r-- | source/blender/editors/uvedit/uvedit_draw.c | 828 |
1 files changed, 473 insertions, 355 deletions
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index 7b793697077..cb8aa9660cf 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -33,6 +33,8 @@ #include <stdlib.h> #include <string.h> +#include "MEM_guardedalloc.h" + #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -52,9 +54,16 @@ #include "BKE_scene.h" -#include "BIF_gl.h" #include "BIF_glutil.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "GPU_batch.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" + #include "ED_image.h" #include "ED_mesh.h" #include "ED_uvedit.h" @@ -65,12 +74,7 @@ #include "uvedit_intern.h" -#include "GPU_basic_shader.h" - -/* use editmesh tessface */ -#define USE_EDBM_LOOPTRIS - -static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset); +static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos); void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) { @@ -81,38 +85,59 @@ void ED_image_draw_cursor(ARegion *ar, const float cursor[2]) mul_v2_fl(zoom, 256.0f * UI_DPI_FAC); x_fac = zoom[0]; y_fac = zoom[1]; - - cpack(0xFFFFFF); - glTranslate2fv(cursor); - fdrawline(-0.05f * x_fac, 0, 0, 0.05f * y_fac); - fdrawline(0, 0.05f * y_fac, 0.05f * x_fac, 0.0f); - fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); - fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); - - setlinestyle(4); - cpack(0xFF); - fdrawline(-0.05f * x_fac, 0.0f, 0.0f, 0.05f * y_fac); - fdrawline(0.0f, 0.05f * y_fac, 0.05f * x_fac, 0.0f); - fdrawline(0.05f * x_fac, 0.0f, 0.0f, -0.05f * y_fac); - fdrawline(0.0f, -0.05f * y_fac, -0.05f * x_fac, 0.0f); - - - setlinestyle(0.0f); - cpack(0x0); - fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); - fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); - fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); - fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); - - setlinestyle(1); - cpack(0xFFFFFF); - fdrawline(-0.020f * x_fac, 0.0f, -0.1f * x_fac, 0.0f); - fdrawline(0.1f * x_fac, 0.0f, 0.020f * x_fac, 0.0f); - fdrawline(0.0f, -0.020f * y_fac, 0.0f, -0.1f * y_fac); - fdrawline(0.0f, 0.1f * y_fac, 0.0f, 0.020f * y_fac); - - glTranslatef(-cursor[0], -cursor[1], 0.0); - setlinestyle(0); + + gpuTranslate2fv(cursor); + + const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); + + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC); + + immUniform1i("num_colors", 2); /* "advanced" mode */ + immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, 2); + immUniform1f("dash_width", 8.0f); + + immBegin(GWN_PRIM_LINES, 8); + + immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f); + immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac); + + immVertex2f(shdr_pos, 0.0f, 0.05f * y_fac); + immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f); + + immVertex2f(shdr_pos, 0.05f * x_fac, 0.0f); + immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac); + + immVertex2f(shdr_pos, 0.0f, -0.05f * y_fac); + immVertex2f(shdr_pos, -0.05f * x_fac, 0.0f); + + immEnd(); + + immUniformArray4fv("colors", (float *)(float[][4]){{1.0f, 1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f, 1.0f}}, 2); + immUniform1f("dash_width", 2.0f); + + immBegin(GWN_PRIM_LINES, 8); + + immVertex2f(shdr_pos, -0.020f * x_fac, 0.0f); + immVertex2f(shdr_pos, -0.1f * x_fac, 0.0f); + + immVertex2f(shdr_pos, 0.1f * x_fac, 0.0f); + immVertex2f(shdr_pos, 0.020f * x_fac, 0.0f); + + immVertex2f(shdr_pos, 0.0f, -0.020f * y_fac); + immVertex2f(shdr_pos, 0.0f, -0.1f * y_fac); + + immVertex2f(shdr_pos, 0.0f, 0.1f * y_fac); + immVertex2f(shdr_pos, 0.0f, 0.020f * y_fac); + + immEnd(); + + immUnbindProgram(); + + gpuTranslate2f(-cursor[0], -cursor[1]); } static int draw_uvs_face_check(Scene *scene) @@ -136,46 +161,33 @@ static void draw_uvs_shadow(Object *obedit) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - BMFace *efa; - BMIter iter; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - /* draws the mesh when painting */ - UI_ThemeColor(TH_UV_SHADOW); + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); - } -} + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); -static int draw_uvs_dm_shadow(DerivedMesh *dm) -{ - /* draw shadow mesh - this is the mesh with the modifier applied */ + /* draws the mesh when painting */ + immUniformThemeColor(TH_UV_SHADOW); - if (dm && dm->drawUVEdges && CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) { - UI_ThemeColor(TH_UV_SHADOW); - dm->drawUVEdges(dm); - return 1; - } + draw_uvs_lineloop_bmfaces(bm, cd_loop_uv_offset, pos); - return 0; + immUnbindProgram(); } -static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTexPoly *activetf) +static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, Object *obedit, BMEditMesh *em, const BMFace *efa_act) { BMesh *bm = em->bm; BMFace *efa; BMLoop *l; BMIter iter, liter; - MTexPoly *tf; MLoopUV *luv; Image *ima = sima->image; float aspx, aspy, col[4]; int i; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); @@ -191,7 +203,6 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe const int efa_len = efa->len; float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len); float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len); - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -203,28 +214,37 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe totarea += BM_face_calc_area(efa); totuvarea += area_poly_v2(tf_uv, efa->len); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); } else { - if (tf == activetf) - activetf = NULL; + if (efa == efa_act) { + efa_act = NULL; + } BM_elem_flag_disable(efa, BM_ELEM_TAG); } } - + + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + if (totarea < FLT_EPSILON || totuvarea < FLT_EPSILON) { col[0] = 1.0; col[1] = col[2] = 0.0; - glColor3fv(col); + + immUniformColor3fv(col); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - glBegin(GL_POLYGON); + immBegin(GWN_PRIM_TRI_FAN, efa->len); + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } - glEnd(); + + immEnd(); } } } @@ -254,18 +274,23 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe areadiff = 1.0f - (area / uvarea); weight_to_rgb(col, areadiff); - glColor3fv(col); + immUniformColor3fv(col); - /* TODO: USE_EDBM_LOOPTRIS */ - glBegin(GL_POLYGON); + /* TODO: use editmesh tessface */ + immBegin(GWN_PRIM_TRI_FAN, efa->len); + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } - glEnd(); + + immEnd(); } } } + + immUnbindProgram(); + break; } case SI_UVDT_STRETCH_ANGLE: @@ -278,11 +303,15 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe BLI_buffer_declare_static(vec2f, auv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); col[3] = 0.5f; /* hard coded alpha, not that nice */ - + + Gwn_VertFormat *format = immVertexFormat(); + unsigned int pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + unsigned int color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_SMOOTH_COLOR); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - - if (uvedit_face_visible_test(scene, ima, efa, tf)) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { const int efa_len = efa->len; float (*tf_uv)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa_len); float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_reinit_data(&tf_uvorig_buf, vec2f, efa_len); @@ -319,24 +348,26 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe ang[i] = angle_normalized_v3v3(av[i], av[(i + 1) % efa_len]); } - /* TODO: USE_EDBM_LOOPTRIS */ - glBegin(GL_POLYGON); + /* TODO: use editmesh tessface */ + immBegin(GWN_PRIM_TRI_FAN, efa->len); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); a = fabsf(uvang[i] - ang[i]) / (float)M_PI; weight_to_rgb(col, 1.0f - pow2f(1.0f - a)); - glColor3fv(col); - glVertex2fv(luv->uv); + immAttrib3fv(color, col); + immVertex2fv(pos, luv->uv); } - glEnd(); + immEnd(); } else { - if (tf == activetf) - activetf = NULL; + if (efa == efa_act) + efa_act = NULL; BM_elem_flag_disable(efa, BM_ELEM_TAG); } } + immUnbindProgram(); + BLI_buffer_free(&uvang_buf); BLI_buffer_free(&ang_buf); BLI_buffer_free(&av_buf); @@ -350,58 +381,99 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe BLI_buffer_free(&tf_uvorig_buf); } -static void draw_uvs_lineloop_bmface(BMFace *efa, const int cd_loop_uv_offset) +static void draw_uvs_lineloop_bmfaces(BMesh *bm, const int cd_loop_uv_offset, const uint shdr_pos) { - BMIter liter; + BMIter iter, liter; + BMFace *efa; BMLoop *l; MLoopUV *luv; - glBegin(GL_LINE_LOOP); - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); + /* For more efficiency first transfer the entire buffer to vram. */ + Gwn_Batch *uv_batch = immBeginBatchAtMost(GWN_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. */ + GWN_batch_program_use_begin(uv_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; + + GWN_batch_draw_range_ex(uv_batch, index, efa->len, false); + index += efa->len; } - glEnd(); + GWN_batch_program_use_end(uv_batch); + + GWN_vertbuf_discard(uv_batch->verts[0]); + GWN_batch_discard(uv_batch); + + immUnbindProgram(); + + immEnd(); } -static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly) +static void draw_uvs_lineloop_mpoly(Mesh *me, MPoly *mpoly, unsigned int pos) { MLoopUV *mloopuv; int i; - glBegin(GL_LINE_LOOP); + immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop); + mloopuv = &me->mloopuv[mpoly->loopstart]; for (i = mpoly->totloop; i != 0; i--, mloopuv++) { - glVertex2fv(mloopuv->uv); + immVertex2fv(pos, mloopuv->uv); } - glEnd(); + + immEnd(); } -static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter) +static void draw_uvs_other_mesh_texface(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) { Mesh *me = ob->data; MPoly *mpoly = me->mpoly; - MTexPoly *mtpoly = me->mtpoly; int a; if (me->mloopuv == NULL) { return; } - for (a = me->totpoly; a != 0; a--, mpoly++, mtpoly++) { + Image **image_array = NULL; + + if (other_uv_filter == SI_FILTER_SAME_IMAGE) { + image_array = BKE_object_material_edit_image_get_array(ob); + } + + for (a = me->totpoly; a != 0; a--, mpoly++) { if (other_uv_filter == SI_FILTER_ALL) { /* Nothing to compare, all UV faces are visible. */ } else if (other_uv_filter == SI_FILTER_SAME_IMAGE) { - if (mtpoly->tpage != curimage) { + if (mpoly[a].mat_nr >= ob->totcol) { + continue; + } + if (image_array[mpoly[a].mat_nr] != curimage) { continue; } } - draw_uvs_lineloop_mpoly(me, mpoly); + draw_uvs_lineloop_mpoly(me, mpoly, pos); + } + + if (image_array) { + MEM_freeN(image_array); } } -static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter) +static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, const int other_uv_filter, unsigned int pos) { Mesh *me = ob->data; MPoly *mpoly = me->mpoly; @@ -453,41 +525,43 @@ static void draw_uvs_other_mesh_new_shading(Object *ob, const Image *curimage, c } } - draw_uvs_lineloop_mpoly(me, mpoly); + draw_uvs_lineloop_mpoly(me, mpoly, pos); } } static void draw_uvs_other_mesh(Object *ob, const Image *curimage, const bool new_shading_nodes, - const int other_uv_filter) + const int other_uv_filter, unsigned int pos) { if (new_shading_nodes) { - draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter); + draw_uvs_other_mesh_new_shading(ob, curimage, other_uv_filter, pos); } else { - draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter); + draw_uvs_other_mesh_texface(ob, curimage, other_uv_filter, pos); } } -static void draw_uvs_other(Scene *scene, Object *obedit, const Image *curimage, const bool new_shading_nodes, +static void draw_uvs_other(ViewLayer *view_layer, Object *obedit, const Image *curimage, const bool new_shading_nodes, const int other_uv_filter) { - Base *base; - - UI_ThemeColor(TH_UV_OTHERS); + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); - for (base = scene->base.first; base; base = base->next) { - Object *ob = base->object; + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); - if (!(base->flag & SELECT)) continue; - if (!(base->lay & scene->lay)) continue; - if (ob->restrictflag & OB_RESTRICT_VIEW) continue; + immUniformThemeColor(TH_UV_OTHERS); - if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) { - draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter); + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (((base->flag & BASE_SELECTED) != 0) && + ((base->flag & BASE_VISIBLED) != 0)) + { + Object *ob = base->object; + if ((ob->type == OB_MESH) && (ob != obedit) && ((Mesh *)ob->data)->mloopuv) { + draw_uvs_other_mesh(ob, curimage, new_shading_nodes, other_uv_filter, pos); + } } } + immUnbindProgram(); } -static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) +static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *ob) { const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); Image *curimage = ED_space_image(sima); @@ -495,11 +569,9 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) Material *ma; if (sima->flag & SI_DRAW_OTHER) { - draw_uvs_other(scene, ob, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, ob, curimage, new_shading_nodes, sima->other_uv_filter); } - UI_ThemeColor(TH_UV_SHADOW); - ma = give_current_material(ob, ob->actcol); if (me->mloopuv) { @@ -512,24 +584,33 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob) mloopuv = me->mloopuv; } + unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_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; - glBegin(GL_LINE_LOOP); + + immBegin(GWN_PRIM_LINE_LOOP, mpoly->totloop); mloopuv = mloopuv_base + mpoly->loopstart; for (b = 0; b < mpoly->totloop; b++, mloopuv++) { - glVertex2fv(mloopuv->uv); + immVertex2fv(pos, mloopuv->uv); } - glEnd(); + + immEnd(); } + + immUnbindProgram(); } } -#ifdef USE_EDBM_LOOPTRIS -static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset) +static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const int cd_loop_uv_offset, unsigned int pos) { unsigned int i = *r_loop_index; BMFace *f = em->looptris[i][0]->f; @@ -537,16 +618,15 @@ static void draw_uvs_looptri(BMEditMesh *em, unsigned int *r_loop_index, const i unsigned int j; for (j = 0; j < 3; j++) { MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(em->looptris[i][j], cd_loop_uv_offset); - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } i++; } while (i != em->tottri && (f == em->looptris[i][0]->f)); *r_loop_index = i - 1; } -#endif /* draws uv's in the image space */ -static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) +static void draw_uvs(SpaceImage *sima, Scene *scene, ViewLayer *view_layer, Object *obedit, Depsgraph *depsgraph) { const bool new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); ToolSettings *ts; @@ -554,26 +634,19 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; BMFace *efa, *efa_act; -#ifndef USE_EDBM_LOOPTRIS - BMFace *activef; -#endif BMLoop *l; BMIter iter, liter; - MTexPoly *tf, *activetf = NULL; MLoopUV *luv; - DerivedMesh *finaldm, *cagedm; - unsigned char col1[4], col2[4]; + float col1[4], col2[4]; float pointsize; int drawfaces, interpedges; Image *ima = sima->image; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY); - efa_act = EDBM_uv_active_face_get(em, false, false, &activetf); /* will be set to NULL if hidden */ -#ifndef USE_EDBM_LOOPTRIS - activef = BM_mesh_active_face_get(bm, false, false); -#endif + unsigned int pos, color; + + efa_act = EDBM_uv_active_face_get(em, false, false); /* will be set to NULL if hidden */ ts = scene->toolsettings; drawfaces = draw_uvs_face_check(scene); @@ -595,263 +668,267 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) } } else { - curimage = (activetf) ? activetf->tpage : ima; + curimage = (efa_act) ? BKE_object_material_edit_image_get(obedit, efa_act->mat_nr) : ima; } - draw_uvs_other(scene, obedit, curimage, new_shading_nodes, sima->other_uv_filter); + draw_uvs_other(view_layer, obedit, curimage, new_shading_nodes, sima->other_uv_filter); } /* 1. draw shadow mesh */ if (sima->flag & SI_DRAWSHADOW) { - DM_update_materials(em->derivedFinal, obedit); - /* first try existing derivedmesh */ - if (!draw_uvs_dm_shadow(em->derivedFinal)) { - /* create one if it does not exist */ - cagedm = editbmesh_get_derived_cage_and_final( - scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH | CD_MASK_MTFACE, - &finaldm); - - /* when sync selection is enabled, all faces are drawn (except for hidden) - * so if cage is the same as the final, theres no point in drawing this */ - if (!((ts->uv_flag & UV_SYNC_SELECTION) && (cagedm == finaldm))) - draw_uvs_dm_shadow(finaldm); - - /* release derivedmesh again */ - if (cagedm != finaldm) cagedm->release(cagedm); - finaldm->release(finaldm); + Object *ob_cage = DEG_get_evaluated_object(depsgraph, obedit); + /* XXX TODO: Need to check if shadow mesh is different than original mesh. */ + bool is_cage_like_final_meshes = (ob_cage == obedit); + + /* 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) == 0) || is_cage_like_final_meshes) { + draw_uvs_shadow(ob_cage); } } - + /* 2. draw colored faces */ if (sima->flag & SI_DRAW_STRETCH) { - draw_uvs_stretch(sima, scene, em, activetf); + draw_uvs_stretch(sima, scene, obedit, em, efa_act); } - else if (!(sima->flag & SI_NO_DRAWFACES)) { - /* draw transparent faces */ - UI_GetThemeColor4ubv(TH_FACE, col1); - UI_GetThemeColor4ubv(TH_FACE_SELECT, col2); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - -#ifdef USE_EDBM_LOOPTRIS - { - unsigned int i; - for (i = 0; i < em->tottri; i++) { + else { + unsigned int tri_count = 0; + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + if (uvedit_face_visible_test(scene, obedit, ima, efa)) { + BM_elem_flag_enable(efa, BM_ELEM_TAG); + tri_count += efa->len - 2; + } + else { + BM_elem_flag_disable(efa, BM_ELEM_TAG); + } + } + + if (tri_count && !(sima->flag & SI_NO_DRAWFACES)) { + /* draw transparent faces */ + UI_GetThemeColor4fv(TH_FACE, col1); + UI_GetThemeColor4fv(TH_FACE_SELECT, col2); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + Gwn_VertFormat *format = immVertexFormat(); + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + + immBegin(GWN_PRIM_TRIS, tri_count * 3); + for (unsigned int i = 0; i < em->tottri; i++) { efa = em->looptris[i][0]->f; - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { + if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { const bool is_select = uvedit_face_select_test(scene, efa, cd_loop_uv_offset); - BM_elem_flag_enable(efa, BM_ELEM_TAG); - if (tf == activetf) { + if (efa == efa_act) { /* only once */ - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - UI_ThemeColor4(TH_EDITMESH_ACTIVE); + float tmp_col[4]; + UI_GetThemeColor4fv(TH_EDITMESH_ACTIVE, tmp_col); + immAttrib4fv(color, tmp_col); } else { - glColor4ubv((GLubyte *)(is_select ? col2 : col1)); + immAttrib4fv(color, is_select ? col2 : col1); } - glBegin(GL_TRIANGLES); - draw_uvs_looptri(em, &i, cd_loop_uv_offset); - glEnd(); - - if (tf == activetf) { - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - } - } - else { - BM_elem_flag_disable(efa, BM_ELEM_TAG); + draw_uvs_looptri(em, &i, cd_loop_uv_offset, pos); } } - } -#else - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { - BM_elem_flag_enable(efa, BM_ELEM_TAG); - if (tf == activetf) continue; /* important the temp boolean is set above */ + immEnd(); - if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) - glColor4ubv((GLubyte *)col2); - else - glColor4ubv((GLubyte *)col1); - - glBegin(GL_POLYGON); - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); - } - glEnd(); - } - else { - if (tf == activetf) - activetf = NULL; - BM_elem_flag_disable(efa, BM_ELEM_TAG); - } - } -#endif - glDisable(GL_BLEND); - } - else { - /* would be nice to do this within a draw loop but most below are optional, so it would involve too many checks */ - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); + immUnbindProgram(); - if (uvedit_face_visible_test(scene, ima, efa, tf)) { - BM_elem_flag_enable(efa, BM_ELEM_TAG); - } - else { - if (tf == activetf) - activetf = NULL; - BM_elem_flag_disable(efa, BM_ELEM_TAG); + glDisable(GL_BLEND); + } + else { + if (efa_act && !uvedit_face_visible_test(scene, obedit, ima, efa_act)) { + efa_act = NULL; } } - } /* 3. draw active face stippled */ -#ifndef USE_EDBM_LOOPTRIS - if (activef) { - tf = BM_ELEM_CD_GET_VOID_P(activef, cd_poly_tex_offset); - if (uvedit_face_visible_test(scene, ima, activef, tf)) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - UI_ThemeColor4(TH_EDITMESH_ACTIVE); - - GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR); - GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE); - - glBegin(GL_POLYGON); - BM_ITER_ELEM (l, &liter, activef, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); - } - glEnd(); + /* (removed during OpenGL upgrade, reimplement if needed) */ - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - glDisable(GL_BLEND); - } - } -#endif - /* 4. draw edges */ if (sima->flag & SI_SMOOTH_UV) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } - glLineWidth(1); + pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); switch (sima->dt_uv) { case SI_UVDT_DASH: - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; - tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset); - - if (tf) { - cpack(0x111111); - - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); + { + immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR); - setlinestyle(2); - cpack(0x909090); + float viewport_size[4]; + glGetFloatv(GL_VIEWPORT, viewport_size); + immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC); - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); + immUniform1i("num_colors", 2); /* "advanced" mode */ + immUniformArray4fv("colors", (float *)(float[][4]){{0.56f, 0.56f, 0.56f, 1.0f}, {0.07f, 0.07f, 0.07f, 1.0f}}, 2); + immUniform1f("dash_width", 4.0f); + glLineWidth(1.0f); - setlinestyle(0); - } - } break; + } case SI_UVDT_BLACK: /* black/white */ - case SI_UVDT_WHITE: - if (sima->dt_uv == SI_UVDT_WHITE) glColor3f(1.0f, 1.0f, 1.0f); - else glColor3f(0.0f, 0.0f, 0.0f); - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; - - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); + case SI_UVDT_WHITE: + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + if (sima->dt_uv == SI_UVDT_WHITE) { + immUniformColor3f(1.0f, 1.0f, 1.0f); + } + else { + immUniformColor3f(0.0f, 0.0f, 0.0f); } + glLineWidth(1.0f); + break; case SI_UVDT_OUTLINE: - glLineWidth(3); - cpack(0x0); - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + imm_cpack(0x0); + glLineWidth(3.0f); - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); - } - - glLineWidth(1); - UI_GetThemeColor4ubv(TH_WIRE_EDIT, col2); - glColor4ubv((unsigned char *)col2); + break; + } - if (me->drawflag & ME_DRAWEDGES) { - int sel, lastsel = -1; - UI_GetThemeColor4ubv(TH_EDGE_SELECT, col1); + /* For more efficiency first transfer the entire buffer to vram. */ + Gwn_Batch *uv_batch = immBeginBatchAtMost(GWN_PRIM_LINE_LOOP, bm->totloop); + Gwn_VertBuf* uv_vbo = uv_batch->verts[0]; + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; - if (interpedges) { - GPU_basic_shader_bind(GPU_SHADER_USE_COLOR); - 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(pos, luv->uv); + } + } + immEnd(); - glBegin(GL_LINE_LOOP); - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); - glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); + /* Then draw each face contour separately. */ + GWN_batch_program_use_begin(uv_batch); + unsigned int index = 0, vbo_len_used; + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); - } - glEnd(); - } + GWN_batch_draw_range_ex(uv_batch, index, efa->len, false); + index += efa->len; + } + vbo_len_used = index; + GWN_batch_program_use_end(uv_batch); + immUnbindProgram(); + + + if (sima->dt_uv == SI_UVDT_OUTLINE) { + glLineWidth(1.0f); + UI_GetThemeColor4fv(TH_WIRE_EDIT, col2); + + if (me->drawflag & ME_DRAWEDGES) { + int sel; + UI_GetThemeColor4fv(TH_EDGE_SELECT, col1); + + if (interpedges) { + /* Create a color buffer. */ + static Gwn_VertFormat format = {0}; + static uint shdr_col; + if (format.attrib_ct == 0) { + shdr_col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); } - else { - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) - continue; - glBegin(GL_LINES); - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - sel = uvedit_edge_select_test(scene, l, cd_loop_uv_offset); - if (sel != lastsel) { - glColor4ubv(sel ? (GLubyte *)col1 : (GLubyte *)col2); - lastsel = sel; - } - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - glVertex2fv(luv->uv); - luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - glVertex2fv(luv->uv); - } - glEnd(); + Gwn_VertBuf *vbo_col = GWN_vertbuf_create_with_format(&format); + GWN_vertbuf_data_alloc(vbo_col, vbo_len_used); + + index = 0; + 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) { + sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + GWN_vertbuf_attr_set(vbo_col, shdr_col, index++, sel ? col1 : col2); } } + /* Reuse the UV buffer and add the color buffer. */ + GWN_batch_vertbuf_add_ex(uv_batch, vbo_col, true); + + /* Now draw each face contour separately with another builtin program. */ + GWN_batch_program_set_builtin(uv_batch, GPU_SHADER_2D_SMOOTH_COLOR); + gpuBindMatrices(uv_batch->interface); + + GWN_batch_program_use_begin(uv_batch); + index = 0; + BM_ITER_MESH(efa, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; + + GWN_batch_draw_range_ex(uv_batch, index, efa->len, false); + index += efa->len; + } + GWN_batch_program_use_end(uv_batch); } else { - /* no nice edges */ + Gwn_VertFormat *format = immVertexFormat(); + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + + /* Use batch here to avoid problems with `IMM_BUFFER_SIZE`. */ + Gwn_Batch *flat_edges_batch = immBeginBatchAtMost(GWN_PRIM_LINES, vbo_len_used * 2); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; - - draw_uvs_lineloop_bmface(efa, cd_loop_uv_offset); + + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + sel = uvedit_edge_select_test(scene, l, cd_loop_uv_offset); + immAttrib4fv(color, sel ? col1 : col2); + + luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + immVertex2fv(pos, luv->uv); + luv = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); + immVertex2fv(pos, luv->uv); + } } + immEnd(); + + GWN_batch_draw(flat_edges_batch); + GWN_vertbuf_discard(flat_edges_batch->verts[0]); + GWN_batch_discard(flat_edges_batch); + + immUnbindProgram(); } - - break; + } + else { + GWN_batch_uniform_4fv(uv_batch, "color", col2); + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + + /* no nice edges */ + GWN_batch_program_use_begin(uv_batch); + index = 0; + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) + continue; + + GWN_batch_draw_range_ex(uv_batch, index, efa->len, false); + index += efa->len; + } + GWN_batch_program_use_end(uv_batch); + immUnbindProgram(); + } } + GWN_vertbuf_discard(uv_vbo); + GWN_batch_discard(uv_batch); + if (sima->flag & SI_SMOOTH_UV) { glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); @@ -861,50 +938,80 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) if (drawfaces) { float cent[2]; - + bool col_set = false; + + Gwn_VertFormat *format = immVertexFormat(); + pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR); + pointsize = UI_GetThemeValuef(TH_FACEDOT_SIZE); glPointSize(pointsize); - glBegin(GL_POINTS); + immBeginAtMost(GWN_PRIM_POINTS, bm->totface); /* unselected faces */ - UI_ThemeColor(TH_WIRE); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + /* Only set color for the first face */ + if (!col_set) { + UI_GetThemeColor3fv(TH_WIRE, col1); + immAttrib3fv(color, col1); + + col_set = true; + } + uv_poly_center(efa, cent, cd_loop_uv_offset); - glVertex2fv(cent); + immVertex2fv(pos, cent); } } + col_set = false; + /* selected faces */ - UI_ThemeColor(TH_FACE_DOT); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + /* Only set color for the first face */ + if (!col_set) { + UI_GetThemeColor3fv(TH_FACE_DOT, col1); + immAttrib3fv(color, col1); + + col_set = true; + } + uv_poly_center(efa, cent, cd_loop_uv_offset); - glVertex2fv(cent); + immVertex2fv(pos, cent); } } - glEnd(); + immEnd(); + + immUnbindProgram(); } /* 6. draw uv vertices */ if (drawfaces != 2) { /* 2 means Mesh Face Mode */ + pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); + /* unselected uvs */ - UI_ThemeColor(TH_VERTEX); + immUniformThemeColor(TH_VERTEX); pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); glPointSize(pointsize); - - glBegin(GL_POINTS); + + immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; @@ -912,17 +1019,19 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } } - glEnd(); + + immEnd(); /* pinned uvs */ /* give odd pointsizes odd pin pointsizes */ glPointSize(pointsize * 2 + (((int)pointsize % 2) ? (-1) : 0)); - cpack(0xFF); + imm_cpack(0xFF); - glBegin(GL_POINTS); + immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; @@ -931,16 +1040,18 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (luv->flag & MLOOPUV_PINNED) - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } } - glEnd(); + + immEnd(); /* selected uvs */ - UI_ThemeColor(TH_VERTEX_SELECT); + immUniformThemeColor(TH_VERTEX_SELECT); glPointSize(pointsize); - glBegin(GL_POINTS); + immBeginAtMost(GWN_PRIM_POINTS, bm->totloop); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_TAG)) continue; @@ -949,15 +1060,20 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) - glVertex2fv(luv->uv); + immVertex2fv(pos, luv->uv); } } - glEnd(); + + immEnd(); + + immUnbindProgram(); } } -static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint) +static void draw_uv_shadows_get( + SpaceImage *sima, const EvaluationContext *eval_ctx, Object *ob, Object *obedit, + bool *show_shadow, bool *show_texpaint) { *show_shadow = *show_texpaint = false; @@ -970,24 +1086,26 @@ static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bo *show_shadow = EDBM_uv_check(em); } - *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT); + *show_texpaint = (ob && ob->type == OB_MESH && eval_ctx->object_mode == OB_MODE_TEXTURE_PAINT); } -void ED_uvedit_draw_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact) +void ED_uvedit_draw_main( + SpaceImage *sima, const EvaluationContext *eval_ctx, + ARegion *ar, Scene *scene, ViewLayer *view_layer, Object *obedit, Object *obact, Depsgraph *depsgraph) { ToolSettings *toolsettings = scene->toolsettings; bool show_uvedit, show_uvshadow, show_texpaint_uvshadow; show_uvedit = ED_space_image_show_uvedit(sima, obedit); - draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow); + draw_uv_shadows_get(sima, eval_ctx, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow); if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) { if (show_uvshadow) draw_uvs_shadow(obedit); else if (show_uvedit) - draw_uvs(sima, scene, obedit); + draw_uvs(sima, scene, view_layer, obedit, depsgraph); else - draw_uvs_texpaint(sima, scene, obact); + draw_uvs_texpaint(sima, scene, view_layer, obact); if (show_uvedit && !(toolsettings->use_uv_sculpt)) ED_image_draw_cursor(ar, sima->cursor); |