2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): Blender Foundation, full update, glsl support
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/editors/space_view3d/drawmesh.c
33 #include "MEM_guardedalloc.h"
35 #include "BLI_blenlib.h"
37 #include "BLI_edgehash.h"
38 #include "BLI_editVert.h"
39 #include "BLI_utildefines.h"
41 #include "DNA_material_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_node_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_property_types.h"
46 #include "DNA_scene_types.h"
47 #include "DNA_screen_types.h"
48 #include "DNA_view3d_types.h"
50 #include "BKE_DerivedMesh.h"
51 #include "BKE_effect.h"
52 #include "BKE_image.h"
53 #include "BKE_material.h"
54 #include "BKE_paint.h"
55 #include "BKE_property.h"
56 #include "BKE_scene.h"
59 #include "BIF_glutil.h"
61 #include "UI_resources.h"
63 #include "GPU_buffers.h"
64 #include "GPU_extensions.h"
66 #include "GPU_material.h"
69 #include "ED_uvedit.h"
71 #include "view3d_intern.h" // own include
73 /**************************** Face Select Mode *******************************/
75 /* Flags for marked edges */
77 eEdge_Visible = (1<<0),
78 eEdge_Select = (1<<1),
81 /* Creates a hash of edges to flags indicating selected/visible */
82 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
86 if(!BLI_edgehash_haskey(eh, v0, v1))
87 BLI_edgehash_insert(eh, v0, v1, NULL);
89 flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
93 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
95 EdgeHash *eh = BLI_edgehash_new();
99 for(i=0; i<me->totface; i++) {
102 if(!(mf->flag & ME_HIDE)) {
103 unsigned int flags = eEdge_Visible;
104 if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
106 get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
107 get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
110 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
111 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
114 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
122 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
124 struct { Mesh *me; EdgeHash *eh; } *data = userData;
126 MEdge *med = &me->medge[index];
127 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
129 if(me->drawflag & ME_DRAWEDGES) {
130 if(me->drawflag & ME_HIDDENEDGES)
133 return (flags & eEdge_Visible);
136 return (flags & eEdge_Select);
139 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
141 struct { Mesh *me; EdgeHash *eh; } *data = userData;
142 MEdge *med = &data->me->medge[index];
143 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
145 return flags & eEdge_Select;
148 /* draws unselected */
149 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
151 Mesh *me = (Mesh*)userData;
153 MFace *mface = &me->mface[index];
154 if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
155 return 2; /* Don't set color */
160 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
162 struct { Mesh *me; EdgeHash *eh; } data;
165 data.eh = get_tface_mesh_marked_edge_info(me);
167 glEnable(GL_DEPTH_TEST);
168 glDisable(GL_LIGHTING);
169 bglPolygonOffset(rv3d->dist, 1.0);
171 /* Draw (Hidden) Edges */
173 UI_ThemeColor(TH_EDGE_FACESEL);
174 dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
177 /* Draw Selected Faces */
178 if(me->drawflag & ME_DRAWFACES) {
180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181 /* dull unselected faces so as not to get in the way of seeing color */
182 glColor4ub(96, 96, 96, 64);
183 dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, (void*)me);
188 bglPolygonOffset(rv3d->dist, 1.0);
190 /* Draw Stippled Outline for selected faces */
191 glColor3ub(255, 255, 255);
193 dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
196 bglPolygonOffset(rv3d->dist, 0.0); // resets correctly now, even after calling accumulated offsets
198 BLI_edgehash_free(data.eh, NULL);
201 /***************************** Texture Drawing ******************************/
203 static Material *give_current_material_or_def(Object *ob, int matnr)
205 extern Material defmaterial; // render module abuse...
206 Material *ma= give_current_material(ob, matnr);
208 return ma?ma:&defmaterial;
211 /* Icky globals, fix with userdata parameter */
213 static struct TextureDrawState {
217 unsigned char obcol[4];
218 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
220 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
222 static Material *c_ma;
223 static int c_textured;
224 static MTFace *c_texface;
225 static int c_backculled;
229 Object *litob = NULL; //to get mode to turn off mipmap in painting mode
230 int backculled = GEMAT_BACKCULL;
236 c_textured= c_lit= c_backculled= -1;
237 c_texface= (MTFace*) -1;
240 textured = gtexdraw.istex;
244 /* convert number of lights into boolean */
245 if (gtexdraw.islit) lit = 1;
248 alphablend = ma->game.alpha_blend;
249 if (ma->mode & MA_SHLESS) lit = 0;
250 backculled = ma->game.flag & GEMAT_BACKCULL;
254 textured = textured && (texface->tpage);
256 /* no material, render alpha if texture has depth=32 */
257 if (!ma && BKE_image_has_alpha(texface->tpage))
258 alphablend = GPU_BLEND_ALPHA;
264 if (backculled!=c_backculled) {
265 if (backculled) glEnable(GL_CULL_FACE);
266 else glDisable(GL_CULL_FACE);
268 c_backculled= backculled;
271 if (textured!=c_textured || texface!=c_texface) {
273 c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
275 GPU_set_tpage(NULL, 0, 0);
278 c_textured= textured;
282 if (c_badtex) lit= 0;
283 if (lit!=c_lit || ma!=c_ma) {
286 if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
288 spec[0]= ma->spec*ma->specr;
289 spec[1]= ma->spec*ma->specg;
290 spec[2]= ma->spec*ma->specb;
293 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
294 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
295 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
296 glEnable(GL_LIGHTING);
297 glEnable(GL_COLOR_MATERIAL);
300 glDisable(GL_LIGHTING);
301 glDisable(GL_COLOR_MATERIAL);
309 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
311 unsigned char obcol[4];
314 // XXX scene->obedit warning
316 /* texture draw is abused for mask selection mode, do this so wire draw
317 * with face selection in weight paint is not lit. */
318 if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
322 else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
323 /* draw with default lights in solid draw mode and edit mode */
328 /* draw with lights in the scene otherwise */
330 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
333 obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
334 obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
335 obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
336 obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
338 glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
339 if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
343 Gtexdraw.istex = istex;
344 Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
345 memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
346 set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
347 glShadeModel(GL_SMOOTH);
350 static void draw_textured_end(void)
352 /* switch off textures */
353 GPU_set_tpage(NULL, 0, 0);
355 glShadeModel(GL_FLAT);
356 glDisable(GL_CULL_FACE);
358 /* XXX, bad patch - GPU_default_lights() calls
359 * glLightfv(GL_LIGHT_POSITION, ...) which
360 * is transformed by the current matrix... we
361 * need to make sure that matrix is identity.
363 * It would be better if drawmesh.c kept track
364 * of and restored the light settings it changed.
369 GPU_default_lights();
373 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
375 Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
378 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
380 validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
382 if (tface && validtexture) {
383 glColor3ub(0xFF, 0x00, 0xFF);
384 return 2; /* Don't set color */
385 } else if (ma && ma->shade_flag&MA_OBCOLOR) {
386 glColor3ubv(Gtexdraw.obcol);
387 return 2; /* Don't set color */
388 } else if (!has_mcol) {
389 if (tface) glColor3f(1.0, 1.0, 1.0);
393 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
394 else copy_v3_v3(col, &ma->r);
398 else glColor3f(1.0, 1.0, 1.0);
400 return 2; /* Don't set color */
402 return 1; /* Set color from mcol */
406 static int draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
408 if (has_mcol) return 1;
412 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
414 Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
416 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
418 if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
419 return 2; /* Don't set color */
420 } else if (tface && tface->mode&TF_OBCOL) {
421 return 2; /* Don't set color */
422 } else if (!has_mcol) {
423 return 1; /* Don't set color */
425 return 1; /* Set color from mcol */
428 static void add_tface_color_layer(DerivedMesh *dm)
430 MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
431 MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
434 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
436 mcol = dm->getFaceDataArray(dm, CD_MCOL);
438 finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
439 for(i=0;i<dm->getNumFaces(dm);i++) {
440 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
442 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
444 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
447 finalCol[i*4+j].b = 255;
448 finalCol[i*4+j].g = 255;
449 finalCol[i*4+j].r = 255;
452 else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
454 finalCol[i*4+j].b = 255;
455 finalCol[i*4+j].g = 0;
456 finalCol[i*4+j].r = 255;
458 } else if (tface && tface->mode&TF_OBCOL) {
460 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
461 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
462 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
467 finalCol[i*4+j].b = 255;
468 finalCol[i*4+j].g = 255;
469 finalCol[i*4+j].r = 255;
474 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
477 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
478 else copy_v3_v3(col, &ma->r);
481 finalCol[i*4+j].b = FTOCHAR(col[0]);
482 finalCol[i*4+j].g = FTOCHAR(col[1]);
483 finalCol[i*4+j].r = FTOCHAR(col[2]);
488 finalCol[i*4+j].b = 255;
489 finalCol[i*4+j].g = 255;
490 finalCol[i*4+j].r = 255;
495 finalCol[i*4+j].r = mcol[i*4+j].r;
496 finalCol[i*4+j].g = mcol[i*4+j].g;
497 finalCol[i*4+j].b = mcol[i*4+j].b;
501 CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
504 static int draw_tface_mapped__set_draw(void *userData, int index)
506 Mesh *me = (Mesh*)userData;
507 MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
508 MFace *mface = &me->mface[index];
509 const int matnr = mface->mat_nr;
510 if (mface->flag & ME_HIDE) return 0;
511 return draw_tface__set_draw(tface, (me->mcol != NULL), matnr);
514 static int draw_em_tf_mapped__set_draw(void *userData, int index)
516 struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data = userData;
517 EditMesh *em = data->em;
518 EditFace *efa= EM_get_face_for_index(index);
525 tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
528 return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
531 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
533 Mesh *me = (Mesh*)userData;
535 if (me->mat && me->mface) {
536 Material *ma= me->mat[me->mface[index].mat_nr];
537 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
546 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
550 MFace *mf, *mface= me->mface;
551 MTFace *tface= me->mtface;
552 MCol *mcol= me->mcol; /* why does mcol exist? */
553 bProperty *prop = get_ob_property(ob, "Text");
554 GPUVertexAttribs gattribs;
555 int a, totface= me->totface;
557 /* don't draw without tfaces */
561 /* don't draw when editing */
562 if(ob->mode & OB_MODE_EDIT)
565 if(paint_facesel_test(ob) || paint_vertsel_test(ob))
568 ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
570 for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
571 short matnr= mf->mat_nr;
572 int mf_smooth= mf->flag & ME_SMOOTH;
573 Material *mat = me->mat[matnr];
574 int mode= mat->game.flag;
576 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
577 float v1[3], v2[3], v3[3], v4[3];
578 char string[MAX_PROPSTRING];
579 int characters, i, glattrib= -1, badtex= 0;
582 GPU_enable_material(matnr+1, &gattribs);
584 for(i=0; i<gattribs.totlayer; i++) {
585 if(gattribs.layer[i].type == CD_MTFACE) {
586 glattrib = gattribs.layer[i].glindex;
592 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
599 ddm->getVertCo(ddm, mf->v1, v1);
600 ddm->getVertCo(ddm, mf->v2, v2);
601 ddm->getVertCo(ddm, mf->v3, v3);
602 if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
604 // The BM_FONT handling is in the gpu module, shared with the
605 // game engine, was duplicated previously
607 set_property_valstr(prop, string);
608 characters = strlen(string);
610 if(!BKE_image_get_ibuf(tface->tpage, NULL))
616 normal_tri_v3( nor,v1, v2, v3);
621 GPU_render_text(tface, mode, string, characters,
622 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
632 static int compareDrawOptions(void *userData, int cur_index, int next_index)
634 DerivedMesh *dm= (DerivedMesh*) userData;
635 MFace *mf = DM_get_face_data_layer(dm, CD_MFACE);
636 MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
638 if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
641 if(tf && tf[cur_index].tpage != tf[next_index].tpage)
647 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
649 struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data= userData;
650 MFace *mf = DM_get_face_data_layer(data->dm, CD_MFACE);
651 MTFace *tf = DM_get_face_data_layer(data->dm, CD_MTFACE);
653 if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
656 if(tf && tf[cur_index].tpage != tf[next_index].tpage)
662 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
666 /* correct for negative scale */
667 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
668 else glFrontFace(GL_CCW);
670 /* draw the textured mesh */
671 draw_textured_begin(scene, v3d, rv3d, ob);
673 glColor4f(1.0f,1.0f,1.0f,1.0f);
675 if(ob->mode & OB_MODE_EDIT) {
676 struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} data;
679 data.em= me->edit_mesh;
680 data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
681 data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
683 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
685 else if(draw_flags & DRAW_FACE_SELECT) {
686 if(ob->mode & OB_MODE_WEIGHT_PAINT)
687 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, GPU_enable_material, NULL, me, 1);
689 dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, NULL, me);
692 if(GPU_buffer_legacy(dm)) {
693 if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
694 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
696 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
699 if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
700 add_tface_color_layer(dm);
702 dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, dm);
706 /* draw game engine text hack */
707 if(get_ob_property(ob, "Text"))
708 draw_mesh_text(scene, ob, 0);
712 /* draw edges and selected faces over textured mesh */
713 if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
714 draw_mesh_face_select(rv3d, me, dm);
716 /* reset from negative scale correction */
719 /* in editmode, the blend mode needs to be set incase it was ADD */
720 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
723 /************************** NEW SHADING NODES ********************************/
725 typedef struct TexMatCallback {
732 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
734 /* all we have to do here is simply enable the GLSL material, but note
735 that the GLSL code will give different result depending on the drawtype,
736 in texture draw mode it will output the active texture node, in material
737 draw mode it will show the full material. */
738 GPU_enable_material(mat_nr, attribs);
741 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
743 /* texture draw mode without GLSL */
744 TexMatCallback *data= (TexMatCallback*)userData;
745 GPUVertexAttribs *gattribs = attribs;
751 /* draw image texture if we find one */
752 if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
753 /* get openl texture */
755 int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
756 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
759 NodeTexBase *texbase= node->storage;
761 /* disable existing material */
762 GPU_disable_material();
763 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
764 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
765 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
768 glEnable(GL_COLOR_MATERIAL);
769 glEnable(GL_TEXTURE_2D);
771 glBindTexture(GL_TEXTURE_2D, ima->bindcode);
772 glColor3f(1.0f, 1.0f, 1.0f);
774 glMatrixMode(GL_TEXTURE);
775 glLoadMatrixf(texbase->tex_mapping.mat);
776 glMatrixMode(GL_MODELVIEW);
778 /* use active UV texture layer */
779 memset(gattribs, 0, sizeof(*gattribs));
781 gattribs->layer[0].type= CD_MTFACE;
782 gattribs->layer[0].name[0]= '\0';
783 gattribs->layer[0].gltexco= 1;
784 gattribs->totlayer= 1;
791 glMatrixMode(GL_TEXTURE);
793 glMatrixMode(GL_MODELVIEW);
795 /* disable texture */
796 glDisable(GL_TEXTURE_2D);
797 glDisable(GL_COLOR_MATERIAL);
799 /* draw single color */
800 GPU_enable_material(mat_nr, attribs);
804 static int tex_mat_set_face_mesh_cb(void *userData, int index)
806 /* faceselect mode face hiding */
807 TexMatCallback *data= (TexMatCallback*)userData;
808 Mesh *me = (Mesh*)data->me;
809 MFace *mface = &me->mface[index];
811 return !(mface->flag & ME_HIDE);
814 static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
816 /* editmode face hiding */
817 EditFace *efa= EM_get_face_for_index(index);
822 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
824 if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
825 draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
829 /* set opengl state for negative scale & color */
830 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
831 else glFrontFace(GL_CCW);
833 glEnable(GL_LIGHTING);
835 if(ob->mode & OB_MODE_WEIGHT_PAINT) {
836 /* weight paint mode exception */
839 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions,
840 GPU_enable_material, NULL, ob->data, useColors);
844 TexMatCallback data = {scene, ob, me, dm};
845 int (*set_face_cb)(void*, int);
848 /* face hiding callback depending on mode */
849 if(ob == scene->obedit)
850 set_face_cb= tex_mat_set_face_editmesh_cb;
851 else if(draw_flags & DRAW_FACE_SELECT)
852 set_face_cb= tex_mat_set_face_mesh_cb;
856 /* test if we can use glsl */
857 glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
859 GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
863 dm->drawMappedFacesMat(dm,
864 tex_mat_set_material_cb,
868 float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
871 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
872 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
873 glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
875 dm->drawMappedFacesMat(dm,
876 tex_mat_set_texture_cb,
880 GPU_end_object_materials();
883 /* reset opengl state */
884 glDisable(GL_COLOR_MATERIAL);
885 glDisable(GL_TEXTURE_2D);
886 glDisable(GL_LIGHTING);
887 glBindTexture(GL_TEXTURE_2D, 0);
890 glMatrixMode(GL_TEXTURE);
892 glMatrixMode(GL_MODELVIEW);
894 /* faceselect mode drawing over textured mesh */
895 if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
896 draw_mesh_face_select(rv3d, ob->data, dm);