Cycles: add location/rotate/scale and XYZ mapping options for all texture nodes,
[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_blenlib.h"
36 #include "BLI_math.h"
37 #include "BLI_edgehash.h"
38 #include "BLI_editVert.h"
39 #include "BLI_utildefines.h"
40
41 #include "DNA_material_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_node_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_property_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_view3d_types.h"
49
50 #include "BKE_DerivedMesh.h"
51 #include "BKE_effect.h"
52 #include "BKE_image.h"
53 #include "BKE_material.h"
54 #include "BKE_paint.h"
55 #include "BKE_property.h"
56 #include "BKE_scene.h"
57
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60
61 #include "UI_resources.h"
62
63 #include "GPU_buffers.h"
64 #include "GPU_extensions.h"
65 #include "GPU_draw.h"
66 #include "GPU_material.h"
67
68 #include "ED_mesh.h"
69 #include "ED_uvedit.h"
70
71 #include "view3d_intern.h"      // own include
72
73 /**************************** Face Select Mode *******************************/
74
75 /* Flags for marked edges */
76 enum {
77         eEdge_Visible = (1<<0),
78         eEdge_Select = (1<<1),
79 };
80
81 /* Creates a hash of edges to flags indicating selected/visible */
82 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
83 {
84         int *flags_p;
85
86         if(!BLI_edgehash_haskey(eh, v0, v1))
87                 BLI_edgehash_insert(eh, v0, v1, NULL);
88
89         flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
90         *flags_p |= flags;
91 }
92
93 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
94 {
95         EdgeHash *eh = BLI_edgehash_new();
96         MFace *mf;
97         int i;
98         
99         for(i=0; i<me->totface; i++) {
100                 mf = &me->mface[i];
101
102                 if(!(mf->flag & ME_HIDE)) {
103                         unsigned int flags = eEdge_Visible;
104                         if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
105
106                         get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
107                         get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
108
109                         if(mf->v4) {
110                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
111                                 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
112                         }
113                         else
114                                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
115                 }
116         }
117
118         return eh;
119 }
120
121
122 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
123 {
124         struct { Mesh *me; EdgeHash *eh; } *data = userData;
125         Mesh *me= data->me;
126         MEdge *med = &me->medge[index];
127         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
128
129         if(me->drawflag & ME_DRAWEDGES) { 
130                 if(me->drawflag & ME_HIDDENEDGES)
131                         return 1;
132                 else
133                         return (flags & eEdge_Visible);
134         }
135         else
136                 return (flags & eEdge_Select);
137 }
138
139 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
140 {
141         struct { Mesh *me; EdgeHash *eh; } *data = userData;
142         MEdge *med = &data->me->medge[index];
143         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
144
145         return flags & eEdge_Select;
146 }
147
148 /* draws unselected */
149 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
150 {
151         Mesh *me = (Mesh*)userData;
152
153         MFace *mface = &me->mface[index];
154         if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
155                 return 2; /* Don't set color */
156         else
157                 return 0;
158 }
159
160 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
161 {
162         struct { Mesh *me; EdgeHash *eh; } data;
163
164         data.me = me;
165         data.eh = get_tface_mesh_marked_edge_info(me);
166
167         glEnable(GL_DEPTH_TEST);
168         glDisable(GL_LIGHTING);
169         bglPolygonOffset(rv3d->dist, 1.0);
170
171         /* Draw (Hidden) Edges */
172         setlinestyle(1);
173         UI_ThemeColor(TH_EDGE_FACESEL);
174         dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
175         setlinestyle(0);
176
177         /* Draw Selected Faces */
178         if(me->drawflag & ME_DRAWFACES) {
179                 glEnable(GL_BLEND);
180                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181                 /* dull unselected faces so as not to get in the way of seeing color */
182                 glColor4ub(96, 96, 96, 64);
183                 dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, (void*)me);
184                 
185                 glDisable(GL_BLEND);
186         }
187         
188         bglPolygonOffset(rv3d->dist, 1.0);
189
190                 /* Draw Stippled Outline for selected faces */
191         glColor3ub(255, 255, 255);
192         setlinestyle(1);
193         dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
194         setlinestyle(0);
195
196         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
197
198         BLI_edgehash_free(data.eh, NULL);
199 }
200
201 /***************************** Texture Drawing ******************************/
202
203 static Material *give_current_material_or_def(Object *ob, int matnr)
204 {
205         extern Material defmaterial;    // render module abuse...
206         Material *ma= give_current_material(ob, matnr);
207
208         return ma?ma:&defmaterial;
209 }
210
211 /* Icky globals, fix with userdata parameter */
212
213 static struct TextureDrawState {
214         Object *ob;
215         int islit, istex;
216         int color_profile;
217         unsigned char obcol[4];
218 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
219
220 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
221 {
222         static Material *c_ma;
223         static int c_textured;
224         static MTFace *c_texface;
225         static int c_backculled;
226         static int c_badtex;
227         static int c_lit;
228
229         Object *litob = NULL; //to get mode to turn off mipmap in painting mode
230         int backculled = GEMAT_BACKCULL;
231         int alphablend = 0;
232         int textured = 0;
233         int lit = 0;
234         
235         if (clearcache) {
236                 c_textured= c_lit= c_backculled= -1;
237                 c_texface= (MTFace*) -1;
238                 c_badtex= 0;
239         } else {
240                 textured = gtexdraw.istex;
241                 litob = gtexdraw.ob;
242         }
243
244         /* convert number of lights into boolean */
245         if (gtexdraw.islit) lit = 1;
246
247         if (ma) {
248                 alphablend = ma->game.alpha_blend;
249                 if (ma->mode & MA_SHLESS) lit = 0;
250                 backculled = ma->game.flag & GEMAT_BACKCULL;
251         }
252
253         if (texface) {
254                 textured = textured && (texface->tpage);
255
256                 /* no material, render alpha if texture has depth=32 */
257                 if (!ma && BKE_image_has_alpha(texface->tpage))
258                         alphablend = GPU_BLEND_ALPHA;
259         }
260
261         else
262                 textured = 0;
263
264         if (backculled!=c_backculled) {
265                 if (backculled) glEnable(GL_CULL_FACE);
266                 else glDisable(GL_CULL_FACE);
267
268                 c_backculled= backculled;
269         }
270
271         if (textured!=c_textured || texface!=c_texface) {
272                 if (textured ) {
273                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
274                 } else {
275                         GPU_set_tpage(NULL, 0, 0);
276                         c_badtex= 0;
277                 }
278                 c_textured= textured;
279                 c_texface= texface;
280         }
281
282         if (c_badtex) lit= 0;
283         if (lit!=c_lit || ma!=c_ma) {
284                 if (lit) {
285                         float spec[4];
286                         if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
287
288                         spec[0]= ma->spec*ma->specr;
289                         spec[1]= ma->spec*ma->specg;
290                         spec[2]= ma->spec*ma->specb;
291                         spec[3]= 1.0;
292
293                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
294                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
295                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
296                         glEnable(GL_LIGHTING);
297                         glEnable(GL_COLOR_MATERIAL);
298                 }
299                 else {
300                         glDisable(GL_LIGHTING); 
301                         glDisable(GL_COLOR_MATERIAL);
302                 }
303                 c_lit= lit;
304         }
305
306         return c_badtex;
307 }
308
309 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
310 {
311         unsigned char obcol[4];
312         int istex, solidtex;
313
314         // XXX scene->obedit warning
315
316         /* texture draw is abused for mask selection mode, do this so wire draw
317          * with face selection in weight paint is not lit. */
318         if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
319                 solidtex= FALSE;
320                 Gtexdraw.islit= 0;
321         }
322         else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
323                 /* draw with default lights in solid draw mode and edit mode */
324                 solidtex= TRUE;
325                 Gtexdraw.islit= -1;
326         }
327         else {
328                 /* draw with lights in the scene otherwise */
329                 solidtex= FALSE;
330                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
331         }
332         
333         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
334         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
335         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
336         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
337         
338         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
339         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
340         else istex= 0;
341
342         Gtexdraw.ob = ob;
343         Gtexdraw.istex = istex;
344         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
345         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
346         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
347         glShadeModel(GL_SMOOTH);
348 }
349
350 static void draw_textured_end(void)
351 {
352         /* switch off textures */
353         GPU_set_tpage(NULL, 0, 0);
354
355         glShadeModel(GL_FLAT);
356         glDisable(GL_CULL_FACE);
357
358         /* XXX, bad patch - GPU_default_lights() calls
359          * glLightfv(GL_LIGHT_POSITION, ...) which
360          * is transformed by the current matrix... we
361          * need to make sure that matrix is identity.
362          * 
363          * It would be better if drawmesh.c kept track
364          * of and restored the light settings it changed.
365          *  - zr
366          */
367         glPushMatrix();
368         glLoadIdentity();       
369         GPU_default_lights();
370         glPopMatrix();
371 }
372
373 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
374 {
375         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
376         int validtexture=0;
377
378         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
379
380         validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
381
382         if (tface && validtexture) {
383                 glColor3ub(0xFF, 0x00, 0xFF);
384                 return 2; /* Don't set color */
385         } else if (ma && ma->shade_flag&MA_OBCOLOR) {
386                 glColor3ubv(Gtexdraw.obcol);
387                 return 2; /* Don't set color */
388         } else if (!has_mcol) {
389                 if (tface) glColor3f(1.0, 1.0, 1.0);
390                 else {
391                         if(ma) {
392                                 float col[3];
393                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
394                                 else copy_v3_v3(col, &ma->r);
395                                 
396                                 glColor3fv(col);
397                         }
398                         else glColor3f(1.0, 1.0, 1.0);
399                 }
400                 return 2; /* Don't set color */
401         } else {
402                 return 1; /* Set color from mcol */
403         }
404 }
405 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
406 {
407         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
408
409         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
410
411         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
412                 return 2; /* Don't set color */
413         } else if (tface && tface->mode&TF_OBCOL) {
414                 return 2; /* Don't set color */
415         } else if (!has_mcol) {
416                 return 1; /* Don't set color */
417         } else {
418                 return 1; /* Set color from mcol */
419         }
420 }
421 static void add_tface_color_layer(DerivedMesh *dm)
422 {
423         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
424         MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
425         MCol *finalCol;
426         int i,j;
427         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
428         if(!mcol)
429                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
430
431         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
432         for(i=0;i<dm->getNumFaces(dm);i++) {
433                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
434
435                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
436                         if( mcol )
437                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
438                         else
439                                 for(j=0;j<4;j++) {
440                                         finalCol[i*4+j].b = 255;
441                                         finalCol[i*4+j].g = 255;
442                                         finalCol[i*4+j].r = 255;
443                                 }
444                 }
445                 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
446                         for(j=0;j<4;j++) {
447                                 finalCol[i*4+j].b = 255;
448                                 finalCol[i*4+j].g = 0;
449                                 finalCol[i*4+j].r = 255;
450                         }
451                 } else if (tface && tface->mode&TF_OBCOL) {
452                         for(j=0;j<4;j++) {
453                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
454                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
455                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
456                         }
457                 } else if (!mcol) {
458                         if (tface) {
459                                 for(j=0;j<4;j++) {
460                                         finalCol[i*4+j].b = 255;
461                                         finalCol[i*4+j].g = 255;
462                                         finalCol[i*4+j].r = 255;
463                                 }
464                         }
465                         else {
466                                 float col[3];
467                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
468                                 
469                                 if(ma) {
470                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
471                                         else copy_v3_v3(col, &ma->r);
472                                         
473                                         for(j=0;j<4;j++) {
474                                                 finalCol[i*4+j].b = FTOCHAR(col[0]);
475                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
476                                                 finalCol[i*4+j].r = FTOCHAR(col[2]);
477                                         }
478                                 }
479                                 else
480                                         for(j=0;j<4;j++) {
481                                                 finalCol[i*4+j].b = 255;
482                                                 finalCol[i*4+j].g = 255;
483                                                 finalCol[i*4+j].r = 255;
484                                         }
485                         }
486                 } else {
487                         for(j=0;j<4;j++) {
488                                 finalCol[i*4+j].r = mcol[i*4+j].r;
489                                 finalCol[i*4+j].g = mcol[i*4+j].g;
490                                 finalCol[i*4+j].b = mcol[i*4+j].b;
491                         }
492                 }
493         }
494         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
495 }
496
497 static int draw_tface_mapped__set_draw(void *userData, int index)
498 {
499         Mesh *me = (Mesh*)userData;
500         MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
501         MFace *mface = &me->mface[index];
502         const int matnr = mface->mat_nr;
503         if (mface->flag & ME_HIDE) return 0;
504         return draw_tface__set_draw(tface, (me->mcol != NULL), matnr);
505 }
506
507 static int draw_em_tf_mapped__set_draw(void *userData, int index)
508 {
509         struct {EditMesh *em; short has_mcol; short has_mtface;} *data = userData;
510         EditMesh *em = data->em;
511         EditFace *efa= EM_get_face_for_index(index);
512         MTFace *tface;
513         int matnr;
514
515         if (efa->h)
516                 return 0;
517
518         tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
519         matnr = efa->mat_nr;
520
521         return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
522 }
523
524 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
525 {
526         Mesh *me = (Mesh*)userData;
527
528         if (me->mat && me->mface) {
529                 Material *ma= me->mat[me->mface[index].mat_nr];
530                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
531                         return 0;
532                 }
533         }
534
535         *drawSmooth_r = 1;
536         return 1;
537 }
538
539 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
540 {
541         Mesh *me = ob->data;
542         DerivedMesh *ddm;
543         MFace *mf, *mface= me->mface;
544         MTFace *tface= me->mtface;
545         MCol *mcol= me->mcol;   /* why does mcol exist? */
546         bProperty *prop = get_ob_property(ob, "Text");
547         GPUVertexAttribs gattribs;
548         int a, totface= me->totface;
549
550         /* don't draw without tfaces */
551         if(!tface)
552                 return;
553
554         /* don't draw when editing */
555         if(ob->mode & OB_MODE_EDIT)
556                 return;
557         else if(ob==OBACT)
558                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
559                         return;
560
561         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
562
563         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
564                 short matnr= mf->mat_nr;
565                 int mf_smooth= mf->flag & ME_SMOOTH;
566                 Material *mat = me->mat[matnr];
567                 int mode= mat->game.flag;
568
569                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
570                         float v1[3], v2[3], v3[3], v4[3];
571                         char string[MAX_PROPSTRING];
572                         int characters, i, glattrib= -1, badtex= 0;
573
574                         if(glsl) {
575                                 GPU_enable_material(matnr+1, &gattribs);
576
577                                 for(i=0; i<gattribs.totlayer; i++) {
578                                         if(gattribs.layer[i].type == CD_MTFACE) {
579                                                 glattrib = gattribs.layer[i].glindex;
580                                                 break;
581                                         }
582                                 }
583                         }
584                         else {
585                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
586                                 if (badtex) {
587                                         if (mcol) mcol+=4;
588                                         continue;
589                                 }
590                         }
591
592                         ddm->getVertCo(ddm, mf->v1, v1);
593                         ddm->getVertCo(ddm, mf->v2, v2);
594                         ddm->getVertCo(ddm, mf->v3, v3);
595                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
596
597                         // The BM_FONT handling is in the gpu module, shared with the
598                         // game engine, was duplicated previously
599
600                         set_property_valstr(prop, string);
601                         characters = strlen(string);
602                         
603                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
604                                 characters = 0;
605
606                         if (!mf_smooth) {
607                                 float nor[3];
608
609                                 normal_tri_v3( nor,v1, v2, v3);
610
611                                 glNormal3fv(nor);
612                         }
613
614                         GPU_render_text(tface, mode, string, characters,
615                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
616                 }
617                 if (mcol) {
618                         mcol+=4;
619                 }
620         }
621
622         ddm->release(ddm);
623 }
624
625 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
626 {
627         Mesh *me= ob->data;
628         
629         /* correct for negative scale */
630         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
631         else glFrontFace(GL_CCW);
632         
633         /* draw the textured mesh */
634         draw_textured_begin(scene, v3d, rv3d, ob);
635
636         glColor4f(1.0f,1.0f,1.0f,1.0f);
637
638         if(ob->mode & OB_MODE_EDIT) {
639                 struct {EditMesh *em; short has_mcol; short has_mtface;} data;
640
641                 data.em= me->edit_mesh;
642                 data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
643                 data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
644
645                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, &data);
646         }
647         else if(faceselect) {
648                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
649                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
650                 else
651                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
652         }
653         else {
654                 if(GPU_buffer_legacy(dm)) {
655                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
656                 }
657                 else {
658                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
659                                 add_tface_color_layer(dm);
660
661                         dm->drawFacesTex(dm, draw_tface__set_draw);
662                 }
663         }
664
665         /* draw game engine text hack */
666         if(get_ob_property(ob, "Text")) 
667                 draw_mesh_text(scene, ob, 0);
668
669         draw_textured_end();
670         
671         /* draw edges and selected faces over textured mesh */
672         if(!(ob == scene->obedit) && faceselect)
673                 draw_mesh_face_select(rv3d, me, dm);
674
675         /* reset from negative scale correction */
676         glFrontFace(GL_CCW);
677         
678         /* in editmode, the blend mode needs to be set incase it was ADD */
679         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
680 }
681
682 /************************** NEW SHADING NODES ********************************/
683
684 typedef struct TexMatCallback {
685         Scene *scene;
686         Object *ob;
687         Mesh *me;
688         DerivedMesh *dm;
689 } TexMatCallback;
690
691 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
692 {
693         /* all we have to do here is simply enable the GLSL material, but note
694            that the GLSL code will give different result depending on the drawtype,
695            in texture draw mode it will output the active texture node, in material
696            draw mode it will show the full material. */
697         GPU_enable_material(mat_nr, attribs);
698 }
699
700 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
701 {
702         /* texture draw mode without GLSL */
703         TexMatCallback *data= (TexMatCallback*)userData;
704         GPUVertexAttribs *gattribs = attribs;
705         Image *ima;
706         ImageUser *iuser;
707         bNode *node;
708         int texture_set= 0;
709
710         /* draw image texture if we find one */
711         if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
712                 /* get openl texture */
713                 int mipmap= 1;
714                 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
715                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
716
717                 if(bindcode) {
718                         NodeTexBase *texbase= node->storage;
719
720                         /* disable existing material */
721                         GPU_disable_material();
722                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
723                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
724                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
725
726                         /* bind texture */
727                         glEnable(GL_COLOR_MATERIAL);
728                         glEnable(GL_TEXTURE_2D);
729
730                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
731                         glColor3f(1.0f, 1.0f, 1.0f);
732
733                         glMatrixMode(GL_TEXTURE);
734                         glLoadMatrixf(texbase->tex_mapping.mat);
735                         glMatrixMode(GL_MODELVIEW);
736
737                         /* use active UV texture layer */
738                         memset(gattribs, 0, sizeof(*gattribs));
739
740                         gattribs->layer[0].type= CD_MTFACE;
741                         gattribs->layer[0].name[0]= '\0';
742                         gattribs->layer[0].gltexco= 1;
743                         gattribs->totlayer= 1;
744
745                         texture_set= 1;
746                 }
747         }
748
749         if(!texture_set) {
750                 glMatrixMode(GL_TEXTURE);
751                 glLoadIdentity();
752                 glMatrixMode(GL_MODELVIEW);
753
754                 /* disable texture */
755                 glDisable(GL_TEXTURE_2D);
756                 glDisable(GL_COLOR_MATERIAL);
757
758                 /* draw single color */
759                 GPU_enable_material(mat_nr, attribs);
760         }
761 }
762
763 static int tex_mat_set_face_mesh_cb(void *userData, int index)
764 {
765         /* faceselect mode face hiding */
766         TexMatCallback *data= (TexMatCallback*)userData;
767         Mesh *me = (Mesh*)data->me;
768         MFace *mface = &me->mface[index];
769
770         return !(mface->flag & ME_HIDE);
771 }
772
773 static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
774 {
775         /* editmode face hiding */
776         EditFace *efa= EM_get_face_for_index(index);
777
778         return !(efa->h);
779 }
780
781 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
782 {
783         if(!scene_use_new_shading_nodes(scene)) {
784                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, faceselect);
785                 return;
786         }
787
788         /* set opengl state for negative scale & color */
789         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
790         else glFrontFace(GL_CCW);
791
792         glEnable(GL_LIGHTING);
793
794         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
795                 /* weight paint mode exception */
796                 int useColors= 1;
797
798                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
799                         ob->data, useColors, GPU_enable_material, NULL);
800         }
801         else {
802                 Mesh *me= ob->data;
803                 TexMatCallback data = {scene, ob, me, dm};
804                 int (*set_face_cb)(void*, int);
805                 int glsl;
806                 
807                 /* face hiding callback depending on mode */
808                 if(ob == scene->obedit)
809                         set_face_cb= tex_mat_set_face_editmesh_cb;
810                 else if(faceselect)
811                         set_face_cb= tex_mat_set_face_mesh_cb;
812                 else
813                         set_face_cb= NULL;
814
815                 /* test if we can use glsl */
816                 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
817
818                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
819
820                 if(glsl) {
821                         /* draw glsl */
822                         dm->drawMappedFacesMat(dm,
823                                 tex_mat_set_material_cb,
824                                 set_face_cb, &data);
825                 }
826                 else {
827                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
828
829                         /* draw textured */
830                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
831                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
832                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
833
834                         dm->drawMappedFacesMat(dm,
835                                 tex_mat_set_texture_cb,
836                                 set_face_cb, &data);
837                 }
838
839                 GPU_end_object_materials();
840         }
841
842         /* reset opengl state */
843         glDisable(GL_COLOR_MATERIAL);
844         glDisable(GL_TEXTURE_2D);
845         glDisable(GL_LIGHTING);
846         glBindTexture(GL_TEXTURE_2D, 0);
847         glFrontFace(GL_CCW);
848
849         glMatrixMode(GL_TEXTURE);
850         glLoadIdentity();
851         glMatrixMode(GL_MODELVIEW);
852
853         /* faceselect mode drawing over textured mesh */
854         if(!(ob == scene->obedit) && faceselect)
855                 draw_mesh_face_select(rv3d, ob->data, dm);
856 }
857