More DM func renames, fixing some build breaks, renaming more stuff, also seems like...
[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 /**************************** 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         MPoly *mface = &me->mpoly[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 = GEMAT_BACKCULL;
234         int alphablend = 0;
235         int textured = 0;
236         int lit = 0;
237         
238         if (clearcache) {
239                 c_textured= c_lit= c_backculled= -1;
240                 c_texface= (MTFace*) -1;
241                 c_badtex= 0;
242         } else {
243                 textured = gtexdraw.istex;
244                 litob = gtexdraw.ob;
245         }
246
247         /* convert number of lights into boolean */
248         if (gtexdraw.islit) lit = 1;
249
250         if (ma) {
251                 alphablend = ma->game.alpha_blend;
252                 if (ma->mode & MA_SHLESS) lit = 0;
253                 backculled = ma->game.flag & GEMAT_BACKCULL;
254         }
255
256         if (texface) {
257                 textured = textured && (texface->tpage);
258
259                 /* no material, render alpha if texture has depth=32 */
260                 if (!ma && BKE_image_has_alpha(texface->tpage))
261                         alphablend = GPU_BLEND_ALPHA;
262         }
263
264         else
265                 textured = 0;
266
267         if (backculled!=c_backculled) {
268                 if (backculled) glEnable(GL_CULL_FACE);
269                 else glDisable(GL_CULL_FACE);
270
271                 c_backculled= backculled;
272         }
273
274         if (textured!=c_textured || texface!=c_texface) {
275                 if (textured ) {
276                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
277                 } else {
278                         GPU_set_tpage(NULL, 0, 0);
279                         c_badtex= 0;
280                 }
281                 c_textured= textured;
282                 c_texface= texface;
283         }
284
285         if (c_badtex) lit= 0;
286         if (lit!=c_lit || ma!=c_ma) {
287                 if (lit) {
288                         float spec[4];
289                         if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
290
291                         spec[0]= ma->spec*ma->specr;
292                         spec[1]= ma->spec*ma->specg;
293                         spec[2]= ma->spec*ma->specb;
294                         spec[3]= 1.0;
295
296                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
297                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
298                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
299                         glEnable(GL_LIGHTING);
300                         glEnable(GL_COLOR_MATERIAL);
301                 }
302                 else {
303                         glDisable(GL_LIGHTING); 
304                         glDisable(GL_COLOR_MATERIAL);
305                 }
306                 c_lit= lit;
307         }
308
309         return c_badtex;
310 }
311
312 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
313 {
314         unsigned char obcol[4];
315         int istex, solidtex;
316
317         // XXX scene->obedit warning
318
319         /* texture draw is abused for mask selection mode, do this so wire draw
320          * with face selection in weight paint is not lit. */
321         if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
322                 solidtex= FALSE;
323                 Gtexdraw.islit= 0;
324         }
325         else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
326                 /* draw with default lights in solid draw mode and edit mode */
327                 solidtex= TRUE;
328                 Gtexdraw.islit= -1;
329         }
330         else {
331                 /* draw with lights in the scene otherwise */
332                 solidtex= FALSE;
333                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
334         }
335         
336         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
337         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
338         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
339         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
340         
341         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
342         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
343         else istex= 0;
344
345         Gtexdraw.ob = ob;
346         Gtexdraw.istex = istex;
347         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
348         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
349         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
350         glShadeModel(GL_SMOOTH);
351 }
352
353 static void draw_textured_end(void)
354 {
355         /* switch off textures */
356         GPU_set_tpage(NULL, 0, 0);
357
358         glShadeModel(GL_FLAT);
359         glDisable(GL_CULL_FACE);
360
361         /* XXX, bad patch - GPU_default_lights() calls
362          * glLightfv(GL_LIGHT_POSITION, ...) which
363          * is transformed by the current matrix... we
364          * need to make sure that matrix is identity.
365          * 
366          * It would be better if drawmesh.c kept track
367          * of and restored the light settings it changed.
368          *  - zr
369          */
370         glPushMatrix();
371         glLoadIdentity();       
372         GPU_default_lights();
373         glPopMatrix();
374 }
375
376 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
377 {
378         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
379         int validtexture=0;
380
381         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
382
383         validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
384
385         if (tface && validtexture) {
386                 glColor3ub(0xFF, 0x00, 0xFF);
387                 return 2; /* Don't set color */
388         } else if (ma && ma->shade_flag&MA_OBCOLOR) {
389                 glColor3ubv(Gtexdraw.obcol);
390                 return 2; /* Don't set color */
391         } else if (!has_mcol) {
392                 if (tface) glColor3f(1.0, 1.0, 1.0);
393                 else {
394                         if(ma) {
395                                 float col[3];
396                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
397                                 else copy_v3_v3(col, &ma->r);
398                                 
399                                 glColor3fv(col);
400                         }
401                         else glColor3f(1.0, 1.0, 1.0);
402                 }
403                 return 2; /* Don't set color */
404         } else {
405                 return 1; /* Set color from mcol */
406         }
407 }
408
409 static int draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
410 {
411         if (has_mcol) return 1;
412         else return 2;
413 }
414
415 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
416 {
417         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
418
419         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
420
421         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
422                 return 2; /* Don't set color */
423         } else if (tface && tface->mode&TF_OBCOL) {
424                 return 2; /* Don't set color */
425         } else if (!has_mcol) {
426                 return 1; /* Don't set color */
427         } else {
428                 return 1; /* Set color from mcol */
429         }
430 }
431 static void add_tface_color_layer(DerivedMesh *dm)
432 {
433         MTFace *tface = DM_get_poly_data_layer(dm, CD_MTFACE);
434         MFace *mface = dm->getTessFaceArray(dm);
435         MCol *finalCol;
436         int i,j;
437         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
438         if(!mcol)
439                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
440
441         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
442         for(i=0;i<dm->getNumTessFaces(dm);i++) {
443                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
444
445                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
446                         if( mcol )
447                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
448                         else
449                                 for(j=0;j<4;j++) {
450                                         finalCol[i*4+j].b = 255;
451                                         finalCol[i*4+j].g = 255;
452                                         finalCol[i*4+j].r = 255;
453                                 }
454                 }
455                 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
456                         for(j=0;j<4;j++) {
457                                 finalCol[i*4+j].b = 255;
458                                 finalCol[i*4+j].g = 0;
459                                 finalCol[i*4+j].r = 255;
460                         }
461                 } else if (tface && tface->mode&TF_OBCOL) {
462                         for(j=0;j<4;j++) {
463                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
464                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
465                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
466                         }
467                 } else if (!mcol) {
468                         if (tface) {
469                                 for(j=0;j<4;j++) {
470                                         finalCol[i*4+j].b = 255;
471                                         finalCol[i*4+j].g = 255;
472                                         finalCol[i*4+j].r = 255;
473                                 }
474                         }
475                         else {
476                                 float col[3];
477                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
478                                 
479                                 if(ma) {
480                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
481                                         else copy_v3_v3(col, &ma->r);
482                                         
483                                         for(j=0;j<4;j++) {
484                                                 finalCol[i*4+j].b = FTOCHAR(col[0]);
485                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
486                                                 finalCol[i*4+j].r = FTOCHAR(col[2]);
487                                         }
488                                 }
489                                 else
490                                         for(j=0;j<4;j++) {
491                                                 finalCol[i*4+j].b = 255;
492                                                 finalCol[i*4+j].g = 255;
493                                                 finalCol[i*4+j].r = 255;
494                                         }
495                         }
496                 } else {
497                         for(j=0;j<4;j++) {
498                                 finalCol[i*4+j].r = mcol[i*4+j].r;
499                                 finalCol[i*4+j].g = mcol[i*4+j].g;
500                                 finalCol[i*4+j].b = mcol[i*4+j].b;
501                         }
502                 }
503         }
504         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData );
505 }
506
507 static int draw_tface_mapped__set_draw(void *userData, int index)
508 {
509         Mesh *me = (Mesh*)userData;
510         MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
511         MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
512         MTFace mtf;
513         int matnr = me->mpoly[index].mat_nr;
514
515         BLI_assert(index >= 0 && index < me->totpoly);
516
517         if (mpoly && mpoly->flag&ME_HIDE) return 0;
518
519         memset(&mtf, 0, sizeof(mtf));
520         if (tpoly) {
521                 mtf.flag = tpoly->flag;
522                 mtf.tpage = tpoly->tpage;
523                 mtf.transp = tpoly->transp;
524                 mtf.mode = tpoly->mode;
525                 mtf.tile = tpoly->tile;
526                 mtf.unwrap = tpoly->unwrap;
527         }
528
529         return draw_tface__set_draw(&mtf, (me->mcol != NULL), matnr);
530 }
531
532 static int draw_em_tf_mapped__set_draw(void *userData, int index)
533 {
534         struct {BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData;
535         BMEditMesh *em = data->em;
536         BMFace *efa= EDBM_get_face_for_index(em, index);
537
538         if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN)) {
539                 return 0;
540         }
541         else {
542                 MTFace mtf= {{{0}}};
543                 int matnr = efa->mat_nr;
544
545                 if (data->has_mtface) {
546                         MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
547                         mtf.flag = tpoly->flag;
548                         mtf.tpage = tpoly->tpage;
549                         mtf.transp = tpoly->transp;
550                         mtf.mode = tpoly->mode;
551                         mtf.tile = tpoly->tile;
552                         mtf.unwrap = tpoly->unwrap;
553
554                 }
555
556                 return draw_tface__set_draw_legacy(&mtf, data->has_mcol, matnr);
557         }
558 }
559
560 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
561 {
562         Mesh *me = (Mesh*)userData;
563
564         if (me->mat && me->mpoly) {
565                 Material *ma= me->mat[me->mpoly[index].mat_nr];
566                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
567                         return 0;
568                 }
569         }
570
571         *drawSmooth_r = 1;
572         return 1;
573 }
574
575 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
576 {
577         Mesh *me = ob->data;
578         DerivedMesh *ddm;
579         MFace *mf, *mface= me->mface;
580         MTFace *tface= me->mtface;
581         MCol *mcol= me->mcol;   /* why does mcol exist? */
582         bProperty *prop = get_ob_property(ob, "Text");
583         GPUVertexAttribs gattribs;
584         int a, totface= me->totface;
585
586         /* don't draw without tfaces */
587         if(!tface)
588                 return;
589
590         /* don't draw when editing */
591         if(ob->mode & OB_MODE_EDIT)
592                 return;
593         else if(ob==OBACT)
594                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
595                         return;
596
597         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
598
599         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
600                 short matnr= mf->mat_nr;
601                 int mf_smooth= mf->flag & ME_SMOOTH;
602                 Material *mat = me->mat[matnr];
603                 int mode= mat->game.flag;
604
605                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
606                         float v1[3], v2[3], v3[3], v4[3];
607                         char string[MAX_PROPSTRING];
608                         int characters, i, glattrib= -1, badtex= 0;
609
610                         if(glsl) {
611                                 GPU_enable_material(matnr+1, &gattribs);
612
613                                 for(i=0; i<gattribs.totlayer; i++) {
614                                         if(gattribs.layer[i].type == CD_MTFACE) {
615                                                 glattrib = gattribs.layer[i].glindex;
616                                                 break;
617                                         }
618                                 }
619                         }
620                         else {
621                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
622                                 if (badtex) {
623                                         if (mcol) mcol+=4;
624                                         continue;
625                                 }
626                         }
627
628                         ddm->getVertCo(ddm, mf->v1, v1);
629                         ddm->getVertCo(ddm, mf->v2, v2);
630                         ddm->getVertCo(ddm, mf->v3, v3);
631                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
632
633                         // The BM_FONT handling is in the gpu module, shared with the
634                         // game engine, was duplicated previously
635
636                         set_property_valstr(prop, string);
637                         characters = strlen(string);
638                         
639                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
640                                 characters = 0;
641
642                         if (!mf_smooth) {
643                                 float nor[3];
644
645                                 normal_tri_v3( nor,v1, v2, v3);
646
647                                 glNormal3fv(nor);
648                         }
649
650                         GPU_render_text(tface, mode, string, characters,
651                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
652                 }
653                 if (mcol) {
654                         mcol+=4;
655                 }
656         }
657
658         ddm->release(ddm);
659 }
660
661 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
662 {
663         Mesh *me= ob->data;
664         
665         /* correct for negative scale */
666         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
667         else glFrontFace(GL_CCW);
668         
669         /* draw the textured mesh */
670         draw_textured_begin(scene, v3d, rv3d, ob);
671
672         glColor4f(1.0f,1.0f,1.0f,1.0f);
673
674         if(ob->mode & OB_MODE_EDIT) {
675                 struct {BMEditMesh *em; short has_mcol; short has_mtface;} data;
676
677                 data.em= me->edit_btmesh;
678                 data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
679                 data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
680
681                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, &data);
682         }
683         else if(draw_flags & DRAW_FACE_SELECT) {
684                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
685                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
686                 else
687                         dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, me);
688         }
689         else {
690                 if(GPU_buffer_legacy(dm)) {
691                         if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
692                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy);
693                         else 
694                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
695                 }
696                 else {
697                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
698                                 add_tface_color_layer(dm);
699
700                         dm->drawFacesTex(dm, draw_tface__set_draw);
701                 }
702         }
703
704         /* draw game engine text hack */
705         if(get_ob_property(ob, "Text")) 
706                 draw_mesh_text(scene, ob, 0);
707
708         draw_textured_end();
709         
710         /* draw edges and selected faces over textured mesh */
711         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
712                 draw_mesh_face_select(rv3d, me, dm);
713
714         /* reset from negative scale correction */
715         glFrontFace(GL_CCW);
716         
717         /* in editmode, the blend mode needs to be set incase it was ADD */
718         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
719 }
720
721 /************************** NEW SHADING NODES ********************************/
722
723 typedef struct TexMatCallback {
724         Scene *scene;
725         Object *ob;
726         Mesh *me;
727         DerivedMesh *dm;
728 } TexMatCallback;
729
730 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
731 {
732         /* all we have to do here is simply enable the GLSL material, but note
733            that the GLSL code will give different result depending on the drawtype,
734            in texture draw mode it will output the active texture node, in material
735            draw mode it will show the full material. */
736         GPU_enable_material(mat_nr, attribs);
737 }
738
739 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
740 {
741         /* texture draw mode without GLSL */
742         TexMatCallback *data= (TexMatCallback*)userData;
743         GPUVertexAttribs *gattribs = attribs;
744         Image *ima;
745         ImageUser *iuser;
746         bNode *node;
747         int texture_set= 0;
748
749         /* draw image texture if we find one */
750         if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
751                 /* get openl texture */
752                 int mipmap= 1;
753                 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
754                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
755
756                 if(bindcode) {
757                         NodeTexBase *texbase= node->storage;
758
759                         /* disable existing material */
760                         GPU_disable_material();
761                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
762                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
763                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
764
765                         /* bind texture */
766                         glEnable(GL_COLOR_MATERIAL);
767                         glEnable(GL_TEXTURE_2D);
768
769                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
770                         glColor3f(1.0f, 1.0f, 1.0f);
771
772                         glMatrixMode(GL_TEXTURE);
773                         glLoadMatrixf(texbase->tex_mapping.mat);
774                         glMatrixMode(GL_MODELVIEW);
775
776                         /* use active UV texture layer */
777                         memset(gattribs, 0, sizeof(*gattribs));
778
779                         gattribs->layer[0].type= CD_MTFACE;
780                         gattribs->layer[0].name[0]= '\0';
781                         gattribs->layer[0].gltexco= 1;
782                         gattribs->totlayer= 1;
783
784                         texture_set= 1;
785                 }
786         }
787
788         if(!texture_set) {
789                 glMatrixMode(GL_TEXTURE);
790                 glLoadIdentity();
791                 glMatrixMode(GL_MODELVIEW);
792
793                 /* disable texture */
794                 glDisable(GL_TEXTURE_2D);
795                 glDisable(GL_COLOR_MATERIAL);
796
797                 /* draw single color */
798                 GPU_enable_material(mat_nr, attribs);
799         }
800 }
801
802 static int tex_mat_set_face_mesh_cb(void *userData, int index)
803 {
804         /* faceselect mode face hiding */
805         TexMatCallback *data= (TexMatCallback*)userData;
806         Mesh *me = (Mesh*)data->me;
807         MPoly *mface = &me->mpoly[index];
808
809         return !(mface->flag & ME_HIDE);
810 }
811
812 static int tex_mat_set_face_editmesh_cb(void *userData, int index)
813 {
814         /* editmode face hiding */
815         TexMatCallback *data= (TexMatCallback*)userData;
816         Mesh *me = (Mesh*)data->me;
817         BMFace *efa= EDBM_get_face_for_index(me->edit_btmesh, index);
818
819         return !BM_TestHFlag(efa, BM_HIDDEN);
820 }
821
822 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
823 {
824         if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
825                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
826                 return;
827         }
828
829         /* set opengl state for negative scale & color */
830         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
831         else glFrontFace(GL_CCW);
832
833         glEnable(GL_LIGHTING);
834
835         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
836                 /* weight paint mode exception */
837                 int useColors= 1;
838
839                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
840                         ob->data, useColors, GPU_enable_material, NULL);
841         }
842         else {
843                 Mesh *me= ob->data;
844                 TexMatCallback data = {scene, ob, me, dm};
845                 int (*set_face_cb)(void*, int);
846                 int glsl;
847                 
848                 /* face hiding callback depending on mode */
849                 if(ob == scene->obedit)
850                         set_face_cb= tex_mat_set_face_editmesh_cb;
851                 else if(draw_flags & DRAW_FACE_SELECT)
852                         set_face_cb= tex_mat_set_face_mesh_cb;
853                 else
854                         set_face_cb= NULL;
855
856                 /* test if we can use glsl */
857                 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
858
859                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
860
861                 if(glsl) {
862                         /* draw glsl */
863                         dm->drawMappedFacesMat(dm,
864                                 tex_mat_set_material_cb,
865                                 set_face_cb, &data);
866                 }
867                 else {
868                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
869
870                         /* draw textured */
871                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
872                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
873                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
874
875                         dm->drawMappedFacesMat(dm,
876                                 tex_mat_set_texture_cb,
877                                 set_face_cb, &data);
878                 }
879
880                 GPU_end_object_materials();
881         }
882
883         /* reset opengl state */
884         glDisable(GL_COLOR_MATERIAL);
885         glDisable(GL_TEXTURE_2D);
886         glDisable(GL_LIGHTING);
887         glBindTexture(GL_TEXTURE_2D, 0);
888         glFrontFace(GL_CCW);
889
890         glMatrixMode(GL_TEXTURE);
891         glLoadIdentity();
892         glMatrixMode(GL_MODELVIEW);
893
894         /* faceselect mode drawing over textured mesh */
895         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
896                 draw_mesh_face_select(rv3d, ob->data, dm);
897 }
898