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