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