LEFT | RIGHT |
1 /* | 1 /* |
2 * $Id$ | |
3 * | |
4 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
5 * | 3 * |
6 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
7 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
8 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
9 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
10 * | 8 * |
11 * This program is distributed in the hope that it will be useful, | 9 * This program is distributed in the hope that it will be useful, |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
15 * | 13 * |
16 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
17 * along with this program; if not, write to the Free Software Foundation, | 15 * along with this program; if not, write to the Free Software Foundation, |
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
19 * | 17 * |
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. | 18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. |
21 * All rights reserved. | 19 * All rights reserved. |
22 * | 20 * |
23 * Contributor(s): Blender Foundation, full update, glsl support | 21 * Contributor(s): Blender Foundation, full update, glsl support |
24 * | 22 * |
25 * ***** END GPL LICENSE BLOCK ***** | 23 * ***** END GPL LICENSE BLOCK ***** |
26 */ | 24 */ |
27 | 25 |
28 /** \file blender/editors/space_view3d/drawmesh.c | 26 /** \file blender/editors/space_view3d/drawmesh.c |
29 * \ingroup spview3d | 27 * \ingroup spview3d |
30 */ | 28 */ |
31 | 29 |
32 | |
33 #include <string.h> | 30 #include <string.h> |
34 #include <math.h> | 31 #include <math.h> |
35 | 32 |
36 #include "MEM_guardedalloc.h" | 33 #include "MEM_guardedalloc.h" |
37 | 34 |
| 35 #include "BLI_utildefines.h" |
38 #include "BLI_blenlib.h" | 36 #include "BLI_blenlib.h" |
| 37 #include "BLI_bitmap.h" |
39 #include "BLI_math.h" | 38 #include "BLI_math.h" |
40 #include "BLI_edgehash.h" | |
41 #include "BLI_editVert.h" | |
42 #include "BLI_utildefines.h" | 39 #include "BLI_utildefines.h" |
43 | 40 |
44 #include "DNA_material_types.h" | 41 #include "DNA_material_types.h" |
| 42 #include "DNA_mesh_types.h" |
45 #include "DNA_meshdata_types.h" | 43 #include "DNA_meshdata_types.h" |
| 44 #include "DNA_node_types.h" |
| 45 #include "DNA_object_types.h" |
46 #include "DNA_property_types.h" | 46 #include "DNA_property_types.h" |
47 #include "DNA_scene_types.h" | 47 #include "DNA_scene_types.h" |
48 #include "DNA_screen_types.h" | 48 #include "DNA_screen_types.h" |
49 #include "DNA_view3d_types.h" | 49 #include "DNA_view3d_types.h" |
50 #include "DNA_object_types.h" | 50 #include "DNA_windowmanager_types.h" |
51 | 51 |
52 #include "BKE_DerivedMesh.h" | 52 #include "BKE_DerivedMesh.h" |
53 #include "BKE_effect.h" | 53 #include "BKE_effect.h" |
| 54 #include "BKE_global.h" |
54 #include "BKE_image.h" | 55 #include "BKE_image.h" |
55 #include "BKE_material.h" | 56 #include "BKE_material.h" |
56 #include "BKE_paint.h" | 57 #include "BKE_paint.h" |
57 #include "BKE_property.h" | 58 #include "BKE_property.h" |
58 | 59 #include "BKE_editmesh.h" |
| 60 #include "BKE_scene.h" |
59 | 61 |
60 #include "BIF_gl.h" | 62 #include "BIF_gl.h" |
61 #include "BIF_glutil.h" | 63 #include "BIF_glutil.h" |
62 | |
63 #include "UI_resources.h" | |
64 | |
65 #include "GPU_buffers.h" | 64 #include "GPU_buffers.h" |
66 #include "GPU_extensions.h" | 65 #include "GPU_extensions.h" |
67 #include "GPU_draw.h" | 66 #include "GPU_draw.h" |
68 | 67 |
69 #include "ED_mesh.h" | 68 #include "ED_mesh.h" |
70 | 69 |
71 #include "view3d_intern.h" // own include | |
72 | |
73 /***/ | |
74 | |
75 /* Flags for marked edges */ | |
76 enum { | |
77 eEdge_Visible = (1<<0), | |
78 eEdge_Select = (1<<1), | |
79 }; | |
80 | |
81 /* Creates a hash of edges to flags indicating | |
82 * adjacent tface select/active/etc flags. | |
83 */ | |
84 static void get_marked_edge_info__orFlags(EdgeHash *eh, int v0, int v1, int flag
s) | |
85 { | |
86 int *flags_p; | |
87 | |
88 if (!BLI_edgehash_haskey(eh, v0, v1)) { | |
89 BLI_edgehash_insert(eh, v0, v1, NULL); | |
90 } | |
91 | |
92 flags_p = (int*) BLI_edgehash_lookup_p(eh, v0, v1); | |
93 *flags_p |= flags; | |
94 } | |
95 | |
96 static EdgeHash *get_tface_mesh_marked_edge_info(Mesh *me) | |
97 { | |
98 EdgeHash *eh = BLI_edgehash_new(); | |
99 int i; | |
100 MFace *mf; | |
101 ········ | |
102 for (i=0; i<me->totface; i++) { | |
103 mf = &me->mface[i]; | |
104 | |
105 if (mf->v3) { | |
106 if (!(mf->flag&ME_HIDE)) { | |
107 unsigned int flags = eEdge_Visible; | |
108 if (mf->flag&ME_FACE_SEL) flags |= eEdge_Select; | |
109 | |
110 get_marked_edge_info__orFlags(eh, mf->v1, mf->v2
, flags); | |
111 get_marked_edge_info__orFlags(eh, mf->v2, mf->v3
, flags); | |
112 if (mf->v4) { | |
113 get_marked_edge_info__orFlags(eh, mf->v3
, mf->v4, flags); | |
114 get_marked_edge_info__orFlags(eh, mf->v4
, mf->v1, flags); | |
115 } else { | |
116 get_marked_edge_info__orFlags(eh, mf->v3
, mf->v1, flags); | |
117 } | |
118 } | |
119 } | |
120 } | |
121 | |
122 return eh; | |
123 } | |
124 | |
125 | |
126 static int draw_tfaces3D__setHiddenOpts(void *userData, int index) | |
127 { | |
128 struct { Mesh *me; EdgeHash *eh; } *data = userData; | |
129 Mesh *me= data->me; | |
130 MEdge *med = &me->medge[index]; | |
131 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med-
>v2); | |
132 | |
133 if((me->drawflag & ME_DRAWSEAMS) && (med->flag&ME_SEAM)) { | |
134 return 0; | |
135 } else if(me->drawflag & ME_DRAWEDGES){· | |
136 if (me->drawflag & ME_HIDDENEDGES) { | |
137 return 1; | |
138 } else { | |
139 return (flags & eEdge_Visible); | |
140 } | |
141 } else { | |
142 return (flags & eEdge_Select); | |
143 } | |
144 } | |
145 | |
146 static int draw_tfaces3D__setSeamOpts(void *userData, int index) | |
147 { | |
148 struct { Mesh *me; EdgeHash *eh; } *data = userData; | |
149 Mesh *me= data->me; | |
150 MEdge *med = &data->me->medge[index]; | |
151 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med-
>v2); | |
152 | |
153 if (med->flag & ME_SEAM) { | |
154 if (me->drawflag & ME_HIDDENEDGES) { | |
155 return 1; | |
156 } else { | |
157 return (flags & eEdge_Visible); | |
158 } | |
159 } else { | |
160 return 0; | |
161 } | |
162 } | |
163 | |
164 static int draw_tfaces3D__setSelectOpts(void *userData, int index) | |
165 { | |
166 struct { Mesh *me; EdgeHash *eh; } *data = userData; | |
167 MEdge *med = &data->me->medge[index]; | |
168 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med-
>v2); | |
169 | |
170 return flags & eEdge_Select; | |
171 } | |
172 | |
173 #if 0 | |
174 static int draw_tfaces3D__setActiveOpts(void *userData, int index) | |
175 { | |
176 struct { Mesh *me; EdgeHash *eh; } *data = userData; | |
177 MEdge *med = &data->me->medge[index]; | |
178 uintptr_t flags = (intptr_t) BLI_edgehash_lookup(data->eh, med->v1, med-
>v2); | |
179 | |
180 if (flags & eEdge_Select) { | |
181 return 1; | |
182 } else { | |
183 return 0; | |
184 } | |
185 } | |
186 | |
187 static int draw_tfaces3D__drawFaceOpts(void *userData, int index) | |
188 { | |
189 Mesh *me = (Mesh*)userData; | |
190 | |
191 MFace *mface = &me->mface[index]; | |
192 if (!(mface->flag&ME_HIDE) && (mface->flag&ME_FACE_SEL)) | |
193 return 2; /* Don't set color */ | |
194 else | |
195 return 0; | |
196 } | |
197 #endif | |
198 | |
199 /* draws unselected */ | |
200 static int draw_tfaces3D__drawFaceOptsInv(void *userData, int index) | |
201 { | |
202 Mesh *me = (Mesh*)userData; | |
203 | |
204 MFace *mface = &me->mface[index]; | |
205 if (!(mface->flag&ME_HIDE) && !(mface->flag&ME_FACE_SEL)) | |
206 return 2; /* Don't set color */ | |
207 else | |
208 return 0; | |
209 } | |
210 | |
211 static void draw_tfaces3D(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm, short d
raw_seams) | |
212 { | |
213 struct { Mesh *me; EdgeHash *eh; } data; | |
214 | |
215 data.me = me; | |
216 data.eh = get_tface_mesh_marked_edge_info(me); | |
217 | |
218 glEnable(GL_DEPTH_TEST); | |
219 glDisable(GL_LIGHTING); | |
220 bglPolygonOffset(rv3d->dist, 1.0); | |
221 | |
222 /* Draw (Hidden) Edges */ | |
223 setlinestyle(1); | |
224 UI_ThemeColor(TH_EDGE_FACESEL); | |
225 dm->drawMappedEdges(dm, draw_tfaces3D__setHiddenOpts, &data); | |
226 setlinestyle(0); | |
227 | |
228 /* Draw Seams */ | |
229 if(draw_seams && me->drawflag & ME_DRAWSEAMS) { | |
230 UI_ThemeColor(TH_EDGE_SEAM); | |
231 glLineWidth(2); | |
232 dm->drawMappedEdges(dm, draw_tfaces3D__setSeamOpts, &data); | |
233 glLineWidth(1); | |
234 } | |
235 | |
236 /* Draw Selected Faces */ | |
237 if(me->drawflag & ME_DRAWFACES) { | |
238 glEnable(GL_BLEND); | |
239 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
240 #if 0 | |
241 UI_ThemeColor4(TH_FACE_SELECT); | |
242 | |
243 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOpts, (void*)m
e); | |
244 #else | |
245 /* dull unselected faces so as not to get in the way of seeing c
olor */ | |
246 glColor4ub(96, 96, 96, 64); | |
247 dm->drawMappedFacesTex(dm, draw_tfaces3D__drawFaceOptsInv, (void
*)me); | |
248 #endif | |
249 ················ | |
250 glDisable(GL_BLEND); | |
251 } | |
252 ········ | |
253 bglPolygonOffset(rv3d->dist, 1.0); | |
254 | |
255 /* Draw Stippled Outline for selected faces */ | |
256 glColor3ub(255, 255, 255); | |
257 setlinestyle(1); | |
258 dm->drawMappedEdges(dm, draw_tfaces3D__setSelectOpts, &data); | |
259 setlinestyle(0); | |
260 | |
261 bglPolygonOffset(rv3d->dist, 0.0); // resets correctly now, even af
ter calling accumulated offsets | |
262 | |
263 BLI_edgehash_free(data.eh, NULL); | |
264 } | |
265 | |
266 static Material *give_current_material_or_def(Object *ob, int matnr) | |
267 { | |
268 extern Material defmaterial; // render module abuse... | |
269 Material *ma= give_current_material(ob, matnr); | |
270 | |
271 return ma?ma:&defmaterial; | |
272 } | |
273 | |
274 /* Icky globals, fix with userdata parameter */ | |
275 | |
276 static struct TextureDrawState { | |
277 Object *ob; | |
278 int islit, istex; | |
279 int color_profile; | |
280 unsigned char obcol[4]; | |
281 } Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}}; | |
282 | |
283 static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *m
a, struct TextureDrawState gtexdraw) | |
284 { | |
285 static Material *c_ma; | |
286 static int c_textured; | |
287 static MTFace *c_texface; | |
288 static int c_doublesided; | |
289 static int c_badtex; | |
290 static int c_lit; | |
291 | |
292 Object *litob = NULL; //to get mode to turn off mipmap in painting mode | |
293 int doublesided = 0; | |
294 int alphablend = 0; | |
295 int textured = 0; | |
296 int lit = 0; | |
297 ········ | |
298 if (clearcache) { | |
299 c_textured= c_lit= c_doublesided= -1; | |
300 c_texface= (MTFace*) -1; | |
301 c_badtex= 0; | |
302 } else { | |
303 textured = gtexdraw.istex; | |
304 litob = gtexdraw.ob; | |
305 } | |
306 | |
307 /* convert number of lights into boolean */ | |
308 if (gtexdraw.islit) lit = 1; | |
309 | |
310 if (ma) { | |
311 alphablend = ma->game.alpha_blend; | |
312 if (ma->mode & MA_SHLESS) lit = 0; | |
313 if (ma->game.flag) doublesided= GEMAT_TWOSIDED; | |
314 } | |
315 | |
316 if (texface) | |
317 textured = textured && (texface->tpage); | |
318 else | |
319 textured = 0; | |
320 | |
321 if (doublesided!=c_doublesided) { | |
322 if (doublesided) glDisable(GL_CULL_FACE); | |
323 else glEnable(GL_CULL_FACE); | |
324 | |
325 c_doublesided= doublesided; | |
326 } | |
327 | |
328 if (textured!=c_textured || texface!=c_texface) { | |
329 if (textured ) { | |
330 c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MOD
E_TEXTURE_PAINT), alphablend); | |
331 } else { | |
332 GPU_set_tpage(NULL, 0, 0); | |
333 c_badtex= 0; | |
334 } | |
335 c_textured= textured; | |
336 c_texface= texface; | |
337 } | |
338 | |
339 if (c_badtex) lit= 0; | |
340 if (lit!=c_lit || ma!=c_ma) { | |
341 if (lit) { | |
342 float spec[4]; | |
343 if (!ma)ma= give_current_material_or_def(NULL, 0); //def
ault material | |
344 | |
345 spec[0]= ma->spec*ma->specr; | |
346 spec[1]= ma->spec*ma->specg; | |
347 spec[2]= ma->spec*ma->specb; | |
348 spec[3]= 1.0; | |
349 | |
350 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); | |
351 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); | |
352 glEnable(GL_LIGHTING); | |
353 glEnable(GL_COLOR_MATERIAL); | |
354 } | |
355 else { | |
356 glDisable(GL_LIGHTING);· | |
357 glDisable(GL_COLOR_MATERIAL); | |
358 } | |
359 c_lit= lit; | |
360 } | |
361 | |
362 return c_badtex; | |
363 } | |
364 | |
365 static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O
bject *ob) | |
366 { | |
367 unsigned char obcol[4]; | |
368 int istex, solidtex= 0; | |
369 | |
370 // XXX scene->obedit warning | |
371 if(v3d->drawtype==OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtyp
e!=OB_TEXTURE)) { | |
372 /* draw with default lights in solid draw mode and edit mode */ | |
373 solidtex= 1; | |
374 Gtexdraw.islit= -1; | |
375 } | |
376 else { | |
377 /* draw with lights in the scene otherwise */ | |
378 Gtexdraw.islit= GPU_scene_object_lights(scene, ob, v3d->lay, rv3
d->viewmat, get_view3d_ortho(v3d, rv3d)); | |
379 } | |
380 ········ | |
381 obcol[0]= CLAMPIS(ob->col[0]*255, 0, 255); | |
382 obcol[1]= CLAMPIS(ob->col[1]*255, 0, 255); | |
383 obcol[2]= CLAMPIS(ob->col[2]*255, 0, 255); | |
384 obcol[3]= CLAMPIS(ob->col[3]*255, 0, 255); | |
385 ········ | |
386 glCullFace(GL_BACK); glEnable(GL_CULL_FACE); | |
387 if(solidtex || v3d->drawtype==OB_TEXTURE) istex= 1; | |
388 else istex= 0; | |
389 | |
390 Gtexdraw.ob = ob; | |
391 Gtexdraw.istex = istex; | |
392 Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; | |
393 memcpy(Gtexdraw.obcol, obcol, sizeof(obcol)); | |
394 set_draw_settings_cached(1, NULL, NULL, Gtexdraw); | |
395 glShadeModel(GL_SMOOTH); | |
396 } | |
397 | |
398 static void draw_textured_end(void) | |
399 { | |
400 /* switch off textures */ | |
401 GPU_set_tpage(NULL, 0, 0); | |
402 | |
403 glShadeModel(GL_FLAT); | |
404 glDisable(GL_CULL_FACE); | |
405 | |
406 /* XXX, bad patch - GPU_default_lights() calls | |
407 * glLightfv(GL_LIGHT_POSITION, ...) which | |
408 * is transformed by the current matrix... we | |
409 * need to make sure that matrix is identity. | |
410 *· | |
411 * It would be better if drawmesh.c kept track | |
412 * of and restored the light settings it changed. | |
413 * - zr | |
414 */ | |
415 glPushMatrix(); | |
416 glLoadIdentity();······· | |
417 GPU_default_lights(); | |
418 glPopMatrix(); | |
419 } | |
420 | |
421 static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr) | |
422 { | |
423 Material *ma= give_current_material(Gtexdraw.ob, matnr+1); | |
424 int validtexture=0; | |
425 | |
426 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; | |
427 | |
428 validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw); | |
429 | |
430 if (tface && validtexture) { | |
431 glColor3ub(0xFF, 0x00, 0xFF); | |
432 return 2; /* Don't set color */ | |
433 } else if (ma && ma->shade_flag&MA_OBCOLOR) { | |
434 glColor3ubv(Gtexdraw.obcol); | |
435 return 2; /* Don't set color */ | |
436 } else if (!mcol) { | |
437 if (tface) glColor3f(1.0, 1.0, 1.0); | |
438 else { | |
439 if(ma) { | |
440 float col[3]; | |
441 if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_
v3(col, &ma->r); | |
442 else copy_v3_v3(col, &ma->r); | |
443 ································ | |
444 glColor3fv(col); | |
445 } | |
446 else glColor3f(1.0, 1.0, 1.0); | |
447 } | |
448 return 2; /* Don't set color */ | |
449 } else { | |
450 return 1; /* Set color from mcol */ | |
451 } | |
452 } | |
453 static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) | |
454 { | |
455 Material *ma= give_current_material(Gtexdraw.ob, matnr+1); | |
456 | |
457 if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; | |
458 | |
459 if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) { | |
460 return 2; /* Don't set color */ | |
461 } else if (tface && tface->mode&TF_OBCOL) { | |
462 return 2; /* Don't set color */ | |
463 } else if (!mcol) { | |
464 return 1; /* Don't set color */ | |
465 } else { | |
466 return 1; /* Set color from mcol */ | |
467 } | |
468 } | |
469 static void add_tface_color_layer(DerivedMesh *dm) | |
470 { | |
471 MTFace *tface = DM_get_face_data_layer(dm, CD_MTFACE); | |
472 MFace *mface = DM_get_face_data_layer(dm, CD_MFACE); | |
473 MCol *finalCol; | |
474 int i,j; | |
475 MCol *mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL); | |
476 if(!mcol) | |
477 mcol = dm->getFaceDataArray(dm, CD_MCOL); | |
478 | |
479 finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_col
or_layer"); | |
480 for(i=0;i<dm->getNumFaces(dm);i++) { | |
481 Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr
+1); | |
482 | |
483 if (ma && (ma->game.flag&GEMAT_INVISIBLE)) { | |
484 if( mcol ) | |
485 memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4)
; | |
486 else | |
487 for(j=0;j<4;j++) { | |
488 finalCol[i*4+j].b = 255; | |
489 finalCol[i*4+j].g = 255; | |
490 finalCol[i*4+j].r = 255; | |
491 } | |
492 } | |
493 else if (tface && mface && set_draw_settings_cached(0, tface, ma
, Gtexdraw)) { | |
494 for(j=0;j<4;j++) { | |
495 finalCol[i*4+j].b = 255; | |
496 finalCol[i*4+j].g = 0; | |
497 finalCol[i*4+j].r = 255; | |
498 } | |
499 } else if (tface && tface->mode&TF_OBCOL) { | |
500 for(j=0;j<4;j++) { | |
501 finalCol[i*4+j].r = FTOCHAR(Gtexdraw.obcol[0]); | |
502 finalCol[i*4+j].g = FTOCHAR(Gtexdraw.obcol[1]); | |
503 finalCol[i*4+j].b = FTOCHAR(Gtexdraw.obcol[2]); | |
504 } | |
505 } else if (!mcol) { | |
506 if (tface) { | |
507 for(j=0;j<4;j++) { | |
508 finalCol[i*4+j].b = 255; | |
509 finalCol[i*4+j].g = 255; | |
510 finalCol[i*4+j].r = 255; | |
511 } | |
512 } | |
513 else { | |
514 float col[3]; | |
515 Material *ma= give_current_material(Gtexdraw.ob,
mface[i].mat_nr+1); | |
516 ································ | |
517 if(ma) { | |
518 if(Gtexdraw.color_profile) linearrgb_to_
srgb_v3_v3(col, &ma->r); | |
519 else copy_v3_v3(col, &ma->r); | |
520 ········································ | |
521 for(j=0;j<4;j++) { | |
522 finalCol[i*4+j].b = FTOCHAR(col[
2]); | |
523 finalCol[i*4+j].g = FTOCHAR(col[
1]); | |
524 finalCol[i*4+j].r = FTOCHAR(col[
0]); | |
525 } | |
526 } | |
527 else | |
528 for(j=0;j<4;j++) { | |
529 finalCol[i*4+j].b = 255; | |
530 finalCol[i*4+j].g = 255; | |
531 finalCol[i*4+j].r = 255; | |
532 } | |
533 } | |
534 } else { | |
535 for(j=0;j<4;j++) { | |
536 finalCol[i*4+j].b = mcol[i*4+j].r; | |
537 finalCol[i*4+j].g = mcol[i*4+j].g; | |
538 finalCol[i*4+j].r = mcol[i*4+j].b; | |
539 } | |
540 } | |
541 } | |
542 CustomData_add_layer( &dm->faceData, CD_TEXTURE_MCOL, CD_ASSIGN, finalCo
l, dm->numFaceData ); | |
543 } | |
544 | |
545 static int draw_tface_mapped__set_draw(void *userData, int index) | |
546 { | |
547 Mesh *me = (Mesh*)userData; | |
548 MTFace *tface = (me->mtface)? &me->mtface[index]: NULL; | |
549 MFace *mface = &me->mface[index]; | |
550 MCol *mcol = (me->mcol)? &me->mcol[index]: NULL; | |
551 const int matnr = mface->mat_nr; | |
552 if (mface->flag & ME_HIDE) return 0; | |
553 return draw_tface__set_draw(tface, mcol, matnr); | |
554 } | |
555 | |
556 static int draw_em_tf_mapped__set_draw(void *userData, int index) | |
557 { | |
558 EditMesh *em = userData; | |
559 EditFace *efa= EM_get_face_for_index(index); | |
560 MTFace *tface; | |
561 MCol *mcol; | |
562 int matnr; | |
563 | |
564 if (efa->h) | |
565 return 0; | |
566 | |
567 tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); | |
568 mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL); | |
569 matnr = efa->mat_nr; | |
570 | |
571 return draw_tface__set_draw_legacy(tface, mcol, matnr); | |
572 } | |
573 | |
574 static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot
h_r) | |
575 { | |
576 Mesh *me = (Mesh*)userData; | |
577 Material *ma; | |
578 | |
579 if (me->mface) { | |
580 int matnr = me->mface[index].mat_nr; | |
581 ma = me->mat[matnr]; | |
582 } | |
583 | |
584 if ( ma && (ma->game.flag & GEMAT_INVISIBLE)) { | |
585 return 0; | |
586 } | |
587 | |
588 *drawSmooth_r = 1; | |
589 return 1; | |
590 } | |
591 | |
592 static void draw_mesh_text(Scene *scene, Object *ob, int glsl) | |
593 { | |
594 Mesh *me = ob->data; | |
595 DerivedMesh *ddm; | |
596 MFace *mf, *mface= me->mface; | |
597 MTFace *tface= me->mtface; | |
598 MCol *mcol= me->mcol; /* why does mcol exist? */ | |
599 bProperty *prop = get_ob_property(ob, "Text"); | |
600 GPUVertexAttribs gattribs; | |
601 int a, totface= me->totface; | |
602 | |
603 /* don't draw without tfaces */ | |
604 if(!tface) | |
605 return; | |
606 | |
607 /* don't draw when editing */ | |
608 if(ob->mode & OB_MODE_EDIT) | |
609 return; | |
610 else if(ob==OBACT) | |
611 if(paint_facesel_test(ob)) | |
612 return; | |
613 | |
614 ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); | |
615 | |
616 for(a=0, mf=mface; a<totface; a++, tface++, mf++) { | |
617 int matnr= mf->mat_nr; | |
618 int mf_smooth= mf->flag & ME_SMOOTH; | |
619 Material *mat = me->mat[matnr]; | |
620 int mode= mat->game.flag; | |
621 | |
622 if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) { | |
623 float v1[3], v2[3], v3[3], v4[3]; | |
624 char string[MAX_PROPSTRING]; | |
625 int characters, i, glattrib= -1, badtex= 0; | |
626 | |
627 if(glsl) { | |
628 GPU_enable_material(matnr+1, &gattribs); | |
629 | |
630 for(i=0; i<gattribs.totlayer; i++) { | |
631 if(gattribs.layer[i].type == CD_MTFACE)
{ | |
632 glattrib = gattribs.layer[i].gli
ndex; | |
633 break; | |
634 } | |
635 } | |
636 } | |
637 else { | |
638 badtex = set_draw_settings_cached(0, tface, mat,
Gtexdraw); | |
639 if (badtex) { | |
640 if (mcol) mcol+=4; | |
641 continue; | |
642 } | |
643 } | |
644 | |
645 ddm->getVertCo(ddm, mf->v1, v1); | |
646 ddm->getVertCo(ddm, mf->v2, v2); | |
647 ddm->getVertCo(ddm, mf->v3, v3); | |
648 if (mf->v4) ddm->getVertCo(ddm, mf->v4, v4); | |
649 | |
650 // The BM_FONT handling is in the gpu module, shared wit
h the | |
651 // game engine, was duplicated previously | |
652 | |
653 set_property_valstr(prop, string); | |
654 characters = strlen(string); | |
655 ························ | |
656 if(!BKE_image_get_ibuf(tface->tpage, NULL)) | |
657 characters = 0; | |
658 | |
659 if (!mf_smooth) { | |
660 float nor[3]; | |
661 | |
662 normal_tri_v3( nor,v1, v2, v3); | |
663 | |
664 glNormal3fv(nor); | |
665 } | |
666 | |
667 GPU_render_text(tface, mode, string, characters, | |
668 (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NU
LL), glattrib); | |
669 } | |
670 if (mcol) { | |
671 mcol+=4; | |
672 } | |
673 } | |
674 | |
675 ddm->release(ddm); | |
676 } | |
677 | |
678 void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *o
b, DerivedMesh *dm, int faceselect) | |
679 { | |
680 Mesh *me= ob->data; | |
681 ········ | |
682 /* correct for negative scale */ | |
683 if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW); | |
684 else glFrontFace(GL_CCW); | |
685 ········ | |
686 /* draw the textured mesh */ | |
687 draw_textured_begin(scene, v3d, rv3d, ob); | |
688 | |
689 glColor4f(1.0f,1.0f,1.0f,1.0f); | |
690 | |
691 if(ob->mode & OB_MODE_EDIT) { | |
692 dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, me->edit
_mesh); | |
693 } else if(faceselect) { | |
694 if(ob->mode & OB_MODE_WEIGHT_PAINT) | |
695 dm->drawMappedFaces(dm, wpaint__setSolidDrawOptions, me,
1, GPU_enable_material); | |
696 else | |
697 dm->drawMappedFacesTex(dm, me->mface ? draw_tface_mapped
__set_draw : NULL, me); | |
698 } | |
699 else { | |
700 if( GPU_buffer_legacy(dm) ) | |
701 dm->drawFacesTex(dm, draw_tface__set_draw_legacy); | |
702 else { | |
703 if( !CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL)
) | |
704 add_tface_color_layer(dm); | |
705 dm->drawFacesTex(dm, draw_tface__set_draw); | |
706 } | |
707 } | |
708 | |
709 /* draw game engine text hack */ | |
710 if(get_ob_property(ob, "Text"))· | |
711 draw_mesh_text(scene, ob, 0); | |
712 | |
713 draw_textured_end(); | |
714 ········ | |
715 /* draw edges and selected faces over textured mesh */ | |
716 if(!(ob == scene->obedit) && faceselect) | |
717 draw_tfaces3D(rv3d, me, dm, ob->mode & OB_MODE_WEIGHT_PAINT); | |
718 | |
719 /* reset from negative scale correction */ | |
720 glFrontFace(GL_CCW); | |
721 ········ | |
722 /* in editmode, the blend mode needs to be set incase it was ADD */ | |
723 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
724 } | |
LEFT | RIGHT |