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