svn merge ^/trunk/blender -r42521:42550
[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, NULL, (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; MFace *mf; MTFace *tf;} *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 static int compareDrawOptions(void *userData, int cur_index, int next_index)
662 {
663         struct { MFace *mf; MTFace *tf; } *data = userData;
664
665         if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
666                 return 0;
667
668         if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
669                 return 0;
670
671         return 1;
672 }
673
674 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
675 {
676         struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
677
678         if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
679                 return 0;
680
681         if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
682                 return 0;
683
684         return 1;
685 }
686
687 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
688 {
689         Mesh *me= ob->data;
690         
691         /* correct for negative scale */
692         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
693         else glFrontFace(GL_CCW);
694         
695         /* draw the textured mesh */
696         draw_textured_begin(scene, v3d, rv3d, ob);
697
698         glColor4f(1.0f,1.0f,1.0f,1.0f);
699
700         if(ob->mode & OB_MODE_EDIT) {
701                 struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
702
703                 data.em= me->edit_btmesh;
704                 data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
705                 data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
706                 data.mf= DM_get_tessface_data_layer(dm, CD_MFACE);
707                 data.tf= DM_get_tessface_data_layer(dm, CD_MTFACE);
708
709                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
710         }
711         else if(draw_flags & DRAW_FACE_SELECT) {
712                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
713                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, GPU_enable_material, NULL, me, 1);
714                 else
715                         dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, NULL, me);
716         }
717         else {
718                 if(GPU_buffer_legacy(dm)) {
719                         if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
720                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
721                         else 
722                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
723                 }
724                 else {
725                         struct { MFace *mf; MTFace *tf; } userData;
726
727                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
728                                 add_tface_color_layer(dm);
729
730                         userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
731                         userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
732
733                         dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
734                 }
735         }
736
737         /* draw game engine text hack */
738         if(get_ob_property(ob, "Text")) 
739                 draw_mesh_text(scene, ob, 0);
740
741         draw_textured_end();
742         
743         /* draw edges and selected faces over textured mesh */
744         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
745                 draw_mesh_face_select(rv3d, me, dm);
746
747         /* reset from negative scale correction */
748         glFrontFace(GL_CCW);
749         
750         /* in editmode, the blend mode needs to be set incase it was ADD */
751         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
752 }
753
754 /************************** NEW SHADING NODES ********************************/
755
756 typedef struct TexMatCallback {
757         Scene *scene;
758         Object *ob;
759         Mesh *me;
760         DerivedMesh *dm;
761 } TexMatCallback;
762
763 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
764 {
765         /* all we have to do here is simply enable the GLSL material, but note
766            that the GLSL code will give different result depending on the drawtype,
767            in texture draw mode it will output the active texture node, in material
768            draw mode it will show the full material. */
769         GPU_enable_material(mat_nr, attribs);
770 }
771
772 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
773 {
774         /* texture draw mode without GLSL */
775         TexMatCallback *data= (TexMatCallback*)userData;
776         GPUVertexAttribs *gattribs = attribs;
777         Image *ima;
778         ImageUser *iuser;
779         bNode *node;
780         int texture_set= 0;
781
782         /* draw image texture if we find one */
783         if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
784                 /* get openl texture */
785                 int mipmap= 1;
786                 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
787                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
788
789                 if(bindcode) {
790                         NodeTexBase *texbase= node->storage;
791
792                         /* disable existing material */
793                         GPU_disable_material();
794                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
795                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
796                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
797
798                         /* bind texture */
799                         glEnable(GL_COLOR_MATERIAL);
800                         glEnable(GL_TEXTURE_2D);
801
802                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
803                         glColor3f(1.0f, 1.0f, 1.0f);
804
805                         glMatrixMode(GL_TEXTURE);
806                         glLoadMatrixf(texbase->tex_mapping.mat);
807                         glMatrixMode(GL_MODELVIEW);
808
809                         /* use active UV texture layer */
810                         memset(gattribs, 0, sizeof(*gattribs));
811
812                         gattribs->layer[0].type= CD_MTFACE;
813                         gattribs->layer[0].name[0]= '\0';
814                         gattribs->layer[0].gltexco= 1;
815                         gattribs->totlayer= 1;
816
817                         texture_set= 1;
818                 }
819         }
820
821         if(!texture_set) {
822                 glMatrixMode(GL_TEXTURE);
823                 glLoadIdentity();
824                 glMatrixMode(GL_MODELVIEW);
825
826                 /* disable texture */
827                 glDisable(GL_TEXTURE_2D);
828                 glDisable(GL_COLOR_MATERIAL);
829
830                 /* draw single color */
831                 GPU_enable_material(mat_nr, attribs);
832         }
833 }
834
835 static int tex_mat_set_face_mesh_cb(void *userData, int index)
836 {
837         /* faceselect mode face hiding */
838         TexMatCallback *data= (TexMatCallback*)userData;
839         Mesh *me = (Mesh*)data->me;
840         MPoly *mface = &me->mpoly[index];
841
842         return !(mface->flag & ME_HIDE);
843 }
844
845 static int tex_mat_set_face_editmesh_cb(void *userData, int index)
846 {
847         /* editmode face hiding */
848         TexMatCallback *data= (TexMatCallback*)userData;
849         Mesh *me = (Mesh*)data->me;
850         BMFace *efa= EDBM_get_face_for_index(me->edit_btmesh, index);
851
852         return !BM_TestHFlag(efa, BM_HIDDEN);
853 }
854
855 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
856 {
857         if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
858                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
859                 return;
860         }
861
862         /* set opengl state for negative scale & color */
863         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
864         else glFrontFace(GL_CCW);
865
866         glEnable(GL_LIGHTING);
867
868         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
869                 /* weight paint mode exception */
870                 int useColors= 1;
871
872                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
873                         GPU_enable_material, NULL, ob->data, useColors);
874         }
875         else {
876                 Mesh *me= ob->data;
877                 TexMatCallback data = {scene, ob, me, dm};
878                 int (*set_face_cb)(void*, int);
879                 int glsl;
880                 
881                 /* face hiding callback depending on mode */
882                 if(ob == scene->obedit)
883                         set_face_cb= tex_mat_set_face_editmesh_cb;
884                 else if(draw_flags & DRAW_FACE_SELECT)
885                         set_face_cb= tex_mat_set_face_mesh_cb;
886                 else
887                         set_face_cb= NULL;
888
889                 /* test if we can use glsl */
890                 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
891
892                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
893
894                 if(glsl) {
895                         /* draw glsl */
896                         dm->drawMappedFacesMat(dm,
897                                 tex_mat_set_material_cb,
898                                 set_face_cb, &data);
899                 }
900                 else {
901                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
902
903                         /* draw textured */
904                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
905                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
906                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
907
908                         dm->drawMappedFacesMat(dm,
909                                 tex_mat_set_texture_cb,
910                                 set_face_cb, &data);
911                 }
912
913                 GPU_end_object_materials();
914         }
915
916         /* reset opengl state */
917         glDisable(GL_COLOR_MATERIAL);
918         glDisable(GL_TEXTURE_2D);
919         glDisable(GL_LIGHTING);
920         glBindTexture(GL_TEXTURE_2D, 0);
921         glFrontFace(GL_CCW);
922
923         glMatrixMode(GL_TEXTURE);
924         glLoadIdentity();
925         glMatrixMode(GL_MODELVIEW);
926
927         /* faceselect mode drawing over textured mesh */
928         if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
929                 draw_mesh_face_select(rv3d, ob->data, dm);
930 }
931