Blender V2.61 - r43446
|
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