diff options
Diffstat (limited to 'source/blender/editors/space_view3d/drawmesh.c')
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 106 |
1 files changed, 89 insertions, 17 deletions
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index bf0b7850839..348e6e526fe 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -212,12 +212,16 @@ static Material *give_current_material_or_def(Object *ob, int matnr) static struct TextureDrawState { Object *ob; + Image *stencil; + bool stencil_invert; bool use_game_mat; int is_lit, is_tex; int color_profile; bool use_backface_culling; unsigned char obcol[4]; -} Gtexdraw = {NULL, false, 0, 0, 0, false, {0, 0, 0, 0}}; + float stencil_col[4]; + bool is_texpaint; +} Gtexdraw = {NULL, NULL, false, false, 0, 0, 0, false, {0, 0, 0, 0}, {0.0f, 0.0f, 0.0f, 1.0f}, false}; static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw) { @@ -229,13 +233,15 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * static int c_lit; static int c_has_texface; - Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */ int backculled = 1; int alphablend = GPU_BLEND_SOLID; int textured = 0; int lit = 0; int has_texface = texface != NULL; bool need_set_tpage = false; + bool texpaint = ((gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) != 0); + + Image *ima = NULL; if (ma != NULL) { if (ma->mode & MA_TRANSP) { @@ -248,10 +254,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * memset(&c_texface, 0, sizeof(MTFace)); c_badtex = false; c_has_texface = -1; + c_ma = NULL; } else { textured = gtexdraw.is_tex; - litob = gtexdraw.ob; } /* convert number of lights into boolean */ @@ -266,14 +272,16 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * } } - if (texface) { + if (texface && !texpaint) { textured = textured && (texface->tpage); /* no material, render alpha if texture has depth=32 */ if (!ma && BKE_image_has_alpha(texface->tpage)) alphablend = GPU_BLEND_ALPHA; } - + else if (texpaint && ma) { + ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL; + } else textured = 0; @@ -287,11 +295,25 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * /* need to re-set tpage if textured flag changed or existsment of texface changed.. */ need_set_tpage = textured != c_textured || has_texface != c_has_texface; /* ..or if settings inside texface were changed (if texface was used) */ - need_set_tpage |= texface && memcmp(&c_texface, texface, sizeof(c_texface)); + need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface))); if (need_set_tpage) { if (textured) { - c_badtex = !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend); + if (texpaint) { + c_badtex = false; + if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) { + glEnable(GL_TEXTURE_2D); + } + else { + c_badtex = true; + GPU_clear_tpage(true); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } + } + else { + c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend); + } } else { GPU_set_tpage(NULL, 0, 0); @@ -325,6 +347,7 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material * glDisable(GL_COLOR_MATERIAL); } c_lit = lit; + c_ma = ma; } return c_badtex; @@ -335,6 +358,7 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O unsigned char obcol[4]; bool is_tex, solidtex; Mesh *me = ob->data; + ImagePaintSettings *imapaint = &scene->toolsettings->imapaint; /* XXX scene->obedit warning */ @@ -364,8 +388,34 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O else is_tex = false; Gtexdraw.ob = ob; + Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL; + Gtexdraw.stencil_invert = ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) != 0); + Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT); + copy_v3_v3(Gtexdraw.stencil_col, imapaint->stencil_col); Gtexdraw.is_tex = is_tex; + /* load the stencil texture here */ + if (Gtexdraw.is_texpaint && (Gtexdraw.stencil != NULL)) { + glActiveTexture(GL_TEXTURE1); + if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) { + glEnable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE); + glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT); + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Gtexdraw.stencil_col); + if (!Gtexdraw.stencil_invert) { + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR); + } + else { + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + } + } + glActiveTexture(GL_TEXTURE0); + } + Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene); Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0; Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0; @@ -379,8 +429,24 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O static void draw_textured_end(void) { - /* switch off textures */ - GPU_set_tpage(NULL, 0, 0); + if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) { + if (Gtexdraw.stencil != NULL) { + glActiveTexture(GL_TEXTURE1); + glDisable(GL_TEXTURE_2D); + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + } + /* manual reset, since we don't use tpage */ + glBindTexture(GL_TEXTURE_2D, 0); + /* force switch off textures */ + GPU_clear_tpage(true); + } + else { + /* switch off textures */ + GPU_set_tpage(NULL, 0, 0); + } glShadeModel(GL_FLAT); glDisable(GL_CULL_FACE); @@ -456,7 +522,7 @@ static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mc if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; - if (tface) + if (tface || Gtexdraw.is_texpaint) set_draw_settings_cached(0, tface, ma, Gtexdraw); /* always use color from mcol, as set in update_tface_color_layer */ @@ -770,7 +836,8 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d Object *ob, DerivedMesh *dm, const int draw_flags) { Mesh *me = ob->data; - + DMDrawFlag uvflag = DM_DRAW_USE_ACTIVE_UV; + /* correct for negative scale */ if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); else glFrontFace(GL_CCW); @@ -780,6 +847,10 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + if (ob->mode & OB_MODE_TEXTURE_PAINT) { + uvflag = DM_DRAW_USE_TEXPAINT_UV; + } + if (ob->mode & OB_MODE_EDIT) { drawEMTFMapped_userData data; @@ -789,7 +860,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d data.mf = DM_get_tessface_data_layer(dm, CD_MFACE); data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data); + dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0); } else if (draw_flags & DRAW_FACE_SELECT) { if (ob->mode & OB_MODE_WEIGHT_PAINT) @@ -801,15 +872,15 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE); userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); userData.me = me; - dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData); + dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag); } } else { if (GPU_buffer_legacy(dm)) { if (draw_flags & DRAW_MODIFIERS_PREVIEW) - dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL); + dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag); else - dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL); + dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag); } else { drawTFace_userData userData; @@ -820,7 +891,7 @@ static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE); userData.me = NULL; - dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData); + dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag); } } @@ -955,7 +1026,8 @@ void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, /* if not cycles, or preview-modifiers, or drawing matcaps */ if ((draw_flags & DRAW_MODIFIERS_PREVIEW) || (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) || - (BKE_scene_use_new_shading_nodes(scene) == false)) + (BKE_scene_use_new_shading_nodes(scene) == false) || + ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID))) { draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags); return; |