2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, full update, glsl support
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/space_view3d/drawmesh.c
33 #include "MEM_guardedalloc.h"
35 #include "BLI_utildefines.h"
36 #include "BLI_blenlib.h"
38 #include "BLI_edgehash.h"
39 #include "BLI_utildefines.h"
41 #include "DNA_material_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_node_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_property_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_view3d_types.h"
50 #include "DNA_windowmanager_types.h"
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_effect.h"
54 #include "BKE_image.h"
55 #include "BKE_material.h"
56 #include "BKE_paint.h"
57 #include "BKE_property.h"
58 #include "BKE_tessmesh.h"
59 #include "BKE_scene.h"
62 #include "BIF_glutil.h"
64 #include "UI_resources.h"
66 #include "GPU_buffers.h"
67 #include "GPU_extensions.h"
69 #include "GPU_material.h"
72 #include "ED_uvedit.h"
74 #include "view3d_intern.h" /* own include */
76 /* user data structures for derived mesh callbacks */
77 typedef struct drawMeshFaceSelect_userData {
80 } drawMeshFaceSelect_userData;
82 typedef struct drawEMTFMapped_userData {
88 } drawEMTFMapped_userData;
90 typedef struct drawTFace_userData {
95 /**************************** Face Select Mode *******************************/
97 /* Flags for marked edges */
99 eEdge_Visible = (1 << 0),
100 eEdge_Select = (1 << 1),
103 /* Creates a hash of edges to flags indicating selected/visible */
104 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
108 if (!BLI_edgehash_haskey(eh, v0, v1))
109 BLI_edgehash_insert(eh, v0, v1, NULL);
111 flags_p = (int *) BLI_edgehash_lookup_p(eh, v0, v1);
115 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
117 EdgeHash *eh = BLI_edgehash_new();
123 for (i = 0; i < me->totpoly; i++) {
126 if (!(mp->flag & ME_HIDE)) {
127 unsigned int flags = eEdge_Visible;
128 if (mp->flag & ME_FACE_SEL) flags |= eEdge_Select;
130 ml = me->mloop + mp->loopstart;
131 for (j = 0; j < mp->totloop; j++, ml++) {
132 ml_next = ME_POLY_LOOP_NEXT(me->mloop, mp, j);
133 get_marked_edge_info__orFlags(eh, ml->v, ml_next->v, flags);
142 static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int index)
144 drawMeshFaceSelect_userData *data = userData;
146 MEdge *med = &me->medge[index];
147 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
149 if (me->drawflag & ME_DRAWEDGES) {
150 if ((me->drawflag & ME_HIDDENEDGES) || (flags & eEdge_Visible))
151 return DM_DRAW_OPTION_NORMAL;
153 return DM_DRAW_OPTION_SKIP;
155 else if (flags & eEdge_Select)
156 return DM_DRAW_OPTION_NORMAL;
158 return DM_DRAW_OPTION_SKIP;
161 static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index)
163 drawMeshFaceSelect_userData *data = userData;
164 MEdge *med = &data->me->medge[index];
165 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
167 return (flags & eEdge_Select) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
170 /* draws unselected */
171 static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
173 Mesh *me = (Mesh *)userData;
175 MPoly *mpoly = &me->mpoly[index];
176 if (!(mpoly->flag & ME_HIDE) && !(mpoly->flag & ME_FACE_SEL))
177 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
179 return DM_DRAW_OPTION_SKIP;
182 void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
184 drawMeshFaceSelect_userData data;
187 data.eh = get_tface_mesh_marked_edge_info(me);
189 glEnable(GL_DEPTH_TEST);
190 glDisable(GL_LIGHTING);
191 bglPolygonOffset(rv3d->dist, 1.0);
193 /* Draw (Hidden) Edges */
195 UI_ThemeColor(TH_EDGE_FACESEL);
196 dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
199 /* Draw Selected Faces */
200 if (me->drawflag & ME_DRAWFACES) {
202 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
203 /* dull unselected faces so as not to get in the way of seeing color */
204 glColor4ub(96, 96, 96, 64);
205 dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, 0);
209 bglPolygonOffset(rv3d->dist, 1.0);
211 /* Draw Stippled Outline for selected faces */
212 glColor3ub(255, 255, 255);
214 dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
217 bglPolygonOffset(rv3d->dist, 0.0); /* resets correctly now, even after calling accumulated offsets */
219 BLI_edgehash_free(data.eh, NULL);
222 /***************************** Texture Drawing ******************************/
224 static Material *give_current_material_or_def(Object *ob, int matnr)
226 extern Material defmaterial; /* render module abuse... */
227 Material *ma = give_current_material(ob, matnr);
229 return ma ? ma : &defmaterial;
232 /* Icky globals, fix with userdata parameter */
234 static struct TextureDrawState {
238 unsigned char obcol[4];
239 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
241 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
243 static Material *c_ma;
244 static int c_textured;
245 static MTFace c_texface;
246 static int c_backculled;
249 static int c_has_texface;
251 Object *litob = NULL; /* to get mode to turn off mipmap in painting mode */
252 int backculled = GEMAT_BACKCULL;
256 int has_texface = texface != NULL;
257 int need_set_tpage = FALSE;
260 c_textured = c_lit = c_backculled = -1;
261 memset(&c_texface, 0, sizeof(MTFace));
266 textured = gtexdraw.is_tex;
270 /* convert number of lights into boolean */
271 if (gtexdraw.is_lit) lit = 1;
274 alphablend = ma->game.alpha_blend;
275 if (ma->mode & MA_SHLESS) lit = 0;
276 backculled = ma->game.flag & GEMAT_BACKCULL;
280 textured = textured && (texface->tpage);
282 /* no material, render alpha if texture has depth=32 */
283 if (!ma && BKE_image_has_alpha(texface->tpage))
284 alphablend = GPU_BLEND_ALPHA;
290 if (backculled != c_backculled) {
291 if (backculled) glEnable(GL_CULL_FACE);
292 else glDisable(GL_CULL_FACE);
294 c_backculled = backculled;
297 /* need to re-set tpage if textured flag changed or existsment of texface changed.. */
298 need_set_tpage = textured != c_textured || has_texface != c_has_texface;
299 /* ..or if settings inside texface were changed (if texface was used) */
300 need_set_tpage |= texface && memcmp(&c_texface, texface, sizeof(c_texface));
302 if (need_set_tpage) {
304 c_badtex = !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
307 GPU_set_tpage(NULL, 0, 0);
310 c_textured = textured;
311 c_has_texface = has_texface;
313 memcpy(&c_texface, texface, sizeof(c_texface));
316 if (c_badtex) lit = 0;
317 if (lit != c_lit || ma != c_ma) {
320 if (!ma) ma = give_current_material_or_def(NULL, 0); /* default material */
322 spec[0] = ma->spec * ma->specr;
323 spec[1] = ma->spec * ma->specg;
324 spec[2] = ma->spec * ma->specb;
327 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
328 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
329 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
330 glEnable(GL_LIGHTING);
331 glEnable(GL_COLOR_MATERIAL);
334 glDisable(GL_LIGHTING);
335 glDisable(GL_COLOR_MATERIAL);
343 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
345 unsigned char obcol[4];
346 int is_tex, solidtex;
349 /* XXX scene->obedit warning */
351 /* texture draw is abused for mask selection mode, do this so wire draw
352 * with face selection in weight paint is not lit. */
353 if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
357 else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE)) {
358 /* draw with default lights in solid draw mode and edit mode */
360 Gtexdraw.is_lit = -1;
363 /* draw with lights in the scene otherwise */
365 Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
368 rgba_float_to_uchar(obcol, ob->col);
370 if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = 1;
374 Gtexdraw.is_tex = is_tex;
375 Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
376 memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
377 set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
378 glShadeModel(GL_SMOOTH);
379 if (v3d->flag2 & V3D_BACKFACE_CULLING) {
380 glEnable(GL_CULL_FACE);
384 glDisable(GL_CULL_FACE);
386 glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
389 static void draw_textured_end(void)
391 /* switch off textures */
392 GPU_set_tpage(NULL, 0, 0);
394 glShadeModel(GL_FLAT);
395 glDisable(GL_CULL_FACE);
397 /* XXX, bad patch - GPU_default_lights() calls
398 * glLightfv(GL_POSITION, ...) which
399 * is transformed by the current matrix... we
400 * need to make sure that matrix is identity.
402 * It would be better if drawmesh.c kept track
403 * of and restored the light settings it changed.
408 GPU_default_lights();
412 static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
414 Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
415 int validtexture = 0;
417 if (ma && (ma->game.flag & GEMAT_INVISIBLE))
418 return DM_DRAW_OPTION_SKIP;
420 validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
422 if (tface && validtexture) {
423 glColor3ub(0xFF, 0x00, 0xFF);
424 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
426 else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
427 glColor3ubv(Gtexdraw.obcol);
428 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
430 else if (!has_mcol) {
431 if (tface) glColor3f(1.0, 1.0, 1.0);
435 if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
436 else copy_v3_v3(col, &ma->r);
440 else glColor3f(1.0, 1.0, 1.0);
442 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
445 return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
449 static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
452 return DM_DRAW_OPTION_NORMAL;
454 return DM_DRAW_OPTION_NO_MCOL;
457 static DMDrawOption draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
459 Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
461 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
463 if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
464 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
466 else if (tface && (tface->mode & TF_OBCOL)) {
467 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
469 else if (!has_mcol) {
470 /* XXX: this return value looks wrong (and doesn't match comment) */
471 return DM_DRAW_OPTION_NORMAL; /* Don't set color */
474 return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
478 static void update_tface_color_layer(DerivedMesh *dm)
480 MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE);
481 MFace *mface = dm->getTessFaceArray(dm);
484 MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
486 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
488 if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
489 finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
492 finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer");
494 CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData);
497 for (i = 0; i < dm->getNumTessFaces(dm); i++) {
498 Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
500 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
502 memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
504 for (j = 0; j < 4; j++) {
505 finalCol[i * 4 + j].b = 255;
506 finalCol[i * 4 + j].g = 255;
507 finalCol[i * 4 + j].r = 255;
510 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
511 for (j = 0; j < 4; j++) {
512 finalCol[i * 4 + j].b = 255;
513 finalCol[i * 4 + j].g = 0;
514 finalCol[i * 4 + j].r = 255;
517 else if (tface && (tface->mode & TF_OBCOL)) {
518 for (j = 0; j < 4; j++) {
519 finalCol[i * 4 + j].b = FTOCHAR(Gtexdraw.obcol[0]);
520 finalCol[i * 4 + j].g = FTOCHAR(Gtexdraw.obcol[1]);
521 finalCol[i * 4 + j].r = FTOCHAR(Gtexdraw.obcol[2]);
526 for (j = 0; j < 4; j++) {
527 finalCol[i * 4 + j].b = 255;
528 finalCol[i * 4 + j].g = 255;
529 finalCol[i * 4 + j].r = 255;
534 Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
537 if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
538 else copy_v3_v3(col, &ma->r);
540 for (j = 0; j < 4; j++) {
541 finalCol[i * 4 + j].b = FTOCHAR(col[0]);
542 finalCol[i * 4 + j].g = FTOCHAR(col[1]);
543 finalCol[i * 4 + j].r = FTOCHAR(col[2]);
547 for (j = 0; j < 4; j++) {
548 finalCol[i * 4 + j].b = 255;
549 finalCol[i * 4 + j].g = 255;
550 finalCol[i * 4 + j].r = 255;
555 for (j = 0; j < 4; j++) {
556 finalCol[i * 4 + j].r = mcol[i * 4 + j].r;
557 finalCol[i * 4 + j].g = mcol[i * 4 + j].g;
558 finalCol[i * 4 + j].b = mcol[i * 4 + j].b;
564 static DMDrawOption draw_tface_mapped__set_draw(void *userData, int index)
566 Mesh *me = (Mesh *)userData;
568 /* array checked for NULL before calling */
569 MPoly *mpoly = &me->mpoly[index];
571 BLI_assert(index >= 0 && index < me->totpoly);
573 if (mpoly->flag & ME_HIDE) {
574 return DM_DRAW_OPTION_SKIP;
577 MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[index] : NULL;
578 MTFace mtf = {{{0}}};
579 int matnr = mpoly->mat_nr;
582 ME_MTEXFACE_CPY(&mtf, tpoly);
585 return draw_tface__set_draw(&mtf, (me->mloopcol != NULL), matnr);
589 static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index)
591 drawEMTFMapped_userData *data = userData;
592 BMEditMesh *em = data->em;
593 BMFace *efa = EDBM_face_at_index(em, index);
595 if (efa == NULL || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
596 return DM_DRAW_OPTION_SKIP;
599 MTFace mtf = {{{0}}};
600 int matnr = efa->mat_nr;
602 if (data->has_mtface) {
603 MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
604 ME_MTEXFACE_CPY(&mtf, tpoly);
607 return draw_tface__set_draw_legacy(data->has_mtface ? &mtf : NULL,
608 data->has_mcol, matnr);
612 /* when face select is on, use face hidden flag */
613 static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
615 Mesh *me = (Mesh *)userData;
616 MPoly *mp = &me->mpoly[index];
617 if (mp->flag & ME_HIDE)
618 return DM_DRAW_OPTION_SKIP;
619 return DM_DRAW_OPTION_NORMAL;
622 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
626 MPoly *mp, *mface = me->mpoly;
627 MTexPoly *mtpoly = me->mtpoly;
628 MLoopUV *mloopuv = me->mloopuv;
630 MLoopCol *mloopcol = me->mloopcol; /* why does mcol exist? */
633 bProperty *prop = get_ob_property(ob, "Text");
634 GPUVertexAttribs gattribs;
635 int a, totpoly = me->totpoly;
637 /* fake values to pass to GPU_render_text() */
638 MCol tmp_mcol[4] = {{0}};
639 MCol *tmp_mcol_pt = mloopcol ? tmp_mcol : NULL;
640 MTFace tmp_tf = {{{0}}};
642 /* don't draw without tfaces */
643 if (!mtpoly || !mloopuv)
646 /* don't draw when editing */
647 if (ob->mode & OB_MODE_EDIT)
649 else if (ob == OBACT)
650 if (paint_facesel_test(ob) || paint_vertsel_test(ob))
653 ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
655 for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
656 short matnr = mp->mat_nr;
657 int mf_smooth = mp->flag & ME_SMOOTH;
658 Material *mat = me->mat[matnr];
659 int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
661 if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
662 /* get the polygon as a tri/quad */
664 float v1[3], v2[3], v3[3], v4[3];
665 char string[MAX_PROPSTRING];
666 int characters, i, glattrib = -1, badtex = 0;
670 ME_MTEXFACE_CPY(&tmp_tf, mtpoly);
673 GPU_enable_material(matnr + 1, &gattribs);
675 for (i = 0; i < gattribs.totlayer; i++) {
676 if (gattribs.layer[i].type == CD_MTFACE) {
677 glattrib = gattribs.layer[i].glindex;
683 badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw);
689 mp_vi[0] = me->mloop[mp->loopstart + 0].v;
690 mp_vi[1] = me->mloop[mp->loopstart + 1].v;
691 mp_vi[2] = me->mloop[mp->loopstart + 2].v;
692 mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;
695 luv = &mloopuv[mp->loopstart];
696 copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++;
697 copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++;
698 copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++;
699 if (mp->totloop >= 4) {
700 copy_v2_v2(tmp_tf.uv[3], luv->uv);
705 unsigned int totloop_clamp = MIN2(4, mp->totloop);
707 lcol = &mloopcol[mp->loopstart];
709 for (j = 0; j <= totloop_clamp; j++, lcol++) {
710 MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
715 ddm->getVertCo(ddm, mp_vi[0], v1);
716 ddm->getVertCo(ddm, mp_vi[1], v2);
717 ddm->getVertCo(ddm, mp_vi[2], v3);
718 if (mp->totloop >= 4) {
719 ddm->getVertCo(ddm, mp_vi[3], v4);
724 /* The BM_FONT handling is in the gpu module, shared with the
725 * game engine, was duplicated previously */
727 set_property_valstr(prop, string);
728 characters = strlen(string);
730 if (!BKE_image_get_ibuf(mtpoly->tpage, NULL))
736 normal_tri_v3(nor, v1, v2, v3);
741 GPU_render_text(&tmp_tf, mode, string, characters,
742 (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib);
749 static int compareDrawOptions(void *userData, int cur_index, int next_index)
751 drawTFace_userData *data = userData;
753 if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
756 if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
762 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
764 drawEMTFMapped_userData *data = userData;
766 if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
769 if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
775 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d,
776 Object *ob, DerivedMesh *dm, const int draw_flags)
780 /* correct for negative scale */
781 if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
782 else glFrontFace(GL_CCW);
784 /* draw the textured mesh */
785 draw_textured_begin(scene, v3d, rv3d, ob);
787 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
789 if (ob->mode & OB_MODE_EDIT) {
790 drawEMTFMapped_userData data;
792 data.em = me->edit_btmesh;
793 data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
794 data.has_mtface = CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
795 data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
796 data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
798 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
800 else if (draw_flags & DRAW_FACE_SELECT) {
801 if (ob->mode & OB_MODE_WEIGHT_PAINT)
802 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me,
803 DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
805 dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, NULL, me);
808 if (GPU_buffer_legacy(dm)) {
809 if (draw_flags & DRAW_MODIFIERS_PREVIEW)
810 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
812 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
815 drawTFace_userData userData;
817 update_tface_color_layer(dm);
819 userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
820 userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
822 dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
826 /* draw game engine text hack */
827 if (get_ob_property(ob, "Text"))
828 draw_mesh_text(scene, ob, 0);
832 /* draw edges and selected faces over textured mesh */
833 if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
834 draw_mesh_face_select(rv3d, me, dm);
836 /* reset from negative scale correction */
839 /* in editmode, the blend mode needs to be set in case it was ADD */
840 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
843 /************************** NEW SHADING NODES ********************************/
845 typedef struct TexMatCallback {
852 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
854 /* all we have to do here is simply enable the GLSL material, but note
855 * that the GLSL code will give different result depending on the drawtype,
856 * in texture draw mode it will output the active texture node, in material
857 * draw mode it will show the full material. */
858 GPU_enable_material(mat_nr, attribs);
861 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
863 /* texture draw mode without GLSL */
864 TexMatCallback *data = (TexMatCallback *)userData;
865 GPUVertexAttribs *gattribs = attribs;
871 /* draw image texture if we find one */
872 if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
873 /* get openl texture */
875 int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, FALSE) : 0;
876 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
879 NodeTexBase *texbase = node->storage;
881 /* disable existing material */
882 GPU_disable_material();
883 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
884 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
885 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
888 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
889 glEnable(GL_COLOR_MATERIAL);
890 glEnable(GL_TEXTURE_2D);
892 glBindTexture(GL_TEXTURE_2D, ima->bindcode);
893 glColor3f(1.0f, 1.0f, 1.0f);
895 glMatrixMode(GL_TEXTURE);
896 glLoadMatrixf(texbase->tex_mapping.mat);
897 glMatrixMode(GL_MODELVIEW);
899 /* use active UV texture layer */
900 memset(gattribs, 0, sizeof(*gattribs));
902 gattribs->layer[0].type = CD_MTFACE;
903 gattribs->layer[0].name[0] = '\0';
904 gattribs->layer[0].gltexco = 1;
905 gattribs->totlayer = 1;
912 glMatrixMode(GL_TEXTURE);
914 glMatrixMode(GL_MODELVIEW);
916 /* disable texture */
917 glDisable(GL_TEXTURE_2D);
918 glDisable(GL_COLOR_MATERIAL);
920 /* draw single color */
921 GPU_enable_material(mat_nr, attribs);
925 static int tex_mat_set_face_mesh_cb(void *userData, int index)
927 /* faceselect mode face hiding */
928 TexMatCallback *data = (TexMatCallback *)userData;
929 Mesh *me = (Mesh *)data->me;
930 MPoly *mp = &me->mpoly[index];
932 return !(mp->flag & ME_HIDE);
935 static int tex_mat_set_face_editmesh_cb(void *userData, int index)
937 /* editmode face hiding */
938 TexMatCallback *data = (TexMatCallback *)userData;
939 Mesh *me = (Mesh *)data->me;
940 BMFace *efa = EDBM_face_at_index(me->edit_btmesh, index);
942 return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
945 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
946 Object *ob, DerivedMesh *dm, const int draw_flags)
948 if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW)) {
949 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
952 else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
953 draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
957 /* set opengl state for negative scale & color */
958 if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
959 else glFrontFace(GL_CCW);
961 glEnable(GL_LIGHTING);
965 TexMatCallback data = {scene, ob, me, dm};
966 int (*set_face_cb)(void *, int);
969 /* face hiding callback depending on mode */
970 if (ob == scene->obedit)
971 set_face_cb = tex_mat_set_face_editmesh_cb;
972 else if (draw_flags & DRAW_FACE_SELECT)
973 set_face_cb = tex_mat_set_face_mesh_cb;
977 /* test if we can use glsl */
978 glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
980 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
984 dm->drawMappedFacesMat(dm,
985 tex_mat_set_material_cb,
989 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
992 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
993 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
994 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
996 dm->drawMappedFacesMat(dm,
997 tex_mat_set_texture_cb,
1001 GPU_end_object_materials();
1004 /* reset opengl state */
1005 glDisable(GL_COLOR_MATERIAL);
1006 glDisable(GL_TEXTURE_2D);
1007 glDisable(GL_LIGHTING);
1008 glBindTexture(GL_TEXTURE_2D, 0);
1009 glFrontFace(GL_CCW);
1011 glMatrixMode(GL_TEXTURE);
1013 glMatrixMode(GL_MODELVIEW);
1015 /* faceselect mode drawing over textured mesh */
1016 if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
1017 draw_mesh_face_select(rv3d, ob->data, dm);
1020 /* Vertex Paint and Weight Paint */
1022 void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
1023 Object *ob, DerivedMesh *dm, const int draw_flags)
1025 DMSetDrawOptions facemask = NULL;
1026 Mesh *me = ob->data;
1027 const short do_light = (v3d->drawtype >= OB_SOLID);
1029 /* hide faces in face select mode */
1030 if (draw_flags & DRAW_FACE_SELECT)
1031 facemask = wpaint__setSolidDrawOptions_facemask;
1033 if (ob && ob->mode & OB_MODE_WEIGHT_PAINT) {
1036 const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
1038 /* enforce default material settings */
1039 GPU_enable_material(0, NULL);
1041 /* but set default spec */
1042 glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
1043 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
1046 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1047 glEnable(GL_LIGHTING);
1048 glEnable(GL_COLOR_MATERIAL);
1051 dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1052 DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1055 glDisable(GL_COLOR_MATERIAL);
1056 glDisable(GL_LIGHTING);
1058 GPU_disable_material();
1061 else if (ob->mode & OB_MODE_VERTEX_PAINT) {
1063 dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1064 DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1067 glColor3f(1.0f, 1.0f, 1.0f);
1068 dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1069 DM_DRAW_ALWAYS_SMOOTH);
1073 /* draw face selection on top */
1074 if (draw_flags & DRAW_FACE_SELECT) {
1075 draw_mesh_face_select(rv3d, me, dm);
1077 else if ((do_light == FALSE) || (ob->dtx & OB_DRAWWIRE)) {
1079 /* weight paint in solid mode, special case. focus on making the weights clear
1080 * rather than the shading, this is also forced in wire view */
1082 bglPolygonOffset(rv3d->dist, 1.0);
1083 glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */
1086 glColor4ub(255, 255, 255, 96);
1087 glEnable(GL_LINE_STIPPLE);
1088 glLineStipple(1, 0xAAAA);
1090 dm->drawEdges(dm, 1, 1);
1092 bglPolygonOffset(rv3d->dist, 0.0);
1094 glDisable(GL_LINE_STIPPLE);
1095 glDisable(GL_BLEND);