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