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