Another rip fix for rip grabbing the wrong side of the split edges
[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= 0;
316
317         // XXX scene->obedit warning
318         if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
319                 /* draw with default lights in solid draw mode and edit mode */
320                 solidtex= 1;
321                 Gtexdraw.islit= -1;
322         }
323         else {
324                 /* draw with lights in the scene otherwise */
325                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
326         }
327         
328         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
329         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
330         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
331         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
332         
333         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
334         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
335         else istex= 0;
336
337         Gtexdraw.ob = ob;
338         Gtexdraw.istex = istex;
339         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
340         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
341         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
342         glShadeModel(GL_SMOOTH);
343 }
344
345 static void draw_textured_end(void)
346 {
347         /* switch off textures */
348         GPU_set_tpage(NULL, 0, 0);
349
350         glShadeModel(GL_FLAT);
351         glDisable(GL_CULL_FACE);
352
353         /* XXX, bad patch - GPU_default_lights() calls
354          * glLightfv(GL_LIGHT_POSITION, ...) which
355          * is transformed by the current matrix... we
356          * need to make sure that matrix is identity.
357          * 
358          * It would be better if drawmesh.c kept track
359          * of and restored the light settings it changed.
360          *  - zr
361          */
362         glPushMatrix();
363         glLoadIdentity();       
364         GPU_default_lights();
365         glPopMatrix();
366 }
367
368 static int draw_tface__set_draw_legacy(MTFace *tface, int has_vcol, int matnr)
369 {
370         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
371         int validtexture=0;
372
373         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
374
375         validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
376
377         if (tface && validtexture) {
378                 glColor3ub(0xFF, 0x00, 0xFF);
379                 return 2; /* Don't set color */
380         } else if (ma && ma->shade_flag&MA_OBCOLOR) {
381                 glColor3ubv(Gtexdraw.obcol);
382                 return 2; /* Don't set color */
383         } else if (!has_vcol) {
384                 if (tface) glColor3f(1.0, 1.0, 1.0);
385                 else {
386                         if(ma) {
387                                 float col[3];
388                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
389                                 else copy_v3_v3(col, &ma->r);
390                                 
391                                 glColor3fv(col);
392                         }
393                         else glColor3f(1.0, 1.0, 1.0);
394                 }
395                 return 2; /* Don't set color */
396         } else {
397                 return 1; /* Set color from mcol */
398         }
399 }
400 static int draw_tface__set_draw(MTFace *tface, int has_vcol, int matnr)
401 {
402         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
403
404         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
405
406         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
407                 return 2; /* Don't set color */
408         } else if (tface && tface->mode&TF_OBCOL) {
409                 return 2; /* Don't set color */
410         } else if (!has_vcol) {
411                 return 1; /* Don't set color */
412         } else {
413                 return 1; /* Set color from mcol */
414         }
415 }
416 static void add_tface_color_layer(DerivedMesh *dm)
417 {
418         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
419         MFace *mface = dm->getTessFaceArray(dm);
420         MCol *finalCol;
421         int i,j;
422         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
423         if(!mcol)
424                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
425
426         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
427         for(i=0;i<dm->getNumTessFaces(dm);i++) {
428                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
429
430                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
431                         if( mcol )
432                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
433                         else
434                                 for(j=0;j<4;j++) {
435                                         finalCol[i*4+j].b = 255;
436                                         finalCol[i*4+j].g = 255;
437                                         finalCol[i*4+j].r = 255;
438                                 }
439                 }
440                 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
441                         for(j=0;j<4;j++) {
442                                 finalCol[i*4+j].b = 255;
443                                 finalCol[i*4+j].g = 0;
444                                 finalCol[i*4+j].r = 255;
445                         }
446                 } else if (tface && tface->mode&TF_OBCOL) {
447                         for(j=0;j<4;j++) {
448                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]);
449                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
450                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]);
451                         }
452                 } else if (!mcol) {
453                         if (tface) {
454                                 for(j=0;j<4;j++) {
455                                         finalCol[i*4+j].b = 255;
456                                         finalCol[i*4+j].g = 255;
457                                         finalCol[i*4+j].r = 255;
458                                 }
459                         }
460                         else {
461                                 float col[3];
462                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
463                                 
464                                 if(ma) {
465                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
466                                         else copy_v3_v3(col, &ma->r);
467                                         
468                                         for(j=0;j<4;j++) {
469                                                 finalCol[i*4+j].b = FTOCHAR(col[2]);
470                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
471                                                 finalCol[i*4+j].r = FTOCHAR(col[0]);
472                                         }
473                                 }
474                                 else
475                                         for(j=0;j<4;j++) {
476                                                 finalCol[i*4+j].b = 255;
477                                                 finalCol[i*4+j].g = 255;
478                                                 finalCol[i*4+j].r = 255;
479                                         }
480                         }
481                 } else {
482                         for(j=0;j<4;j++) {
483                                 finalCol[i*4+j].b = mcol[i*4+j].r;
484                                 finalCol[i*4+j].g = mcol[i*4+j].g;
485                                 finalCol[i*4+j].r = mcol[i*4+j].b;
486                         }
487                 }
488         }
489         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
490 }
491
492 static int draw_tface_mapped__set_draw(void *userData, int index)
493 {
494         Mesh *me = (Mesh*)userData;
495         MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
496         MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
497         MTFace mtf;
498         int has_vcol= (me->mcol != NULL);
499         int matnr = me->mpoly[index].mat_nr;
500
501         if (mpoly && mpoly->flag&ME_HIDE) return 0;
502
503         memset(&mtf, 0, sizeof(mtf));
504         if (tpoly) {
505                 mtf.flag = tpoly->flag;
506                 mtf.tpage = tpoly->tpage;
507                 mtf.transp = tpoly->transp;
508                 mtf.mode = tpoly->mode;
509                 mtf.tile = tpoly->tile;
510                 mtf.unwrap = tpoly->unwrap;
511         }
512
513         return draw_tface__set_draw(&mtf, has_vcol, matnr);
514 }
515
516 static int draw_em_tf_mapped__set_draw(void *userData, int index)
517 {
518         BMEditMesh *em = userData;
519         BMFace *efa= EDBM_get_face_for_index(em, index);
520         MTexPoly *tpoly;
521         MTFace mtf;
522         int has_vcol;
523         int matnr;
524
525         if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN))
526                 return 0;
527
528         tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
529         has_vcol = CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL);
530         matnr = efa->mat_nr;
531
532         memset(&mtf, 0, sizeof(mtf));
533
534         if (tpoly) {
535                 mtf.flag = tpoly->flag;
536                 mtf.tpage = tpoly->tpage;
537                 mtf.transp = tpoly->transp;
538                 mtf.mode = tpoly->mode;
539                 mtf.tile = tpoly->tile;
540                 mtf.unwrap = tpoly->unwrap;
541         }
542
543         return draw_tface__set_draw_legacy(&mtf, has_vcol, matnr);
544 }
545
546 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
547 {
548         Mesh *me = (Mesh*)userData;
549
550         if (me->mface) {
551                 short matnr= me->mface[index].mat_nr;
552                 Material *ma= me->mat[matnr];
553
554                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
555                         return 0;
556                 }
557         }
558
559         *drawSmooth_r = 1;
560         return 1;
561 }
562
563 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
564 {
565         Mesh *me = ob->data;
566         DerivedMesh *ddm;
567         MFace *mf, *mface= me->mface;
568         MTFace *tface= me->mtface;
569         MCol *mcol= me->mcol;   /* why does mcol exist? */
570         bProperty *prop = get_ob_property(ob, "Text");
571         GPUVertexAttribs gattribs;
572         int a, totface= me->totface;
573
574         /* don't draw without tfaces */
575         if(!tface)
576                 return;
577
578         /* don't draw when editing */
579         if(ob->mode & OB_MODE_EDIT)
580                 return;
581         else if(ob==OBACT)
582                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
583                         return;
584
585         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
586
587         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
588                 short matnr= mf->mat_nr;
589                 int mf_smooth= mf->flag & ME_SMOOTH;
590                 Material *mat = me->mat[matnr];
591                 int mode= mat->game.flag;
592
593                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
594                         float v1[3], v2[3], v3[3], v4[3];
595                         char string[MAX_PROPSTRING];
596                         int characters, i, glattrib= -1, badtex= 0;
597
598                         if(glsl) {
599                                 GPU_enable_material(matnr+1, &gattribs);
600
601                                 for(i=0; i<gattribs.totlayer; i++) {
602                                         if(gattribs.layer[i].type == CD_MTFACE) {
603                                                 glattrib = gattribs.layer[i].glindex;
604                                                 break;
605                                         }
606                                 }
607                         }
608                         else {
609                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
610                                 if (badtex) {
611                                         if (mcol) mcol+=4;
612                                         continue;
613                                 }
614                         }
615
616                         ddm->getVertCo(ddm, mf->v1, v1);
617                         ddm->getVertCo(ddm, mf->v2, v2);
618                         ddm->getVertCo(ddm, mf->v3, v3);
619                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
620
621                         // The BM_FONT handling is in the gpu module, shared with the
622                         // game engine, was duplicated previously
623
624                         set_property_valstr(prop, string);
625                         characters = strlen(string);
626                         
627                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
628                                 characters = 0;
629
630                         if (!mf_smooth) {
631                                 float nor[3];
632
633                                 normal_tri_v3( nor,v1, v2, v3);
634
635                                 glNormal3fv(nor);
636                         }
637
638                         GPU_render_text(tface, mode, string, characters,
639                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
640                 }
641                 if (mcol) {
642                         mcol+=4;
643                 }
644         }
645
646         ddm->release(ddm);
647 }
648
649 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
650 {
651         Mesh *me= ob->data;
652         
653         /* correct for negative scale */
654         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
655         else glFrontFace(GL_CCW);
656         
657         /* draw the textured mesh */
658         draw_textured_begin(scene, v3d, rv3d, ob);
659
660         glColor4f(1.0f,1.0f,1.0f,1.0f);
661
662         if(ob->mode & OB_MODE_EDIT) {
663                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_btmesh);
664         }
665         else if(faceselect) {
666                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
667                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
668                 else
669                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
670         }
671         else {
672                 if(GPU_buffer_legacy(dm)) {
673                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
674                 }
675                 else {
676                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
677                                 add_tface_color_layer(dm);
678
679                         dm->drawFacesTex(dm, draw_tface__set_draw);
680                 }
681         }
682
683         /* draw game engine text hack */
684         if(get_ob_property(ob, "Text")) 
685                 draw_mesh_text(scene, ob, 0);
686
687         draw_textured_end();
688         
689         /* draw edges and selected faces over textured mesh */
690         if(!(ob == scene->obedit) && faceselect)
691                 draw_mesh_face_select(rv3d, me, dm);
692
693         /* reset from negative scale correction */
694         glFrontFace(GL_CCW);
695         
696         /* in editmode, the blend mode needs to be set incase it was ADD */
697         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
698 }
699