merge with/from trunk at r35190
[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 #include <string.h>
29 #include <math.h>
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BLI_blenlib.h"
34 #include "BLI_math.h"
35 #include "BLI_edgehash.h"
36 #include "BLI_editVert.h"
37 #include "BLI_utildefines.h"
38
39 #include "DNA_material_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_property_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_view3d_types.h"
45 #include "DNA_windowmanager_types.h"
46 #include "DNA_object_types.h"
47
48 #include "BKE_DerivedMesh.h"
49 #include "BKE_effect.h"
50 #include "BKE_image.h"
51 #include "BKE_material.h"
52 #include "BKE_paint.h"
53 #include "BKE_property.h"
54 #include "BKE_tessmesh.h"
55
56
57 #include "BIF_gl.h"
58 #include "BIF_glutil.h"
59
60 #include "UI_resources.h"
61
62 #include "GPU_buffers.h"
63 #include "GPU_extensions.h"
64 #include "GPU_draw.h"
65
66 #include "ED_mesh.h"
67
68 #include "view3d_intern.h"      // own include
69
70 /***/
71
72         /* Flags for marked edges */
73 enum {
74         eEdge_Visible = (1<<0),
75         eEdge_Select = (1<<1),
76 };
77
78         /* Creates a hash of edges to flags indicating
79          * adjacent tface select/active/etc flags.
80          */
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, 0);
87         }
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         int i;
97         MFace *mf;
98         
99         for (i=0; i<me->totface; i++) {
100                 mf = &me->mface[i];
101
102                 if (mf->v3) {
103                         if (!(mf->flag&ME_HIDE)) {
104                                 unsigned int flags = eEdge_Visible;
105                                 if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select;
106
107                                 get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
108                                 get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
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                                 } else {
113                                         get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
114                                 }
115                         }
116                 }
117         }
118
119         return eh;
120 }
121
122
123 static int draw_tfaces3D__setHiddenOpts(void *userData, int index)
124 {
125         struct { Mesh *me; EdgeHash *eh; } *data = userData;
126         Mesh *me= data->me;
127         MEdge *med = &me->medge[index];
128         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
129
130         if((me->drawflag & ME_DRAWSEAMS) && (med->flag&ME_SEAM)) {
131                 return 0;
132         } else if(me->drawflag & ME_DRAWEDGES){ 
133                 if (me->drawflag & ME_HIDDENEDGES) {
134                         return 1;
135                 } else {
136                         return (flags & eEdge_Visible);
137                 }
138         } else {
139                 return (flags & eEdge_Select);
140         }
141 }
142
143 static int draw_tfaces3D__setSeamOpts(void *userData, int index)
144 {
145         struct { Mesh *me; EdgeHash *eh; } *data = userData;
146         Mesh *me= data->me;
147         MEdge *med = &data->me->medge[index];
148         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
149
150         if (med->flag & ME_SEAM) {
151                 if (me->drawflag & ME_HIDDENEDGES) {
152                         return 1;
153                 } else {
154                         return (flags & eEdge_Visible);
155                 }
156         } else {
157                 return 0;
158         }
159 }
160
161 static int draw_tfaces3D__setSelectOpts(void *userData, int index)
162 {
163         struct { Mesh *me; EdgeHash *eh; } *data = userData;
164         MEdge *med = &data->me->medge[index];
165         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
166
167         return flags & eEdge_Select;
168 }
169
170 #if 0
171 static int draw_tfaces3D__setActiveOpts(void *userData, int index)
172 {
173         struct { Mesh *me; EdgeHash *eh; } *data = userData;
174         MEdge *med = &data->me->medge[index];
175         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
176
177         if (flags & eEdge_Select) {
178                 return 1;
179         } else {
180                 return 0;
181         }
182 }
183
184 static int draw_tfaces3D__drawFaceOpts(void *userData, int index)
185 {
186         Mesh *me = (Mesh*)userData;
187
188         MFace *mface = &me->mface[index];
189         if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL))
190                 return 2; /* Don't set color */
191         else
192                 return 0;
193 }
194 #endif
195
196 /* draws unselected */
197 static int draw_tfaces3D__drawFaceOptsInv(void *userData, int index)
198 {
199         Mesh *me = (Mesh*)userData;
200
201         MFace *mface = &me->mface[index];
202         if (!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
203                 return 2; /* Don't set color */
204         else
205                 return 0;
206 }
207
208 static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short draw_seams)
209 {
210         struct { Mesh *me; EdgeHash *eh; } data;
211
212         data.me = me;
213         data.eh = get_tface_mesh_marked_edge_info(me);
214
215         glEnable(GL_DEPTH_TEST);
216         glDisable(GL_LIGHTING);
217         bglPolygonOffset(rv3d->dist, 1.0);
218
219         /* Draw (Hidden) Edges */
220         setlinestyle(1);
221         UI_ThemeColor(TH_EDGE_FACESEL);
222         dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data);
223         setlinestyle(0);
224
225         /* Draw Seams */
226         if(draw_seams && me->drawflag & ME_DRAWSEAMS) {
227                 UI_ThemeColor(TH_EDGE_SEAM);
228                 glLineWidth(2);
229                 dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data);
230                 glLineWidth(1);
231         }
232
233         /* Draw Selected Faces */
234         if(me->drawflag & ME_DRAWFACES) {
235                 glEnable(GL_BLEND);
236                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
237 #if 0
238                 UI_ThemeColor4(TH_FACE_SELECT);
239
240                 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me);
241 #else
242                 /* dull unselected faces so as not to get in the way of seeing color */
243                 glColor4ub(96, 96, 96, 64);
244                 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOptsInv, (void*)me);
245 #endif
246                 
247                 glDisable(GL_BLEND);
248         }
249         
250         bglPolygonOffset(rv3d->dist, 1.0);
251
252                 /* Draw Stippled Outline for selected faces */
253         glColor3ub(255, 255, 255);
254         setlinestyle(1);
255         dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data);
256         setlinestyle(0);
257
258         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
259
260         BLI_edgehash_free(data.eh, NULL);
261 }
262
263 static Material *give_current_material_or_def(Object *ob, int matnr)
264 {
265         extern Material defmaterial;    // render module abuse...
266         Material *ma= give_current_material(ob, matnr);
267
268         return ma?ma:&defmaterial;
269 }
270
271 static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
272 {
273         static int c_textured;
274         static int c_lit;
275         static int c_doublesided;
276         static MTFace *c_texface;
277         static Object *c_litob;
278         static int c_litmatnr;
279         static int c_badtex;
280
281         if (clearcache) {
282                 c_textured= c_lit= c_doublesided= -1;
283                 c_texface= (MTFace*) -1;
284                 c_litob= (Object*) -1;
285                 c_litmatnr= -1;
286                 c_badtex= 0;
287         }
288
289         if (texface) {
290                 lit = lit && (lit==-1 || texface->mode&TF_LIGHT);
291                 textured = textured && (texface->mode&TF_TEX);
292                 doublesided = texface->mode&TF_TWOSIDE;
293         } else {
294                 textured = 0;
295         }
296
297         if (doublesided!=c_doublesided) {
298                 if (doublesided) glDisable(GL_CULL_FACE);
299                 else glEnable(GL_CULL_FACE);
300
301                 c_doublesided= doublesided;
302         }
303
304         if (textured!=c_textured || texface!=c_texface) {
305                 if (textured ) {
306                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT));
307                 } else {
308                         GPU_set_tpage(NULL, 0);
309                         c_badtex= 0;
310                 }
311                 c_textured= textured;
312                 c_texface= texface;
313         }
314
315         if (c_badtex) lit= 0;
316         if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
317                 if (lit) {
318                         Material *ma= give_current_material_or_def(litob, litmatnr+1);
319                         float spec[4];
320
321                         spec[0]= ma->spec*ma->specr;
322                         spec[1]= ma->spec*ma->specg;
323                         spec[2]= ma->spec*ma->specb;
324                         spec[3]= 1.0;
325
326                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
327                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
328                         glEnable(GL_LIGHTING);
329                         glEnable(GL_COLOR_MATERIAL);
330                 }
331                 else {
332                         glDisable(GL_LIGHTING); 
333                         glDisable(GL_COLOR_MATERIAL);
334                 }
335                 c_lit= lit;
336                 c_litob= litob;
337                 c_litmatnr= litmatnr;
338         }
339
340         return c_badtex;
341 }
342
343 /* Icky globals, fix with userdata parameter */
344
345 static struct TextureDrawState {
346         Object *ob;
347         int islit, istex;
348         int color_profile;
349         unsigned char obcol[4];
350 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
351
352 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
353 {
354         unsigned char obcol[4];
355         int istex, solidtex= 0;
356
357         // XXX scene->obedit warning
358         if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
359                 /* draw with default lights in solid draw mode and edit mode */
360                 solidtex= 1;
361                 Gtexdraw.islit= -1;
362         }
363         else {
364                 /* draw with lights in the scene otherwise */
365                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, get_view3d_ortho(v3d, rv3d));
366         }
367         
368         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
369         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
370         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
371         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
372         
373         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
374         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
375         else istex= 0;
376
377         Gtexdraw.ob = ob;
378         Gtexdraw.istex = istex;
379         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
380         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
381         set_draw_settings_cached(1, 0, 0, Gtexdraw.islit, 0, 0, 0);
382         glShadeModel(GL_SMOOTH);
383 }
384
385 static void draw_textured_end(void)
386 {
387         /* switch off textures */
388         GPU_set_tpage(NULL, 0);
389
390         glShadeModel(GL_FLAT);
391         glDisable(GL_CULL_FACE);
392
393         /* XXX, bad patch - GPU_default_lights() calls
394          * glLightfv(GL_LIGHT_POSITION, ...) which
395          * is transformed by the current matrix... we
396          * need to make sure that matrix is identity.
397          * 
398          * It would be better if drawmesh.c kept track
399          * of and restored the light settings it changed.
400          *  - zr
401          */
402         glPushMatrix();
403         glLoadIdentity();       
404         GPU_default_lights();
405         glPopMatrix();
406 }
407
408 static int draw_tface__set_draw_legacy(MTFace *tface, int has_vcol, int matnr)
409 {
410         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
411
412         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
413                 glColor3ub(0xFF, 0x00, 0xFF);
414                 return 2; /* Don't set color */
415         } else if (tface && tface->mode&TF_OBCOL) {
416                 glColor3ubv(Gtexdraw.obcol);
417                 return 2; /* Don't set color */
418         } else if (!has_vcol) {
419                 if (tface) glColor3f(1.0, 1.0, 1.0);
420                 else {
421                         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
422                         if(ma) {
423                                 float col[3];
424                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
425                                 else copy_v3_v3(col, &ma->r);
426                                 
427                                 glColor3fv(col);
428                         }
429                         else glColor3f(1.0, 1.0, 1.0);
430                 }
431                 return 2; /* Don't set color */
432         } else {
433                 return 1; /* Set color from mcol */
434         }
435 }
436 static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
437 {
438         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
439
440         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
441                 return 2; /* Don't set color */
442         } else if (tface && tface->mode&TF_OBCOL) {
443                 return 2; /* Don't set color */
444         } else if (!mcol) {
445                 return 1; /* Don't set color */
446         } else {
447                 return 1; /* Set color from mcol */
448         }
449 }
450 static void add_tface_color_layer(DerivedMesh *dm)
451 {
452         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
453         MFace *mface = dm->getTessFaceArray(dm);
454         MCol *finalCol;
455         int i,j;
456         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
457         if(!mcol)
458                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
459
460         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
461         for(i=0;i<dm->getNumTessFaces(dm);i++) {
462                 if (tface && (tface->mode&TF_INVISIBLE)) {
463                         if( mcol )
464                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
465                         else
466                                 for(j=0;j<4;j++) {
467                                         finalCol[i*4+j].b = 255;
468                                         finalCol[i*4+j].g = 255;
469                                         finalCol[i*4+j].r = 255;
470                                 }
471                 }
472                 else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
473                         for(j=0;j<4;j++) {
474                                 finalCol[i*4+j].b = 255;
475                                 finalCol[i*4+j].g = 0;
476                                 finalCol[i*4+j].r = 255;
477                         }
478                 } else if (tface && tface->mode&TF_OBCOL) {
479                         for(j=0;j<4;j++) {
480                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]);
481                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
482                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]);
483                         }
484                 } else if (!mcol) {
485                         if (tface) {
486                                 for(j=0;j<4;j++) {
487                                         finalCol[i*4+j].b = 255;
488                                         finalCol[i*4+j].g = 255;
489                                         finalCol[i*4+j].r = 255;
490                                 }
491                         }
492                         else {
493                                 float col[3];
494                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
495                                 
496                                 if(ma) {
497                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
498                                         else copy_v3_v3(col, &ma->r);
499                                         
500                                         for(j=0;j<4;j++) {
501                                                 finalCol[i*4+j].b = FTOCHAR(col[2]);
502                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
503                                                 finalCol[i*4+j].r = FTOCHAR(col[0]);
504                                         }
505                                 }
506                                 else
507                                         for(j=0;j<4;j++) {
508                                                 finalCol[i*4+j].b = 255;
509                                                 finalCol[i*4+j].g = 255;
510                                                 finalCol[i*4+j].r = 255;
511                                         }
512                         }
513                 } else {
514                         for(j=0;j<4;j++) {
515                                 finalCol[i*4+j].b = mcol[i*4+j].r;
516                                 finalCol[i*4+j].g = mcol[i*4+j].g;
517                                 finalCol[i*4+j].r = mcol[i*4+j].b;
518                         }
519                 }
520         }
521         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
522 }
523
524 static int draw_tface_mapped__set_draw(void *userData, int index)
525 {
526         Mesh *me = (Mesh*)userData;
527         MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
528         MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
529         MTFace mtf;
530         int matnr = me->mpoly[index].mat_nr;
531
532         if (mpoly && mpoly->flag&ME_HIDE) return 0;
533
534         memset(&mtf, 0, sizeof(mtf));
535         if (tpoly) {
536                 mtf.flag = tpoly->flag;
537                 mtf.tpage = tpoly->tpage;
538                 mtf.transp = tpoly->transp;
539                 mtf.mode = tpoly->mode;
540                 mtf.tile = tpoly->tile;
541                 mtf.unwrap = tpoly->unwrap;
542         }
543
544         return draw_tface__set_draw(&mtf, CustomData_has_layer(&me->ldata, CD_MLOOPCOL), matnr);
545 }
546
547 static int draw_em_tf_mapped__set_draw(void *userData, int index)
548 {
549         BMEditMesh *em = userData;
550         BMFace *efa= EDBM_get_face_for_index(em, index);
551         MTexPoly *tpoly;
552         MTFace mtf;
553         int matnr, has_vcol;
554
555         if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN))
556                 return 0;
557
558         tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
559         has_vcol = CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL);
560         matnr = efa->mat_nr;
561
562         memset(&mtf, 0, sizeof(mtf));
563
564         if (tpoly) {
565                 mtf.flag = tpoly->flag;
566                 mtf.tpage = tpoly->tpage;
567                 mtf.transp = tpoly->transp;
568                 mtf.mode = tpoly->mode;
569                 mtf.tile = tpoly->tile;
570                 mtf.unwrap = tpoly->unwrap;
571         }
572
573         return draw_tface__set_draw_legacy(&mtf, has_vcol, matnr);
574 }
575
576 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
577 {
578         Mesh *me = (Mesh*)userData;
579
580         if (    (me->mface && me->mface[index].flag & ME_HIDE) ||
581                         (me->mtface && (me->mtface[index].mode & TF_INVISIBLE))
582         ) {
583                 return 0;
584         }
585
586         *drawSmooth_r = 1;
587         return 1;
588 }
589
590 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
591 {
592         Mesh *me = ob->data;
593         DerivedMesh *ddm;
594         MFace *mf, *mface= me->mface;
595         MTFace *tface= me->mtface;
596         MCol *mcol= me->mcol;   /* why does mcol exist? */
597         bProperty *prop = get_ob_property(ob, "Text");
598         GPUVertexAttribs gattribs;
599         int a, totface= me->totface;
600
601         /* don't draw without tfaces */
602         if(!tface)
603                 return;
604
605         /* don't draw when editing */
606         if(ob->mode & OB_MODE_EDIT)
607                 return;
608         else if(ob==OBACT)
609                 if(paint_facesel_test(ob))
610                         return;
611
612         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
613
614         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
615                 int mode= tface->mode;
616                 int matnr= mf->mat_nr;
617                 int mf_smooth= mf->flag & ME_SMOOTH;
618
619                 if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
620                         float v1[3], v2[3], v3[3], v4[3];
621                         char string[MAX_PROPSTRING];
622                         int characters, i, glattrib= -1, badtex= 0;
623
624                         if(glsl) {
625                                 GPU_enable_material(matnr+1, &gattribs);
626
627                                 for(i=0; i<gattribs.totlayer; i++) {
628                                         if(gattribs.layer[i].type == CD_MTFACE) {
629                                                 glattrib = gattribs.layer[i].glindex;
630                                                 break;
631                                         }
632                                 }
633                         }
634                         else {
635                                 badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
636                                 if (badtex) {
637                                         if (mcol) mcol+=4;
638                                         continue;
639                                 }
640                         }
641
642                         ddm->getVertCo(ddm, mf->v1, v1);
643                         ddm->getVertCo(ddm, mf->v2, v2);
644                         ddm->getVertCo(ddm, mf->v3, v3);
645                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
646
647                         // The BM_FONT handling is in the gpu module, shared with the
648                         // game engine, was duplicated previously
649
650                         set_property_valstr(prop, string);
651                         characters = strlen(string);
652                         
653                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
654                                 characters = 0;
655
656                         if (!mf_smooth) {
657                                 float nor[3];
658
659                                 normal_tri_v3( nor,v1, v2, v3);
660
661                                 glNormal3fv(nor);
662                         }
663
664                         GPU_render_text(tface, tface->mode, string, characters,
665                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
666                 }
667                 if (mcol) {
668                         mcol+=4;
669                 }
670         }
671
672         ddm->release(ddm);
673 }
674
675 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
676 {
677         Mesh *me= ob->data;
678         
679         /* correct for negative scale */
680         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
681         else glFrontFace(GL_CCW);
682         
683         /* draw the textured mesh */
684         draw_textured_begin(scene, v3d, rv3d, ob);
685
686         glColor4f(1.0f,1.0f,1.0f,1.0f);
687
688         if(ob->mode & OB_MODE_EDIT) {
689                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_btmesh);
690         } else if(faceselect) {
691                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
692                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material);
693                 else
694                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
695         }
696         else {
697                 if( GPU_buffer_legacy(dm) )
698                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
699                 else {
700                         if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) )
701                                 add_tface_color_layer(dm);
702                         dm->drawFacesTex(dm, draw_tface__set_draw);
703                 }
704         }
705
706         /* draw game engine text hack */
707         if(get_ob_property(ob, "Text")) 
708                 draw_mesh_text(scene, ob, 0);
709
710         draw_textured_end();
711         
712         /* draw edges and selected faces over textured mesh */
713         if(!(ob == scene->obedit) && faceselect)
714                 draw_tfaces3D(rv3d, me, dm, ob->mode & OB_MODE_WEIGHT_PAINT);
715
716         /* reset from negative scale correction */
717         glFrontFace(GL_CCW);
718         
719         /* in editmode, the blend mode needs to be set incase it was ADD */
720         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
721 }
722