31046603216b4543e0249c5b191bf36fa179b3e2
[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         MFace *mface = &me->mface[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 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
409 {
410         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
411
412         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
413
414         if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
415                 return 2; /* Don't set color */
416         } else if (tface && tface->mode&TF_OBCOL) {
417                 return 2; /* Don't set color */
418         } else if (!has_mcol) {
419                 return 1; /* Don't set color */
420         } else {
421                 return 1; /* Set color from mcol */
422         }
423 }
424 static void add_tface_color_layer(DerivedMesh *dm)
425 {
426         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
427         MFace *mface = dm->getTessFaceArray(dm);
428         MCol *finalCol;
429         int i,j;
430         MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
431         if(!mcol)
432                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
433
434         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumTessFaces(dm),"add_tface_color_layer");
435         for(i=0;i<dm->getNumTessFaces(dm);i++) {
436                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
437
438                 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
439                         if( mcol )
440                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
441                         else
442                                 for(j=0;j<4;j++) {
443                                         finalCol[i*4+j].b = 255;
444                                         finalCol[i*4+j].g = 255;
445                                         finalCol[i*4+j].r = 255;
446                                 }
447                 }
448                 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
449                         for(j=0;j<4;j++) {
450                                 finalCol[i*4+j].b = 255;
451                                 finalCol[i*4+j].g = 0;
452                                 finalCol[i*4+j].r = 255;
453                         }
454                 } else if (tface && tface->mode&TF_OBCOL) {
455                         for(j=0;j<4;j++) {
456                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
457                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
458                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
459                         }
460                 } else if (!mcol) {
461                         if (tface) {
462                                 for(j=0;j<4;j++) {
463                                         finalCol[i*4+j].b = 255;
464                                         finalCol[i*4+j].g = 255;
465                                         finalCol[i*4+j].r = 255;
466                                 }
467                         }
468                         else {
469                                 float col[3];
470                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
471                                 
472                                 if(ma) {
473                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
474                                         else copy_v3_v3(col, &ma->r);
475                                         
476                                         for(j=0;j<4;j++) {
477                                                 finalCol[i*4+j].b = FTOCHAR(col[0]);
478                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
479                                                 finalCol[i*4+j].r = FTOCHAR(col[2]);
480                                         }
481                                 }
482                                 else
483                                         for(j=0;j<4;j++) {
484                                                 finalCol[i*4+j].b = 255;
485                                                 finalCol[i*4+j].g = 255;
486                                                 finalCol[i*4+j].r = 255;
487                                         }
488                         }
489                 } else {
490                         for(j=0;j<4;j++) {
491                                 finalCol[i*4+j].r = mcol[i*4+j].r;
492                                 finalCol[i*4+j].g = mcol[i*4+j].g;
493                                 finalCol[i*4+j].b = mcol[i*4+j].b;
494                         }
495                 }
496         }
497         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
498 }
499
500 static int draw_tface_mapped__set_draw(void *userData, int index)
501 {
502         Mesh *me = (Mesh*)userData;
503         MTexPoly *tpoly = (me->mtpoly)? &me->mtpoly[index]: NULL;
504         MPoly *mpoly = (me->mpoly)? &me->mpoly[index]: NULL;
505         MTFace mtf;
506         int matnr = me->mpoly[index].mat_nr;
507
508         if (mpoly && mpoly->flag&ME_HIDE) return 0;
509
510         memset(&mtf, 0, sizeof(mtf));
511         if (tpoly) {
512                 mtf.flag = tpoly->flag;
513                 mtf.tpage = tpoly->tpage;
514                 mtf.transp = tpoly->transp;
515                 mtf.mode = tpoly->mode;
516                 mtf.tile = tpoly->tile;
517                 mtf.unwrap = tpoly->unwrap;
518         }
519
520         return draw_tface__set_draw(&mtf, (me->mcol != NULL), matnr);
521 }
522
523 static int draw_em_tf_mapped__set_draw(void *userData, int index)
524 {
525         struct {BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData;
526         BMEditMesh *em = data->em;
527         BMFace *efa= EDBM_get_face_for_index(em, index);
528
529         if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN)) {
530                 return 0;
531         }
532         else {
533                 MTFace mtf= {{{0}}};
534                 int matnr = efa->mat_nr;
535
536                 if (data->has_mtface) {
537                         MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
538                         mtf.flag = tpoly->flag;
539                         mtf.tpage = tpoly->tpage;
540                         mtf.transp = tpoly->transp;
541                         mtf.mode = tpoly->mode;
542                         mtf.tile = tpoly->tile;
543                         mtf.unwrap = tpoly->unwrap;
544
545                 }
546
547                 return draw_tface__set_draw_legacy(&mtf, data->has_mcol, matnr);
548         }
549 }
550
551 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
552 {
553         Mesh *me = (Mesh*)userData;
554
555         if (me->mat && me->mface) {
556                 Material *ma= me->mat[me->mface[index].mat_nr];
557                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
558                         return 0;
559                 }
560         }
561
562         *drawSmooth_r = 1;
563         return 1;
564 }
565
566 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
567 {
568         Mesh *me = ob->data;
569         DerivedMesh *ddm;
570         MFace *mf, *mface= me->mface;
571         MTFace *tface= me->mtface;
572         MCol *mcol= me->mcol;   /* why does mcol exist? */
573         bProperty *prop = get_ob_property(ob, "Text");
574         GPUVertexAttribs gattribs;
575         int a, totface= me->totface;
576
577         /* don't draw without tfaces */
578         if(!tface)
579                 return;
580
581         /* don't draw when editing */
582         if(ob->mode & OB_MODE_EDIT)
583                 return;
584         else if(ob==OBACT)
585                 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
586                         return;
587
588         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
589
590         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
591                 short matnr= mf->mat_nr;
592                 int mf_smooth= mf->flag & ME_SMOOTH;
593                 Material *mat = me->mat[matnr];
594                 int mode= mat->game.flag;
595
596                 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
597                         float v1[3], v2[3], v3[3], v4[3];
598                         char string[MAX_PROPSTRING];
599                         int characters, i, glattrib= -1, badtex= 0;
600
601                         if(glsl) {
602                                 GPU_enable_material(matnr+1, &gattribs);
603
604                                 for(i=0; i<gattribs.totlayer; i++) {
605                                         if(gattribs.layer[i].type == CD_MTFACE) {
606                                                 glattrib = gattribs.layer[i].glindex;
607                                                 break;
608                                         }
609                                 }
610                         }
611                         else {
612                                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
613                                 if (badtex) {
614                                         if (mcol) mcol+=4;
615                                         continue;
616                                 }
617                         }
618
619                         ddm->getVertCo(ddm, mf->v1, v1);
620                         ddm->getVertCo(ddm, mf->v2, v2);
621                         ddm->getVertCo(ddm, mf->v3, v3);
622                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
623
624                         // The BM_FONT handling is in the gpu module, shared with the
625                         // game engine, was duplicated previously
626
627                         set_property_valstr(prop, string);
628                         characters = strlen(string);
629                         
630                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
631                                 characters = 0;
632
633                         if (!mf_smooth) {
634                                 float nor[3];
635
636                                 normal_tri_v3( nor,v1, v2, v3);
637
638                                 glNormal3fv(nor);
639                         }
640
641                         GPU_render_text(tface, mode, string, characters,
642                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
643                 }
644                 if (mcol) {
645                         mcol+=4;
646                 }
647         }
648
649         ddm->release(ddm);
650 }
651
652 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
653 {
654         Mesh *me= ob->data;
655         
656         /* correct for negative scale */
657         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
658         else glFrontFace(GL_CCW);
659         
660         /* draw the textured mesh */
661         draw_textured_begin(scene, v3d, rv3d, ob);
662
663         glColor4f(1.0f,1.0f,1.0f,1.0f);
664
665         if(ob->mode & OB_MODE_EDIT) {
666                 struct {BMEditMesh *em; short has_mcol; short has_mtface;} data;
667
668                 data.em= me->edit_btmesh;
669                 data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
670                 data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
671
672                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, &data);
673         }
674         else if(faceselect) {
675                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
676                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material, NULL);
677                 else
678                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
679         }
680         else {
681                 if(GPU_buffer_legacy(dm)) {
682                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
683                 }
684                 else {
685                         if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
686                                 add_tface_color_layer(dm);
687
688                         dm->drawFacesTex(dm, draw_tface__set_draw);
689                 }
690         }
691
692         /* draw game engine text hack */
693         if(get_ob_property(ob, "Text")) 
694                 draw_mesh_text(scene, ob, 0);
695
696         draw_textured_end();
697         
698         /* draw edges and selected faces over textured mesh */
699         if(!(ob == scene->obedit) && faceselect)
700                 draw_mesh_face_select(rv3d, me, dm);
701
702         /* reset from negative scale correction */
703         glFrontFace(GL_CCW);
704         
705         /* in editmode, the blend mode needs to be set incase it was ADD */
706         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
707 }
708
709 /************************** NEW SHADING NODES ********************************/
710
711 typedef struct TexMatCallback {
712         Scene *scene;
713         Object *ob;
714         Mesh *me;
715         DerivedMesh *dm;
716 } TexMatCallback;
717
718 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
719 {
720         /* all we have to do here is simply enable the GLSL material, but note
721            that the GLSL code will give different result depending on the drawtype,
722            in texture draw mode it will output the active texture node, in material
723            draw mode it will show the full material. */
724         GPU_enable_material(mat_nr, attribs);
725 }
726
727 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
728 {
729         /* texture draw mode without GLSL */
730         TexMatCallback *data= (TexMatCallback*)userData;
731         GPUVertexAttribs *gattribs = attribs;
732         Image *ima;
733         ImageUser *iuser;
734         bNode *node;
735         int texture_set= 0;
736
737         /* draw image texture if we find one */
738         if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
739                 /* get openl texture */
740                 int mipmap= 1;
741                 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
742                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
743
744                 if(bindcode) {
745                         NodeTexBase *texbase= node->storage;
746
747                         /* disable existing material */
748                         GPU_disable_material();
749                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
750                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
751                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
752
753                         /* bind texture */
754                         glEnable(GL_COLOR_MATERIAL);
755                         glEnable(GL_TEXTURE_2D);
756
757                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
758                         glColor3f(1.0f, 1.0f, 1.0f);
759
760                         glMatrixMode(GL_TEXTURE);
761                         glLoadMatrixf(texbase->tex_mapping.mat);
762                         glMatrixMode(GL_MODELVIEW);
763
764                         /* use active UV texture layer */
765                         memset(gattribs, 0, sizeof(*gattribs));
766
767                         gattribs->layer[0].type= CD_MTFACE;
768                         gattribs->layer[0].name[0]= '\0';
769                         gattribs->layer[0].gltexco= 1;
770                         gattribs->totlayer= 1;
771
772                         texture_set= 1;
773                 }
774         }
775
776         if(!texture_set) {
777                 glMatrixMode(GL_TEXTURE);
778                 glLoadIdentity();
779                 glMatrixMode(GL_MODELVIEW);
780
781                 /* disable texture */
782                 glDisable(GL_TEXTURE_2D);
783                 glDisable(GL_COLOR_MATERIAL);
784
785                 /* draw single color */
786                 GPU_enable_material(mat_nr, attribs);
787         }
788 }
789
790 static int tex_mat_set_face_mesh_cb(void *userData, int index)
791 {
792         /* faceselect mode face hiding */
793         TexMatCallback *data= (TexMatCallback*)userData;
794         Mesh *me = (Mesh*)data->me;
795         MFace *mface = &me->mface[index];
796
797         return !(mface->flag & ME_HIDE);
798 }
799
800 static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
801 {
802         /* editmode face hiding */
803         EditFace *efa= EM_get_face_for_index(index);
804
805         return !(efa->h);
806 }
807
808 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
809 {
810         if(!scene_use_new_shading_nodes(scene)) {
811                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, faceselect);
812                 return;
813         }
814
815         /* set opengl state for negative scale & color */
816         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
817         else glFrontFace(GL_CCW);
818
819         glEnable(GL_LIGHTING);
820
821         if(ob->mode & OB_MODE_WEIGHT_PAINT) {
822                 /* weight paint mode exception */
823                 int useColors= 1;
824
825                 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
826                         ob->data, useColors, GPU_enable_material, NULL);
827         }
828         else {
829                 Mesh *me= ob->data;
830                 TexMatCallback data = {scene, ob, me, dm};
831                 int (*set_face_cb)(void*, int);
832                 int glsl;
833                 
834                 /* face hiding callback depending on mode */
835                 if(ob == scene->obedit)
836                         set_face_cb= tex_mat_set_face_editmesh_cb;
837                 else if(faceselect)
838                         set_face_cb= tex_mat_set_face_mesh_cb;
839                 else
840                         set_face_cb= NULL;
841
842                 /* test if we can use glsl */
843                 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
844
845                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
846
847                 if(glsl) {
848                         /* draw glsl */
849                         dm->drawMappedFacesMat(dm,
850                                 tex_mat_set_material_cb,
851                                 set_face_cb, &data);
852                 }
853                 else {
854                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
855
856                         /* draw textured */
857                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
858                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
859                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
860
861                         dm->drawMappedFacesMat(dm,
862                                 tex_mat_set_texture_cb,
863                                 set_face_cb, &data);
864                 }
865
866                 GPU_end_object_materials();
867         }
868
869         /* reset opengl state */
870         glDisable(GL_COLOR_MATERIAL);
871         glDisable(GL_TEXTURE_2D);
872         glDisable(GL_LIGHTING);
873         glBindTexture(GL_TEXTURE_2D, 0);
874         glFrontFace(GL_CCW);
875
876         glMatrixMode(GL_TEXTURE);
877         glLoadIdentity();
878         glMatrixMode(GL_MODELVIEW);
879
880         /* faceselect mode drawing over textured mesh */
881         if(!(ob == scene->obedit) && faceselect)
882                 draw_mesh_face_select(rv3d, ob->data, dm);
883 }
884