Merge with trunk r39928
[blender-staging.git] / source / blender / editors / space_view3d / drawmesh.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation, full update, glsl support
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/space_view3d/drawmesh.c
29  *  \ingroup spview3d
30  */
31
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_blenlib.h"
38 #include "BLI_math.h"
39 #include "BLI_edgehash.h"
40 #include "BLI_editVert.h"
41 #include "BLI_utildefines.h"
42
43 #include "DNA_material_types.h"
44 #include "DNA_meshdata_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"
49 #include "DNA_object_types.h"
50
51 #include "BKE_DerivedMesh.h"
52 #include "BKE_effect.h"
53 #include "BKE_image.h"
54 #include "BKE_material.h"
55 #include "BKE_paint.h"
56 #include "BKE_property.h"
57
58
59 #include "BIF_gl.h"
60 #include "BIF_glutil.h"
61
62 #include "UI_resources.h"
63
64 #include "GPU_buffers.h"
65 #include "GPU_extensions.h"
66 #include "GPU_draw.h"
67
68 #include "ED_mesh.h"
69
70 #include "view3d_intern.h"      // own include
71
72 /**************************** Face Select Mode *******************************/
73
74 /* Flags for marked edges */
75 enum {
76         eEdge_Visible = (1<<0),
77         eEdge_Select = (1<<1),
78 };
79
80 /* Creates a hash of edges to flags indicating selected/visible */
81 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
82 {
83         int *flags_p;
84
85         if(!BLI_edgehash_haskey(eh, v0, v1))
86                 BLI_edgehash_insert(eh, v0, v1, NULL);
87
88         flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
89         *flags_p |= flags;
90 }
91
92 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
93 {
94         EdgeHash *eh = BLI_edgehash_new();
95         MFace *mf;
96         int i;
97         
98         for(i=0; i<me->totface; i++) {
99                 mf = &me->mface[i];
100
101                 if(!(mf->flag & ME_HIDE)) {
102                         unsigned int flags = eEdge_Visible;
103                         if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
104
105                         get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
106                         get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
107
108                         if(mf->v4) {
109                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
110                                 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
111                         }
112                         else
113                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
114                 }
115         }
116
117         return eh;
118 }
119
120
121 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
122 {
123         struct { Mesh *me; EdgeHash *eh; } *data = userData;
124         Mesh *me= data->me;
125         MEdge *med = &me->medge[index];
126         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
127
128         if(me->drawflag & ME_DRAWEDGES) { 
129                 if(me->drawflag & ME_HIDDENEDGES)
130                         return 1;
131                 else
132                         return (flags & eEdge_Visible);
133         }
134         else
135                 return (flags & eEdge_Select);
136 }
137
138 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
139 {
140         struct { Mesh *me; EdgeHash *eh; } *data = userData;
141         MEdge *med = &data->me->medge[index];
142         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
143
144         return flags & eEdge_Select;
145 }
146
147 /* draws unselected */
148 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
149 {
150         Mesh *me = (Mesh*)userData;
151
152         MFace *mface = &me->mface[index];
153         if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
154                 return 2; /* Don't set color */
155         else
156                 return 0;
157 }
158
159 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
160 {
161         struct { Mesh *me; EdgeHash *eh; } data;
162
163         data.me = me;
164         data.eh = get_tface_mesh_marked_edge_info(me);
165
166         glEnable(GL_DEPTH_TEST);
167         glDisable(GL_LIGHTING);
168         bglPolygonOffset(rv3d->dist, 1.0);
169
170         /* Draw (Hidden) Edges */
171         setlinestyle(1);
172         UI_ThemeColor(TH_EDGE_FACESEL);
173         dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
174         setlinestyle(0);
175
176         /* Draw Selected Faces */
177         if(me->drawflag & ME_DRAWFACES) {
178                 glEnable(GL_BLEND);
179                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
180                 /* dull unselected faces so as not to get in the way of seeing color */
181                 glColor4ub(96, 96, 96, 64);
182                 dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, (void*)me);
183                 
184                 glDisable(GL_BLEND);
185         }
186         
187         bglPolygonOffset(rv3d->dist, 1.0);
188
189                 /* Draw Stippled Outline for selected faces */
190         glColor3ub(255, 255, 255);
191         setlinestyle(1);
192         dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
193         setlinestyle(0);
194
195         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
196
197         BLI_edgehash_free(data.eh, NULL);
198 }
199
200 /***************************** Texture Drawing ******************************/
201
202 static Material *give_current_material_or_def(Object *ob, int matnr)
203 {
204         extern Material defmaterial;    // render module abuse...
205         Material *ma= give_current_material(ob, matnr);
206
207         return ma?ma:&defmaterial;
208 }
209
210 static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
211 {
212         static int c_textured;
213         static int c_lit;
214         static int c_doublesided;
215         static MTFace *c_texface;
216         static Object *c_litob;
217         static int c_litmatnr;
218         static int c_badtex;
219
220         if (clearcache) {
221                 c_textured= c_lit= c_doublesided= -1;
222                 c_texface= (MTFace*) -1;
223                 c_litob= (Object*) -1;
224                 c_litmatnr= -1;
225                 c_badtex= 0;
226         }
227
228         if (texface) {
229                 lit = lit && (lit==-1 || texface->mode&TF_LIGHT);
230                 textured = textured && (texface->mode&TF_TEX);
231                 doublesided = texface->mode&TF_TWOSIDE;
232         } else {
233                 textured = 0;
234         }
235
236         if (doublesided!=c_doublesided) {
237                 if (doublesided) glDisable(GL_CULL_FACE);
238                 else glEnable(GL_CULL_FACE);
239
240                 c_doublesided= doublesided;
241         }
242
243         if (textured!=c_textured || texface!=c_texface) {
244                 if (textured ) {
245                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT));
246                 } else {
247                         GPU_set_tpage(NULL, 0);
248                         c_badtex= 0;
249                 }
250                 c_textured= textured;
251                 c_texface= texface;
252         }
253
254         if (c_badtex) lit= 0;
255         if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
256                 if (lit) {
257                         Material *ma= give_current_material_or_def(litob, litmatnr+1);
258                         float spec[4];
259
260                         spec[0]= ma->spec*ma->specr;
261                         spec[1]= ma->spec*ma->specg;
262                         spec[2]= ma->spec*ma->specb;
263                         spec[3]= 1.0;
264
265                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
266                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
267                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
268                         glEnable(GL_LIGHTING);
269                         glEnable(GL_COLOR_MATERIAL);
270                 }
271                 else {
272                         glDisable(GL_LIGHTING); 
273                         glDisable(GL_COLOR_MATERIAL);
274                 }
275                 c_lit= lit;
276                 c_litob= litob;
277                 c_litmatnr= litmatnr;
278         }
279
280         return c_badtex;
281 }
282
283 /* Icky globals, fix with userdata parameter */
284
285 static struct TextureDrawState {
286         Object *ob;
287         int islit, istex;
288         int color_profile;
289         unsigned char obcol[4];
290 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
291
292 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
293 {
294         unsigned char obcol[4];
295         int istex, solidtex= 0;
296
297         // XXX scene->obedit warning
298         if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
299                 /* draw with default lights in solid draw mode and edit mode */
300                 solidtex= 1;
301                 Gtexdraw.islit= -1;
302         }
303         else {
304                 /* draw with lights in the scene otherwise */
305                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
306         }
307         
308         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
309         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
310         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
311         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
312         
313         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
314         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
315         else istex= 0;
316
317         Gtexdraw.ob = ob;
318         Gtexdraw.istex = istex;
319         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
320         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
321         set_draw_settings_cached(1, 0, NULL, Gtexdraw.islit, NULL, 0, 0);
322         glShadeModel(GL_SMOOTH);
323 }
324
325 static void draw_textured_end(void)
326 {
327         /* switch off textures */
328         GPU_set_tpage(NULL, 0);
329
330         glShadeModel(GL_FLAT);
331         glDisable(GL_CULL_FACE);
332
333         /* XXX, bad patch - GPU_default_lights() calls
334          * glLightfv(GL_LIGHT_POSITION, ...) which
335          * is transformed by the current matrix... we
336          * need to make sure that matrix is identity.
337          * 
338          * It would be better if drawmesh.c kept track
339          * of and restored the light settings it changed.
340          *  - zr
341          */
342         glPushMatrix();
343         glLoadIdentity();       
344         GPU_default_lights();
345         glPopMatrix();
346 }
347
348 static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
349 {
350         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
351
352         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
353                 glColor3ub(0xFF, 0x00, 0xFF);
354                 return 2; /* Don't set color */
355         } else if (tface && tface->mode&TF_OBCOL) {
356                 glColor3ubv(Gtexdraw.obcol);
357                 return 2; /* Don't set color */
358         } else if (!mcol) {
359                 if (tface) glColor3f(1.0, 1.0, 1.0);
360                 else {
361                         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
362                         if(ma) {
363                                 float col[3];
364                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
365                                 else copy_v3_v3(col, &ma->r);
366                                 
367                                 glColor3fv(col);
368                         }
369                         else glColor3f(1.0, 1.0, 1.0);
370                 }
371                 return 2; /* Don't set color */
372         } else {
373                 return 1; /* Set color from mcol */
374         }
375 }
376 static int draw_mcol__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
377 {
378         if (mcol) return 1;
379         else return 2;
380 }
381 static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
382 {
383         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
384
385         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
386                 return 2; /* Don't set color */
387         } else if (tface && tface->mode&TF_OBCOL) {
388                 return 2; /* Don't set color */
389         } else if (!mcol) {
390                 return 1; /* Don't set color */
391         } else {
392                 return 1; /* Set color from mcol */
393         }
394 }
395 static void add_tface_color_layer(DerivedMesh *dm)
396 {
397         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
398         MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
399         MCol *finalCol;
400         int i,j;
401         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
402         if(!mcol)
403                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
404
405         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
406         for(i=0;i<dm->getNumFaces(dm);i++) {
407                 if (tface && (tface->mode&TF_INVISIBLE)) {
408                         if( mcol )
409                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
410                         else
411                                 for(j=0;j<4;j++) {
412                                         finalCol[i*4+j].b = 255;
413                                         finalCol[i*4+j].g = 255;
414                                         finalCol[i*4+j].r = 255;
415                                 }
416                 }
417                 else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
418                         for(j=0;j<4;j++) {
419                                 finalCol[i*4+j].b = 255;
420                                 finalCol[i*4+j].g = 0;
421                                 finalCol[i*4+j].r = 255;
422                         }
423                 } else if (tface && tface->mode&TF_OBCOL) {
424                         for(j=0;j<4;j++) {
425                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]);
426                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
427                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]);
428                         }
429                 } else if (!mcol) {
430                         if (tface) {
431                                 for(j=0;j<4;j++) {
432                                         finalCol[i*4+j].b = 255;
433                                         finalCol[i*4+j].g = 255;
434                                         finalCol[i*4+j].r = 255;
435                                 }
436                         }
437                         else {
438                                 float col[3];
439                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
440                                 
441                                 if(ma) {
442                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
443                                         else copy_v3_v3(col, &ma->r);
444                                         
445                                         for(j=0;j<4;j++) {
446                                                 finalCol[i*4+j].b = FTOCHAR(col[2]);
447                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
448                                                 finalCol[i*4+j].r = FTOCHAR(col[0]);
449                                         }
450                                 }
451                                 else
452                                         for(j=0;j<4;j++) {
453                                                 finalCol[i*4+j].b = 255;
454                                                 finalCol[i*4+j].g = 255;
455                                                 finalCol[i*4+j].r = 255;
456                                         }
457                         }
458                 } else {
459                         for(j=0;j<4;j++) {
460                                 finalCol[i*4+j].b = mcol[i*4+j].r;
461                                 finalCol[i*4+j].g = mcol[i*4+j].g;
462                                 finalCol[i*4+j].r = mcol[i*4+j].b;
463                         }
464                 }
465         }
466         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
467 }
468
469 static int draw_tface_mapped__set_draw(void *userData, int index)
470 {
471         Mesh *me = (Mesh*)userData;
472         MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
473         MFace *mface = &me->mface[index];
474         MCol *mcol = (me->mcol)? &me->mcol[index]: NULL;
475         const int matnr = mface->mat_nr;
476         if (mface->flag & ME_HIDE) return 0;
477         return draw_tface__set_draw(tface, mcol, matnr);
478 }
479
480 static int draw_em_tf_mapped__set_draw(void *userData, int index)
481 {
482         EditMesh *em = userData;
483         EditFace *efa= EM_get_face_for_index(index);
484         MTFace *tface;
485         MCol *mcol;
486         int matnr;
487
488         if (efa->h)
489                 return 0;
490
491         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
492         mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
493         matnr = efa->mat_nr;
494
495         return draw_tface__set_draw_legacy(tface, mcol, matnr);
496 }
497
498 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
499 {
500         Mesh *me = (Mesh*)userData;
501
502         if (    (me->mface && me->mface[index].flag & ME_HIDE) ||
503                         (me->mtface && (me->mtface[index].mode & TF_INVISIBLE))
504         ) {
505                 return 0;
506         }
507
508         *drawSmooth_r = 1;
509         return 1;
510 }
511
512 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
513 {
514         Mesh *me = ob->data;
515         DerivedMesh *ddm;
516         MFace *mf, *mface= me->mface;
517         MTFace *tface= me->mtface;
518         MCol *mcol= me->mcol;   /* why does mcol exist? */
519         bProperty *prop = get_ob_property(ob, "Text");
520         GPUVertexAttribs gattribs;
521         int a, totface= me->totface;
522
523         /* don't draw without tfaces */
524         if(!tface)
525                 return;
526
527         /* don't draw when editing */
528         if(ob->mode & OB_MODE_EDIT)
529                 return;
530         else if(ob==OBACT)
531                 if(paint_facesel_test(ob))
532                         return;
533
534         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
535
536         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
537                 int mode= tface->mode;
538                 int matnr= mf->mat_nr;
539                 int mf_smooth= mf->flag & ME_SMOOTH;
540
541                 if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
542                         float v1[3], v2[3], v3[3], v4[3];
543                         char string[MAX_PROPSTRING];
544                         int characters, i, glattrib= -1, badtex= 0;
545
546                         if(glsl) {
547                                 GPU_enable_material(matnr+1, &gattribs);
548
549                                 for(i=0; i<gattribs.totlayer; i++) {
550                                         if(gattribs.layer[i].type == CD_MTFACE) {
551                                                 glattrib = gattribs.layer[i].glindex;
552                                                 break;
553                                         }
554                                 }
555                         }
556                         else {
557                                 badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
558                                 if (badtex) {
559                                         if (mcol) mcol+=4;
560                                         continue;
561                                 }
562                         }
563
564                         ddm->getVertCo(ddm, mf->v1, v1);
565                         ddm->getVertCo(ddm, mf->v2, v2);
566                         ddm->getVertCo(ddm, mf->v3, v3);
567                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
568
569                         // The BM_FONT handling is in the gpu module, shared with the
570                         // game engine, was duplicated previously
571
572                         set_property_valstr(prop, string);
573                         characters = strlen(string);
574                         
575                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
576                                 characters = 0;
577
578                         if (!mf_smooth) {
579                                 float nor[3];
580
581                                 normal_tri_v3( nor,v1, v2, v3);
582
583                                 glNormal3fv(nor);
584                         }
585
586                         GPU_render_text(tface, tface->mode, string, characters,
587                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
588                 }
589                 if (mcol) {
590                         mcol+=4;
591                 }
592         }
593
594         ddm->release(ddm);
595 }
596
597 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
598 {
599         Mesh *me= ob->data;
600         
601         /* correct for negative scale */
602         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
603         else glFrontFace(GL_CCW);
604         
605         /* draw the textured mesh */
606         draw_textured_begin(scene, v3d, rv3d, ob);
607
608         glColor4f(1.0f,1.0f,1.0f,1.0f);
609
610         if(ob->mode & OB_MODE_EDIT) {
611                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh);
612         }
613         else if(draw_flags & DRAW_IS_PAINT_SEL) {
614                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
615                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
616                 else
617                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
618         }
619         else {
620                 if(GPU_buffer_legacy(dm)) {
621                         if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
622                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy);
623                         else 
624                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
625                 }
626                 else {
627                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
628                                 add_tface_color_layer(dm);
629
630                         dm->drawFacesTex(dm, draw_tface__set_draw);
631                 }
632         }
633
634         /* draw game engine text hack */
635         if(get_ob_property(ob, "Text")) 
636                 draw_mesh_text(scene, ob, 0);
637
638         draw_textured_end();
639         
640         /* draw edges and selected faces over textured mesh */
641         if(!(ob == scene->obedit) && (draw_flags & DRAW_IS_PAINT_SEL))
642                 draw_mesh_face_select(rv3d, me, dm);
643
644         /* reset from negative scale correction */
645         glFrontFace(GL_CCW);
646         
647         /* in editmode, the blend mode needs to be set incase it was ADD */
648         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
649 }
650