LEFT | RIGHT |
1 /* | 1 /* |
2 * ***** BEGIN GPL LICENSE BLOCK ***** | 2 * ***** BEGIN GPL LICENSE BLOCK ***** |
3 * | 3 * |
4 * This program is free software; you can redistribute it and/or | 4 * This program is free software; you can redistribute it and/or |
5 * modify it under the terms of the GNU General Public License | 5 * modify it under the terms of the GNU General Public License |
6 * as published by the Free Software Foundation; either version 2 | 6 * as published by the Free Software Foundation; either version 2 |
7 * of the License, or (at your option) any later version. | 7 * of the License, or (at your option) any later version. |
8 * | 8 * |
9 * 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, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 #include "BKE_global.h" | 54 #include "BKE_global.h" |
55 #include "BKE_image.h" | 55 #include "BKE_image.h" |
56 #include "BKE_material.h" | 56 #include "BKE_material.h" |
57 #include "BKE_paint.h" | 57 #include "BKE_paint.h" |
58 #include "BKE_property.h" | 58 #include "BKE_property.h" |
59 #include "BKE_editmesh.h" | 59 #include "BKE_editmesh.h" |
60 #include "BKE_scene.h" | 60 #include "BKE_scene.h" |
61 | 61 |
62 #include "BIF_gl.h" | 62 #include "BIF_gl.h" |
63 #include "BIF_glutil.h" | 63 #include "BIF_glutil.h" |
64 | |
65 #include "UI_resources.h" | |
66 | |
67 #include "GPU_buffers.h" | 64 #include "GPU_buffers.h" |
68 #include "GPU_extensions.h" | 65 #include "GPU_extensions.h" |
69 #include "GPU_draw.h" | 66 #include "GPU_draw.h" |
70 #include "GPU_material.h" | |
71 | 67 |
72 #include "ED_mesh.h" | 68 #include "ED_mesh.h" |
73 #include "ED_uvedit.h" | |
74 | 69 |
75 #include "view3d_intern.h" /* own include */ | |
76 | |
77 /* user data structures for derived mesh callbacks */ | |
78 typedef struct drawMeshFaceSelect_userData { | |
79 Mesh *me; | |
80 BLI_bitmap *edge_flags; /* pairs of edge options (visible, select) */ | |
81 } drawMeshFaceSelect_userData; | |
82 | |
83 typedef struct drawEMTFMapped_userData { | |
84 BMEditMesh *em; | |
85 short has_mcol; | |
86 short has_mtface; | |
87 MFace *mf; | |
88 MTFace *tf; | |
89 } drawEMTFMapped_userData; | |
90 | |
91 typedef struct drawTFace_userData { | |
92 Mesh *me; | |
93 MFace *mf; | |
94 MTFace *tf; | |
95 } drawTFace_userData; | |
96 | |
97 /**************************** Face Select Mode *******************************/ | |
98 | |
99 /* mainly to be less confusing */ | |
100 BLI_INLINE int edge_vis_index(const int index) { return index * 2; } | |
101 BLI_INLINE int edge_sel_index(const int index) { return index * 2 + 1; } | |
102 | |
103 static BLI_bitmap *get_tface_mesh_marked_edge_info(Mesh *me) | |
104 { | |
105 BLI_bitmap *bitmap_edge_flags = BLI_BITMAP_NEW(me->totedge * 2, __func__
); | |
106 MPoly *mp; | |
107 MLoop *ml; | |
108 int i, j; | |
109 bool select_set; | |
110 ········ | |
111 for (i = 0; i < me->totpoly; i++) { | |
112 mp = &me->mpoly[i]; | |
113 | |
114 if (!(mp->flag & ME_HIDE)) { | |
115 select_set = (mp->flag & ME_FACE_SEL) != 0; | |
116 | |
117 ml = me->mloop + mp->loopstart; | |
118 for (j = 0; j < mp->totloop; j++, ml++) { | |
119 BLI_BITMAP_SET(bitmap_edge_flags, edge_vis_index
(ml->e)); | |
120 if (select_set) BLI_BITMAP_SET(bitmap_edge_flags
, edge_sel_index(ml->e)); | |
121 } | |
122 } | |
123 } | |
124 | |
125 return bitmap_edge_flags; | |
126 } | |
127 | |
128 | |
129 static DMDrawOption draw_mesh_face_select__setHiddenOpts(void *userData, int ind
ex) | |
130 { | |
131 drawMeshFaceSelect_userData *data = userData; | |
132 Mesh *me = data->me; | |
133 | |
134 if (me->drawflag & ME_DRAWEDGES) { | |
135 if ((me->drawflag & ME_HIDDENEDGES) || (BLI_BITMAP_GET(data->edg
e_flags, edge_vis_index(index)))) | |
136 return DM_DRAW_OPTION_NORMAL; | |
137 else | |
138 return DM_DRAW_OPTION_SKIP; | |
139 } | |
140 else if (BLI_BITMAP_GET(data->edge_flags, edge_sel_index(index))) | |
141 return DM_DRAW_OPTION_NORMAL; | |
142 else | |
143 return DM_DRAW_OPTION_SKIP; | |
144 } | |
145 | |
146 static DMDrawOption draw_mesh_face_select__setSelectOpts(void *userData, int ind
ex) | |
147 { | |
148 drawMeshFaceSelect_userData *data = userData; | |
149 return (BLI_BITMAP_GET(data->edge_flags, edge_sel_index(index))) ? DM_DR
AW_OPTION_NORMAL : DM_DRAW_OPTION_SKIP; | |
150 } | |
151 | |
152 /* draws unselected */ | |
153 static DMDrawOption draw_mesh_face_select__drawFaceOptsInv(void *userData, int i
ndex) | |
154 { | |
155 Mesh *me = (Mesh *)userData; | |
156 | |
157 MPoly *mpoly = &me->mpoly[index]; | |
158 if (!(mpoly->flag & ME_HIDE) && !(mpoly->flag & ME_FACE_SEL)) | |
159 return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */ | |
160 else | |
161 return DM_DRAW_OPTION_SKIP; | |
162 } | |
163 | |
164 void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) | |
165 { | |
166 drawMeshFaceSelect_userData data; | |
167 | |
168 data.me = me; | |
169 data.edge_flags = get_tface_mesh_marked_edge_info(me); | |
170 | |
171 glEnable(GL_DEPTH_TEST); | |
172 glDisable(GL_LIGHTING); | |
173 bglPolygonOffset(rv3d->dist, 1.0); | |
174 | |
175 /* Draw (Hidden) Edges */ | |
176 setlinestyle(1); | |
177 UI_ThemeColor(TH_EDGE_FACESEL); | |
178 dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data); | |
179 setlinestyle(0); | |
180 | |
181 /* Draw Selected Faces */ | |
182 if (me->drawflag & ME_DRAWFACES) { | |
183 glEnable(GL_BLEND); | |
184 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
185 /* dull unselected faces so as not to get in the way of seeing c
olor */ | |
186 glColor4ub(96, 96, 96, 64); | |
187 dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv,
NULL, NULL, (void *)me, 0); | |
188 glDisable(GL_BLEND); | |
189 } | |
190 ········ | |
191 bglPolygonOffset(rv3d->dist, 1.0); | |
192 | |
193 /* Draw Stippled Outline for selected faces */ | |
194 glColor3ub(255, 255, 255); | |
195 setlinestyle(1); | |
196 dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); | |
197 setlinestyle(0); | |
198 | |
199 bglPolygonOffset(rv3d->dist, 0.0); /* resets correctly now, even after
calling accumulated offsets */ | |
200 | |
201 MEM_freeN(data.edge_flags); | |
202 } | |
203 | |
204 /***************************** Texture Drawing ******************************/ | |
205 | |
206 static Material *give_current_material_or_def(Object *ob, int matnr) | |
207 { | |
208 extern Material defmaterial; /* render module abuse... */ | |
209 Material *ma = give_current_material(ob, matnr); | |
210 | |
211 return ma ? ma : &defmaterial; | |
212 } | |
213 | |
214 /* Icky globals, fix with userdata parameter */ | |
215 | |
216 static struct TextureDrawState { | |
217 Object *ob; | |
218 int is_lit, is_tex; | |
219 int color_profile; | |
220 bool use_backface_culling; | |
221 unsigned char obcol[4]; | |
222 } Gtexdraw = {NULL, 0, 0, 0, false, {0, 0, 0, 0}}; | |
223 | |
224 static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
ma, struct TextureDrawState gtexdraw) | |
225 { | |
226 static Material *c_ma; | |
227 static int c_textured; | |
228 static MTFace c_texface; | |
229 static int c_backculled; | |
230 static bool c_badtex; | |
231 static int c_lit; | |
232 static int c_has_texface; | |
233 | |
234 Object *litob = NULL; /* to get mode to turn off mipmap in painting mod
e */ | |
235 int backculled = 1; | |
236 int alphablend = 0; | |
237 int textured = 0; | |
238 int lit = 0; | |
239 int has_texface = texface != NULL; | |
240 bool need_set_tpage = false; | |
241 | |
242 if (clearcache) { | |
243 c_textured = c_lit = c_backculled = -1; | |
244 memset(&c_texface, 0, sizeof(MTFace)); | |
245 c_badtex = false; | |
246 c_has_texface = -1; | |
247 } | |
248 else { | |
249 textured = gtexdraw.is_tex; | |
250 litob = gtexdraw.ob; | |
251 } | |
252 | |
253 /* convert number of lights into boolean */ | |
254 if (gtexdraw.is_lit) lit = 1; | |
255 | |
256 if (ma) { | |
257 alphablend = ma->game.alpha_blend; | |
258 if (ma->mode & MA_SHLESS) lit = 0; | |
259 backculled = (ma->game.flag & GEMAT_BACKCULL) || gtexdraw.use_ba
ckface_culling; | |
260 } | |
261 | |
262 if (texface) { | |
263 textured = textured && (texface->tpage); | |
264 | |
265 /* no material, render alpha if texture has depth=32 */ | |
266 if (!ma && BKE_image_has_alpha(texface->tpage)) | |
267 alphablend = GPU_BLEND_ALPHA; | |
268 } | |
269 | |
270 else | |
271 return ma?ma:&defmaterial; | |
272 } | |
273 | |
274 static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac
e, int lit, Object *litob, int litmatnr, int doublesided) | |
275 { | |
276 static int c_textured; | |
277 static int c_lit; | |
278 static int c_doublesided; | |
279 static MTFace *c_texface; | |
280 static Object *c_litob; | |
281 static int c_litmatnr; | |
282 static int c_badtex; | |
283 | |
284 if (clearcache) { | |
285 c_textured= c_lit= c_doublesided= -1; | |
286 c_texface= (MTFace*) -1; | |
287 c_litob= (Object*) -1; | |
288 c_litmatnr= -1; | |
289 c_badtex= 0; | |
290 } | |
291 | |
292 if (texface) { | |
293 lit = lit && (lit==-1 || texface->mode&TF_LIGHT); | |
294 textured = textured && (texface->mode&TF_TEX); | |
295 doublesided = texface->mode&TF_TWOSIDE; | |
296 } else { | |
297 textured = 0; | |
298 } | |
299 | |
300 if (doublesided!=c_doublesided) { | |
301 if (doublesided) glDisable(GL_CULL_FACE); | |
302 else glEnable(GL_CULL_FACE); | |
LEFT | RIGHT |