TexFace to Material Settings big patch
[blender.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 #include "GPU_material.h"
68
69 #include "ED_mesh.h"
70
71 #include "view3d_intern.h"      // own include
72
73 /**************************** Face Select Mode *******************************/
74
75 /* Flags for marked edges */
76 enum {
77         eEdge_Visible = (1<<0),
78         eEdge_Select = (1<<1),
79 };
80
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)
83 {
84         int *flags_p;
85
86         if(!BLI_edgehash_haskey(eh, v0, v1))
87                 BLI_edgehash_insert(eh, v0, v1, NULL);
88
89         flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
90         *flags_p |= flags;
91 }
92
93 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
94 {
95         EdgeHash *eh = BLI_edgehash_new();
96         MFace *mf;
97         int i;
98         
99         for(i=0; i<me->totface; i++) {
100                 mf = &me->mface[i];
101
102                 if(!(mf->flag & ME_HIDE)) {
103                         unsigned int flags = eEdge_Visible;
104                         if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
105
106                         get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
107                         get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
108
109                         if(mf->v4) {
110                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
111                                 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
112                         }
113                         else
114                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
115                 }
116         }
117
118         return eh;
119 }
120
121
122 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
123 {
124         struct { Mesh *me; EdgeHash *eh; } *data = userData;
125         Mesh *me= data->me;
126         MEdge *med = &me->medge[index];
127         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
128
129         if(me->drawflag & ME_DRAWEDGES) { 
130                 if(me->drawflag & ME_HIDDENEDGES)
131                         return 1;
132                 else
133                         return (flags & eEdge_Visible);
134         }
135         else
136                 return (flags & eEdge_Select);
137 }
138
139 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
140 {
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);
144
145         return flags & eEdge_Select;
146 }
147
148 /* draws unselected */
149 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
150 {
151         Mesh *me = (Mesh*)userData;
152
153         MFace *mface = &me->mface[index];
154         if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
155                 return 2; /* Don't set color */
156         else
157                 return 0;
158 }
159
160 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
161 {
162         struct { Mesh *me; EdgeHash *eh; } data;
163
164         data.me = me;
165         data.eh = get_tface_mesh_marked_edge_info(me);
166
167         glEnable(GL_DEPTH_TEST);
168         glDisable(GL_LIGHTING);
169         bglPolygonOffset(rv3d->dist, 1.0);
170
171         /* Draw (Hidden) Edges */
172         setlinestyle(1);
173         UI_ThemeColor(TH_EDGE_FACESEL);
174         dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
175         setlinestyle(0);
176
177         /* Draw Selected Faces */
178         if(me->drawflag & ME_DRAWFACES) {
179                 glEnable(GL_BLEND);
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, (void*)me);
184                 
185                 glDisable(GL_BLEND);
186         }
187         
188         bglPolygonOffset(rv3d->dist, 1.0);
189
190                 /* Draw Stippled Outline for selected faces */
191         glColor3ub(255, 255, 255);
192         setlinestyle(1);
193         dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
194         setlinestyle(0);
195
196         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
197
198         BLI_edgehash_free(data.eh, NULL);
199 }
200
201 /***************************** Texture Drawing ******************************/
202
203 static Material *give_current_material_or_def(Object *ob, int matnr)
204 {
205         extern Material defmaterial;    // render module abuse...
206         Material *ma= give_current_material(ob, matnr);
207
208         return ma?ma:&defmaterial;
209 }
210
211 /* Icky globals, fix with userdata parameter */
212
213 static struct TextureDrawState {
214         Object *ob;
215         int islit, istex;
216         int color_profile;
217         unsigned char obcol[4];
218 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
219
220 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
221 {
222         static Material *c_ma;
223         static int c_textured;
224         static MTFace *c_texface;
225         static int c_backculled;
226         static int c_badtex;
227         static int c_lit;
228
229         Object *litob = NULL; //to get mode to turn off mipmap in painting mode
230         int backculled = 0;
231         int alphablend = 0;
232         int textured = 0;
233         int lit = 0;
234         
235         if (clearcache) {
236                 c_textured= c_lit= c_backculled= -1;
237                 c_texface= (MTFace*) -1;
238                 c_badtex= 0;
239         } else {
240                 textured = gtexdraw.istex;
241                 litob = gtexdraw.ob;
242         }
243
244         /* convert number of lights into boolean */
245         if (gtexdraw.islit) lit = 1;
246
247         if (ma) {
248                 alphablend = ma->game.alpha_blend;
249                 if (ma->mode & MA_SHLESS) lit = 0;
250                 backculled = ma->game.flag & GEMAT_BACKCULL;
251         }
252
253         if (texface) {
254                 textured = textured && (texface->tpage);
255
256                 /* no material, render alpha if texture has depth=32 */
257                 if (!ma && BKE_image_has_alpha(texface->tpage))
258                         alphablend = GPU_BLEND_ALPHA;
259         }
260
261         else
262                 textured = 0;
263
264         if (backculled!=c_backculled) {
265                 if (backculled) glEnable(GL_CULL_FACE);
266                 else glDisable(GL_CULL_FACE);
267
268                 c_backculled= backculled;
269         }
270
271         if (textured!=c_textured || texface!=c_texface) {
272                 if (textured ) {
273                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
274                 } else {
275                         GPU_set_tpage(NULL, 0, 0);
276                         c_badtex= 0;
277                 }
278                 c_textured= textured;
279                 c_texface= texface;
280         }
281
282         if (c_badtex) lit= 0;
283         if (lit!=c_lit || ma!=c_ma) {
284                 if (lit) {
285                         float spec[4];
286                         if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
287
288                         spec[0]= ma->spec*ma->specr;
289                         spec[1]= ma->spec*ma->specg;
290                         spec[2]= ma->spec*ma->specb;
291                         spec[3]= 1.0;
292
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);
298                 }
299                 else {
300                         glDisable(GL_LIGHTING); 
301                         glDisable(GL_COLOR_MATERIAL);
302                 }
303                 c_lit= lit;
304         }
305
306         return c_badtex;
307 }
308
309 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
310 {
311         unsigned char obcol[4];
312         int istex, solidtex= 0;
313
314         // XXX scene->obedit warning
315         if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
316                 /* draw with default lights in solid draw mode and edit mode */
317                 solidtex= 1;
318                 Gtexdraw.islit= -1;
319         }
320         else {
321                 /* draw with lights in the scene otherwise */
322                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
323         }
324         
325         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
326         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
327         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
328         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
329         
330         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
331         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
332         else istex= 0;
333
334         Gtexdraw.ob = ob;
335         Gtexdraw.istex = istex;
336         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
337         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
338         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
339         glShadeModel(GL_SMOOTH);
340 }
341
342 static void draw_textured_end(void)
343 {
344         /* switch off textures */
345         GPU_set_tpage(NULL, 0, 0);
346
347         glShadeModel(GL_FLAT);
348         glDisable(GL_CULL_FACE);
349
350         /* XXX, bad patch - GPU_default_lights() calls
351          * glLightfv(GL_LIGHT_POSITION, ...) which
352          * is transformed by the current matrix... we
353          * need to make sure that matrix is identity.
354          * 
355          * It would be better if drawmesh.c kept track
356          * of and restored the light settings it changed.
357          *  - zr
358          */
359         glPushMatrix();
360         glLoadIdentity();       
361         GPU_default_lights();
362         glPopMatrix();
363 }
364
365 static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
366 {
367         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
368         int validtexture=0;
369
370         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
371
372         validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
373
374         if (tface && validtexture) {
375                 glColor3ub(0xFF, 0x00, 0xFF);
376                 return 2; /* Don't set color */
377         } else if (ma && ma->shade_flag&MA_OBCOLOR) {
378                 glColor3ubv(Gtexdraw.obcol);
379                 return 2; /* Don't set color */
380         } else if (!mcol) {
381                 if (tface) glColor3f(1.0, 1.0, 1.0);
382                 else {
383                         if(ma) {
384                                 float col[3];
385                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
386                                 else copy_v3_v3(col, &ma->r);
387                                 
388                                 glColor3fv(col);
389                         }
390                         else glColor3f(1.0, 1.0, 1.0);
391                 }
392                 return 2; /* Don't set color */
393         } else {
394                 return 1; /* Set color from mcol */
395         }
396 }
397 static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
398 {
399         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
400
401         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
402
403         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
404                 return 2; /* Don't set color */
405         } else if (tface && tface->mode&TF_OBCOL) {
406                 return 2; /* Don't set color */
407         } else if (!mcol) {
408                 return 1; /* Don't set color */
409         } else {
410                 return 1; /* Set color from mcol */
411         }
412 }
413 static void add_tface_color_layer(DerivedMesh *dm)
414 {
415         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
416         MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
417         MCol *finalCol;
418         int i,j;
419         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
420         if(!mcol)
421                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
422
423         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
424         for(i=0;i<dm->getNumFaces(dm);i++) {
425                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
426
427                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
428                         if( mcol )
429                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
430                         else
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 if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
438                         for(j=0;j<4;j++) {
439                                 finalCol[i*4+j].b = 255;
440                                 finalCol[i*4+j].g = 0;
441                                 finalCol[i*4+j].r = 255;
442                         }
443                 } else if (tface && tface->mode&TF_OBCOL) {
444                         for(j=0;j<4;j++) {
445                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]);
446                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
447                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]);
448                         }
449                 } else if (!mcol) {
450                         if (tface) {
451                                 for(j=0;j<4;j++) {
452                                         finalCol[i*4+j].b = 255;
453                                         finalCol[i*4+j].g = 255;
454                                         finalCol[i*4+j].r = 255;
455                                 }
456                         }
457                         else {
458                                 float col[3];
459                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
460                                 
461                                 if(ma) {
462                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
463                                         else copy_v3_v3(col, &ma->r);
464                                         
465                                         for(j=0;j<4;j++) {
466                                                 finalCol[i*4+j].b = FTOCHAR(col[2]);
467                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
468                                                 finalCol[i*4+j].r = FTOCHAR(col[0]);
469                                         }
470                                 }
471                                 else
472                                         for(j=0;j<4;j++) {
473                                                 finalCol[i*4+j].b = 255;
474                                                 finalCol[i*4+j].g = 255;
475                                                 finalCol[i*4+j].r = 255;
476                                         }
477                         }
478                 } else {
479                         for(j=0;j<4;j++) {
480                                 finalCol[i*4+j].b = mcol[i*4+j].r;
481                                 finalCol[i*4+j].g = mcol[i*4+j].g;
482                                 finalCol[i*4+j].r = mcol[i*4+j].b;
483                         }
484                 }
485         }
486         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
487 }
488
489 static int draw_tface_mapped__set_draw(void *userData, int index)
490 {
491         Mesh *me = (Mesh*)userData;
492         MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
493         MFace *mface = &me->mface[index];
494         MCol *mcol = (me->mcol)? &me->mcol[index]: NULL;
495         const int matnr = mface->mat_nr;
496         if (mface->flag & ME_HIDE) return 0;
497         return draw_tface__set_draw(tface, mcol, matnr);
498 }
499
500 static int draw_em_tf_mapped__set_draw(void *userData, int index)
501 {
502         EditMesh *em = userData;
503         EditFace *efa= EM_get_face_for_index(index);
504         MTFace *tface;
505         MCol *mcol;
506         int matnr;
507
508         if (efa->h)
509                 return 0;
510
511         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
512         mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
513         matnr = efa->mat_nr;
514
515         return draw_tface__set_draw_legacy(tface, mcol, matnr);
516 }
517
518 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
519 {
520         Mesh *me = (Mesh*)userData;
521         Material *ma;
522
523         if (me->mface) {
524                 int matnr = me->mface[index].mat_nr;
525                 ma = me->mat[matnr];
526         }
527
528         if ( ma && (ma->game.flag & GEMAT_INVISIBLE)) {
529                 return 0;
530         }
531
532         *drawSmooth_r = 1;
533         return 1;
534 }
535
536 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
537 {
538         Mesh *me = ob->data;
539         DerivedMesh *ddm;
540         MFace *mf, *mface= me->mface;
541         MTFace *tface= me->mtface;
542         MCol *mcol= me->mcol;   /* why does mcol exist? */
543         bProperty *prop = get_ob_property(ob, "Text");
544         GPUVertexAttribs gattribs;
545         int a, totface= me->totface;
546
547         /* don't draw without tfaces */
548         if(!tface)
549                 return;
550
551         /* don't draw when editing */
552         if(ob->mode & OB_MODE_EDIT)
553                 return;
554         else if(ob==OBACT)
555                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
556                         return;
557
558         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
559
560         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
561                 int matnr= mf->mat_nr;
562                 int mf_smooth= mf->flag & ME_SMOOTH;
563                 Material *mat = me->mat[matnr];
564                 int mode= mat->game.flag;
565
566                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
567                         float v1[3], v2[3], v3[3], v4[3];
568                         char string[MAX_PROPSTRING];
569                         int characters, i, glattrib= -1, badtex= 0;
570
571                         if(glsl) {
572                                 GPU_enable_material(matnr+1, &gattribs);
573
574                                 for(i=0; i<gattribs.totlayer; i++) {
575                                         if(gattribs.layer[i].type == CD_MTFACE) {
576                                                 glattrib = gattribs.layer[i].glindex;
577                                                 break;
578                                         }
579                                 }
580                         }
581                         else {
582                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
583                                 if (badtex) {
584                                         if (mcol) mcol+=4;
585                                         continue;
586                                 }
587                         }
588
589                         ddm->getVertCo(ddm, mf->v1, v1);
590                         ddm->getVertCo(ddm, mf->v2, v2);
591                         ddm->getVertCo(ddm, mf->v3, v3);
592                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
593
594                         // The BM_FONT handling is in the gpu module, shared with the
595                         // game engine, was duplicated previously
596
597                         set_property_valstr(prop, string);
598                         characters = strlen(string);
599                         
600                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
601                                 characters = 0;
602
603                         if (!mf_smooth) {
604                                 float nor[3];
605
606                                 normal_tri_v3( nor,v1, v2, v3);
607
608                                 glNormal3fv(nor);
609                         }
610
611                         GPU_render_text(tface, mode, string, characters,
612                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
613                 }
614                 if (mcol) {
615                         mcol+=4;
616                 }
617         }
618
619         ddm->release(ddm);
620 }
621
622 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
623 {
624         Mesh *me= ob->data;
625         
626         /* correct for negative scale */
627         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
628         else glFrontFace(GL_CCW);
629         
630         /* draw the textured mesh */
631         draw_textured_begin(scene, v3d, rv3d, ob);
632
633         glColor4f(1.0f,1.0f,1.0f,1.0f);
634
635         if(ob->mode & OB_MODE_EDIT) {
636                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh);
637         }
638         else if(faceselect) {
639                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
640                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
641                 else
642                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
643         }
644         else {
645                 if(GPU_buffer_legacy(dm)) {
646                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
647                 }
648                 else {
649                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
650                                 add_tface_color_layer(dm);
651
652                         dm->drawFacesTex(dm, draw_tface__set_draw);
653                 }
654         }
655
656         /* draw game engine text hack */
657         if(get_ob_property(ob, "Text")) 
658                 draw_mesh_text(scene, ob, 0);
659
660         draw_textured_end();
661         
662         /* draw edges and selected faces over textured mesh */
663         if(!(ob == scene->obedit) && faceselect)
664                 draw_mesh_face_select(rv3d, me, dm);
665
666         /* reset from negative scale correction */
667         glFrontFace(GL_CCW);
668         
669         /* in editmode, the blend mode needs to be set incase it was ADD */
670         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
671 }
672