code cleanup: favor braces when blocks have mixed brace use.
[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_utildefines.h"
40
41 #include "DNA_material_types.h"
42 #include "DNA_mesh_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_global.h"
55 #include "BKE_image.h"
56 #include "BKE_material.h"
57 #include "BKE_paint.h"
58 #include "BKE_property.h"
59 #include "BKE_tessmesh.h"
60 #include "BKE_scene.h"
61
62 #include "BIF_gl.h"
63 #include "BIF_glutil.h"
64
65 #include "UI_resources.h"
66
67 #include "GPU_buffers.h"
68 #include "GPU_extensions.h"
69 #include "GPU_draw.h"
70 #include "GPU_material.h"
71
72 #include "ED_mesh.h"
73 #include "ED_uvedit.h"
74
75 #include "view3d_intern.h"  /* own include */
76
77 /* user data structures for derived mesh callbacks */
78 typedef struct drawMeshFaceSelect_userData {
79         Mesh *me;
80         EdgeHash *eh;
81 } drawMeshFaceSelect_userData;
82
83 typedef struct drawEMTFMapped_userData {
84         BMEditMesh *em;
85         short has_mcol;
86         short has_mtface;
87         MFace *mf;
88         MTFace *tf;
89 } drawEMTFMapped_userData;
90
91 typedef struct drawTFace_userData {
92         MFace *mf;
93         MTFace *tf;
94 } drawTFace_userData;
95
96 /**************************** Face Select Mode *******************************/
97
98 /* Flags for marked edges */
99 enum {
100         eEdge_Visible = (1 << 0),
101         eEdge_Select = (1 << 1),
102 };
103
104 /* Creates a hash of edges to flags indicating selected/visible */
105 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
106 {
107         int *flags_p;
108
109         if (!BLI_edgehash_haskey(eh, v0, v1))
110                 BLI_edgehash_insert(eh, v0, v1, NULL);
111
112         flags_p = (int *) BLI_edgehash_lookup_p(eh, v0, v1);
113         *flags_p |= flags;
114 }
115
116 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
117 {
118         EdgeHash *eh = BLI_edgehash_new();
119         MPoly *mp;
120         MLoop *ml;
121         MLoop *ml_next;
122         int i, j;
123         
124         for (i = 0; i < me->totpoly; i++) {
125                 mp = &me->mpoly[i];
126
127                 if (!(mp->flag & ME_HIDE)) {
128                         unsigned int flags = eEdge_Visible;
129                         if (mp->flag & ME_FACE_SEL) flags |= eEdge_Select;
130
131                         ml = me->mloop + mp->loopstart;
132                         for (j = 0; j < mp->totloop; j++, ml++) {
133                                 ml_next = ME_POLY_LOOP_NEXT(me->mloop, mp, j);
134                                 get_marked_edge_info__orFlags(eh, ml->v, ml_next->v, flags);
135                         }
136                 }
137         }
138
139         return eh;
140 }
141
142
143 static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int index)
144 {
145         drawMeshFaceSelect_userData *data = userData;
146         Mesh *me = data->me;
147         MEdge *med = &me->medge[index];
148         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
149
150         if (me->drawflag & ME_DRAWEDGES) {
151                 if ((me->drawflag & ME_HIDDENEDGES) || (flags & eEdge_Visible))
152                         return DM_DRAW_OPTION_NORMAL;
153                 else
154                         return DM_DRAW_OPTION_SKIP;
155         }
156         else if (flags & eEdge_Select)
157                 return DM_DRAW_OPTION_NORMAL;
158         else
159                 return DM_DRAW_OPTION_SKIP;
160 }
161
162 static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int index)
163 {
164         drawMeshFaceSelect_userData *data = userData;
165         MEdge *med = &data->me->medge[index];
166         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
167
168         return (flags & eEdge_Select) ? DM_DRAW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP;
169 }
170
171 /* draws unselected */
172 static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
173 {
174         Mesh *me = (Mesh *)userData;
175
176         MPoly *mpoly = &me->mpoly[index];
177         if (!(mpoly->flag & ME_HIDE) && !(mpoly->flag & ME_FACE_SEL))
178                 return DM_DRAW_OPTION_NO_MCOL;  /* Don't set color */
179         else
180                 return DM_DRAW_OPTION_SKIP;
181 }
182
183 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
184 {
185         drawMeshFaceSelect_userData data;
186
187         data.me = me;
188         data.eh = get_tface_mesh_marked_edge_info(me);
189
190         glEnable(GL_DEPTH_TEST);
191         glDisable(GL_LIGHTING);
192         bglPolygonOffset(rv3d->dist, 1.0);
193
194         /* Draw (Hidden) Edges */
195         setlinestyle(1);
196         UI_ThemeColor(TH_EDGE_FACESEL);
197         dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
198         setlinestyle(0);
199
200         /* Draw Selected Faces */
201         if (me->drawflag & ME_DRAWFACES) {
202                 glEnable(GL_BLEND);
203                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
204                 /* dull unselected faces so as not to get in the way of seeing color */
205                 glColor4ub(96, 96, 96, 64);
206                 dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, 0);
207                 glDisable(GL_BLEND);
208         }
209         
210         bglPolygonOffset(rv3d->dist, 1.0);
211
212         /* Draw Stippled Outline for selected faces */
213         glColor3ub(255, 255, 255);
214         setlinestyle(1);
215         dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
216         setlinestyle(0);
217
218         bglPolygonOffset(rv3d->dist, 0.0);  /* resets correctly now, even after calling accumulated offsets */
219
220         BLI_edgehash_free(data.eh, NULL);
221 }
222
223 /***************************** Texture Drawing ******************************/
224
225 static Material *give_current_material_or_def(Object *ob, int matnr)
226 {
227         extern Material defmaterial;  /* render module abuse... */
228         Material *ma = give_current_material(ob, matnr);
229
230         return ma ? ma : &defmaterial;
231 }
232
233 /* Icky globals, fix with userdata parameter */
234
235 static struct TextureDrawState {
236         Object *ob;
237         int is_lit, is_tex;
238         int color_profile;
239         bool use_backface_culling;
240         unsigned char obcol[4];
241 } Gtexdraw = {NULL, 0, 0, 0, false, {0, 0, 0, 0}};
242
243 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
244 {
245         static Material *c_ma;
246         static int c_textured;
247         static MTFace c_texface;
248         static int c_backculled;
249         static int c_badtex;
250         static int c_lit;
251         static int c_has_texface;
252
253         Object *litob = NULL;  /* to get mode to turn off mipmap in painting mode */
254         int backculled = GEMAT_BACKCULL || gtexdraw.use_backface_culling;
255         int alphablend = 0;
256         int textured = 0;
257         int lit = 0;
258         int has_texface = texface != NULL;
259         int need_set_tpage = FALSE;
260
261         if (clearcache) {
262                 c_textured = c_lit = c_backculled = -1;
263                 memset(&c_texface, 0, sizeof(MTFace));
264                 c_badtex = 0;
265                 c_has_texface = -1;
266         }
267         else {
268                 textured = gtexdraw.is_tex;
269                 litob = gtexdraw.ob;
270         }
271
272         /* convert number of lights into boolean */
273         if (gtexdraw.is_lit) lit = 1;
274
275         if (ma) {
276                 alphablend = ma->game.alpha_blend;
277                 if (ma->mode & MA_SHLESS) lit = 0;
278                 backculled = (ma->game.flag & GEMAT_BACKCULL) || gtexdraw.use_backface_culling;
279         }
280
281         if (texface) {
282                 textured = textured && (texface->tpage);
283
284                 /* no material, render alpha if texture has depth=32 */
285                 if (!ma && BKE_image_has_alpha(texface->tpage))
286                         alphablend = GPU_BLEND_ALPHA;
287         }
288
289         else
290                 textured = 0;
291
292         if (backculled != c_backculled) {
293                 if (backculled) glEnable(GL_CULL_FACE);
294                 else glDisable(GL_CULL_FACE);
295
296                 c_backculled = backculled;
297         }
298
299         /* need to re-set tpage if textured flag changed or existsment of texface changed..  */
300         need_set_tpage = textured != c_textured || has_texface != c_has_texface;
301         /* ..or if settings inside texface were changed (if texface was used) */
302         need_set_tpage |= texface && memcmp(&c_texface, texface, sizeof(c_texface));
303
304         if (need_set_tpage) {
305                 if (textured) {
306                         c_badtex = !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
307                 }
308                 else {
309                         GPU_set_tpage(NULL, 0, 0);
310                         c_badtex = 0;
311                 }
312                 c_textured = textured;
313                 c_has_texface = has_texface;
314                 if (texface)
315                         memcpy(&c_texface, texface, sizeof(c_texface));
316         }
317
318         if (c_badtex) lit = 0;
319         if (lit != c_lit || ma != c_ma) {
320                 if (lit) {
321                         float spec[4];
322                         if (!ma) ma = give_current_material_or_def(NULL, 0);  /* default material */
323
324                         spec[0] = ma->spec * ma->specr;
325                         spec[1] = ma->spec * ma->specg;
326                         spec[2] = ma->spec * ma->specb;
327                         spec[3] = 1.0;
328
329                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
330                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
331                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
332                         glEnable(GL_LIGHTING);
333                         glEnable(GL_COLOR_MATERIAL);
334                 }
335                 else {
336                         glDisable(GL_LIGHTING); 
337                         glDisable(GL_COLOR_MATERIAL);
338                 }
339                 c_lit = lit;
340         }
341
342         return c_badtex;
343 }
344
345 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
346 {
347         unsigned char obcol[4];
348         int is_tex, solidtex;
349         Mesh *me = ob->data;
350
351         /* XXX scene->obedit warning */
352
353         /* texture draw is abused for mask selection mode, do this so wire draw
354          * with face selection in weight paint is not lit. */
355         if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
356                 solidtex = FALSE;
357                 Gtexdraw.is_lit = 0;
358         }
359         else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE)) {
360                 /* draw with default lights in solid draw mode and edit mode */
361                 solidtex = TRUE;
362                 Gtexdraw.is_lit = -1;
363         }
364         else {
365                 /* draw with lights in the scene otherwise */
366                 solidtex = FALSE;
367                 Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
368         }
369         
370         rgba_float_to_uchar(obcol, ob->col);
371
372         if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = 1;
373         else is_tex = 0;
374
375         Gtexdraw.ob = ob;
376         Gtexdraw.is_tex = is_tex;
377
378         Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
379         Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
380
381         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
382         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
383         glShadeModel(GL_SMOOTH);
384         glCullFace(GL_BACK);
385         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
386 }
387
388 static void draw_textured_end(void)
389 {
390         /* switch off textures */
391         GPU_set_tpage(NULL, 0, 0);
392
393         glShadeModel(GL_FLAT);
394         glDisable(GL_CULL_FACE);
395         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
396
397         /* XXX, bad patch - GPU_default_lights() calls
398          * glLightfv(GL_POSITION, ...) which
399          * is transformed by the current matrix... we
400          * need to make sure that matrix is identity.
401          * 
402          * It would be better if drawmesh.c kept track
403          * of and restored the light settings it changed.
404          *  - zr
405          */
406         glPushMatrix();
407         glLoadIdentity();
408         GPU_default_lights();
409         glPopMatrix();
410 }
411
412 static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
413 {
414         Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
415         int invalidtexture = 0;
416
417         if (ma && (ma->game.flag & GEMAT_INVISIBLE))
418                 return DM_DRAW_OPTION_SKIP;
419
420         invalidtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
421
422         if (tface && invalidtexture) {
423                 glColor3ub(0xFF, 0x00, 0xFF);
424                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
425         }
426         else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
427                 glColor3ubv(Gtexdraw.obcol);
428                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
429         }
430         else if (!has_mcol) {
431                 if (tface) {
432                         glColor3f(1.0, 1.0, 1.0);
433                 }
434                 else {
435                         if (ma) {
436                                 float col[3];
437                                 if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
438                                 else copy_v3_v3(col, &ma->r);
439                                 
440                                 glColor3fv(col);
441                         }
442                         else {
443                                 glColor3f(1.0, 1.0, 1.0);
444                         }
445                 }
446                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
447         }
448         else {
449                 return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
450         }
451 }
452
453 static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
454 {
455         if (has_mcol)
456                 return DM_DRAW_OPTION_NORMAL;
457         else
458                 return DM_DRAW_OPTION_NO_MCOL;
459 }
460
461 static DMDrawOption draw_tface__set_draw(MTFace *tface, int UNUSED(has_mcol), int matnr)
462 {
463         Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
464
465         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
466
467         if (tface)
468                 set_draw_settings_cached(0, tface, ma, Gtexdraw);
469
470         /* always use color from mcol, as set in update_tface_color_layer */
471         return DM_DRAW_OPTION_NORMAL;
472 }
473
474 static void update_tface_color_layer(DerivedMesh *dm)
475 {
476         MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE);
477         MFace *mface = dm->getTessFaceArray(dm);
478         MCol *finalCol;
479         int i, j;
480         MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
481         if (!mcol)
482                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
483
484         if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
485                 finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
486         }
487         else {
488                 finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer");
489
490                 CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData);
491         }
492
493         for (i = 0; i < dm->getNumTessFaces(dm); i++) {
494                 Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
495
496                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
497                         if (mcol)
498                                 memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
499                         else
500                                 for (j = 0; j < 4; j++) {
501                                         finalCol[i * 4 + j].b = 255;
502                                         finalCol[i * 4 + j].g = 255;
503                                         finalCol[i * 4 + j].r = 255;
504                                 }
505                 }
506                 else if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
507                         for (j = 0; j < 4; j++) {
508                                 finalCol[i * 4 + j].b = 255;
509                                 finalCol[i * 4 + j].g = 0;
510                                 finalCol[i * 4 + j].r = 255;
511                         }
512                 }
513                 else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
514                         for (j = 0; j < 4; j++) {
515                                 finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
516                                 finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
517                                 finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
518                         }
519                 }
520                 else if (!mcol) {
521                         if (tface) {
522                                 for (j = 0; j < 4; j++) {
523                                         finalCol[i * 4 + j].b = 255;
524                                         finalCol[i * 4 + j].g = 255;
525                                         finalCol[i * 4 + j].r = 255;
526                                 }
527                         }
528                         else {
529                                 float col[3];
530
531                                 if (ma) {
532                                         if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
533                                         else copy_v3_v3(col, &ma->r);
534                                         
535                                         for (j = 0; j < 4; j++) {
536                                                 finalCol[i * 4 + j].b = FTOCHAR(col[0]);
537                                                 finalCol[i * 4 + j].g = FTOCHAR(col[1]);
538                                                 finalCol[i * 4 + j].r = FTOCHAR(col[2]);
539                                         }
540                                 }
541                                 else
542                                         for (j = 0; j < 4; j++) {
543                                                 finalCol[i * 4 + j].b = 255;
544                                                 finalCol[i * 4 + j].g = 255;
545                                                 finalCol[i * 4 + j].r = 255;
546                                         }
547                         }
548                 }
549                 else {
550                         for (j = 0; j < 4; j++) {
551                                 finalCol[i * 4 + j].r = mcol[i * 4 + j].r;
552                                 finalCol[i * 4 + j].g = mcol[i * 4 + j].g;
553                                 finalCol[i * 4 + j].b = mcol[i * 4 + j].b;
554                         }
555                 }
556         }
557 }
558
559 static DMDrawOption draw_tface_mapped__set_draw(void *userData, int index)
560 {
561         Mesh *me = (Mesh *)userData;
562
563         /* array checked for NULL before calling */
564         MPoly *mpoly = &me->mpoly[index];
565
566         BLI_assert(index >= 0 && index < me->totpoly);
567
568         if (mpoly->flag & ME_HIDE) {
569                 return DM_DRAW_OPTION_SKIP;
570         }
571         else {
572                 MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[index] : NULL;
573                 MTFace mtf = {{{0}}};
574                 int matnr = mpoly->mat_nr;
575
576                 if (tpoly) {
577                         ME_MTEXFACE_CPY(&mtf, tpoly);
578                 }
579
580                 return draw_tface__set_draw(&mtf, (me->mloopcol != NULL), matnr);
581         }
582 }
583
584 static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index)
585 {
586         drawEMTFMapped_userData *data = userData;
587         BMEditMesh *em = data->em;
588         BMFace *efa = EDBM_face_at_index(em, index);
589
590         if (efa == NULL || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
591                 return DM_DRAW_OPTION_SKIP;
592         }
593         else {
594                 MTFace mtf = {{{0}}};
595                 int matnr = efa->mat_nr;
596
597                 if (data->has_mtface) {
598                         MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
599                         ME_MTEXFACE_CPY(&mtf, tpoly);
600                 }
601
602                 return draw_tface__set_draw_legacy(data->has_mtface ? &mtf : NULL,
603                                                    data->has_mcol, matnr);
604         }
605 }
606
607 /* when face select is on, use face hidden flag */
608 static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
609 {
610         Mesh *me = (Mesh *)userData;
611         MPoly *mp = &me->mpoly[index];
612         if (mp->flag & ME_HIDE)
613                 return DM_DRAW_OPTION_SKIP;
614         return DM_DRAW_OPTION_NORMAL;
615 }
616
617 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
618 {
619         Mesh *me = ob->data;
620         DerivedMesh *ddm;
621         MPoly *mp, *mface  = me->mpoly;
622         MTexPoly *mtpoly   = me->mtpoly;
623         MLoopUV *mloopuv   = me->mloopuv;
624         MLoopUV *luv;
625         MLoopCol *mloopcol = me->mloopcol;  /* why does mcol exist? */
626         MLoopCol *lcol;
627
628         bProperty *prop = BKE_bproperty_object_get(ob, "Text");
629         GPUVertexAttribs gattribs;
630         int a, totpoly = me->totpoly;
631
632         /* fake values to pass to GPU_render_text() */
633         MCol  tmp_mcol[4]  = {{0}};
634         MCol *tmp_mcol_pt  = mloopcol ? tmp_mcol : NULL;
635         MTFace tmp_tf      = {{{0}}};
636
637         /* don't draw without tfaces */
638         if (!mtpoly || !mloopuv)
639                 return;
640
641         /* don't draw when editing */
642         if (ob->mode & OB_MODE_EDIT)
643                 return;
644         else if (ob == OBACT)
645                 if (paint_facesel_test(ob) || paint_vertsel_test(ob))
646                         return;
647
648         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
649
650         for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
651                 short matnr = mp->mat_nr;
652                 int mf_smooth = mp->flag & ME_SMOOTH;
653                 Material *mat = me->mat[matnr];
654                 int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
655
656                 if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
657                         /* get the polygon as a tri/quad */
658                         int mp_vi[4];
659                         float v1[3], v2[3], v3[3], v4[3];
660                         char string[MAX_PROPSTRING];
661                         int characters, i, glattrib = -1, badtex = 0;
662
663
664                         /* TEXFACE */
665                         ME_MTEXFACE_CPY(&tmp_tf, mtpoly);
666
667                         if (glsl) {
668                                 GPU_enable_material(matnr + 1, &gattribs);
669
670                                 for (i = 0; i < gattribs.totlayer; i++) {
671                                         if (gattribs.layer[i].type == CD_MTFACE) {
672                                                 glattrib = gattribs.layer[i].glindex;
673                                                 break;
674                                         }
675                                 }
676                         }
677                         else {
678                                 badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw);
679                                 if (badtex) {
680                                         continue;
681                                 }
682                         }
683
684                         mp_vi[0] = me->mloop[mp->loopstart + 0].v;
685                         mp_vi[1] = me->mloop[mp->loopstart + 1].v;
686                         mp_vi[2] = me->mloop[mp->loopstart + 2].v;
687                         mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;
688
689                         /* UV */
690                         luv = &mloopuv[mp->loopstart];
691                         copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++;
692                         copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++;
693                         copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++;
694                         if (mp->totloop >= 4) {
695                                 copy_v2_v2(tmp_tf.uv[3], luv->uv);
696                         }
697
698                         /* COLOR */
699                         if (mloopcol) {
700                                 unsigned int totloop_clamp = min_ii(4, mp->totloop);
701                                 unsigned int j;
702                                 lcol = &mloopcol[mp->loopstart];
703
704                                 for (j = 0; j < totloop_clamp; j++, lcol++) {
705                                         MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
706                                 }
707                         }
708
709                         /* LOCATION */
710                         ddm->getVertCo(ddm, mp_vi[0], v1);
711                         ddm->getVertCo(ddm, mp_vi[1], v2);
712                         ddm->getVertCo(ddm, mp_vi[2], v3);
713                         if (mp->totloop >= 4) {
714                                 ddm->getVertCo(ddm, mp_vi[3], v4);
715                         }
716
717
718
719                         /* The BM_FONT handling is in the gpu module, shared with the
720                          * game engine, was duplicated previously */
721
722                         BKE_bproperty_set_valstr(prop, string);
723                         characters = strlen(string);
724                         
725                         if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
726                                 characters = 0;
727
728                         if (!mf_smooth) {
729                                 float nor[3];
730
731                                 normal_tri_v3(nor, v1, v2, v3);
732
733                                 glNormal3fv(nor);
734                         }
735
736                         GPU_render_text(&tmp_tf, mode, string, characters,
737                                         (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib);
738                 }
739         }
740
741         ddm->release(ddm);
742 }
743
744 static int compareDrawOptions(void *userData, int cur_index, int next_index)
745 {
746         drawTFace_userData *data = userData;
747
748         if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
749                 return 0;
750
751         if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
752                 return 0;
753
754         return 1;
755 }
756
757 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
758 {
759         drawEMTFMapped_userData *data = userData;
760
761         if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
762                 return 0;
763
764         if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
765                 return 0;
766
767         return 1;
768 }
769
770 static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d,
771                                    Object *ob, DerivedMesh *dm, const int draw_flags)
772 {
773         Mesh *me = ob->data;
774         
775         /* correct for negative scale */
776         if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
777         else glFrontFace(GL_CCW);
778         
779         /* draw the textured mesh */
780         draw_textured_begin(scene, v3d, rv3d, ob);
781
782         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
783
784         if (ob->mode & OB_MODE_EDIT) {
785                 drawEMTFMapped_userData data;
786
787                 data.em = me->edit_btmesh;
788                 data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
789                 data.has_mtface = CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
790                 data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
791                 data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
792
793                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
794         }
795         else if (draw_flags & DRAW_FACE_SELECT) {
796                 if (ob->mode & OB_MODE_WEIGHT_PAINT)
797                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me,
798                                             DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
799                 else
800                         dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, NULL, me);
801         }
802         else {
803                 if (GPU_buffer_legacy(dm)) {
804                         if (draw_flags & DRAW_MODIFIERS_PREVIEW)
805                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
806                         else 
807                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
808                 }
809                 else {
810                         drawTFace_userData userData;
811
812                         update_tface_color_layer(dm);
813
814                         userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
815                         userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
816
817                         dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
818                 }
819         }
820
821         /* draw game engine text hack */
822         if (BKE_bproperty_object_get(ob, "Text"))
823                 draw_mesh_text(scene, ob, 0);
824
825         draw_textured_end();
826         
827         /* draw edges and selected faces over textured mesh */
828         if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
829                 draw_mesh_face_select(rv3d, me, dm);
830
831         /* reset from negative scale correction */
832         glFrontFace(GL_CCW);
833         
834         /* in editmode, the blend mode needs to be set in case it was ADD */
835         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
836 }
837
838 /************************** NEW SHADING NODES ********************************/
839
840 typedef struct TexMatCallback {
841         Scene *scene;
842         Object *ob;
843         Mesh *me;
844         DerivedMesh *dm;
845 } TexMatCallback;
846
847 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
848 {
849         /* all we have to do here is simply enable the GLSL material, but note
850          * that the GLSL code will give different result depending on the drawtype,
851          * in texture draw mode it will output the active texture node, in material
852          * draw mode it will show the full material. */
853         GPU_enable_material(mat_nr, attribs);
854 }
855
856 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
857 {
858         /* texture draw mode without GLSL */
859         TexMatCallback *data = (TexMatCallback *)userData;
860         GPUVertexAttribs *gattribs = attribs;
861         Image *ima;
862         ImageUser *iuser;
863         bNode *node;
864         int texture_set = 0;
865
866         /* draw image texture if we find one */
867         if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
868                 /* get openl texture */
869                 int mipmap = 1;
870                 int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, FALSE) : 0;
871                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
872
873                 if (bindcode) {
874                         NodeTexBase *texbase = node->storage;
875
876                         /* disable existing material */
877                         GPU_disable_material();
878                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
879                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
880                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
881
882                         /* bind texture */
883                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
884                         glEnable(GL_COLOR_MATERIAL);
885                         glEnable(GL_TEXTURE_2D);
886
887                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
888                         glColor3f(1.0f, 1.0f, 1.0f);
889
890                         glMatrixMode(GL_TEXTURE);
891                         glLoadMatrixf(texbase->tex_mapping.mat);
892                         glMatrixMode(GL_MODELVIEW);
893
894                         /* use active UV texture layer */
895                         memset(gattribs, 0, sizeof(*gattribs));
896
897                         gattribs->layer[0].type = CD_MTFACE;
898                         gattribs->layer[0].name[0] = '\0';
899                         gattribs->layer[0].gltexco = 1;
900                         gattribs->totlayer = 1;
901
902                         texture_set = 1;
903                 }
904         }
905
906         if (!texture_set) {
907                 glMatrixMode(GL_TEXTURE);
908                 glLoadIdentity();
909                 glMatrixMode(GL_MODELVIEW);
910
911                 /* disable texture */
912                 glDisable(GL_TEXTURE_2D);
913                 glDisable(GL_COLOR_MATERIAL);
914
915                 /* draw single color */
916                 GPU_enable_material(mat_nr, attribs);
917         }
918 }
919
920 static int tex_mat_set_face_mesh_cb(void *userData, int index)
921 {
922         /* faceselect mode face hiding */
923         TexMatCallback *data = (TexMatCallback *)userData;
924         Mesh *me = (Mesh *)data->me;
925         MPoly *mp = &me->mpoly[index];
926
927         return !(mp->flag & ME_HIDE);
928 }
929
930 static int tex_mat_set_face_editmesh_cb(void *userData, int index)
931 {
932         /* editmode face hiding */
933         TexMatCallback *data = (TexMatCallback *)userData;
934         Mesh *me = (Mesh *)data->me;
935         BMFace *efa = EDBM_face_at_index(me->edit_btmesh, index);
936
937         return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
938 }
939
940 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
941                         Object *ob, DerivedMesh *dm, const int draw_flags)
942 {
943         /* if not cycles, or preview-modifiers, or drawing matcaps */
944         if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW) || (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)) {
945                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
946                 return;
947         }
948         else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
949                 draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
950                 return;
951         }
952
953         /* set opengl state for negative scale & color */
954         if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
955         else glFrontFace(GL_CCW);
956
957         glEnable(GL_LIGHTING);
958
959         {
960                 Mesh *me = ob->data;
961                 TexMatCallback data = {scene, ob, me, dm};
962                 int (*set_face_cb)(void *, int);
963                 int glsl, picking = (G.f & G_PICKSEL);
964                 
965                 /* face hiding callback depending on mode */
966                 if (ob == scene->obedit)
967                         set_face_cb = tex_mat_set_face_editmesh_cb;
968                 else if (draw_flags & DRAW_FACE_SELECT)
969                         set_face_cb = tex_mat_set_face_mesh_cb;
970                 else
971                         set_face_cb = NULL;
972
973                 /* test if we can use glsl */
974                 glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support() && !picking;
975
976                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
977
978                 if (glsl || picking) {
979                         /* draw glsl */
980                         dm->drawMappedFacesMat(dm,
981                                                tex_mat_set_material_cb,
982                                                set_face_cb, &data);
983                 }
984                 else {
985                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
986
987                         /* draw textured */
988                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
989                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
990                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
991
992                         dm->drawMappedFacesMat(dm,
993                                                tex_mat_set_texture_cb,
994                                                set_face_cb, &data);
995                 }
996
997                 GPU_end_object_materials();
998         }
999
1000         /* reset opengl state */
1001         glDisable(GL_COLOR_MATERIAL);
1002         glDisable(GL_TEXTURE_2D);
1003         glDisable(GL_LIGHTING);
1004         glBindTexture(GL_TEXTURE_2D, 0);
1005         glFrontFace(GL_CCW);
1006
1007         glMatrixMode(GL_TEXTURE);
1008         glLoadIdentity();
1009         glMatrixMode(GL_MODELVIEW);
1010
1011         /* faceselect mode drawing over textured mesh */
1012         if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
1013                 draw_mesh_face_select(rv3d, ob->data, dm);
1014 }
1015
1016 /* Vertex Paint and Weight Paint */
1017
1018 void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
1019                      Object *ob, DerivedMesh *dm, const int draw_flags)
1020 {
1021         DMSetDrawOptions facemask = NULL;
1022         Mesh *me = ob->data;
1023         const short do_light = (v3d->drawtype >= OB_SOLID);
1024
1025         /* hide faces in face select mode */
1026         if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL))
1027                 facemask = wpaint__setSolidDrawOptions_facemask;
1028
1029         if (ob->mode & OB_MODE_WEIGHT_PAINT) {
1030
1031                 if (do_light) {
1032                         const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
1033
1034                         /* enforce default material settings */
1035                         GPU_enable_material(0, NULL);
1036                 
1037                         /* but set default spec */
1038                         glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
1039                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
1040
1041                         /* diffuse */
1042                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1043                         glEnable(GL_LIGHTING);
1044                         glEnable(GL_COLOR_MATERIAL);
1045                 }
1046
1047                 dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1048                                     DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1049
1050                 if (do_light) {
1051                         glDisable(GL_COLOR_MATERIAL);
1052                         glDisable(GL_LIGHTING);
1053
1054                         GPU_disable_material();
1055                 }
1056         }
1057         else if (ob->mode & OB_MODE_VERTEX_PAINT) {
1058                 if (me->mloopcol) {
1059                         dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1060                                             DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1061                 }
1062                 else {
1063                         glColor3f(1.0f, 1.0f, 1.0f);
1064                         dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me,
1065                                             DM_DRAW_ALWAYS_SMOOTH);
1066                 }
1067         }
1068
1069         /* draw face selection on top */
1070         if (draw_flags & DRAW_FACE_SELECT) {
1071                 draw_mesh_face_select(rv3d, me, dm);
1072         }
1073         else if ((do_light == FALSE) || (ob->dtx & OB_DRAWWIRE)) {
1074                 const int use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
1075
1076                 /* weight paint in solid mode, special case. focus on making the weights clear
1077                  * rather than the shading, this is also forced in wire view */
1078
1079                 if (use_depth) {
1080                         bglPolygonOffset(rv3d->dist, 1.0);
1081                         glDepthMask(0);  /* disable write in zbuffer, selected edge wires show better */
1082                 }
1083                 else {
1084                         glDisable(GL_DEPTH_TEST);
1085                 }
1086
1087                 glEnable(GL_BLEND);
1088                 glColor4ub(255, 255, 255, 96);
1089                 glEnable(GL_LINE_STIPPLE);
1090                 glLineStipple(1, 0xAAAA);
1091
1092                 dm->drawEdges(dm, 1, 1);
1093
1094                 if (use_depth) {
1095                         bglPolygonOffset(rv3d->dist, 0.0);
1096                         glDepthMask(1);
1097                 }
1098                 else {
1099                         glEnable(GL_DEPTH_TEST);
1100                 }
1101
1102                 glDisable(GL_LINE_STIPPLE);
1103                 glDisable(GL_BLEND);
1104         }
1105 }
1106