void draw_mesh_paint_weight_edges(RegionView3D *rv3d, DerivedMesh *dm, const bool use_depth, void *edgemask_cb, void *user_data) { /* weight paint in solid mode, special case. focus on making the weights clear * rather than the shading, this is also forced in wire view */ if (use_depth) { bglPolygonOffset(rv3d->dist, 1.0); glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ } else { glDisable(GL_DEPTH_TEST); } glEnable(GL_BLEND); glColor4ub(255, 255, 255, 96); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xAAAA); dm->drawMappedEdges(dm, (DMSetDrawOptions)edgemask_cb, user_data); if (use_depth) { bglPolygonOffset(rv3d->dist, 0.0); glDepthMask(1); } else { glEnable(GL_DEPTH_TEST); } glDisable(GL_LINE_STIPPLE); glDisable(GL_BLEND); }
void draw_mesh_face_select(RegionView3D *rv3d, Mesh *me, DerivedMesh *dm) { drawMeshFaceSelect_userData data; data.me = me; data.edge_flags = get_tface_mesh_marked_edge_info(me); glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); bglPolygonOffset(rv3d->dist, 1.0); /* Draw (Hidden) Edges */ setlinestyle(1); UI_ThemeColor(TH_EDGE_FACESEL); dm->drawMappedEdges(dm, draw_mesh_face_select__setHiddenOpts, &data); setlinestyle(0); /* Draw Selected Faces */ if (me->drawflag & ME_DRAWFACES) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* dull unselected faces so as not to get in the way of seeing color */ glColor4ub(96, 96, 96, 64); dm->drawMappedFaces(dm, draw_mesh_face_select__drawFaceOptsInv, NULL, NULL, (void *)me, 0); glDisable(GL_BLEND); } bglPolygonOffset(rv3d->dist, 1.0); /* Draw Stippled Outline for selected faces */ glColor3ub(255, 255, 255); setlinestyle(1); dm->drawMappedEdges(dm, draw_mesh_face_select__setSelectOpts, &data); setlinestyle(0); bglPolygonOffset(rv3d->dist, 0.0); /* resets correctly now, even after calling accumulated offsets */ MEM_freeN(data.edge_flags); }
/** * Use instead of: ``bglPolygonOffset(rv3d->dist, ...)`` see bug [#37727] */ void ED_view3d_polygon_offset(const RegionView3D *rv3d, const float dist) { float viewdist = rv3d->dist; /* special exception for ortho camera (viewdist isnt used for perspective cameras) */ if (dist != 0.0f) { if (rv3d->persp == RV3D_CAMOB) { if (rv3d->is_persp == false) { viewdist = 1.0f / max_ff(fabsf(rv3d->winmat[0][0]), fabsf(rv3d->winmat[1][1])); } } } bglPolygonOffset(viewdist, dist); }
/* Draw selected verts for strokes being edited */ static void gp_draw_strokes_edit(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, short dflag, const float tcolor[3]) { bGPDstroke *gps; const bool no_xray = (dflag & GP_DRAWDATA_NO_XRAY) != 0; int mask_orig = 0; /* set up depth masks... */ if (dflag & GP_DRAWDATA_ONLY3D) { if (no_xray) { glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); glDepthMask(0); glEnable(GL_DEPTH_TEST); /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(-1.0f, -1.0f); #endif } } /* draw stroke verts */ for (gps = gpf->strokes.first; gps; gps = gps->next) { bGPDspoint *pt; float vsize, bsize; int i; /* check if stroke can be drawn */ if (gp_can_draw_stroke(gps, dflag) == false) continue; /* Optimisation: only draw points for selected strokes * We assume that selected points can only occur in * strokes that are selected too. */ if ((gps->flag & GP_STROKE_SELECT) == 0) continue; /* Get size of verts: * - The selected state needs to be larger than the unselected state so that * they stand out more. * - We use the theme setting for size of the unselected verts */ bsize = UI_GetThemeValuef(TH_GP_VERTEX_SIZE); if ((int)bsize > 8) { vsize = 10.0f; bsize = 8.0f; } else { vsize = bsize + 2; } /* First Pass: Draw all the verts (i.e. these become the unselected state) */ if (tcolor != NULL) { /* for now, we assume that the base color of the points is not too close to the real color */ glColor3fv(tcolor); } else { /* this doesn't work well with the default theme and black strokes... */ UI_ThemeColor(TH_GP_VERTEX); } glPointSize(bsize); glBegin(GL_POINTS); for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { if (gps->flag & GP_STROKE_3DSPACE) { glVertex3fv(&pt->x); } else { float co[2]; gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); glVertex2fv(co); } } glEnd(); /* Second Pass: Draw only verts which are selected */ UI_ThemeColor(TH_GP_VERTEX_SELECT); glPointSize(vsize); glBegin(GL_POINTS); for (i = 0, pt = gps->points; i < gps->totpoints && pt; i++, pt++) { if (pt->flag & GP_SPOINT_SELECT) { if (gps->flag & GP_STROKE_3DSPACE) { glVertex3fv(&pt->x); } else { float co[2]; gp_calc_2d_stroke_xy(pt, gps->flag, offsx, offsy, winx, winy, co); glVertex2fv(co); } } } glEnd(); } /* clear depth mask */ if (dflag & GP_DRAWDATA_ONLY3D) { if (no_xray) { glDepthMask(mask_orig); glDisable(GL_DEPTH_TEST); bglPolygonOffset(0.0, 0.0); #if 0 glDisable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(0, 0); #endif } } }
/* draw a set of strokes */ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, bool debug, short lthick, const float color[4], const float fill_color[4]) { bGPDstroke *gps; for (gps = gpf->strokes.first; gps; gps = gps->next) { /* check if stroke can be drawn */ if (gp_can_draw_stroke(gps, dflag) == false) continue; /* check which stroke-drawer to use */ if (dflag & GP_DRAWDATA_ONLY3D) { const int no_xray = (dflag & GP_DRAWDATA_NO_XRAY); int mask_orig = 0; if (no_xray) { glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); glDepthMask(0); glEnable(GL_DEPTH_TEST); /* first arg is normally rv3d->dist, but this isn't * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(-1.0f, -1.0f); #endif } /* 3D Fill */ if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { glColor4fv(fill_color); gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } /* 3D Stroke */ glColor4fv(color); if (dflag & GP_DRAWDATA_VOLUMETRIC) { /* volumetric stroke drawing */ gp_draw_stroke_volumetric_3d(gps->points, gps->totpoints, lthick, dflag, gps->flag); } else { /* 3D Lines - OpenGL primitives-based */ if (gps->totpoints == 1) { gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } else { gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug, gps->flag); } } if (no_xray) { glDepthMask(mask_orig); glDisable(GL_DEPTH_TEST); bglPolygonOffset(0.0, 0.0); #if 0 glDisable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(0, 0); #endif } } else { /* 2D - Fill */ if ((dflag & GP_DRAWDATA_FILL) && (gps->totpoints >= 3)) { glColor4fv(fill_color); gp_draw_stroke_fill(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } /* 2D Strokes... */ glColor4fv(color); if (dflag & GP_DRAWDATA_VOLUMETRIC) { /* blob/disk-based "volumetric" drawing */ gp_draw_stroke_volumetric_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } else { /* normal 2D strokes */ if (gps->totpoints == 1) { gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); } else { gp_draw_stroke_2d(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy); } } } } }
/* draw a set of strokes */ static void gp_draw_strokes (bGPDframe *gpf, int offsx, int offsy, int winx, int winy, int dflag, short debug, short lthick, float color[4]) { bGPDstroke *gps; /* set color first (may need to reset it again later too) */ glColor4fv(color); for (gps= gpf->strokes.first; gps; gps= gps->next) { /* check if stroke can be drawn - checks here generally fall into pairs */ if ((dflag & GP_DRAWDATA_ONLY3D) && !(gps->flag & GP_STROKE_3DSPACE)) continue; if (!(dflag & GP_DRAWDATA_ONLY3D) && (gps->flag & GP_STROKE_3DSPACE)) continue; if ((dflag & GP_DRAWDATA_ONLYV2D) && !(gps->flag & GP_STROKE_2DSPACE)) continue; if (!(dflag & GP_DRAWDATA_ONLYV2D) && (gps->flag & GP_STROKE_2DSPACE)) continue; if ((dflag & GP_DRAWDATA_ONLYI2D) && !(gps->flag & GP_STROKE_2DIMAGE)) continue; if (!(dflag & GP_DRAWDATA_ONLYI2D) && (gps->flag & GP_STROKE_2DIMAGE)) continue; if ((gps->points == NULL) || (gps->totpoints < 1)) continue; /* check which stroke-drawer to use */ if (gps->totpoints == 1) gp_draw_stroke_point(gps->points, lthick, dflag, gps->flag, offsx, offsy, winx, winy); else if (dflag & GP_DRAWDATA_ONLY3D) { const int no_xray= (dflag & GP_DRAWDATA_NO_XRAY); int mask_orig = 0; if (no_xray) { glGetIntegerv(GL_DEPTH_WRITEMASK, &mask_orig); glDepthMask(0); glEnable(GL_DEPTH_TEST); /* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(-1.0f, -1.0f); #endif } gp_draw_stroke_3d(gps->points, gps->totpoints, lthick, debug); if (no_xray) { glDepthMask(mask_orig); glDisable(GL_DEPTH_TEST); bglPolygonOffset(0.0, 0.0); #if 0 glDisable(GL_POLYGON_OFFSET_LINE); glPolygonOffset(0, 0); #endif } } else if (gps->totpoints > 1) gp_draw_stroke(gps->points, gps->totpoints, lthick, dflag, gps->flag, debug, offsx, offsy, winx, winy); } }
void draw_mesh_paint(View3D *v3d, RegionView3D *rv3d, Object *ob, DerivedMesh *dm, const int draw_flags) { DMSetDrawOptions facemask = NULL; Mesh *me = ob->data; const bool do_light = (v3d->drawtype >= OB_SOLID); /* hide faces in face select mode */ if (me->editflag & (ME_EDIT_PAINT_VERT_SEL | ME_EDIT_PAINT_FACE_SEL)) facemask = wpaint__setSolidDrawOptions_facemask; if (ob->mode & OB_MODE_WEIGHT_PAINT) { if (do_light) { const float spec[4] = {0.47f, 0.47f, 0.47f, 0.47f}; /* enforce default material settings */ GPU_enable_material(0, NULL); /* but set default spec */ glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spec); /* diffuse */ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_LIGHTING); glEnable(GL_COLOR_MATERIAL); } dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me, DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH); if (do_light) { glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); GPU_disable_material(); } } else if (ob->mode & OB_MODE_VERTEX_PAINT) { if (me->mloopcol) { dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me, DM_DRAW_USE_COLORS | DM_DRAW_ALWAYS_SMOOTH); } else { glColor3f(1.0f, 1.0f, 1.0f); dm->drawMappedFaces(dm, facemask, GPU_enable_material, NULL, me, DM_DRAW_ALWAYS_SMOOTH); } } /* draw face selection on top */ if (draw_flags & DRAW_FACE_SELECT) { draw_mesh_face_select(rv3d, me, dm); } else if ((do_light == false) || (ob->dtx & OB_DRAWWIRE)) { const int use_depth = (v3d->flag & V3D_ZBUF_SELECT) || !(ob->mode & OB_MODE_WEIGHT_PAINT); /* weight paint in solid mode, special case. focus on making the weights clear * rather than the shading, this is also forced in wire view */ if (use_depth) { bglPolygonOffset(rv3d->dist, 1.0); glDepthMask(0); /* disable write in zbuffer, selected edge wires show better */ } else { glDisable(GL_DEPTH_TEST); } glEnable(GL_BLEND); glColor4ub(255, 255, 255, 96); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0xAAAA); dm->drawEdges(dm, 1, 1); if (use_depth) { bglPolygonOffset(rv3d->dist, 0.0); glDepthMask(1); } else { glEnable(GL_DEPTH_TEST); } glDisable(GL_LINE_STIPPLE); glDisable(GL_BLEND); } }