Blender V2.61 - r43446

drawmesh.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Blender Foundation, full update, glsl support
00022  *
00023  * ***** END GPL LICENSE BLOCK *****
00024  */
00025 
00030 #include <string.h>
00031 #include <math.h>
00032 
00033 #include "MEM_guardedalloc.h"
00034 
00035 #include "BLI_blenlib.h"
00036 #include "BLI_math.h"
00037 #include "BLI_edgehash.h"
00038 #include "BLI_editVert.h"
00039 #include "BLI_utildefines.h"
00040 
00041 #include "DNA_material_types.h"
00042 #include "DNA_meshdata_types.h"
00043 #include "DNA_node_types.h"
00044 #include "DNA_object_types.h"
00045 #include "DNA_property_types.h"
00046 #include "DNA_scene_types.h"
00047 #include "DNA_screen_types.h"
00048 #include "DNA_view3d_types.h"
00049 
00050 #include "BKE_DerivedMesh.h"
00051 #include "BKE_effect.h"
00052 #include "BKE_image.h"
00053 #include "BKE_material.h"
00054 #include "BKE_paint.h"
00055 #include "BKE_property.h"
00056 #include "BKE_scene.h"
00057 
00058 #include "BIF_gl.h"
00059 #include "BIF_glutil.h"
00060 
00061 #include "UI_resources.h"
00062 
00063 #include "GPU_buffers.h"
00064 #include "GPU_extensions.h"
00065 #include "GPU_draw.h"
00066 #include "GPU_material.h"
00067 
00068 #include "ED_mesh.h"
00069 #include "ED_uvedit.h"
00070 
00071 #include "view3d_intern.h"  // own include
00072 
00073 /* user data structures for derived mesh callbacks */
00074 typedef struct drawMeshFaceSelect_userData {
00075     Mesh *me;
00076     EdgeHash *eh;
00077 } drawMeshFaceSelect_userData;
00078 
00079 typedef struct drawEMTFMapped_userData {
00080     EditMesh *em;
00081     short has_mcol;
00082     short has_mtface;
00083     MFace *mf;
00084     MTFace *tf;
00085 } drawEMTFMapped_userData;
00086 
00087 typedef struct drawTFace_userData {
00088     MFace *mf;
00089     MTFace *tf;
00090 } drawTFace_userData;
00091 
00092 /**************************** Face Select Mode *******************************/
00093 
00094 /* Flags for marked edges */
00095 enum {
00096     eEdge_Visible = (1<<0),
00097     eEdge_Select = (1<<1),
00098 };
00099 
00100 /* Creates a hash of edges to flags indicating selected/visible */
00101 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flags)
00102 {
00103     int *flags_p;
00104 
00105     if(!BLI_edgehash_haskey(eh, v0, v1))
00106         BLI_edgehash_insert(eh, v0, v1, NULL);
00107 
00108     flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1);
00109     *flags_p |= flags;
00110 }
00111 
00112 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me)
00113 {
00114     EdgeHash *eh = BLI_edgehash_new();
00115     MFace *mf;
00116     int i;
00117     
00118     for(i=0; i<me->totface; i++) {
00119         mf = &me->mface[i];
00120 
00121         if(!(mf->flag & ME_HIDE)) {
00122             unsigned int flags = eEdge_Visible;
00123             if(mf->flag & ME_FACE_SEL) flags |= eEdge_Select;
00124 
00125             get_marked_edge_info__orFlags(eh, mf->v1, mf->v2, flags);
00126             get_marked_edge_info__orFlags(eh, mf->v2, mf->v3, flags);
00127 
00128             if(mf->v4) {
00129                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v4, flags);
00130                 get_marked_edge_info__orFlags(eh, mf->v4, mf->v1, flags);
00131             }
00132             else
00133                 get_marked_edge_info__orFlags(eh, mf->v3, mf->v1, flags);
00134         }
00135     }
00136 
00137     return eh;
00138 }
00139 
00140 
00141 static int draw_mesh_face_select__setHiddenOpts(void *userData, int index)
00142 {
00143     drawMeshFaceSelect_userData *data = userData;
00144     Mesh *me= data->me;
00145     MEdge *med = &me->medge[index];
00146     uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00147 
00148     if(me->drawflag & ME_DRAWEDGES) { 
00149         if(me->drawflag & ME_HIDDENEDGES)
00150             return 1;
00151         else
00152             return (flags & eEdge_Visible);
00153     }
00154     else
00155         return (flags & eEdge_Select);
00156 }
00157 
00158 static int draw_mesh_face_select__setSelectOpts(void *userData, int index)
00159 {
00160     drawMeshFaceSelect_userData *data = userData;
00161     MEdge *med = &data->me->medge[index];
00162     uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med->v2);
00163 
00164     return flags & eEdge_Select;
00165 }
00166 
00167 /* draws unselected */
00168 static int draw_mesh_face_select__drawFaceOptsInv(void *userData, int index)
00169 {
00170     Mesh *me = (Mesh*)userData;
00171 
00172     MFace *mface = &me->mface[index];
00173     if(!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL))
00174         return 2; /* Don't set color */
00175     else
00176         return 0;
00177 }
00178 
00179 static void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm)
00180 {
00181     drawMeshFaceSelect_userData data;
00182 
00183     data.me = me;
00184     data.eh = get_tface_mesh_marked_edge_info(me);
00185 
00186     glEnable(GL_DEPTH_TEST);
00187     glDisable(GL_LIGHTING);
00188     bglPolygonOffset(rv3d->dist, 1.0);
00189 
00190     /* Draw (Hidden) Edges */
00191     setlinestyle(1);
00192     UI_ThemeColor(TH_EDGE_FACESEL);
00193     dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data);
00194     setlinestyle(0);
00195 
00196     /* Draw Selected Faces */
00197     if(me->drawflag & ME_DRAWFACES) {
00198         glEnable(GL_BLEND);
00199         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00200         /* dull unselected faces so as not to get in the way of seeing color */
00201         glColor4ub(96, 96, 96, 64);
00202         dm->drawMappedFacesTex(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, (void*)me);
00203         
00204         glDisable(GL_BLEND);
00205     }
00206     
00207     bglPolygonOffset(rv3d->dist, 1.0);
00208 
00209         /* Draw Stippled Outline for selected faces */
00210     glColor3ub(255, 255, 255);
00211     setlinestyle(1);
00212     dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data);
00213     setlinestyle(0);
00214 
00215     bglPolygonOffset(rv3d->dist, 0.0);  // resets correctly now, even after calling accumulated offsets
00216 
00217     BLI_edgehash_free(data.eh, NULL);
00218 }
00219 
00220 /***************************** Texture Drawing ******************************/
00221 
00222 static Material *give_current_material_or_def(Object *ob, int matnr)
00223 {
00224     extern Material defmaterial;    // render module abuse...
00225     Material *ma= give_current_material(ob, matnr);
00226 
00227     return ma?ma:&defmaterial;
00228 }
00229 
00230 /* Icky globals, fix with userdata parameter */
00231 
00232 static struct TextureDrawState {
00233     Object *ob;
00234     int islit, istex;
00235     int color_profile;
00236     unsigned char obcol[4];
00237 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}};
00238 
00239 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw)
00240 {
00241     static Material *c_ma;
00242     static int c_textured;
00243     static MTFace *c_texface;
00244     static int c_backculled;
00245     static int c_badtex;
00246     static int c_lit;
00247 
00248     Object *litob = NULL; //to get mode to turn off mipmap in painting mode
00249     int backculled = GEMAT_BACKCULL;
00250     int alphablend = 0;
00251     int textured = 0;
00252     int lit = 0;
00253     
00254     if (clearcache) {
00255         c_textured= c_lit= c_backculled= -1;
00256         c_texface= (MTFace*) -1;
00257         c_badtex= 0;
00258     } else {
00259         textured = gtexdraw.istex;
00260         litob = gtexdraw.ob;
00261     }
00262 
00263     /* convert number of lights into boolean */
00264     if (gtexdraw.islit) lit = 1;
00265 
00266     if (ma) {
00267         alphablend = ma->game.alpha_blend;
00268         if (ma->mode & MA_SHLESS) lit = 0;
00269         backculled = ma->game.flag & GEMAT_BACKCULL;
00270     }
00271 
00272     if (texface) {
00273         textured = textured && (texface->tpage);
00274 
00275         /* no material, render alpha if texture has depth=32 */
00276         if (!ma && BKE_image_has_alpha(texface->tpage))
00277             alphablend = GPU_BLEND_ALPHA;
00278     }
00279 
00280     else
00281         textured = 0;
00282 
00283     if (backculled!=c_backculled) {
00284         if (backculled) glEnable(GL_CULL_FACE);
00285         else glDisable(GL_CULL_FACE);
00286 
00287         c_backculled= backculled;
00288     }
00289 
00290     if (textured!=c_textured || texface!=c_texface) {
00291         if (textured ) {
00292             c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend);
00293         } else {
00294             GPU_set_tpage(NULL, 0, 0);
00295             c_badtex= 0;
00296         }
00297         c_textured= textured;
00298         c_texface= texface;
00299     }
00300 
00301     if (c_badtex) lit= 0;
00302     if (lit!=c_lit || ma!=c_ma) {
00303         if (lit) {
00304             float spec[4];
00305             if (!ma)ma= give_current_material_or_def(NULL, 0); //default material
00306 
00307             spec[0]= ma->spec*ma->specr;
00308             spec[1]= ma->spec*ma->specg;
00309             spec[2]= ma->spec*ma->specb;
00310             spec[3]= 1.0;
00311 
00312             glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec);
00313             glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
00314             glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(ma->har, 0, 128));
00315             glEnable(GL_LIGHTING);
00316             glEnable(GL_COLOR_MATERIAL);
00317         }
00318         else {
00319             glDisable(GL_LIGHTING); 
00320             glDisable(GL_COLOR_MATERIAL);
00321         }
00322         c_lit= lit;
00323     }
00324 
00325     return c_badtex;
00326 }
00327 
00328 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
00329 {
00330     unsigned char obcol[4];
00331     int istex, solidtex;
00332 
00333     // XXX scene->obedit warning
00334 
00335     /* texture draw is abused for mask selection mode, do this so wire draw
00336      * with face selection in weight paint is not lit. */
00337     if((v3d->drawtype <= OB_WIRE) && (ob->mode & OB_MODE_WEIGHT_PAINT)) {
00338         solidtex= FALSE;
00339         Gtexdraw.islit= 0;
00340     }
00341     else if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype!=OB_TEXTURE)) {
00342         /* draw with default lights in solid draw mode and edit mode */
00343         solidtex= TRUE;
00344         Gtexdraw.islit= -1;
00345     }
00346     else {
00347         /* draw with lights in the scene otherwise */
00348         solidtex= FALSE;
00349         Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
00350     }
00351     
00352     obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255);
00353     obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255);
00354     obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255);
00355     obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255);
00356     
00357     glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
00358     if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1;
00359     else istex= 0;
00360 
00361     Gtexdraw.ob = ob;
00362     Gtexdraw.istex = istex;
00363     Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT;
00364     memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
00365     set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
00366     glShadeModel(GL_SMOOTH);
00367 }
00368 
00369 static void draw_textured_end(void)
00370 {
00371     /* switch off textures */
00372     GPU_set_tpage(NULL, 0, 0);
00373 
00374     glShadeModel(GL_FLAT);
00375     glDisable(GL_CULL_FACE);
00376 
00377     /* XXX, bad patch - GPU_default_lights() calls
00378      * glLightfv(GL_LIGHT_POSITION, ...) which
00379      * is transformed by the current matrix... we
00380      * need to make sure that matrix is identity.
00381      * 
00382      * It would be better if drawmesh.c kept track
00383      * of and restored the light settings it changed.
00384      *  - zr
00385      */
00386     glPushMatrix();
00387     glLoadIdentity();   
00388     GPU_default_lights();
00389     glPopMatrix();
00390 }
00391 
00392 static int draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int matnr)
00393 {
00394     Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
00395     int validtexture=0;
00396 
00397     if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
00398 
00399     validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw);
00400 
00401     if (tface && validtexture) {
00402         glColor3ub(0xFF, 0x00, 0xFF);
00403         return 2; /* Don't set color */
00404     } else if (ma && ma->shade_flag&MA_OBCOLOR) {
00405         glColor3ubv(Gtexdraw.obcol);
00406         return 2; /* Don't set color */
00407     } else if (!has_mcol) {
00408         if (tface) glColor3f(1.0, 1.0, 1.0);
00409         else {
00410             if(ma) {
00411                 float col[3];
00412                 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
00413                 else copy_v3_v3(col, &ma->r);
00414                 
00415                 glColor3fv(col);
00416             }
00417             else glColor3f(1.0, 1.0, 1.0);
00418         }
00419         return 2; /* Don't set color */
00420     } else {
00421         return 1; /* Set color from mcol */
00422     }
00423 }
00424 
00425 static int draw_mcol__set_draw_legacy(MTFace *UNUSED(tface), int has_mcol, int UNUSED(matnr))
00426 {
00427     if (has_mcol) return 1;
00428     else return 2;
00429 }
00430 
00431 static int draw_tface__set_draw(MTFace *tface, int has_mcol, int matnr)
00432 {
00433     Material *ma= give_current_material(Gtexdraw.ob, matnr+1);
00434 
00435     if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0;
00436 
00437     if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
00438         return 2; /* Don't set color */
00439     } else if (tface && tface->mode&TF_OBCOL) {
00440         return 2; /* Don't set color */
00441     } else if (!has_mcol) {
00442         return 1; /* Don't set color */
00443     } else {
00444         return 1; /* Set color from mcol */
00445     }
00446 }
00447 static void add_tface_color_layer(DerivedMesh *dm)
00448 {
00449     MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE);
00450     MFace *mface = DM_get_face_data_layer(dm, CD_MFACE);
00451     MCol *finalCol;
00452     int i,j;
00453     MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
00454     if(!mcol)
00455         mcol = dm->getFaceDataArray(dm, CD_MCOL);
00456 
00457     finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer");
00458     for(i=0;i<dm->getNumFaces(dm);i++) {
00459         Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
00460 
00461         if (ma && (ma->game.flag&GEMAT_INVISIBLE)) {
00462             if( mcol )
00463                 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4);
00464             else
00465                 for(j=0;j<4;j++) {
00466                     finalCol[i*4+j].b = 255;
00467                     finalCol[i*4+j].g = 255;
00468                     finalCol[i*4+j].r = 255;
00469                 }
00470         }
00471         else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) {
00472             for(j=0;j<4;j++) {
00473                 finalCol[i*4+j].b = 255;
00474                 finalCol[i*4+j].g = 0;
00475                 finalCol[i*4+j].r = 255;
00476             }
00477         } else if (tface && tface->mode&TF_OBCOL) {
00478             for(j=0;j<4;j++) {
00479                 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[0]);
00480                 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]);
00481                 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[2]);
00482             }
00483         } else if (!mcol) {
00484             if (tface) {
00485                 for(j=0;j<4;j++) {
00486                     finalCol[i*4+j].b = 255;
00487                     finalCol[i*4+j].g = 255;
00488                     finalCol[i*4+j].r = 255;
00489                 }
00490             }
00491             else {
00492                 float col[3];
00493                 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1);
00494                 
00495                 if(ma) {
00496                     if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r);
00497                     else copy_v3_v3(col, &ma->r);
00498                     
00499                     for(j=0;j<4;j++) {
00500                         finalCol[i*4+j].b = FTOCHAR(col[0]);
00501                         finalCol[i*4+j].g = FTOCHAR(col[1]);
00502                         finalCol[i*4+j].r = FTOCHAR(col[2]);
00503                     }
00504                 }
00505                 else
00506                     for(j=0;j<4;j++) {
00507                         finalCol[i*4+j].b = 255;
00508                         finalCol[i*4+j].g = 255;
00509                         finalCol[i*4+j].r = 255;
00510                     }
00511             }
00512         } else {
00513             for(j=0;j<4;j++) {
00514                 finalCol[i*4+j].r = mcol[i*4+j].r;
00515                 finalCol[i*4+j].g = mcol[i*4+j].g;
00516                 finalCol[i*4+j].b = mcol[i*4+j].b;
00517             }
00518         }
00519     }
00520     CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCol, dm->numFaceData );
00521 }
00522 
00523 static int draw_tface_mapped__set_draw(void *userData, int index)
00524 {
00525     Mesh *me = (Mesh*)userData;
00526     MTFace *tface = (me->mtface)? &me->mtface[index]: NULL;
00527     MFace *mface = &me->mface[index];
00528     const int matnr = mface->mat_nr;
00529     if (mface->flag & ME_HIDE) return 0;
00530     return draw_tface__set_draw(tface, (me->mcol != NULL), matnr);
00531 }
00532 
00533 static int draw_em_tf_mapped__set_draw(void *userData, int index)
00534 {
00535     drawEMTFMapped_userData *data = userData;
00536     EditMesh *em = data->em;
00537     EditFace *efa= EM_get_face_for_index(index);
00538     MTFace *tface;
00539     int matnr;
00540 
00541     if (efa->h)
00542         return 0;
00543 
00544     tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
00545     matnr = efa->mat_nr;
00546 
00547     return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
00548 }
00549 
00550 static int wpaint__setSolidDrawOptions_material(void *userData, int index, int *drawSmooth_r)
00551 {
00552     Mesh *me = (Mesh*)userData;
00553 
00554     if (me->mat && me->mface) {
00555         Material *ma= me->mat[me->mface[index].mat_nr];
00556         if (ma && (ma->game.flag & GEMAT_INVISIBLE)) {
00557             return 0;
00558         }
00559     }
00560 
00561     *drawSmooth_r = 1;
00562     return 1;
00563 }
00564 
00565 /* when face select is on, use face hidden flag */
00566 static int wpaint__setSolidDrawOptions_facemask(void *userData, int index, int *drawSmooth_r)
00567 {
00568     Mesh *me = (Mesh*)userData;
00569     MFace *mface = &me->mface[index];
00570     if (mface->flag & ME_HIDE) return 0;
00571     *drawSmooth_r = 1;
00572     return 1;
00573 }
00574 
00575 static void draw_mesh_text(Scene *scene, Object *ob, int glsl)
00576 {
00577     Mesh *me = ob->data;
00578     DerivedMesh *ddm;
00579     MFace *mf, *mface= me->mface;
00580     MTFace *tface= me->mtface;
00581     MCol *mcol= me->mcol;   /* why does mcol exist? */
00582     bProperty *prop = get_ob_property(ob, "Text");
00583     GPUVertexAttribs gattribs;
00584     int a, totface= me->totface;
00585 
00586     /* don't draw without tfaces */
00587     if(!tface)
00588         return;
00589 
00590     /* don't draw when editing */
00591     if(ob->mode & OB_MODE_EDIT)
00592         return;
00593     else if(ob==OBACT)
00594         if(paint_facesel_test(ob) || paint_vertsel_test(ob))
00595             return;
00596 
00597     ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
00598 
00599     for(a=0, mf=mface; a<totface; a++, tface++, mf++) {
00600         short matnr= mf->mat_nr;
00601         int mf_smooth= mf->flag & ME_SMOOTH;
00602         Material *mat = me->mat[matnr];
00603         int mode= mat->game.flag;
00604 
00605         if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) {
00606             float v1[3], v2[3], v3[3], v4[3];
00607             char string[MAX_PROPSTRING];
00608             int characters, i, glattrib= -1, badtex= 0;
00609 
00610             if(glsl) {
00611                 GPU_enable_material(matnr+1, &gattribs);
00612 
00613                 for(i=0; i<gattribs.totlayer; i++) {
00614                     if(gattribs.layer[i].type == CD_MTFACE) {
00615                         glattrib = gattribs.layer[i].glindex;
00616                         break;
00617                     }
00618                 }
00619             }
00620             else {
00621                 badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw);
00622                 if (badtex) {
00623                     if (mcol) mcol+=4;
00624                     continue;
00625                 }
00626             }
00627 
00628             ddm->getVertCo(ddm, mf->v1, v1);
00629             ddm->getVertCo(ddm, mf->v2, v2);
00630             ddm->getVertCo(ddm, mf->v3, v3);
00631             if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4);
00632 
00633             // The BM_FONT handling is in the gpu module, shared with the
00634             // game engine, was duplicated previously
00635 
00636             set_property_valstr(prop, string);
00637             characters = strlen(string);
00638             
00639             if(!BKE_image_get_ibuf(tface->tpage, NULL))
00640                 characters = 0;
00641 
00642             if (!mf_smooth) {
00643                 float nor[3];
00644 
00645                 normal_tri_v3( nor,v1, v2, v3);
00646 
00647                 glNormal3fv(nor);
00648             }
00649 
00650             GPU_render_text(tface, mode, string, characters,
00651                 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib);
00652         }
00653         if (mcol) {
00654             mcol+=4;
00655         }
00656     }
00657 
00658     ddm->release(ddm);
00659 }
00660 
00661 static int compareDrawOptions(void *userData, int cur_index, int next_index)
00662 {
00663     drawTFace_userData *data = userData;
00664 
00665     if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
00666         return 0;
00667 
00668     if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
00669         return 0;
00670 
00671     return 1;
00672 }
00673 
00674 static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
00675 {
00676     drawEMTFMapped_userData *data= userData;
00677 
00678     if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
00679         return 0;
00680 
00681     if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
00682         return 0;
00683 
00684     return 1;
00685 }
00686 
00687 void draw_mesh_textured_old(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
00688 {
00689     Mesh *me= ob->data;
00690     
00691     /* correct for negative scale */
00692     if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
00693     else glFrontFace(GL_CCW);
00694     
00695     /* draw the textured mesh */
00696     draw_textured_begin(scene, v3d, rv3d, ob);
00697 
00698     glColor4f(1.0f,1.0f,1.0f,1.0f);
00699 
00700     if(ob->mode & OB_MODE_EDIT) {
00701         drawEMTFMapped_userData data;
00702 
00703         data.em= me->edit_mesh;
00704         data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
00705         data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
00706         data.mf= DM_get_face_data_layer(dm, CD_MFACE);
00707         data.tf= DM_get_face_data_layer(dm, CD_MTFACE);
00708 
00709         dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
00710     }
00711     else if(draw_flags & DRAW_FACE_SELECT) {
00712         if(ob->mode & OB_MODE_WEIGHT_PAINT)
00713             dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_facemask, GPU_enable_material, NULL, me, 1);
00714         else
00715             dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped__set_draw : NULL, NULL, me);
00716     }
00717     else {
00718         if(GPU_buffer_legacy(dm)) {
00719             if (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)
00720                 dm->drawFacesTex(dm, draw_mcol__set_draw_legacy, NULL, NULL);
00721             else 
00722                 dm->drawFacesTex(dm, draw_tface__set_draw_legacy, NULL, NULL);
00723         }
00724         else {
00725             drawTFace_userData userData;
00726 
00727             if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
00728                 add_tface_color_layer(dm);
00729 
00730             userData.mf = DM_get_face_data_layer(dm, CD_MFACE);
00731             userData.tf = DM_get_face_data_layer(dm, CD_MTFACE);
00732 
00733             dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
00734         }
00735     }
00736 
00737     /* draw game engine text hack */
00738     if(get_ob_property(ob, "Text")) 
00739         draw_mesh_text(scene, ob, 0);
00740 
00741     draw_textured_end();
00742     
00743     /* draw edges and selected faces over textured mesh */
00744     if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
00745         draw_mesh_face_select(rv3d, me, dm);
00746 
00747     /* reset from negative scale correction */
00748     glFrontFace(GL_CCW);
00749     
00750     /* in editmode, the blend mode needs to be set incase it was ADD */
00751     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00752 }
00753 
00754 /************************** NEW SHADING NODES ********************************/
00755 
00756 typedef struct TexMatCallback {
00757     Scene *scene;
00758     Object *ob;
00759     Mesh *me;
00760     DerivedMesh *dm;
00761 } TexMatCallback;
00762 
00763 static void tex_mat_set_material_cb(void *UNUSED(userData), int mat_nr, void *attribs)
00764 {
00765     /* all we have to do here is simply enable the GLSL material, but note
00766        that the GLSL code will give different result depending on the drawtype,
00767        in texture draw mode it will output the active texture node, in material
00768        draw mode it will show the full material. */
00769     GPU_enable_material(mat_nr, attribs);
00770 }
00771 
00772 static void tex_mat_set_texture_cb(void *userData, int mat_nr, void *attribs)
00773 {
00774     /* texture draw mode without GLSL */
00775     TexMatCallback *data= (TexMatCallback*)userData;
00776     GPUVertexAttribs *gattribs = attribs;
00777     Image *ima;
00778     ImageUser *iuser;
00779     bNode *node;
00780     int texture_set= 0;
00781 
00782     /* draw image texture if we find one */
00783     if(ED_object_get_active_image(data->ob, mat_nr, &ima, &iuser, &node)) {
00784         /* get openl texture */
00785         int mipmap= 1;
00786         int bindcode= (ima)? GPU_verify_image(ima, iuser, 0, 0, mipmap): 0;
00787         float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
00788 
00789         if(bindcode) {
00790             NodeTexBase *texbase= node->storage;
00791 
00792             /* disable existing material */
00793             GPU_disable_material();
00794             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
00795             glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
00796             glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
00797 
00798             /* bind texture */
00799             glEnable(GL_COLOR_MATERIAL);
00800             glEnable(GL_TEXTURE_2D);
00801 
00802             glBindTexture(GL_TEXTURE_2D, ima->bindcode);
00803             glColor3f(1.0f, 1.0f, 1.0f);
00804 
00805             glMatrixMode(GL_TEXTURE);
00806             glLoadMatrixf(texbase->tex_mapping.mat);
00807             glMatrixMode(GL_MODELVIEW);
00808 
00809             /* use active UV texture layer */
00810             memset(gattribs, 0, sizeof(*gattribs));
00811 
00812             gattribs->layer[0].type= CD_MTFACE;
00813             gattribs->layer[0].name[0]= '\0';
00814             gattribs->layer[0].gltexco= 1;
00815             gattribs->totlayer= 1;
00816 
00817             texture_set= 1;
00818         }
00819     }
00820 
00821     if(!texture_set) {
00822         glMatrixMode(GL_TEXTURE);
00823         glLoadIdentity();
00824         glMatrixMode(GL_MODELVIEW);
00825 
00826         /* disable texture */
00827         glDisable(GL_TEXTURE_2D);
00828         glDisable(GL_COLOR_MATERIAL);
00829 
00830         /* draw single color */
00831         GPU_enable_material(mat_nr, attribs);
00832     }
00833 }
00834 
00835 static int tex_mat_set_face_mesh_cb(void *userData, int index)
00836 {
00837     /* faceselect mode face hiding */
00838     TexMatCallback *data= (TexMatCallback*)userData;
00839     Mesh *me = (Mesh*)data->me;
00840     MFace *mface = &me->mface[index];
00841 
00842     return !(mface->flag & ME_HIDE);
00843 }
00844 
00845 static int tex_mat_set_face_editmesh_cb(void *UNUSED(userData), int index)
00846 {
00847     /* editmode face hiding */
00848     EditFace *efa= EM_get_face_for_index(index);
00849 
00850     return !(efa->h);
00851 }
00852 
00853 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, int draw_flags)
00854 {
00855     if((!scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_DYNAMIC_PAINT_PREVIEW)) {
00856         draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
00857         return;
00858     }
00859 
00860     /* set opengl state for negative scale & color */
00861     if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
00862     else glFrontFace(GL_CCW);
00863 
00864     glEnable(GL_LIGHTING);
00865 
00866     if(ob->mode & OB_MODE_WEIGHT_PAINT) {
00867         /* weight paint mode exception */
00868         int useColors= 1;
00869 
00870         dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions_material,
00871             GPU_enable_material, NULL, ob->data, useColors);
00872     }
00873     else {
00874         Mesh *me= ob->data;
00875         TexMatCallback data = {scene, ob, me, dm};
00876         int (*set_face_cb)(void*, int);
00877         int glsl;
00878         
00879         /* face hiding callback depending on mode */
00880         if(ob == scene->obedit)
00881             set_face_cb= tex_mat_set_face_editmesh_cb;
00882         else if(draw_flags & DRAW_FACE_SELECT)
00883             set_face_cb= tex_mat_set_face_mesh_cb;
00884         else
00885             set_face_cb= NULL;
00886 
00887         /* test if we can use glsl */
00888         glsl= (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support();
00889 
00890         GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
00891 
00892         if(glsl) {
00893             /* draw glsl */
00894             dm->drawMappedFacesMat(dm,
00895                 tex_mat_set_material_cb,
00896                 set_face_cb, &data);
00897         }
00898         else {
00899             float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
00900 
00901             /* draw textured */
00902             glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
00903             glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
00904             glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);
00905 
00906             dm->drawMappedFacesMat(dm,
00907                 tex_mat_set_texture_cb,
00908                 set_face_cb, &data);
00909         }
00910 
00911         GPU_end_object_materials();
00912     }
00913 
00914     /* reset opengl state */
00915     glDisable(GL_COLOR_MATERIAL);
00916     glDisable(GL_TEXTURE_2D);
00917     glDisable(GL_LIGHTING);
00918     glBindTexture(GL_TEXTURE_2D, 0);
00919     glFrontFace(GL_CCW);
00920 
00921     glMatrixMode(GL_TEXTURE);
00922     glLoadIdentity();
00923     glMatrixMode(GL_MODELVIEW);
00924 
00925     /* faceselect mode drawing over textured mesh */
00926     if(!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
00927         draw_mesh_face_select(rv3d, ob->data, dm);
00928 }
00929