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