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_blenlib.h"
37 #include "BLI_edgehash.h"
38 #include "BLI_editVert.h"
39 #include "BLI_utildefines.h"
41 #include "DNA_material_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_node_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_property_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_view3d_types.h"
50 #include "BKE_DerivedMesh.h"
51 #include "BKE_effect.h"
52 #include "BKE_image.h"
53 #include "BKE_material.h"
54 #include "BKE_paint.h"
55 #include "BKE_property.h"
56 #include "BKE_scene.h"
59 #include "BIF_glutil.h"
61 #include "UI_resources.h"
63 #include "GPU_buffers.h"
64 #include "GPU_extensions.h"
66 #include "GPU_material.h"
69 #include "ED_uvedit.h"
71 #include "view3d_intern.h" // own include
73 /**************************** Face Select Mode *******************************/
75 /* Flags for marked edges */
77 eEdge_Visible = (1<<0),
78 eEdge_Select = (1<<1),
81 /* Creates a hash of edges to flags indicating selected/visible */
82 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
86 if(!BLI_edgehash_haskey(eh, v0, v1))
87 BLI_edgehash_insert(eh, v0, v1, NULL);
89 flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
93 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
95 EdgeHash *eh = BLI_edgehash_new();
99 for(i=0; i<me->totface; i++) {
102 if(!(mf->flag & ME_HIDE)) {
103 unsigned int flags = eEdge_Visible;
104 if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
106 get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
107 get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
110 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
111 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
114 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
122 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
124 struct { Mesh *me; EdgeHash *eh; } *data = userData;
126 MEdge *med = &me->medge[index];
127 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
129 if(me->drawflag & ME_DRAWEDGES) {
130 if(me->drawflag & ME_HIDDENEDGES)
133 return (flags & eEdge_Visible);
136 return (flags & eEdge_Select);
139 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
141 struct { Mesh *me; EdgeHash *eh; } *data = userData;
142 MEdge *med = &data->me->medge[index];
143 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
145 return flags & eEdge_Select;
148 /* draws unselected */
149 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
151 Mesh *me = (Mesh*)userData;
153 MFace *mface = &me->mface[index];
154 if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
155 return 2; /* Don't set color */
160 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
162 struct { Mesh *me; EdgeHash *eh; } data;
165 data.eh = get_tface_mesh_marked_edge_info(me);
167 glEnable(GL_DEPTH_TEST);
168 glDisable(GL_LIGHTING);
169 bglPolygonOffset(rv3d->dist, 1.0);
171 /* Draw (Hidden) Edges */
173 UI_ThemeColor(TH_EDGE_FACESEL);
174 dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
177 /* Draw Selected Faces */
178 if(me->drawflag & ME_DRAWFACES) {
180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181 /* dull unselected faces so as not to get in the way of seeing color */
182 glColor4ub(96, 96, 96, 64);
183 dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, (void*)me);
188 bglPolygonOffset(rv3d->dist, 1.0);
190 /* Draw Stippled Outline for selected faces */
191 glColor3ub(255, 255, 255);
193 dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
196 bglPolygonOffset(rv3d->dist, 0.0); // resets correctly now, even after calling accumulated offsets
198 BLI_edgehash_free(data.eh, NULL);
201 /***************************** Texture Drawing ******************************/
203 static Material *give_current_material_or_def(Object *ob, int matnr)
205 extern Material defmaterial; // render module abuse...
206 Material *ma= give_current_material(ob, matnr);
208 return ma?ma:&defmaterial;
211 /* Icky globals, fix with userdata parameter */
213 static struct TextureDrawState {
217 unsigned char obcol[4];
218 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
220 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
222 static Material *c_ma;
223 static int c_textured;
224 static MTFace *c_texface;
225 static int c_backculled;
229 Object *litob = NULL; //to get mode to turn off mipmap in painting mode
230 int backculled = GEMAT_BACKCULL;
236 c_textured= c_lit= c_backculled= -1;
237 c_texface= (MTFace*) -1;
240 textured = gtexdraw.istex;
244 /* convert number of lights into boolean */
245 if (gtexdraw.islit) lit = 1;
248 alphablend = ma->game.alpha_blend;
249 if (ma->mode & MA_SHLESS) lit = 0;
250 backculled = ma->game.flag & GEMAT_BACKCULL;
254 textured = textured && (texface->tpage);
256 /* no material, render alpha if texture has depth=32 */
257 if (!ma && BKE_image_has_alpha(texface->tpage))
258 alphablend = GPU_BLEND_ALPHA;
264 if (backculled!=c_backculled) {
265 if (backculled) glEnable(GL_CULL_FACE);
266 else glDisable(GL_CULL_FACE);
268 c_backculled= backculled;
271 if (textured!=c_textured || texface!=c_texface) {
273 c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
275 GPU_set_tpage(NULL, 0, 0);
278 c_textured= textured;
282 if (c_badtex) lit= 0;
283 if (lit!=c_lit || ma!=c_ma) {
286 if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
288 spec[0]= ma->spec*ma->specr;
289 spec[1]= ma->spec*ma->specg;
290 spec[2]= ma->spec*ma->specb;
293 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
294 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
295 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
296 glEnable(GL_LIGHTING);
297 glEnable(GL_COLOR_MATERIAL);
300 glDisable(GL_LIGHTING);
301 glDisable(GL_COLOR_MATERIAL);
309 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
311 unsigned char obcol[4];
314 // XXX scene->obedit warning
316 /* texture draw is abused for mask selection mode, do this so wire draw
317 * with face selection in weight paint is not lit. */
318 if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
322 else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
323 /* draw with default lights in solid draw mode and edit mode */
328 /* draw with lights in the scene otherwise */
330 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
333 obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
334 obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
335 obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
336 obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
338 glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
339 if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
343 Gtexdraw.istex = istex;
344 Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
345 memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
346 set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
347 glShadeModel(GL_SMOOTH);
350 static void draw_textured_end(void)
352 /* switch off textures */
353 GPU_set_tpage(NULL, 0, 0);
355 glShadeModel(GL_FLAT);
356 glDisable(GL_CULL_FACE);
358 /* XXX, bad patch - GPU_default_lights() calls
359 * glLightfv(GL_LIGHT_POSITION, ...) which
360 * is transformed by the current matrix... we
361 * need to make sure that matrix is identity.
363 * It would be better if drawmesh.c kept track
364 * of and restored the light settings it changed.
369 GPU_default_lights();
373 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
375 Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
378 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
380 validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
382 if (tface && validtexture) {
383 glColor3ub(0xFF, 0x00, 0xFF);
384 return 2; /* Don't set color */
385 } else if (ma && ma->shade_flag&MA_OBCOLOR) {
386 glColor3ubv(Gtexdraw.obcol);
387 return 2; /* Don't set color */
388 } else if (!has_mcol) {
389 if (tface) glColor3f(1.0, 1.0, 1.0);
393 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
394 else copy_v3_v3(col, &ma->r);
398 else glColor3f(1.0, 1.0, 1.0);
400 return 2; /* Don't set color */
402 return 1; /* Set color from mcol */
406 static int draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
408 if (has_mcol) return 1;
412 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
414 Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
416 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
418 if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
419 return 2; /* Don't set color */
420 } else if (tface && tface->mode&TF_OBCOL) {
421 return 2; /* Don't set color */
422 } else if (!has_mcol) {
423 return 1; /* Don't set color */
425 return 1; /* Set color from mcol */
428 static void add_tface_color_layer(DerivedMesh *dm)
430 MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
431 MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
434 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
436 mcol = dm->getFaceDataArray(dm, CD_MCOL);
438 finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
439 for(i=0;i<dm->getNumFaces(dm);i++) {
440 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
442 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
444 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
447 finalCol[i*4+j].b = 255;
448 finalCol[i*4+j].g = 255;
449 finalCol[i*4+j].r = 255;
452 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
454 finalCol[i*4+j].b = 255;
455 finalCol[i*4+j].g = 0;
456 finalCol[i*4+j].r = 255;
458 } else if (tface && tface->mode&TF_OBCOL) {
460 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
461 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
462 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
467 finalCol[i*4+j].b = 255;
468 finalCol[i*4+j].g = 255;
469 finalCol[i*4+j].r = 255;
474 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
477 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
478 else copy_v3_v3(col, &ma->r);
481 finalCol[i*4+j].b = FTOCHAR(col[0]);
482 finalCol[i*4+j].g = FTOCHAR(col[1]);
483 finalCol[i*4+j].r = FTOCHAR(col[2]);
488 finalCol[i*4+j].b = 255;
489 finalCol[i*4+j].g = 255;
490 finalCol[i*4+j].r = 255;
495 finalCol[i*4+j].r = mcol[i*4+j].r;
496 finalCol[i*4+j].g = mcol[i*4+j].g;
497 finalCol[i*4+j].b = mcol[i*4+j].b;
501 CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
504 static int draw_tface_mapped__set_draw(void *userData, int index)
506 Mesh *me = (Mesh*)userData;
507 MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
508 MFace *mface = &me->mface[index];
509 const int matnr = mface->mat_nr;
510 if (mface->flag & ME_HIDE) return 0;
511 return draw_tface__set_draw(tface, (me->mcol != NULL), matnr);
514 static int draw_em_tf_mapped__set_draw(void *userData, int index)
516 struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
517 EditMesh *em = data->em;
518 EditFace *efa= EM_get_face_for_index(index);
525 tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
528 return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
531 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
533 Mesh *me = (Mesh*)userData;
535 if (me->mat && me->mface) {
536 Material *ma= me->mat[me->mface[index].mat_nr];
537 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
546 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
550 MFace *mf, *mface= me->mface;
551 MTFace *tface= me->mtface;
552 MCol *mcol= me->mcol; /* why does mcol exist? */
553 bProperty *prop = get_ob_property(ob, "Text");
554 GPUVertexAttribs gattribs;
555 int a, totface= me->totface;
557 /* don't draw without tfaces */
561 /* don't draw when editing */
562 if(ob->mode & OB_MODE_EDIT)
565 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
568 ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
570 for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
571 short matnr= mf->mat_nr;
572 int mf_smooth= mf->flag & ME_SMOOTH;
573 Material *mat = me->mat[matnr];
574 int mode= mat->game.flag;
576 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
577 float v1[3], v2[3], v3[3], v4[3];
578 char string[MAX_PROPSTRING];
579 int characters, i, glattrib= -1, badtex= 0;
582 GPU_enable_material(matnr+1, &gattribs);
584 for(i=0; i<gattribs.totlayer; i++) {
585 if(gattribs.layer[i].type == CD_MTFACE) {
586 glattrib = gattribs.layer[i].glindex;
592 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
599 ddm->getVertCo(ddm, mf->v1, v1);
600 ddm->getVertCo(ddm, mf->v2, v2);
601 ddm->getVertCo(ddm, mf->v3, v3);
602 if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
604 // The BM_FONT handling is in the gpu module, shared with the
605 // game engine, was duplicated previously
607 set_property_valstr(prop, string);
608 characters = strlen(string);
610 if(!BKE_image_get_ibuf(tface->tpage, NULL))
616 normal_tri_v3( nor,v1, v2, v3);
621 GPU_render_text(tface, mode, string, characters,
622 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
632 static int compareDrawOptions(void *userData, int cur_index, int next_index)
634 struct { MFace *mf; MTFace *tf; } *data = userData;
636 if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
639 if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
645 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
647 struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
649 if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
652 if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
658 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
662 /* correct for negative scale */
663 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
664 else glFrontFace(GL_CCW);
666 /* draw the textured mesh */
667 draw_textured_begin(scene, v3d, rv3d, ob);
669 glColor4f(1.0f,1.0f,1.0f,1.0f);
671 if(ob->mode & OB_MODE_EDIT) {
672 struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
674 data.em= me->edit_mesh;
675 data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
676 data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
677 data.mf= DM_get_face_data_layer(dm, CD_MFACE);
678 data.tf= DM_get_face_data_layer(dm, CD_MTFACE);
680 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
682 else if(draw_flags & DRAW_FACE_SELECT) {
683 if(ob->mode & OB_MODE_WEIGHT_PAINT)
684 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, GPU_enable_material, NULL, me, 1);
686 dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, NULL, me);
689 if(GPU_buffer_legacy(dm)) {
690 if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
691 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
693 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
696 struct { MFace *mf; MTFace *tf; } userData;
698 if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
699 add_tface_color_layer(dm);
701 userData.mf = DM_get_face_data_layer(dm, CD_MFACE);
702 userData.tf = DM_get_face_data_layer(dm, CD_MTFACE);
704 dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
708 /* draw game engine text hack */
709 if(get_ob_property(ob, "Text"))
710 draw_mesh_text(scene, ob, 0);
714 /* draw edges and selected faces over textured mesh */
715 if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
716 draw_mesh_face_select(rv3d, me, dm);
718 /* reset from negative scale correction */
721 /* in editmode, the blend mode needs to be set incase it was ADD */
722 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
725 /************************** NEW SHADING NODES ********************************/
727 typedef struct TexMatCallback {
734 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
736 /* all we have to do here is simply enable the GLSL material, but note
737 that the GLSL code will give different result depending on the drawtype,
738 in texture draw mode it will output the active texture node, in material
739 draw mode it will show the full material. */
740 GPU_enable_material(mat_nr, attribs);
743 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
745 /* texture draw mode without GLSL */
746 TexMatCallback *data= (TexMatCallback*)userData;
747 GPUVertexAttribs *gattribs = attribs;
753 /* draw image texture if we find one */
754 if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
755 /* get openl texture */
757 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
758 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
761 NodeTexBase *texbase= node->storage;
763 /* disable existing material */
764 GPU_disable_material();
765 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
766 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
767 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
770 glEnable(GL_COLOR_MATERIAL);
771 glEnable(GL_TEXTURE_2D);
773 glBindTexture(GL_TEXTURE_2D, ima->bindcode);
774 glColor3f(1.0f, 1.0f, 1.0f);
776 glMatrixMode(GL_TEXTURE);
777 glLoadMatrixf(texbase->tex_mapping.mat);
778 glMatrixMode(GL_MODELVIEW);
780 /* use active UV texture layer */
781 memset(gattribs, 0, sizeof(*gattribs));
783 gattribs->layer[0].type= CD_MTFACE;
784 gattribs->layer[0].name[0]= '\0';
785 gattribs->layer[0].gltexco= 1;
786 gattribs->totlayer= 1;
793 glMatrixMode(GL_TEXTURE);
795 glMatrixMode(GL_MODELVIEW);
797 /* disable texture */
798 glDisable(GL_TEXTURE_2D);
799 glDisable(GL_COLOR_MATERIAL);
801 /* draw single color */
802 GPU_enable_material(mat_nr, attribs);
806 static int tex_mat_set_face_mesh_cb(void *userData, int index)
808 /* faceselect mode face hiding */
809 TexMatCallback *data= (TexMatCallback*)userData;
810 Mesh *me = (Mesh*)data->me;
811 MFace *mface = &me->mface[index];
813 return !(mface->flag & ME_HIDE);
816 static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
818 /* editmode face hiding */
819 EditFace *efa= EM_get_face_for_index(index);
824 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
826 if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
827 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
831 /* set opengl state for negative scale & color */
832 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
833 else glFrontFace(GL_CCW);
835 glEnable(GL_LIGHTING);
837 if(ob->mode & OB_MODE_WEIGHT_PAINT) {
838 /* weight paint mode exception */
841 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
842 GPU_enable_material, NULL, ob->data, useColors);
846 TexMatCallback data = {scene, ob, me, dm};
847 int (*set_face_cb)(void*, int);
850 /* face hiding callback depending on mode */
851 if(ob == scene->obedit)
852 set_face_cb= tex_mat_set_face_editmesh_cb;
853 else if(draw_flags & DRAW_FACE_SELECT)
854 set_face_cb= tex_mat_set_face_mesh_cb;
858 /* test if we can use glsl */
859 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
861 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
865 dm->drawMappedFacesMat(dm,
866 tex_mat_set_material_cb,
870 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
873 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
874 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
875 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
877 dm->drawMappedFacesMat(dm,
878 tex_mat_set_texture_cb,
882 GPU_end_object_materials();
885 /* reset opengl state */
886 glDisable(GL_COLOR_MATERIAL);
887 glDisable(GL_TEXTURE_2D);
888 glDisable(GL_LIGHTING);
889 glBindTexture(GL_TEXTURE_2D, 0);
892 glMatrixMode(GL_TEXTURE);
894 glMatrixMode(GL_MODELVIEW);
896 /* faceselect mode drawing over textured mesh */
897 if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
898 draw_mesh_face_select(rv3d, ob->data, dm);