Blender  V2.59
drawmesh.c
Go to the documentation of this file.
00001 /*
00002  * $Id: drawmesh.c 36752 2011-05-18 17:52:26Z campbellbarton $
00003  *
00004  * ***** BEGIN GPL LICENSE BLOCK *****
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software Foundation,
00018  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019  *
00020  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00021  * All rights reserved.
00022  *
00023  * Contributor(s): Blender Foundation, full update, glsl support
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00033 #include <string.h>
00034 #include <math.h>
00035 
00036 #include "MEM_guardedalloc.h"
00037 
00038 #include "BLI_blenlib.h"
00039 #include "BLI_math.h"
00040 #include "BLI_edgehash.h"
00041 #include "BLI_editVert.h"
00042 #include "BLI_utildefines.h"
00043 
00044 #include "DNA_material_types.h"
00045 #include "DNA_meshdata_types.h"
00046 #include "DNA_property_types.h"
00047 #include "DNA_scene_types.h"
00048 #include "DNA_screen_types.h"
00049 #include "DNA_view3d_types.h"
00050 #include "DNA_object_types.h"
00051 
00052 #include "BKE_DerivedMesh.h"
00053 #include "BKE_effect.h"
00054 #include "BKE_image.h"
00055 #include "BKE_material.h"
00056 #include "BKE_paint.h"
00057 #include "BKE_property.h"
00058 
00059 
00060 #include "BIF_gl.h"
00061 #include "BIF_glutil.h"
00062 
00063 #include "UI_resources.h"
00064 
00065 #include "GPU_buffers.h"
00066 #include "GPU_extensions.h"
00067 #include "GPU_draw.h"
00068 
00069 #include "ED_mesh.h"
00070 
00071 #include "view3d_intern.h"      // own include
00072 
00073 /***/
00074 
00075         /* Flags for marked edges */
00076 enum {
00077         eEdge_Visible = (1<<0),
00078         eEdge_Select = (1<<1),
00079 };
00080 
00081         /* Creates a hash of edges to flags indicating
00082          * adjacent tface select/active/etc flags.
00083          */
00084 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
00085 {
00086         int *flags_p;
00087 
00088         if (!BLI_edgehash_haskey(eh, v0, v1)) {
00089                 BLI_edgehash_insert(eh, v0, v1, NULL);
00090         }
00091 
00092         flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
00093         *flags_p |= flags;
00094 }
00095 
00096 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
00097 {
00098         EdgeHash *eh = BLI_edgehash_new();
00099         int i;
00100         MFace *mf;
00101         
00102         for (i=0; i<me->totface; i++) {
00103                 mf = &me->mface[i];
00104 
00105                 if (mf->v3) {
00106                         if (!(mf->flag&ME_HIDE)) {
00107                                 unsigned int flags = eEdge_Visible;
00108                                 if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select;
00109 
00110                                 get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
00111                                 get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
00112                                 if (mf->v4) {
00113                                         get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
00114                                         get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
00115                                 } else {
00116                                         get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
00117                                 }
00118                         }
00119                 }
00120         }
00121 
00122         return eh;
00123 }
00124 
00125 
00126 static int draw_tfaces3D__setHiddenOpts(void *userData, int index)
00127 {
00128         struct { Mesh *me; EdgeHash *eh; } *data = userData;
00129         Mesh *me= data->me;
00130         MEdge *med = &me->medge[index];
00131         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00132 
00133         if((me->drawflag & ME_DRAWSEAMS) && (med->flag&ME_SEAM)) {
00134                 return 0;
00135         } else if(me->drawflag & ME_DRAWEDGES){ 
00136                 if (me->drawflag & ME_HIDDENEDGES) {
00137                         return 1;
00138                 } else {
00139                         return (flags & eEdge_Visible);
00140                 }
00141         } else {
00142                 return (flags & eEdge_Select);
00143         }
00144 }
00145 
00146 static int draw_tfaces3D__setSeamOpts(void *userData, int index)
00147 {
00148         struct { Mesh *me; EdgeHash *eh; } *data = userData;
00149         Mesh *me= data->me;
00150         MEdge *med = &data->me->medge[index];
00151         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00152 
00153         if (med->flag & ME_SEAM) {
00154                 if (me->drawflag & ME_HIDDENEDGES) {
00155                         return 1;
00156                 } else {
00157                         return (flags & eEdge_Visible);
00158                 }
00159         } else {
00160                 return 0;
00161         }
00162 }
00163 
00164 static int draw_tfaces3D__setSelectOpts(void *userData, int index)
00165 {
00166         struct { Mesh *me; EdgeHash *eh; } *data = userData;
00167         MEdge *med = &data->me->medge[index];
00168         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00169 
00170         return flags & eEdge_Select;
00171 }
00172 
00173 #if 0
00174 static int draw_tfaces3D__setActiveOpts(void *userData, int index)
00175 {
00176         struct { Mesh *me; EdgeHash *eh; } *data = userData;
00177         MEdge *med = &data->me->medge[index];
00178         uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00179 
00180         if (flags & eEdge_Select) {
00181                 return 1;
00182         } else {
00183                 return 0;
00184         }
00185 }
00186 
00187 static int draw_tfaces3D__drawFaceOpts(void *userData, int index)
00188 {
00189         Mesh *me = (Mesh*)userData;
00190 
00191         MFace *mface = &me->mface[index];
00192         if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL))
00193                 return 2; /* Don't set color */
00194         else
00195                 return 0;
00196 }
00197 #endif
00198 
00199 /* draws unselected */
00200 static int draw_tfaces3D__drawFaceOptsInv(void *userData, int index)
00201 {
00202         Mesh *me = (Mesh*)userData;
00203 
00204         MFace *mface = &me->mface[index];
00205         if (!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
00206                 return 2; /* Don't set color */
00207         else
00208                 return 0;
00209 }
00210 
00211 static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short draw_seams)
00212 {
00213         struct { Mesh *me; EdgeHash *eh; } data;
00214 
00215         data.me = me;
00216         data.eh = get_tface_mesh_marked_edge_info(me);
00217 
00218         glEnable(GL_DEPTH_TEST);
00219         glDisable(GL_LIGHTING);
00220         bglPolygonOffset(rv3d->dist, 1.0);
00221 
00222         /* Draw (Hidden) Edges */
00223         setlinestyle(1);
00224         UI_ThemeColor(TH_EDGE_FACESEL);
00225         dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data);
00226         setlinestyle(0);
00227 
00228         /* Draw Seams */
00229         if(draw_seams && me->drawflag & ME_DRAWSEAMS) {
00230                 UI_ThemeColor(TH_EDGE_SEAM);
00231                 glLineWidth(2);
00232                 dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data);
00233                 glLineWidth(1);
00234         }
00235 
00236         /* Draw Selected Faces */
00237         if(me->drawflag & ME_DRAWFACES) {
00238                 glEnable(GL_BLEND);
00239                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00240 #if 0
00241                 UI_ThemeColor4(TH_FACE_SELECT);
00242 
00243                 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)me);
00244 #else
00245                 /* dull unselected faces so as not to get in the way of seeing color */
00246                 glColor4ub(96, 96, 96, 64);
00247                 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOptsInv, (void*)me);
00248 #endif
00249                 
00250                 glDisable(GL_BLEND);
00251         }
00252         
00253         bglPolygonOffset(rv3d->dist, 1.0);
00254 
00255                 /* Draw Stippled Outline for selected faces */
00256         glColor3ub(255, 255, 255);
00257         setlinestyle(1);
00258         dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data);
00259         setlinestyle(0);
00260 
00261         bglPolygonOffset(rv3d->dist, 0.0);      // resets correctly now, even after calling accumulated offsets
00262 
00263         BLI_edgehash_free(data.eh, NULL);
00264 }
00265 
00266 static Material *give_current_material_or_def(Object *ob, int matnr)
00267 {
00268         extern Material defmaterial;    // render module abuse...
00269         Material *ma= give_current_material(ob, matnr);
00270 
00271         return ma?ma:&defmaterial;
00272 }
00273 
00274 static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided)
00275 {
00276         static int c_textured;
00277         static int c_lit;
00278         static int c_doublesided;
00279         static MTFace *c_texface;
00280         static Object *c_litob;
00281         static int c_litmatnr;
00282         static int c_badtex;
00283 
00284         if (clearcache) {
00285                 c_textured= c_lit= c_doublesided= -1;
00286                 c_texface= (MTFace*) -1;
00287                 c_litob= (Object*) -1;
00288                 c_litmatnr= -1;
00289                 c_badtex= 0;
00290         }
00291 
00292         if (texface) {
00293                 lit = lit && (lit==-1 || texface->mode&TF_LIGHT);
00294                 textured = textured && (texface->mode&TF_TEX);
00295                 doublesided = texface->mode&TF_TWOSIDE;
00296         } else {
00297                 textured = 0;
00298         }
00299 
00300         if (doublesided!=c_doublesided) {
00301                 if (doublesided) glDisable(GL_CULL_FACE);
00302                 else glEnable(GL_CULL_FACE);
00303 
00304                 c_doublesided= doublesided;
00305         }
00306 
00307         if (textured!=c_textured || texface!=c_texface) {
00308                 if (textured ) {
00309                         c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT));
00310                 } else {
00311                         GPU_set_tpage(NULL, 0);
00312                         c_badtex= 0;
00313                 }
00314                 c_textured= textured;
00315                 c_texface= texface;
00316         }
00317 
00318         if (c_badtex) lit= 0;
00319         if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) {
00320                 if (lit) {
00321                         Material *ma= give_current_material_or_def(litob, litmatnr+1);
00322                         float spec[4];
00323 
00324                         spec[0]= ma->spec*ma->specr;
00325                         spec[1]= ma->spec*ma->specg;
00326                         spec[2]= ma->spec*ma->specb;
00327                         spec[3]= 1.0;
00328 
00329                         glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
00330                         glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00331                         glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
00332                         glEnable(GL_LIGHTING);
00333                         glEnable(GL_COLOR_MATERIAL);
00334                 }
00335                 else {
00336                         glDisable(GL_LIGHTING); 
00337                         glDisable(GL_COLOR_MATERIAL);
00338                 }
00339                 c_lit= lit;
00340                 c_litob= litob;
00341                 c_litmatnr= litmatnr;
00342         }
00343 
00344         return c_badtex;
00345 }
00346 
00347 /* Icky globals, fix with userdata parameter */
00348 
00349 static struct TextureDrawState {
00350         Object *ob;
00351         int islit, istex;
00352         int color_profile;
00353         unsigned char obcol[4];
00354 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
00355 
00356 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
00357 {
00358         unsigned char obcol[4];
00359         int istex, solidtex= 0;
00360 
00361         // XXX scene->obedit warning
00362         if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
00363                 /* draw with default lights in solid draw mode and edit mode */
00364                 solidtex= 1;
00365                 Gtexdraw.islit= -1;
00366         }
00367         else {
00368                 /* draw with lights in the scene otherwise */
00369                 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
00370         }
00371         
00372         obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
00373         obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
00374         obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
00375         obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
00376         
00377         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
00378         if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
00379         else istex= 0;
00380 
00381         Gtexdraw.ob = ob;
00382         Gtexdraw.istex = istex;
00383         Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
00384         memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
00385         set_draw_settings_cached(1, 0, NULL, Gtexdraw.islit, NULL, 0, 0);
00386         glShadeModel(GL_SMOOTH);
00387 }
00388 
00389 static void draw_textured_end(void)
00390 {
00391         /* switch off textures */
00392         GPU_set_tpage(NULL, 0);
00393 
00394         glShadeModel(GL_FLAT);
00395         glDisable(GL_CULL_FACE);
00396 
00397         /* XXX, bad patch - GPU_default_lights() calls
00398          * glLightfv(GL_LIGHT_POSITION, ...) which
00399          * is transformed by the current matrix... we
00400          * need to make sure that matrix is identity.
00401          * 
00402          * It would be better if drawmesh.c kept track
00403          * of and restored the light settings it changed.
00404          *  - zr
00405          */
00406         glPushMatrix();
00407         glLoadIdentity();       
00408         GPU_default_lights();
00409         glPopMatrix();
00410 }
00411 
00412 static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr)
00413 {
00414         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
00415 
00416         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
00417                 glColor3ub(0xFF, 0x00, 0xFF);
00418                 return 2; /* Don't set color */
00419         } else if (tface && tface->mode&TF_OBCOL) {
00420                 glColor3ubv(Gtexdraw.obcol);
00421                 return 2; /* Don't set color */
00422         } else if (!mcol) {
00423                 if (tface) glColor3f(1.0, 1.0, 1.0);
00424                 else {
00425                         Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
00426                         if(ma) {
00427                                 float col[3];
00428                                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
00429                                 else copy_v3_v3(col, &ma->r);
00430                                 
00431                                 glColor3fv(col);
00432                         }
00433                         else glColor3f(1.0, 1.0, 1.0);
00434                 }
00435                 return 2; /* Don't set color */
00436         } else {
00437                 return 1; /* Set color from mcol */
00438         }
00439 }
00440 static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr)
00441 {
00442         if (tface && (tface->mode&TF_INVISIBLE)) return 0;
00443 
00444         if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) {
00445                 return 2; /* Don't set color */
00446         } else if (tface && tface->mode&TF_OBCOL) {
00447                 return 2; /* Don't set color */
00448         } else if (!mcol) {
00449                 return 1; /* Don't set color */
00450         } else {
00451                 return 1; /* Set color from mcol */
00452         }
00453 }
00454 static void add_tface_color_layer(DerivedMesh *dm)
00455 {
00456         MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
00457         MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
00458         MCol *finalCol;
00459         int i,j;
00460         MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
00461         if(!mcol)
00462                 mcol = dm->getFaceDataArray(dm, CD_MCOL);
00463 
00464         finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
00465         for(i=0;i<dm->getNumFaces(dm);i++) {
00466                 if (tface && (tface->mode&TF_INVISIBLE)) {
00467                         if( mcol )
00468                                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
00469                         else
00470                                 for(j=0;j<4;j++) {
00471                                         finalCol[i*4+j].b = 255;
00472                                         finalCol[i*4+j].g = 255;
00473                                         finalCol[i*4+j].r = 255;
00474                                 }
00475                 }
00476                 else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) {
00477                         for(j=0;j<4;j++) {
00478                                 finalCol[i*4+j].b = 255;
00479                                 finalCol[i*4+j].g = 0;
00480                                 finalCol[i*4+j].r = 255;
00481                         }
00482                 } else if (tface && tface->mode&TF_OBCOL) {
00483                         for(j=0;j<4;j++) {
00484                                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]);
00485                                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
00486                                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]);
00487                         }
00488                 } else if (!mcol) {
00489                         if (tface) {
00490                                 for(j=0;j<4;j++) {
00491                                         finalCol[i*4+j].b = 255;
00492                                         finalCol[i*4+j].g = 255;
00493                                         finalCol[i*4+j].r = 255;
00494                                 }
00495                         }
00496                         else {
00497                                 float col[3];
00498                                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
00499                                 
00500                                 if(ma) {
00501                                         if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
00502                                         else copy_v3_v3(col, &ma->r);
00503                                         
00504                                         for(j=0;j<4;j++) {
00505                                                 finalCol[i*4+j].b = FTOCHAR(col[2]);
00506                                                 finalCol[i*4+j].g = FTOCHAR(col[1]);
00507                                                 finalCol[i*4+j].r = FTOCHAR(col[0]);
00508                                         }
00509                                 }
00510                                 else
00511                                         for(j=0;j<4;j++) {
00512                                                 finalCol[i*4+j].b = 255;
00513                                                 finalCol[i*4+j].g = 255;
00514                                                 finalCol[i*4+j].r = 255;
00515                                         }
00516                         }
00517                 } else {
00518                         for(j=0;j<4;j++) {
00519                                 finalCol[i*4+j].b = mcol[i*4+j].r;
00520                                 finalCol[i*4+j].g = mcol[i*4+j].g;
00521                                 finalCol[i*4+j].r = mcol[i*4+j].b;
00522                         }
00523                 }
00524         }
00525         CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
00526 }
00527 
00528 static int draw_tface_mapped__set_draw(void *userData, int index)
00529 {
00530         Mesh *me = (Mesh*)userData;
00531         MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
00532         MFace *mface = &me->mface[index];
00533         MCol *mcol = (me->mcol)? &me->mcol[index]: NULL;
00534         const int matnr = mface->mat_nr;
00535         if (mface->flag & ME_HIDE) return 0;
00536         return draw_tface__set_draw(tface, mcol, matnr);
00537 }
00538 
00539 static int draw_em_tf_mapped__set_draw(void *userData, int index)
00540 {
00541         EditMesh *em = userData;
00542         EditFace *efa= EM_get_face_for_index(index);
00543         MTFace *tface;
00544         MCol *mcol;
00545         int matnr;
00546 
00547         if (efa->h)
00548                 return 0;
00549 
00550         tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
00551         mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
00552         matnr = efa->mat_nr;
00553 
00554         return draw_tface__set_draw_legacy(tface, mcol, matnr);
00555 }
00556 
00557 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
00558 {
00559         Mesh *me = (Mesh*)userData;
00560 
00561         if (    (me->mface && me->mface[index].flag & ME_HIDE) ||
00562                         (me->mtface && (me->mtface[index].mode & TF_INVISIBLE))
00563         ) {
00564                 return 0;
00565         }
00566 
00567         *drawSmooth_r = 1;
00568         return 1;
00569 }
00570 
00571 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
00572 {
00573         Mesh *me = ob->data;
00574         DerivedMesh *ddm;
00575         MFace *mf, *mface= me->mface;
00576         MTFace *tface= me->mtface;
00577         MCol *mcol= me->mcol;   /* why does mcol exist? */
00578         bProperty *prop = get_ob_property(ob, "Text");
00579         GPUVertexAttribs gattribs;
00580         int a, totface= me->totface;
00581 
00582         /* don't draw without tfaces */
00583         if(!tface)
00584                 return;
00585 
00586         /* don't draw when editing */
00587         if(ob->mode & OB_MODE_EDIT)
00588                 return;
00589         else if(ob==OBACT)
00590                 if(paint_facesel_test(ob))
00591                         return;
00592 
00593         ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
00594 
00595         for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
00596                 int mode= tface->mode;
00597                 int matnr= mf->mat_nr;
00598                 int mf_smooth= mf->flag & ME_SMOOTH;
00599 
00600                 if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) {
00601                         float v1[3], v2[3], v3[3], v4[3];
00602                         char string[MAX_PROPSTRING];
00603                         int characters, i, glattrib= -1, badtex= 0;
00604 
00605                         if(glsl) {
00606                                 GPU_enable_material(matnr+1, &gattribs);
00607 
00608                                 for(i=0; i<gattribs.totlayer; i++) {
00609                                         if(gattribs.layer[i].type == CD_MTFACE) {
00610                                                 glattrib = gattribs.layer[i].glindex;
00611                                                 break;
00612                                         }
00613                                 }
00614                         }
00615                         else {
00616                                 badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE);
00617                                 if (badtex) {
00618                                         if (mcol) mcol+=4;
00619                                         continue;
00620                                 }
00621                         }
00622 
00623                         ddm->getVertCo(ddm, mf->v1, v1);
00624                         ddm->getVertCo(ddm, mf->v2, v2);
00625                         ddm->getVertCo(ddm, mf->v3, v3);
00626                         if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
00627 
00628                         // The BM_FONT handling is in the gpu module, shared with the
00629                         // game engine, was duplicated previously
00630 
00631                         set_property_valstr(prop, string);
00632                         characters = strlen(string);
00633                         
00634                         if(!BKE_image_get_ibuf(tface->tpage, NULL))
00635                                 characters = 0;
00636 
00637                         if (!mf_smooth) {
00638                                 float nor[3];
00639 
00640                                 normal_tri_v3( nor,v1, v2, v3);
00641 
00642                                 glNormal3fv(nor);
00643                         }
00644 
00645                         GPU_render_text(tface, tface->mode, string, characters,
00646                                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
00647                 }
00648                 if (mcol) {
00649                         mcol+=4;
00650                 }
00651         }
00652 
00653         ddm->release(ddm);
00654 }
00655 
00656 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int faceselect)
00657 {
00658         Mesh *me= ob->data;
00659         
00660         /* correct for negative scale */
00661         if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
00662         else glFrontFace(GL_CCW);
00663         
00664         /* draw the textured mesh */
00665         draw_textured_begin(scene, v3d, rv3d, ob);
00666 
00667         glColor4f(1.0f,1.0f,1.0f,1.0f);
00668 
00669         if(ob->mode & OB_MODE_EDIT) {
00670                 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit_mesh);
00671         } else if(faceselect) {
00672                 if(ob->mode & OB_MODE_WEIGHT_PAINT)
00673                         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me, 1, GPU_enable_material);
00674                 else
00675                         dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, me);
00676         }
00677         else {
00678                 if( GPU_buffer_legacy(dm) )
00679                         dm->drawFacesTex(dm, draw_tface__set_draw_legacy);
00680                 else {
00681                         if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL) )
00682                                 add_tface_color_layer(dm);
00683                         dm->drawFacesTex(dm, draw_tface__set_draw);
00684                 }
00685         }
00686 
00687         /* draw game engine text hack */
00688         if(get_ob_property(ob, "Text")) 
00689                 draw_mesh_text(scene, ob, 0);
00690 
00691         draw_textured_end();
00692         
00693         /* draw edges and selected faces over textured mesh */
00694         if(!(ob == scene->obedit) && faceselect)
00695                 draw_tfaces3D(rv3d, me, dm, ob->mode & OB_MODE_WEIGHT_PAINT);
00696 
00697         /* reset from negative scale correction */
00698         glFrontFace(GL_CCW);
00699         
00700         /* in editmode, the blend mode needs to be set incase it was ADD */
00701         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00702 }
00703