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