fb97a6ac9f49122778c0289cb8277a497cf2c72a
[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         Image *stencil; /* texture painting stencil */
216         Image *canvas;  /* texture painting canvas, for image mode */
217         bool use_game_mat;
218         int is_lit, is_tex;
219         int color_profile;
220         bool use_backface_culling;
221         unsigned char obcol[4];
222         bool is_texpaint;
223         bool texpaint_material; /* use material slots for texture painting */
224 } Gtexdraw = {NULL, NULL, NULL, false, 0, 0, 0, false, {0, 0, 0, 0}, false, false};
225
226 static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
227 {
228         static Material *c_ma;
229         static int c_textured;
230         static MTFace c_texface;
231         static int c_backculled;
232         static bool c_badtex;
233         static int c_lit;
234         static int c_has_texface;
235
236         int backculled = 1;
237         int alphablend = GPU_BLEND_SOLID;
238         int textured = 0;
239         int lit = 0;
240         int has_texface = texface != NULL;
241         bool need_set_tpage = false;
242         bool texpaint = ((gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) != 0);
243
244         Image *ima = NULL;
245
246         if (ma != NULL) {
247                 if (ma->mode & MA_TRANSP) {
248                         alphablend = GPU_BLEND_ALPHA;
249                 }
250         }
251
252         if (clearcache) {
253                 c_textured = c_lit = c_backculled = -1;
254                 memset(&c_texface, 0, sizeof(MTFace));
255                 c_badtex = false;
256                 c_has_texface = -1;
257                 c_ma = NULL;
258         }
259         else {
260                 textured = gtexdraw.is_tex;
261         }
262
263         /* convert number of lights into boolean */
264         if (gtexdraw.is_lit) lit = 1;
265
266         backculled = gtexdraw.use_backface_culling;
267         if (ma) {
268                 if (ma->mode & MA_SHLESS) lit = 0;
269                 if (gtexdraw.use_game_mat) {
270                         backculled = backculled || (ma->game.flag & GEMAT_BACKCULL);
271                         alphablend = ma->game.alpha_blend;
272                 }
273         }
274
275         if (texface && !texpaint) {
276                 textured = textured && (texface->tpage);
277
278                 /* no material, render alpha if texture has depth=32 */
279                 if (!ma && BKE_image_has_alpha(texface->tpage))
280                         alphablend = GPU_BLEND_ALPHA;
281         }
282         else if (texpaint && ma) {
283                 if (gtexdraw.texpaint_material)
284                         ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
285                 else 
286                         ima = gtexdraw.canvas;
287         }
288         else
289                 textured = 0;
290
291         if (backculled != c_backculled) {
292                 if (backculled) glEnable(GL_CULL_FACE);
293                 else glDisable(GL_CULL_FACE);
294
295                 c_backculled = backculled;
296         }
297
298         /* need to re-set tpage if textured flag changed or existsment of texface changed..  */
299         need_set_tpage = textured != c_textured || has_texface != c_has_texface;
300         /* ..or if settings inside texface were changed (if texface was used) */
301         need_set_tpage |= (texpaint && c_ma != ma) || (texface && memcmp(&c_texface, texface, sizeof(c_texface)));
302
303         if (need_set_tpage) {
304                 if (textured) {
305                         if (texpaint) {
306                                 c_badtex = false;
307                                 if (GPU_verify_image(ima, NULL, 0, 1, 0, false)) {
308                                         glEnable(GL_TEXTURE_2D);
309                                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
310                                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
311                                         glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
312                                         glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
313                                         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
314                                         glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
315                                         
316                                         glActiveTexture(GL_TEXTURE1);
317                                         glEnable(GL_TEXTURE_2D);
318                                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
319                                         glActiveTexture(GL_TEXTURE0);                                   
320                                 }
321                                 else {
322                                         glActiveTexture(GL_TEXTURE1);
323                                         glDisable(GL_TEXTURE_2D);
324                                         glBindTexture(GL_TEXTURE_2D, 0);
325                                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
326                                         glActiveTexture(GL_TEXTURE0);                                                                   
327
328                                         c_badtex = true;
329                                         GPU_clear_tpage(true);
330                                         glDisable(GL_TEXTURE_2D);
331                                         glBindTexture(GL_TEXTURE_2D, 0);
332                                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
333                                 }
334                         }
335                         else {
336                                 c_badtex = !GPU_set_tpage(texface, !texpaint, alphablend);
337                         }
338                 }
339                 else {
340                         GPU_set_tpage(NULL, 0, 0);
341                         c_badtex = false;
342                 }
343                 c_textured = textured;
344                 c_has_texface = has_texface;
345                 if (texface)
346                         memcpy(&c_texface, texface, sizeof(c_texface));
347         }
348
349         if (c_badtex) lit = 0;
350         if (lit != c_lit || ma != c_ma) {
351                 if (lit) {
352                         float spec[4];
353                         if (!ma) ma = give_current_material_or_def(NULL, 0);  /* default material */
354
355                         spec[0] = ma->spec * ma->specr;
356                         spec[1] = ma->spec * ma->specg;
357                         spec[2] = ma->spec * ma->specb;
358                         spec[3] = 1.0;
359
360                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
361                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
362                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
363                         glEnable(GL_LIGHTING);
364                         glEnable(GL_COLOR_MATERIAL);
365                 }
366                 else {
367                         glDisable(GL_LIGHTING); 
368                         glDisable(GL_COLOR_MATERIAL);
369                 }
370                 c_lit = lit;
371                 c_ma = ma;
372         }
373
374         return c_badtex;
375 }
376
377 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
378 {
379         unsigned char obcol[4];
380         bool is_tex, solidtex;
381         Mesh *me = ob->data;
382         ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
383
384         /* XXX scene->obedit warning */
385
386         /* texture draw is abused for mask selection mode, do this so wire draw
387          * with face selection in weight paint is not lit. */
388         if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
389                 solidtex = false;
390                 Gtexdraw.is_lit = 0;
391         }
392         else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE)) {
393                 /* draw with default lights in solid draw mode and edit mode */
394                 solidtex = true;
395                 Gtexdraw.is_lit = -1;
396         }
397         else {
398                 /* draw with lights in the scene otherwise */
399                 solidtex = false;
400                 if (v3d->flag2 & V3D_SHADELESS_TEX)
401                         Gtexdraw.is_lit = 0;
402                 else
403                         Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
404         }
405         
406         rgba_float_to_uchar(obcol, ob->col);
407
408         if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
409         else is_tex = false;
410
411         Gtexdraw.ob = ob;
412         Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
413         Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
414         Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
415         Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
416         Gtexdraw.is_tex = is_tex;
417
418         /* naughty multitexturing hacks to quickly support stencil + shading + alpha blending 
419          * in new texpaint code. The better solution here would be to support GLSL */
420         if (Gtexdraw.is_texpaint) {                     
421                 glActiveTexture(GL_TEXTURE1);
422                 glEnable(GL_TEXTURE_2D);
423                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
424                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
425                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
426                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
427                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
428                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
429                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
430                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
431                 
432                 /* load the stencil texture here */
433                 if (Gtexdraw.stencil != NULL) {
434                         glActiveTexture(GL_TEXTURE2);
435                         if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) {
436                                 float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
437                                 glEnable(GL_TEXTURE_2D);
438                                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
439                                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
440                                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
441                                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
442                                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
443                                 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
444                                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
445                                 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
446                                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
447                                 if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) {
448                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
449                                 }
450                                 else {
451                                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
452                                 }
453                         }
454                 }
455                 glActiveTexture(GL_TEXTURE0);
456         }
457         
458         Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
459         Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
460         Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;
461
462         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
463         set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
464         glShadeModel(GL_SMOOTH);
465         glCullFace(GL_BACK);
466         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
467 }
468
469 static void draw_textured_end(void)
470 {
471         if (Gtexdraw.ob->mode & OB_MODE_TEXTURE_PAINT) {
472                 glActiveTexture(GL_TEXTURE1);
473                 glDisable(GL_TEXTURE_2D);
474                 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
475                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
476                 glBindTexture(GL_TEXTURE_2D, 0);
477
478                 if (Gtexdraw.stencil != NULL) {
479                         glActiveTexture(GL_TEXTURE2);
480                         glDisable(GL_TEXTURE_2D);
481                         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
482                         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
483                         glBindTexture(GL_TEXTURE_2D, 0);
484                 }               
485                 glActiveTexture(GL_TEXTURE0);
486                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
487                 /* manual reset, since we don't use tpage */
488                 glBindTexture(GL_TEXTURE_2D, 0);
489                 /* force switch off textures */
490                 GPU_clear_tpage(true);
491         }
492         else {
493                 /* switch off textures */
494                 GPU_set_tpage(NULL, 0, 0);
495         }
496
497         glShadeModel(GL_FLAT);
498         glDisable(GL_CULL_FACE);
499         glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
500
501         /* XXX, bad patch - GPU_default_lights() calls
502          * glLightfv(GL_POSITION, ...) which
503          * is transformed by the current matrix... we
504          * need to make sure that matrix is identity.
505          * 
506          * It would be better if drawmesh.c kept track
507          * of and restored the light settings it changed.
508          *  - zr
509          */
510         glPushMatrix();
511         glLoadIdentity();
512         GPU_default_lights();
513         glPopMatrix();
514 }
515
516 static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, const bool has_mcol, int matnr)
517 {
518         Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
519         bool invalidtexture = false;
520
521         if (ma && (ma->game.flag & GEMAT_INVISIBLE))
522                 return DM_DRAW_OPTION_SKIP;
523
524         invalidtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
525
526         if (tface && invalidtexture) {
527                 glColor3ub(0xFF, 0x00, 0xFF);
528                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
529         }
530         else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
531                 glColor3ubv(Gtexdraw.obcol);
532                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
533         }
534         else if (!has_mcol) {
535                 if (tface) {
536                         glColor3f(1.0, 1.0, 1.0);
537                 }
538                 else {
539                         if (ma) {
540                                 float col[3];
541                                 if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
542                                 else copy_v3_v3(col, &ma->r);
543                                 
544                                 glColor3fv(col);
545                         }
546                         else {
547                                 glColor3f(1.0, 1.0, 1.0);
548                         }
549                 }
550                 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
551         }
552         else {
553                 return DM_DRAW_OPTION_NORMAL; /* Set color from mcol */
554         }
555 }
556
557 static DMDrawOption draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), const bool has_mcol, int UNUSED(matnr))
558 {
559         if (has_mcol)
560                 return DM_DRAW_OPTION_NORMAL;
561         else
562                 return DM_DRAW_OPTION_NO_MCOL;
563 }
564
565 static DMDrawOption draw_tface__set_draw(MTFace *tface, const bool UNUSED(has_mcol), int matnr)
566 {
567         Material *ma = give_current_material(Gtexdraw.ob, matnr + 1);
568
569         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
570
571         if (tface || Gtexdraw.is_texpaint)
572                 set_draw_settings_cached(0, tface, ma, Gtexdraw);
573
574         /* always use color from mcol, as set in update_tface_color_layer */
575         return DM_DRAW_OPTION_NORMAL;
576 }
577
578 static void update_tface_color_layer(DerivedMesh *dm)
579 {
580         MTFace *tface = DM_get_tessface_data_layer(dm, CD_MTFACE);
581         MFace *mface = dm->getTessFaceArray(dm);
582         MCol *finalCol;
583         int i, j;
584         MCol *mcol = dm->getTessFaceDataArray(dm, CD_PREVIEW_MCOL);
585         if (!mcol)
586                 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
587
588         if (CustomData_has_layer(&dm->faceData, CD_TEXTURE_MCOL)) {
589                 finalCol = CustomData_get_layer(&dm->faceData, CD_TEXTURE_MCOL);
590         }
591         else {
592                 finalCol = MEM_mallocN(sizeof(MCol) * 4 * dm->getNumTessFaces(dm), "add_tface_color_layer");
593
594                 CustomData_add_layer(&dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numTessFaceData);
595         }
596
597         for (i = 0; i < dm->getNumTessFaces(dm); i++) {
598                 Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1);
599
600                 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
601                         if (mcol)
602                                 memcpy(&finalCol[i * 4], &mcol[i * 4], sizeof(MCol) * 4);
603                         else
604                                 for (j = 0; j < 4; j++) {
605                                         finalCol[i * 4 + j].b = 255;
606                                         finalCol[i * 4 + j].g = 255;
607                                         finalCol[i * 4 + j].r = 255;
608                                 }
609                 }
610                 else if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
611                         for (j = 0; j < 4; j++) {
612                                 finalCol[i * 4 + j].b = 255;
613                                 finalCol[i * 4 + j].g = 0;
614                                 finalCol[i * 4 + j].r = 255;
615                         }
616                 }
617                 else if (ma && (ma->shade_flag & MA_OBCOLOR)) {
618                         for (j = 0; j < 4; j++) {
619                                 finalCol[i * 4 + j].b = Gtexdraw.obcol[0];
620                                 finalCol[i * 4 + j].g = Gtexdraw.obcol[1];
621                                 finalCol[i * 4 + j].r = Gtexdraw.obcol[2];
622                         }
623                 }
624                 else if (!mcol) {
625                         if (tface) {
626                                 for (j = 0; j < 4; j++) {
627                                         finalCol[i * 4 + j].b = 255;
628                                         finalCol[i * 4 + j].g = 255;
629                                         finalCol[i * 4 + j].r = 255;
630                                 }
631                         }
632                         else {
633                                 float col[3];
634
635                                 if (ma) {
636                                         if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
637                                         else copy_v3_v3(col, &ma->r);
638                                         
639                                         for (j = 0; j < 4; j++) {
640                                                 finalCol[i * 4 + j].b = FTOCHAR(col[0]);
641                                                 finalCol[i * 4 + j].g = FTOCHAR(col[1]);
642                                                 finalCol[i * 4 + j].r = FTOCHAR(col[2]);
643                                         }
644                                 }
645                                 else
646                                         for (j = 0; j < 4; j++) {
647                                                 finalCol[i * 4 + j].b = 255;
648                                                 finalCol[i * 4 + j].g = 255;
649                                                 finalCol[i * 4 + j].r = 255;
650                                         }
651                         }
652                 }
653                 else {
654                         for (j = 0; j < 4; j++) {
655                                 finalCol[i * 4 + j].r = mcol[i * 4 + j].r;
656                                 finalCol[i * 4 + j].g = mcol[i * 4 + j].g;
657                                 finalCol[i * 4 + j].b = mcol[i * 4 + j].b;
658                         }
659                 }
660         }
661 }
662
663 static DMDrawOption draw_tface_mapped__set_draw(void *userData, int index)
664 {
665         Mesh *me = ((drawTFace_userData *)userData)->me;
666
667         /* array checked for NULL before calling */
668         MPoly *mpoly = &me->mpoly[index];
669
670         BLI_assert(index >= 0 && index < me->totpoly);
671
672         if (mpoly->flag & ME_HIDE) {
673                 return DM_DRAW_OPTION_SKIP;
674         }
675         else {
676                 MTexPoly *tpoly = (me->mtpoly) ? &me->mtpoly[index] : NULL;
677                 MTFace mtf = {{{0}}};
678                 int matnr = mpoly->mat_nr;
679
680                 if (tpoly) {
681                         ME_MTEXFACE_CPY(&mtf, tpoly);
682                 }
683
684                 return draw_tface__set_draw(&mtf, (me->mloopcol != NULL), matnr);
685         }
686 }
687
688 static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index)
689 {
690         drawEMTFMapped_userData *data = userData;
691         BMEditMesh *em = data->em;
692         BMFace *efa;
693
694         if (UNLIKELY(index >= em->bm->totface))
695                 return DM_DRAW_OPTION_NORMAL;
696
697         efa = BM_face_at_index(em->bm, index);
698
699         if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
700                 return DM_DRAW_OPTION_SKIP;
701         }
702         else {
703                 MTFace mtf = {{{0}}};
704                 int matnr = efa->mat_nr;
705
706                 if (data->has_mtface) {
707                         MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
708                         ME_MTEXFACE_CPY(&mtf, tpoly);
709                 }
710
711                 return draw_tface__set_draw_legacy(data->has_mtface ? &mtf : NULL,
712                                                    data->has_mcol, matnr);
713         }
714 }
715
716 /* when face select is on, use face hidden flag */
717 static DMDrawOption wpaint__setSolidDrawOptions_facemask(void *userData, int index)
718 {
719         Mesh *me = (Mesh *)userData;
720         MPoly *mp = &me->mpoly[index];
721         if (mp->flag & ME_HIDE)
722                 return DM_DRAW_OPTION_SKIP;
723         return DM_DRAW_OPTION_NORMAL;
724 }
725
726 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
727 {
728         Mesh *me = ob->data;
729         DerivedMesh *ddm;
730         MPoly *mp, *mface  = me->mpoly;
731         MTexPoly *mtpoly   = me->mtpoly;
732         MLoopUV *mloopuv   = me->mloopuv;
733         MLoopUV *luv;
734         MLoopCol *mloopcol = me->mloopcol;  /* why does mcol exist? */
735         MLoopCol *lcol;
736
737         bProperty *prop = BKE_bproperty_object_get(ob, "Text");
738         GPUVertexAttribs gattribs;
739         int a, totpoly = me->totpoly;
740
741         /* fake values to pass to GPU_render_text() */
742         MCol  tmp_mcol[4]  = {{0}};
743         MCol *tmp_mcol_pt  = mloopcol ? tmp_mcol : NULL;
744         MTFace tmp_tf      = {{{0}}};
745
746         /* don't draw without tfaces */
747         if (!mtpoly || !mloopuv)
748                 return;
749
750         /* don't draw when editing */
751         if (ob->mode & OB_MODE_EDIT)
752                 return;
753         else if (ob == OBACT)
754                 if (BKE_paint_select_elem_test(ob))
755                         return;
756
757         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
758
759         for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) {
760                 short matnr = mp->mat_nr;
761                 int mf_smooth = mp->flag & ME_SMOOTH;
762                 Material *mat = (me->mat) ? me->mat[matnr] : NULL;
763                 int mode = mat ? mat->game.flag : GEMAT_INVISIBLE;
764
765
766                 if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) {
767                         /* get the polygon as a tri/quad */
768                         int mp_vi[4];
769                         float v1[3], v2[3], v3[3], v4[3];
770                         char string[MAX_PROPSTRING];
771                         int characters, i, glattrib = -1, badtex = 0;
772
773
774                         /* TEXFACE */
775                         ME_MTEXFACE_CPY(&tmp_tf, mtpoly);
776
777                         if (glsl) {
778                                 GPU_enable_material(matnr + 1, &gattribs);
779
780                                 for (i = 0; i < gattribs.totlayer; i++) {
781                                         if (gattribs.layer[i].type == CD_MTFACE) {
782                                                 glattrib = gattribs.layer[i].glindex;
783                                                 break;
784                                         }
785                                 }
786                         }
787                         else {
788                                 badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw);
789                                 if (badtex) {
790                                         continue;
791                                 }
792                         }
793
794                         mp_vi[0] = me->mloop[mp->loopstart + 0].v;
795                         mp_vi[1] = me->mloop[mp->loopstart + 1].v;
796                         mp_vi[2] = me->mloop[mp->loopstart + 2].v;
797                         mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0;
798
799                         /* UV */
800                         luv = &mloopuv[mp->loopstart];
801                         copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++;
802                         copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++;
803                         copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++;
804                         if (mp->totloop >= 4) {
805                                 copy_v2_v2(tmp_tf.uv[3], luv->uv);
806                         }
807
808                         /* COLOR */
809                         if (mloopcol) {
810                                 unsigned int totloop_clamp = min_ii(4, mp->totloop);
811                                 unsigned int j;
812                                 lcol = &mloopcol[mp->loopstart];
813
814                                 for (j = 0; j < totloop_clamp; j++, lcol++) {
815                                         MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]);
816                                 }
817                         }
818
819                         /* LOCATION */
820                         ddm->getVertCo(ddm, mp_vi[0], v1);
821                         ddm->getVertCo(ddm, mp_vi[1], v2);
822                         ddm->getVertCo(ddm, mp_vi[2], v3);
823                         if (mp->totloop >= 4) {
824                                 ddm->getVertCo(ddm, mp_vi[3], v4);
825                         }
826
827
828
829                         /* The BM_FONT handling is in the gpu module, shared with the
830                          * game engine, was duplicated previously */
831
832                         BKE_bproperty_set_valstr(prop, string);
833                         characters = strlen(string);
834                         
835                         if (!BKE_image_has_ibuf(mtpoly->tpage, NULL))
836                                 characters = 0;
837
838                         if (!mf_smooth) {
839                                 float nor[3];
840
841                                 normal_tri_v3(nor, v1, v2, v3);
842
843                                 glNormal3fv(nor);
844                         }
845
846                         GPU_render_text(&tmp_tf, mode, string, characters,
847                                         (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib);
848                 }
849         }
850
851         ddm->release(ddm);
852 }
853
854 static int compareDrawOptions(void *userData, int cur_index, int next_index)
855 {
856         drawTFace_userData *data = userData;
857
858         if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
859                 return 0;
860
861         if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
862                 return 0;
863
864         return 1;
865 }
866
867
868 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
869 {
870         drawEMTFMapped_userData *data = userData;
871
872         if (data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
873                 return 0;
874
875         if (data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
876                 return 0;
877
878         return 1;
879 }
880
881 static void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d,
882                                    Object *ob, DerivedMesh *dm, const int draw_flags)
883 {
884         Mesh *me = ob->data;
885         DMDrawFlag uvflag = DM_DRAW_USE_ACTIVE_UV;
886
887         /* correct for negative scale */
888         if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
889         else glFrontFace(GL_CCW);
890         
891         /* draw the textured mesh */
892         draw_textured_begin(scene, v3d, rv3d, ob);
893
894         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
895
896         if (ob->mode & OB_MODE_TEXTURE_PAINT) {
897                 uvflag = DM_DRAW_USE_TEXPAINT_UV;
898         }
899
900         if (ob->mode & OB_MODE_EDIT) {
901                 drawEMTFMapped_userData data;
902
903                 data.em = me->edit_btmesh;
904                 data.has_mcol = CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
905                 data.has_mtface = CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
906                 data.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
907                 data.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
908
909                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data, 0);
910         }
911         else if (draw_flags & DRAW_FACE_SELECT) {
912                 if (ob->mode & OB_MODE_WEIGHT_PAINT)
913                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me,
914                                             DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
915                 else {
916                         drawTFace_userData userData;
917
918                         userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
919                         userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
920                         userData.me = me;
921                         dm->drawMappedFacesTex(dm, me->mpoly ? draw_tface_mapped__set_draw : NULL, compareDrawOptions, &userData, uvflag);
922                 }
923         }
924         else {
925                 if (GPU_buffer_legacy(dm)) {
926                         if (draw_flags & DRAW_MODIFIERS_PREVIEW)
927                                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL, uvflag);
928                         else 
929                                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL, uvflag);
930                 }
931                 else {
932                         drawTFace_userData userData;
933
934                         update_tface_color_layer(dm);
935
936                         userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
937                         userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
938                         userData.me = NULL;
939
940                         dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData, uvflag);
941                 }
942         }
943
944         /* draw game engine text hack */
945         if (BKE_bproperty_object_get(ob, "Text"))
946                 draw_mesh_text(scene, ob, 0);
947
948         draw_textured_end();
949         
950         /* draw edges and selected faces over textured mesh */
951         if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
952                 draw_mesh_face_select(rv3d, me, dm);
953
954         /* reset from negative scale correction */
955         glFrontFace(GL_CCW);
956         
957         /* in editmode, the blend mode needs to be set in case it was ADD */
958         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
959 }
960
961 /************************** NEW SHADING NODES ********************************/
962
963 typedef struct TexMatCallback {
964         Scene *scene;
965         Object *ob;
966         Mesh *me;
967         DerivedMesh *dm;
968 } TexMatCallback;
969
970 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
971 {
972         /* all we have to do here is simply enable the GLSL material, but note
973          * that the GLSL code will give different result depending on the drawtype,
974          * in texture draw mode it will output the active texture node, in material
975          * draw mode it will show the full material. */
976         GPU_enable_material(mat_nr, attribs);
977 }
978
979 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
980 {
981         /* texture draw mode without GLSL */
982         TexMatCallback *data = (TexMatCallback *)userData;
983         GPUVertexAttribs *gattribs = attribs;
984         Image *ima;
985         ImageUser *iuser;
986         bNode *node;
987         int texture_set = 0;
988
989         /* draw image texture if we find one */
990         if (ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node, NULL)) {
991                 /* get openl texture */
992                 int mipmap = 1;
993                 int bindcode = (ima) ? GPU_verify_image(ima, iuser, 0, 0, mipmap, false) : 0;
994                 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
995
996                 if (bindcode) {
997                         NodeTexBase *texbase = node->storage;
998
999                         /* disable existing material */
1000                         GPU_disable_material();
1001                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
1002                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
1003                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
1004
1005                         /* bind texture */
1006                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1007                         glEnable(GL_COLOR_MATERIAL);
1008                         glEnable(GL_TEXTURE_2D);
1009
1010                         glBindTexture(GL_TEXTURE_2D, ima->bindcode);
1011                         glColor3f(1.0f, 1.0f, 1.0f);
1012
1013                         glMatrixMode(GL_TEXTURE);
1014                         glLoadMatrixf(texbase->tex_mapping.mat);
1015                         glMatrixMode(GL_MODELVIEW);
1016
1017                         /* use active UV texture layer */
1018                         memset(gattribs, 0, sizeof(*gattribs));
1019
1020                         gattribs->layer[0].type = CD_MTFACE;
1021                         gattribs->layer[0].name[0] = '\0';
1022                         gattribs->layer[0].gltexco = 1;
1023                         gattribs->totlayer = 1;
1024
1025                         texture_set = 1;
1026                 }
1027         }
1028
1029         if (!texture_set) {
1030                 glMatrixMode(GL_TEXTURE);
1031                 glLoadIdentity();
1032                 glMatrixMode(GL_MODELVIEW);
1033
1034                 /* disable texture */
1035                 glDisable(GL_TEXTURE_2D);
1036                 glDisable(GL_COLOR_MATERIAL);
1037
1038                 /* draw single color */
1039                 GPU_enable_material(mat_nr, attribs);
1040         }
1041 }
1042
1043 static bool tex_mat_set_face_mesh_cb(void *userData, int index)
1044 {
1045         /* faceselect mode face hiding */
1046         TexMatCallback *data = (TexMatCallback *)userData;
1047         Mesh *me = (Mesh *)data->me;
1048         MPoly *mp = &me->mpoly[index];
1049
1050         return !(mp->flag & ME_HIDE);
1051 }
1052
1053 static bool tex_mat_set_face_editmesh_cb(void *userData, int index)
1054 {
1055         /* editmode face hiding */
1056         TexMatCallback *data = (TexMatCallback *)userData;
1057         Mesh *me = (Mesh *)data->me;
1058         BMEditMesh *em = me->edit_btmesh;
1059         BMFace *efa;
1060
1061         if (UNLIKELY(index >= em->bm->totface))
1062                 return DM_DRAW_OPTION_NORMAL;
1063
1064         efa = BM_face_at_index(em->bm, index);
1065
1066         return !BM_elem_flag_test(efa, BM_ELEM_HIDDEN);
1067 }
1068
1069 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
1070                         Object *ob, DerivedMesh *dm, const int draw_flags)
1071 {
1072         /* if not cycles, or preview-modifiers, or drawing matcaps */
1073         if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
1074             (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
1075             (BKE_scene_use_new_shading_nodes(scene) == false) ||
1076             ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
1077         {
1078                 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
1079                 return;
1080         }
1081         else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
1082                 draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
1083                 return;
1084         }
1085
1086         /* set opengl state for negative scale & color */
1087         if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
1088         else glFrontFace(GL_CCW);
1089
1090         if ((v3d->drawtype == OB_TEXTURE) && (v3d->flag2 & V3D_SHADELESS_TEX))
1091                 glColor3f(1.0f, 1.0f, 1.0f);
1092         else
1093                 glEnable(GL_LIGHTING);
1094
1095         {
1096                 Mesh *me = ob->data;
1097                 TexMatCallback data = {scene, ob, me, dm};
1098                 bool (*set_face_cb)(void *, int);
1099                 int glsl, picking = (G.f & G_PICKSEL);
1100                 
1101                 /* face hiding callback depending on mode */
1102                 if (ob == scene->obedit)
1103                         set_face_cb = tex_mat_set_face_editmesh_cb;
1104                 else if (draw_flags & DRAW_FACE_SELECT)
1105                         set_face_cb = tex_mat_set_face_mesh_cb;
1106                 else
1107                         set_face_cb = NULL;
1108
1109                 /* test if we can use glsl */
1110                 glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support() && !picking;
1111
1112                 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
1113
1114                 if (glsl || picking) {
1115                         /* draw glsl or solid */
1116                         dm->drawMappedFacesMat(dm,
1117                                                tex_mat_set_material_cb,
1118                                                set_face_cb, &data);
1119                 }
1120                 else {
1121                         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
1122
1123                         /* draw textured */
1124                         glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
1125                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
1126                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
1127
1128                         dm->drawMappedFacesMat(dm,
1129                                                tex_mat_set_texture_cb,
1130                                                set_face_cb, &data);
1131                 }
1132
1133                 GPU_end_object_materials();
1134         }
1135
1136         /* reset opengl state */
1137         glDisable(GL_COLOR_MATERIAL);
1138         glDisable(GL_TEXTURE_2D);
1139         glDisable(GL_LIGHTING);
1140         glBindTexture(GL_TEXTURE_2D, 0);
1141         glFrontFace(GL_CCW);
1142
1143         glMatrixMode(GL_TEXTURE);
1144         glLoadIdentity();
1145         glMatrixMode(GL_MODELVIEW);
1146
1147         /* faceselect mode drawing over textured mesh */
1148         if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
1149                 draw_mesh_face_select(rv3d, ob->data, dm);
1150 }
1151
1152 /* Vertex Paint and Weight Paint */
1153 static void draw_mesh_paint_light_begin(void)
1154 {
1155         const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f};
1156
1157         GPU_enable_material(0, NULL);
1158
1159         /* but set default spec */
1160         glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);
1161         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
1162
1163         /* diffuse */
1164         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
1165         glEnable(GL_LIGHTING);
1166         glEnable(GL_COLOR_MATERIAL);
1167 }
1168 static void draw_mesh_paint_light_end(void)
1169 {
1170         glDisable(GL_COLOR_MATERIAL);
1171         glDisable(GL_LIGHTING);
1172
1173         GPU_disable_material();
1174 }
1175
1176 void draw_mesh_paint_weight_faces(DerivedMesh *dm, const bool use_light,
1177                                   void *facemask_cb, void *user_data)
1178 {
1179         if (use_light) {
1180                 draw_mesh_paint_light_begin();
1181         }
1182
1183         dm->drawMappedFaces(dm, (DMSetDrawOptions)facemask_cb, GPU_enable_material, NULL, user_data,
1184                             DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1185
1186         if (use_light) {
1187                 draw_mesh_paint_light_end();
1188         }
1189 }
1190
1191 void draw_mesh_paint_vcolor_faces(DerivedMesh *dm, const bool use_light,
1192                                   void *facemask_cb, void *user_data,
1193                                   const Mesh *me)
1194 {
1195         if (use_light) {
1196                 draw_mesh_paint_light_begin();
1197         }
1198
1199         if (me->mloopcol) {
1200                 dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
1201                                     DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH);
1202         }
1203         else {
1204                 glColor3f(1.0f, 1.0f, 1.0f);
1205                 dm->drawMappedFaces(dm, facemask_cb, GPU_enable_material, NULL, user_data,
1206                                     DM_DRAW_ALWAYS_SMOOTH);
1207         }
1208
1209         if (use_light) {
1210                 draw_mesh_paint_light_end();
1211         }
1212 }
1213
1214 void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm,
1215                                   const bool use_depth, const bool use_alpha,
1216                                   void *edgemask_cb, void *user_data)
1217 {
1218         /* weight paint in solid mode, special case. focus on making the weights clear
1219          * rather than the shading, this is also forced in wire view */
1220
1221         if (use_depth) {
1222                 ED_view3d_polygon_offset(rv3d, 1.0);
1223                 glDepthMask(0);  /* disable write in zbuffer, selected edge wires show better */
1224         }
1225         else {
1226                 glDisable(GL_DEPTH_TEST);
1227         }
1228
1229         if (use_alpha) {
1230                 glEnable(GL_BLEND);
1231         }
1232
1233         glColor4ub(255, 255, 255, 96);
1234         glEnable(GL_LINE_STIPPLE);
1235         glLineStipple(1, 0xAAAA);
1236
1237         dm->drawMappedEdges(dm, (DMSetDrawOptions)edgemask_cb, user_data);
1238
1239         if (use_depth) {
1240                 ED_view3d_polygon_offset(rv3d, 0.0);
1241                 glDepthMask(1);
1242         }
1243         else {
1244                 glEnable(GL_DEPTH_TEST);
1245         }
1246
1247         glDisable(GL_LINE_STIPPLE);
1248
1249         if (use_alpha) {
1250                 glDisable(GL_BLEND);
1251         }
1252 }
1253
1254 void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d,
1255                      Object *ob, DerivedMesh *dm, const int draw_flags)
1256 {
1257         DMSetDrawOptions facemask = NULL;
1258         Mesh *me = ob->data;
1259         const bool use_light = (v3d->drawtype >= OB_SOLID);
1260
1261         /* hide faces in face select mode */
1262         if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL))
1263                 facemask = wpaint__setSolidDrawOptions_facemask;
1264
1265         if (ob->mode & OB_MODE_WEIGHT_PAINT) {
1266                 draw_mesh_paint_weight_faces(dm, use_light, facemask, me);
1267         }
1268         else if (ob->mode & OB_MODE_VERTEX_PAINT) {
1269                 draw_mesh_paint_vcolor_faces(dm, use_light, facemask, me, me);
1270         }
1271
1272         /* draw face selection on top */
1273         if (draw_flags & DRAW_FACE_SELECT) {
1274                 draw_mesh_face_select(rv3d, me, dm);
1275         }
1276         else if ((use_light == false) || (ob->dtx & OB_DRAWWIRE)) {
1277                 const bool use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT);
1278                 const bool use_alpha = (ob->mode & OB_MODE_VERTEX_PAINT) == 0;
1279
1280                 if (use_alpha == false) {
1281                         set_inverted_drawing(1);
1282                 }
1283
1284                 draw_mesh_paint_weight_edges(rv3d, dm, use_depth, use_alpha, NULL, NULL);
1285
1286                 if (use_alpha == false) {
1287                         set_inverted_drawing(0);
1288                 }
1289         }
1290 }
1291