svn merge ^/trunk/blender -r42757:42759
[blender.git] / source / blender / editors / space_view3d / drawmesh.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation, full update, glsl support
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/space_view3d/drawmesh.c
27  *  \ingroup spview3d
28  */
29
30 #include <string.h>
31 #include <math.h>
32
33 #include "MEM_guardedalloc.h"
34
35 #include "BLI_utildefines.h"
36 #include "BLI_blenlib.h"
37 #include "BLI_math.h"
38 #include "BLI_edgehash.h"
39 #include "BLI_editVert.h"
40 #include "BLI_utildefines.h"
41
42 #include "DNA_material_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_node_types.h"
45 #include "DNA_object_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
52 #include "BKE_DerivedMesh.h"
53 #include "BKE_effect.h"
54 #include "BKE_image.h"
55 #include "BKE_material.h"
56 #include "BKE_paint.h"
57 #include "BKE_property.h"
58 #include "BKE_tessmesh.h"
59 #include "BKE_scene.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 #include "ED_uvedit.h"
73
74 #include "view3d_intern.h"      // own include
75
76 /* user data structures for derived mesh callbacks */
77 typedef struct drawMeshFaceSelect_userData {
78         Mesh *me;
79         EdgeHash *eh;
80 } drawMeshFaceSelect_userData;
81
82 typedef struct drawEMTFMapped_userData {
83         BMEditMesh *em;
84         short has_mcol;
85         short has_mtface;
86         MFace *mf;
87         MTFace *tf;
88 } drawEMTFMapped_userData;
89
90 typedef struct drawTFace_userData {
91         MFace *mf;
92         MTFace *tf;
93 } drawTFace_userData;
94
95 /**************************** Face Select Mode *******************************/
96
97 /* Flags for marked edges */
98 enum {
99         eEdge_Visible = (1<<0),
100         eEdge_Select = (1<<1),
101 };
102
103 /* Creates a hash of edges to flags indicating selected/visible */
104 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
105 {
106         int *flags_p;
107
108         if(!BLI_edgehash_haskey(eh, v0, v1))
109                 BLI_edgehash_insert(eh, v0, v1, NULL);
110
111         flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
112         *flags_p |= flags;
113 }
114
115 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
116 {
117         EdgeHash *eh = BLI_edgehash_new();
118         MFace *mf;
119         int i;
120         
121         for(i=0; i<me->totface; i++) {
122                 mf = &me->mface[i];
123
124                 if(!(mf->flag & ME_HIDE)) {
125                         unsigned int flags = eEdge_Visible;
126                         if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
127
128                         get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
129                         get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
130
131                         if(mf->v4) {
132                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
133                                 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
134                         }
135                         else
136                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
137                 }
138         }
139
140         return eh;
141 }
142
143
144 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
145 {
146         drawMeshFaceSelect_userData *data = userData;
147         Mesh *me= data->me;
148         MEdge *med = &me->medge[index];
149         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
150
151         if(me->drawflag & ME_DRAWEDGES) { 
152                 if(me->drawflag & ME_HIDDENEDGES)
153                         return 1;
154                 else
155                         return (flags & eEdge_Visible);
156         }
157         else
158                 return (flags & eEdge_Select);
159 }
160
161 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
162 {
163         drawMeshFaceSelect_userData *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 /* draws unselected */
171 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
172 {
173         Mesh *me = (Mesh*)userData;
174
175         MPoly *mface = &me->mpoly[index];
176         if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
177                 return 2; /* Don't set color */
178         else
179                 return 0;
180 }
181
182 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
183 {
184         drawMeshFaceSelect_userData data;
185
186         data.me = me;
187         data.eh = get_tface_mesh_marked_edge_info(me);
188
189         glEnable(GL_DEPTH_TEST);
190         glDisable(GL_LIGHTING);
191         bglPolygonOffset(rv3d->dist, 1.0);
192
193         /* Draw (Hidden) Edges */
194         setlinestyle(1);
195         UI_ThemeColor(TH_EDGE_FACESEL);
196         dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
197         setlinestyle(0);
198
199         /* Draw Selected Faces */
200         if(me->drawflag & ME_DRAWFACES) {
201                 glEnable(GL_BLEND);
202                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
203                 /* dull unselected faces so as not to get in the way of seeing color */
204                 glColor4ub(96, 96, 96, 64);
205                 dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, (void*)me);
206                 
207                 glDisable(GL_BLEND);
208         }
209         
210         bglPolygonOffset(rv3d->dist, 1.0);
211
212                 /* Draw Stippled Outline for selected faces */
213         glColor3ub(255, 255, 255);
214         setlinestyle(1);
215         dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
216         setlinestyle(0);
217
218         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
219
220         BLI_edgehash_free(data.eh, NULL);
221 }
222
223 /***************************** Texture Drawing ******************************/
224
225 static Material *give_current_material_or_def(Object *ob, int matnr)
226 {
227         extern Material defmaterial;    // render module abuse...
228         Material *ma= give_current_material(ob, matnr);
229
230         return ma?ma:&defmaterial;
231 }
232
233 /* Icky globals, fix with userdata parameter */
234
235 static struct TextureDrawState {
236         Object *ob;
237         int islit, istex;
238         int color_profile;
239         unsigned char obcol[4];
240 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
241
242 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
243 {
244         static Material *c_ma;
245         static int c_textured;
246         static MTFace *c_texface;
247         static int c_backculled;
248         static int c_badtex;
249         static int c_lit;
250
251         Object *litob = NULL; //to get mode to turn off mipmap in painting mode
252         int backculled = GEMAT_BACKCULL;
253         int alphablend = 0;
254         int textured = 0;
255         int lit = 0;
256         
257         if (clearcache) {
258                 c_textured= c_lit= c_backculled= -1;
259                 c_texface= (MTFace*) -1;
260                 c_badtex= 0;
261         } else {
262                 textured = gtexdraw.istex;
263                 litob = gtexdraw.ob;
264         }
265
266         /* convert number of lights into boolean */
267         if (gtexdraw.islit) lit = 1;
268
269         if (ma) {
270                 alphablend = ma->game.alpha_blend;
271                 if (ma->mode & MA_SHLESS) lit = 0;
272                 backculled = ma->game.flag & GEMAT_BACKCULL;
273         }
274
275         if (texface) {
276                 textured = textured && (texface->tpage);
277
278                 /* no material, render alpha if texture has depth=32 */
279                 if (!ma && BKE_image_has_alpha(texface->tpage))
280                         alphablend = GPU_BLEND_ALPHA;
281         }
282
283         else
284                 textured = 0;
285
286         if (backculled!=c_backculled) {
287                 if (backculled) glEnable(GL_CULL_FACE);
288                 else glDisable(GL_CULL_FACE);
289
290                 c_backculled= backculled;
291         }
292
293         if (textured!=c_textured || texface!=c_texface) {
294                 if (textured ) {
295                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
296                 } else {
297                         GPU_set_tpage(NULL, 0, 0);
298                         c_badtex= 0;
299                 }
300                 c_textured= textured;
301                 c_texface= texface;
302         }
303
304         if (c_badtex) lit= 0;
305         if (lit!=c_lit || ma!=c_ma) {
306                 if (lit) {
307                         float spec[4];
308                         if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
309
310                         spec[0]= ma->spec*ma->specr;
311                         spec[1]= ma->spec*ma->specg;
312                         spec[2]= ma->spec*ma->specb;
313                         spec[3]= 1.0;
314
315                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
316                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
317                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
318                         glEnable(GL_LIGHTING);
319                         glEnable(GL_COLOR_MATERIAL);
320                 }
321                 else {
322                         glDisable(GL_LIGHTING); 
323                         glDisable(GL_COLOR_MATERIAL);
324                 }
325                 c_lit= lit;
326         }
327
328         return c_badtex;
329 }
330
331 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
332 {
333         unsigned char obcol[4];
334         int istex, solidtex;
335
336         // XXX scene->obedit warning
337
338         /* texture draw is abused for mask selection mode, do this so wire draw
339          * with face selection in weight paint is not lit. */
340         if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
341                 solidtex= FALSE;
342                 Gtexdraw.islit= 0;
343         }
344         else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
345                 /* draw with default lights in solid draw mode and edit mode */
346                 solidtex= TRUE;
347                 Gtexdraw.islit= -1;
348         }
349         else {
350                 /* draw with lights in the scene otherwise */
351                 solidtex= FALSE;
352                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
353         }
354         
355         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
356         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
357         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
358         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
359         
360         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
361         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
362         else istex= 0;
363
364         Gtexdraw.ob = ob;
365         Gtexdraw.istex = istex;
366         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
367         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
368         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
369         glShadeModel(GL_SMOOTH);
370 }
371
372 static void draw_textured_end(void)
373 {
374         /* switch off textures */
375         GPU_set_tpage(NULL, 0, 0);
376
377         glShadeModel(GL_FLAT);
378         glDisable(GL_CULL_FACE);
379
380         /* XXX, bad patch - GPU_default_lights() calls
381          * glLightfv(GL_LIGHT_POSITION, ...) which
382          * is transformed by the current matrix... we
383          * need to make sure that matrix is identity.
384          * 
385          * It would be better if drawmesh.c kept track
386          * of and restored the light settings it changed.
387          *  - zr
388          */
389         glPushMatrix();
390         glLoadIdentity();       
391         GPU_default_lights();
392         glPopMatrix();
393 }
394
395 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
396 {
397         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
398         int validtexture=0;
399
400         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
401
402         validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
403
404         if (tface && validtexture) {
405                 glColor3ub(0xFF, 0x00, 0xFF);
406                 return 2; /* Don't set color */
407         } else if (ma && ma->shade_flag&MA_OBCOLOR) {
408                 glColor3ubv(Gtexdraw.obcol);
409                 return 2; /* Don't set color */
410         } else if (!has_mcol) {
411                 if (tface) glColor3f(1.0, 1.0, 1.0);
412                 else {
413                         if(ma) {
414                                 float col[3];
415                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
416                                 else copy_v3_v3(col, &ma->r);
417                                 
418                                 glColor3fv(col);
419                         }
420                         else glColor3f(1.0, 1.0, 1.0);
421                 }
422                 return 2; /* Don't set color */
423         } else {
424                 return 1; /* Set color from mcol */
425         }
426 }
427
428 static int draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
429 {
430         if (has_mcol) return 1;
431         else return 2;
432 }
433
434 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
435 {
436         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
437
438         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
439
440         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
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 (!has_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_poly_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                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
463
464                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
465                         if( mcol )
466                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
467                         else
468                                 for(j=0;j<4;j++) {
469                                         finalCol[i*4+j].b = 255;
470                                         finalCol[i*4+j].g = 255;
471                                         finalCol[i*4+j].r = 255;
472                                 }
473                 }
474                 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
475                         for(j=0;j<4;j++) {
476                                 finalCol[i*4+j].b = 255;
477                                 finalCol[i*4+j].g = 0;
478                                 finalCol[i*4+j].r = 255;
479                         }
480                 } else if (tface && tface->mode&TF_OBCOL) {
481                         for(j=0;j<4;j++) {
482                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
483                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
484                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
485                         }
486                 } else if (!mcol) {
487                         if (tface) {
488                                 for(j=0;j<4;j++) {
489                                         finalCol[i*4+j].b = 255;
490                                         finalCol[i*4+j].g = 255;
491                                         finalCol[i*4+j].r = 255;
492                                 }
493                         }
494                         else {
495                                 float col[3];
496                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
497                                 
498                                 if(ma) {
499                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
500                                         else copy_v3_v3(col, &ma->r);
501                                         
502                                         for(j=0;j<4;j++) {
503                                                 finalCol[i*4+j].b = FTOCHAR(col[0]);
504                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
505                                                 finalCol[i*4+j].r = FTOCHAR(col[2]);
506                                         }
507                                 }
508                                 else
509                                         for(j=0;j<4;j++) {
510                                                 finalCol[i*4+j].b = 255;
511                                                 finalCol[i*4+j].g = 255;
512                                                 finalCol[i*4+j].r = 255;
513                                         }
514                         }
515                 } else {
516                         for(j=0;j<4;j++) {
517                                 finalCol[i*4+j].r = mcol[i*4+j].r;
518                                 finalCol[i*4+j].g = mcol[i*4+j].g;
519                                 finalCol[i*4+j].b = mcol[i*4+j].b;
520                         }
521                 }
522         }
523         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData );
524 }
525
526 static int draw_tface_mapped__set_draw(void *userData, int index)
527 {
528         Mesh *me = (Mesh*)userData;
529         MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
530         MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
531         MTFace mtf;
532         int matnr = me->mpoly[index].mat_nr;
533
534         BLI_assert(index >= 0 && index < me->totpoly);
535
536         if (mpoly && mpoly->flag&ME_HIDE) return 0;
537
538         memset(&mtf, 0, sizeof(mtf));
539         if (tpoly) {
540                 mtf.flag = tpoly->flag;
541                 mtf.tpage = tpoly->tpage;
542                 mtf.transp = tpoly->transp;
543                 mtf.mode = tpoly->mode;
544                 mtf.tile = tpoly->tile;
545                 mtf.unwrap = tpoly->unwrap;
546         }
547
548         return draw_tface__set_draw(&mtf, (me->mcol != NULL), matnr);
549 }
550
551 static int draw_em_tf_mapped__set_draw(void *userData, int index)
552 {
553         drawEMTFMapped_userData *data = userData;
554         BMEditMesh *em = data->em;
555         BMFace *efa= EDBM_get_face_for_index(em, index);
556
557         if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN)) {
558                 return 0;
559         }
560         else {
561                 MTFace mtf= {{{0}}};
562                 int matnr = efa->mat_nr;
563
564                 if (data->has_mtface) {
565                         MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
566                         mtf.flag = tpoly->flag;
567                         mtf.tpage = tpoly->tpage;
568                         mtf.transp = tpoly->transp;
569                         mtf.mode = tpoly->mode;
570                         mtf.tile = tpoly->tile;
571                         mtf.unwrap = tpoly->unwrap;
572
573                 }
574
575                 return draw_tface__set_draw_legacy(&mtf, data->has_mcol, matnr);
576         }
577 }
578
579 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
580 {
581         Mesh *me = (Mesh*)userData;
582
583         if (me->mat && me->mpoly) {
584                 Material *ma= me->mat[me->mpoly[index].mat_nr];
585                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
586                         return 0;
587                 }
588         }
589
590         *drawSmooth_r = 1;
591         return 1;
592 }
593
594 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
595 {
596         Mesh *me = ob->data;
597         DerivedMesh *ddm;
598         MFace *mf, *mface= me->mface;
599         MTFace *tface= me->mtface;
600         MCol *mcol= me->mcol;   /* why does mcol exist? */
601         bProperty *prop = get_ob_property(ob, "Text");
602         GPUVertexAttribs gattribs;
603         int a, totface= me->totface;
604
605         /* don't draw without tfaces */
606         if(!tface)
607                 return;
608
609         /* don't draw when editing */
610         if(ob->mode & OB_MODE_EDIT)
611                 return;
612         else if(ob==OBACT)
613                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
614                         return;
615
616         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
617
618         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
619                 short matnr= mf->mat_nr;
620                 int mf_smooth= mf->flag & ME_SMOOTH;
621                 Material *mat = me->mat[matnr];
622                 int mode= mat->game.flag;
623
624                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
625                         float v1[3], v2[3], v3[3], v4[3];
626                         char string[MAX_PROPSTRING];
627                         int characters, i, glattrib= -1, badtex= 0;
628
629                         if(glsl) {
630                                 GPU_enable_material(matnr+1, &gattribs);
631
632                                 for(i=0; i<gattribs.totlayer; i++) {
633                                         if(gattribs.layer[i].type == CD_MTFACE) {
634                                                 glattrib = gattribs.layer[i].glindex;
635                                                 break;
636                                         }
637                                 }
638                         }
639                         else {
640                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
641                                 if (badtex) {
642                                         if (mcol) mcol+=4;
643                                         continue;
644                                 }
645                         }
646
647                         ddm->getVertCo(ddm, mf->v1, v1);
648                         ddm->getVertCo(ddm, mf->v2, v2);
649                         ddm->getVertCo(ddm, mf->v3, v3);
650                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
651
652                         // The BM_FONT handling is in the gpu module, shared with the
653                         // game engine, was duplicated previously
654
655                         set_property_valstr(prop, string);
656                         characters = strlen(string);
657                         
658                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
659                                 characters = 0;
660
661                         if (!mf_smooth) {
662                                 float nor[3];
663
664                                 normal_tri_v3( nor,v1, v2, v3);
665
666                                 glNormal3fv(nor);
667                         }
668
669                         GPU_render_text(tface, mode, string, characters,
670                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
671                 }
672                 if (mcol) {
673                         mcol+=4;
674                 }
675         }
676
677         ddm->release(ddm);
678 }
679
680 static int compareDrawOptions(void *userData, int cur_index, int next_index)
681 {
682         drawTFace_userData *data = userData;
683
684         if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
685                 return 0;
686
687         if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
688                 return 0;
689
690         return 1;
691 }
692
693 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
694 {
695         drawEMTFMapped_userData *data= userData;
696
697         if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
698                 return 0;
699
700         if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
701                 return 0;
702
703         return 1;
704 }
705
706 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
707 {
708         Mesh *me= ob->data;
709         
710         /* correct for negative scale */
711         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
712         else glFrontFace(GL_CCW);
713         
714         /* draw the textured mesh */
715         draw_textured_begin(scene, v3d, rv3d, ob);
716
717         glColor4f(1.0f,1.0f,1.0f,1.0f);
718
719         if(ob->mode & OB_MODE_EDIT) {
720                 drawEMTFMapped_userData data;
721
722                 data.em= me->edit_btmesh;
723                 data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
724                 data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
725                 data.mf= DM_get_tessface_data_layer(dm, CD_MFACE);
726                 data.tf= DM_get_tessface_data_layer(dm, CD_MTFACE);
727
728                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
729         }
730         else if(draw_flags & DRAW_FACE_SELECT) {
731                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
732                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, GPU_enable_material, NULL, me, 1);
733                 else
734                         dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, NULL, me);
735         }
736         else {
737                 if(GPU_buffer_legacy(dm)) {
738                         if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
739                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
740                         else 
741                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
742                 }
743                 else {
744                         drawTFace_userData userData;
745
746                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
747                                 add_tface_color_layer(dm);
748
749                         userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
750                         userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
751
752                         dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
753                 }
754         }
755
756         /* draw game engine text hack */
757         if(get_ob_property(ob, "Text")) 
758                 draw_mesh_text(scene, ob, 0);
759
760         draw_textured_end();
761         
762         /* draw edges and selected faces over textured mesh */
763         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
764                 draw_mesh_face_select(rv3d, me, dm);
765
766         /* reset from negative scale correction */
767         glFrontFace(GL_CCW);
768         
769         /* in editmode, the blend mode needs to be set incase it was ADD */
770         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
771 }
772
773 /************************** NEW SHADING NODES ********************************/
774
775 typedef struct TexMatCallback {
776         Scene *scene;
777         Object *ob;
778         Mesh *me;
779         DerivedMesh *dm;
780 } TexMatCallback;
781
782 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
783 {
784         /* all we have to do here is simply enable the GLSL material, but note
785            that the GLSL code will give different result depending on the drawtype,
786            in texture draw mode it will output the active texture node, in material
787            draw mode it will show the full material. */
788         GPU_enable_material(mat_nr, attribs);
789 }
790
791 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
792 {
793         /* texture draw mode without GLSL */
794         TexMatCallback *data= (TexMatCallback*)userData;
795         GPUVertexAttribs *gattribs = attribs;
796         Image *ima;
797         ImageUser *iuser;
798         bNode *node;
799         int texture_set= 0;
800
801         /* draw image texture if we find one */
802         if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
803                 /* get openl texture */
804                 int mipmap= 1;
805                 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
806                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
807
808                 if(bindcode) {
809                         NodeTexBase *texbase= node->storage;
810
811                         /* disable existing material */
812                         GPU_disable_material();
813                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
814                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
815                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
816
817                         /* bind texture */
818                         glEnable(GL_COLOR_MATERIAL);
819                         glEnable(GL_TEXTURE_2D);
820
821                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
822                         glColor3f(1.0f, 1.0f, 1.0f);
823
824                         glMatrixMode(GL_TEXTURE);
825                         glLoadMatrixf(texbase->tex_mapping.mat);
826                         glMatrixMode(GL_MODELVIEW);
827
828                         /* use active UV texture layer */
829                         memset(gattribs, 0, sizeof(*gattribs));
830
831                         gattribs->layer[0].type= CD_MTFACE;
832                         gattribs->layer[0].name[0]= '\0';
833                         gattribs->layer[0].gltexco= 1;
834                         gattribs->totlayer= 1;
835
836                         texture_set= 1;
837                 }
838         }
839
840         if(!texture_set) {
841                 glMatrixMode(GL_TEXTURE);
842                 glLoadIdentity();
843                 glMatrixMode(GL_MODELVIEW);
844
845                 /* disable texture */
846                 glDisable(GL_TEXTURE_2D);
847                 glDisable(GL_COLOR_MATERIAL);
848
849                 /* draw single color */
850                 GPU_enable_material(mat_nr, attribs);
851         }
852 }
853
854 static int tex_mat_set_face_mesh_cb(void *userData, int index)
855 {
856         /* faceselect mode face hiding */
857         TexMatCallback *data= (TexMatCallback*)userData;
858         Mesh *me = (Mesh*)data->me;
859         MPoly *mface = &me->mpoly[index];
860
861         return !(mface->flag & ME_HIDE);
862 }
863
864 static int tex_mat_set_face_editmesh_cb(void *userData, int index)
865 {
866         /* editmode face hiding */
867         TexMatCallback *data= (TexMatCallback*)userData;
868         Mesh *me = (Mesh*)data->me;
869         BMFace *efa= EDBM_get_face_for_index(me->edit_btmesh, index);
870
871         return !BM_TestHFlag(efa, BM_HIDDEN);
872 }
873
874 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
875 {
876         if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
877                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
878                 return;
879         }
880
881         /* set opengl state for negative scale & color */
882         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
883         else glFrontFace(GL_CCW);
884
885         glEnable(GL_LIGHTING);
886
887         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
888                 /* weight paint mode exception */
889                 int useColors= 1;
890
891                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
892                         GPU_enable_material, NULL, ob->data, useColors);
893         }
894         else {
895                 Mesh *me= ob->data;
896                 TexMatCallback data = {scene, ob, me, dm};
897                 int (*set_face_cb)(void*, int);
898                 int glsl;
899                 
900                 /* face hiding callback depending on mode */
901                 if(ob == scene->obedit)
902                         set_face_cb= tex_mat_set_face_editmesh_cb;
903                 else if(draw_flags & DRAW_FACE_SELECT)
904                         set_face_cb= tex_mat_set_face_mesh_cb;
905                 else
906                         set_face_cb= NULL;
907
908                 /* test if we can use glsl */
909                 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
910
911                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
912
913                 if(glsl) {
914                         /* draw glsl */
915                         dm->drawMappedFacesMat(dm,
916                                 tex_mat_set_material_cb,
917                                 set_face_cb, &data);
918                 }
919                 else {
920                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
921
922                         /* draw textured */
923                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
924                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
925                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
926
927                         dm->drawMappedFacesMat(dm,
928                                 tex_mat_set_texture_cb,
929                                 set_face_cb, &data);
930                 }
931
932                 GPU_end_object_materials();
933         }
934
935         /* reset opengl state */
936         glDisable(GL_COLOR_MATERIAL);
937         glDisable(GL_TEXTURE_2D);
938         glDisable(GL_LIGHTING);
939         glBindTexture(GL_TEXTURE_2D, 0);
940         glFrontFace(GL_CCW);
941
942         glMatrixMode(GL_TEXTURE);
943         glLoadIdentity();
944         glMatrixMode(GL_MODELVIEW);
945
946         /* faceselect mode drawing over textured mesh */
947         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
948                 draw_mesh_face_select(rv3d, ob->data, dm);
949 }
950