diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 579 |
1 files changed, 309 insertions, 270 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 0dc505e0146..4d591645679 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1,4 +1,4 @@ -/** +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -45,6 +45,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_rand.h" +#include "BLI_utildefines.h" #include "BKE_anim.h" #include "BKE_context.h" @@ -55,10 +56,7 @@ #include "BKE_global.h" #include "BKE_paint.h" #include "BKE_scene.h" -#include "BKE_screen.h" -#include "BKE_tessmesh.h" #include "BKE_unit.h" -#include "BKE_utildefines.h" #include "RE_pipeline.h" // make_stars @@ -246,15 +244,13 @@ static void drawgrid_draw(ARegion *ar, float wx, float wy, float x, float y, flo #define GRID_MIN_PX 6.0f -static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_unit) +static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit) { /* extern short bgpicmode; */ RegionView3D *rv3d= ar->regiondata; float wx, wy, x, y, fw, fx, fy, dx; float vec4[4]; - char col[3], col2[3]; - - *grid_unit= NULL; + unsigned char col[3], col2[3]; vec4[0]=vec4[1]=vec4[2]=0.0; vec4[3]= 1.0; @@ -269,7 +265,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u x= (wx)*fx/fw; y= (wy)*fy/fw; - vec4[0]=vec4[1]= (unit->system) ? 1.0 : v3d->grid; + vec4[0]=vec4[1]= v3d->grid; vec4[2]= 0.0; vec4[3]= 1.0; @@ -309,7 +305,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u /* Store the smallest drawn grid size units name so users know how big each grid cell is */ if(*grid_unit==NULL) { *grid_unit= bUnit_GetNameDisplay(usys, i); - rv3d->gridview= (scalar * unit->scale_length); + rv3d->gridview= (scalar * v3d->grid) / unit->scale_length; } blend_fac= 1-((GRID_MIN_PX*2)/dx_scalar); @@ -402,17 +398,19 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u setlinestyle(0); /* center cross */ + /* horizontal line */ if( ELEM(rv3d->view, RV3D_VIEW_RIGHT, RV3D_VIEW_LEFT)) - UI_make_axis_color(col, col2, 'y'); - else UI_make_axis_color(col, col2, 'x'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + else UI_make_axis_color(col, col2, 'X'); + glColor3ubv(col2); fdrawline(0.0, y, (float)ar->winx, y); + /* vertical line */ if( ELEM(rv3d->view, RV3D_VIEW_TOP, RV3D_VIEW_BOTTOM)) - UI_make_axis_color(col, col2, 'y'); - else UI_make_axis_color(col, col2, 'z'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + else UI_make_axis_color(col, col2, 'Z'); + glColor3ubv(col2); fdrawline(x, 0.0, x, (float)ar->winy); @@ -420,22 +418,39 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, char **grid_u } #undef GRID_MIN_PX -static void drawfloor(Scene *scene, View3D *v3d) +static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) { - float vert[3], grid; + float vert[3], grid, grid_scale; int a, gridlines, emphasise; - char col[3], col2[3]; + unsigned char col[3], col2[3]; short draw_line = 0; vert[2]= 0.0; if(v3d->gridlines<3) return; + grid_scale= v3d->grid; + /* use 'grid_scale' instead of 'v3d->grid' from now on */ + + /* apply units */ + if(scene->unit.system) { + void *usys; + int len; + + bUnit_GetSystem(&usys, &len, scene->unit.system, B_UNIT_LENGTH); + + if(usys) { + int i= bUnit_GetBaseUnit(usys); + *grid_unit= bUnit_GetNameDisplay(usys, i); + grid_scale = (grid_scale * bUnit_GetScaler(usys, i)) / scene->unit.scale_length; + } + } + if(v3d->zbuf && scene->obedit) glDepthMask(0); // for zbuffer-select gridlines= v3d->gridlines/2; - grid= gridlines*v3d->grid; - + grid= gridlines * grid_scale; + UI_GetThemeColor3ubv(TH_GRID, col); UI_GetThemeColor3ubv(TH_BACK, col2); @@ -450,8 +465,8 @@ static void drawfloor(Scene *scene, View3D *v3d) if(a==0) { /* check for the 'show Y axis' preference */ if (v3d->gridflag & V3D_SHOW_Y) { - UI_make_axis_color(col, col2, 'y'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Y'); + glColor3ubv(col2); draw_line = 1; } else if (v3d->gridflag & V3D_SHOW_FLOOR) { @@ -475,7 +490,7 @@ static void drawfloor(Scene *scene, View3D *v3d) if (draw_line) { glBegin(GL_LINE_STRIP); - vert[0]= a*v3d->grid; + vert[0]= a * grid_scale; vert[1]= grid; glVertex3fv(vert); vert[1]= -grid; @@ -489,8 +504,8 @@ static void drawfloor(Scene *scene, View3D *v3d) if(a==0) { /* check for the 'show X axis' preference */ if (v3d->gridflag & V3D_SHOW_X) { - UI_make_axis_color(col, col2, 'x'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'X'); + glColor3ubv(col2); draw_line = 1; } else if (v3d->gridflag & V3D_SHOW_FLOOR) { @@ -514,7 +529,7 @@ static void drawfloor(Scene *scene, View3D *v3d) if (draw_line) { glBegin(GL_LINE_STRIP); - vert[1]= a*v3d->grid; + vert[1]= a * grid_scale; vert[0]= grid; glVertex3fv(vert ); vert[0]= -grid; @@ -526,8 +541,8 @@ static void drawfloor(Scene *scene, View3D *v3d) /* draw the Z axis line */ /* check for the 'show Z axis' preference */ if (v3d->gridflag & V3D_SHOW_Z) { - UI_make_axis_color(col, col2, 'z'); - glColor3ubv((GLubyte *)col2); + UI_make_axis_color(col, col2, 'Z'); + glColor3ubv(col2); glBegin(GL_LINE_STRIP); vert[0]= 0; @@ -574,94 +589,85 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) } } -/* Draw a live substitute of the view icon, which is always shown */ +/* Draw a live substitute of the view icon, which is always shown + * colors copied from transform_manipulator.c, we should keep these matching. */ static void draw_view_axis(RegionView3D *rv3d) { const float k = U.rvisize; /* axis size */ const float toll = 0.5; /* used to see when view is quasi-orthogonal */ const float start = k + 1.0; /* axis center in screen coordinates, x=y */ float ydisp = 0.0; /* vertical displacement to allow obj info text */ - - /* rvibright ranges approx. from original axis icon color to gizmo color */ - float bright = U.rvibright / 15.0f; - - unsigned char col[3]; - unsigned char gridcol[3]; - float colf[3]; - - float vec[4]; + int bright = 25*(float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ + + float vec[3]; float dx, dy; - float h, s, v; /* thickness of lines is proportional to k */ - /* (log(k)-1) gives a more suitable thickness, but fps decreased by about 3 fps */ - glLineWidth(k / 10); - //glLineWidth(log(k)-1); // a bit slow - - UI_GetThemeColor3ubv(TH_GRID, (char *)gridcol); - + glLineWidth(2); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + /* X */ - vec[0] = vec[3] = 1; + vec[0] = 1; vec[1] = vec[2] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'x'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.3; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(220, 0, 0, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1); } + /* BLF_draw_default disables blending */ + glEnable(GL_BLEND); + /* Y */ - vec[1] = vec[3] = 1; + vec[1] = 1; vec[0] = vec[2] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'y'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.3; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(0, 220, 0, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1); } + + glEnable(GL_BLEND); /* Z */ - vec[2] = vec[3] = 1; + vec[2] = 1; vec[1] = vec[0] = 0; mul_qt_v3(rv3d->viewquat, vec); - - UI_make_axis_color((char *)gridcol, (char *)col, 'z'); - rgb_to_hsv(col[0]/255.0f, col[1]/255.0f, col[2]/255.0f, &h, &s, &v); - s = s<0.5 ? s+0.5 : 1.0; - v = 0.5; - v = (v<1.0-(bright) ? v+bright : 1.0); - hsv_to_rgb(h, s, v, colf, colf+1, colf+2); - glColor3fv(colf); - dx = vec[0] * k; dy = vec[1] * k; - fdrawline(start, start + ydisp, start + dx, start + dy + ydisp); + + glColor4ub(30, 30, 220, bright); + glBegin(GL_LINES); + glVertex2f(start, start + ydisp); + glVertex2f(start + dx, start + dy + ydisp); + glEnd(); + if (fabs(dx) > toll || fabs(dy) > toll) { - BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z"); + BLF_draw_default(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1); } - + /* restore line-width */ + glLineWidth(1.0); + glDisable(GL_BLEND); } @@ -685,9 +691,9 @@ static void draw_view_icon(RegionView3D *rv3d) glDisable(GL_BLEND); } -static char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) +static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) { - char *name = NULL; + const char *name = NULL; switch (rv3d->view) { case RV3D_VIEW_FRONT: @@ -736,24 +742,17 @@ static char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) static void draw_viewport_name(ARegion *ar, View3D *v3d) { RegionView3D *rv3d= ar->regiondata; - char *name = view3d_get_name(v3d, rv3d); - char *printable = NULL; + const char *name= view3d_get_name(v3d, rv3d); + char tmpstr[24]; if (v3d->localvd) { - printable = MEM_mallocN(strlen(name) + strlen(" (Local)_"), "viewport_name"); /* '_' gives space for '\0' */ - strcpy(printable, name); - strcat(printable, " (Local)"); - } else { - printable = name; + BLI_snprintf(tmpstr, sizeof(tmpstr), "%s (Local)", name); + name= tmpstr; } - if (printable) { + if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(22, ar->winy-17, 0.0f, printable); - } - - if (v3d->localvd) { - MEM_freeN(printable); + BLF_draw_default(22, ar->winy-17, 0.0f, name, sizeof(tmpstr)); } } @@ -828,7 +827,7 @@ static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d) sprintf(info, "(%d) %s", CFRA, ob->id.name+2); } - /* colour depends on whether there is a keyframe */ + /* color depends on whether there is a keyframe */ if (id_frame_has_keyframe((ID *)ob, /*BKE_curframe(scene)*/(float)(CFRA), v3d->keyflags)) UI_ThemeColor(TH_VERTEX_SELECT); else @@ -841,17 +840,17 @@ static void draw_selected_name(Scene *scene, Object *ob, View3D *v3d) else sprintf(info, "(%d)", CFRA); - /* colour is always white */ + /* color is always white */ UI_ThemeColor(TH_TEXT_HI); } if (U.uiflag & USER_SHOW_ROTVIEWICON) offset = 14 + (U.rvisize * 2); - BLF_draw_default(offset, 10, 0.0f, info); + BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)-1); } -static void view3d_get_viewborder_size(Scene *scene, ARegion *ar, float size_r[2]) +void view3d_viewborder_size_get(Scene *scene, ARegion *ar, float size_r[2]) { float winmax= MAX2(ar->winx, ar->winy); float aspect= (scene->r.xsch*scene->r.xasp) / (scene->r.ysch*scene->r.yasp); @@ -865,12 +864,12 @@ static void view3d_get_viewborder_size(Scene *scene, ARegion *ar, float size_r[2 } } -void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, rctf *viewborder_r) +void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, View3D *v3d, rctf *viewborder_r, short do_shift) { float zoomfac, size[2]; float dx= 0.0f, dy= 0.0f; - view3d_get_viewborder_size(scene, ar, size); + view3d_viewborder_size_get(scene, ar, size); if (rv3d == NULL) rv3d = ar->regiondata; @@ -904,12 +903,13 @@ void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, Vi viewborder_r->xmax-= dx; viewborder_r->ymax-= dy; - if(v3d->camera && v3d->camera->type==OB_CAMERA) { + if(do_shift && v3d->camera && v3d->camera->type==OB_CAMERA) { Camera *cam= v3d->camera->data; float w = viewborder_r->xmax - viewborder_r->xmin; float h = viewborder_r->ymax - viewborder_r->ymin; float side = MAX2(w, h); - + + if(do_shift == -1) side *= -1; viewborder_r->xmin+= cam->shiftx*side; viewborder_r->xmax+= cam->shiftx*side; viewborder_r->ymin+= cam->shifty*side; @@ -917,67 +917,8 @@ void view3d_calc_camera_border(Scene *scene, ARegion *ar, RegionView3D *rv3d, Vi } } -void view3d_set_1_to_1_viewborder(Scene *scene, ARegion *ar) -{ - RegionView3D *rv3d= ar->regiondata; - float size[2]; - int im_width= (scene->r.size*scene->r.xsch)/100; - - view3d_get_viewborder_size(scene, ar, size); - - rv3d->camzoom= (sqrt(4.0*im_width/size[0]) - M_SQRT2)*50.0; - rv3d->camzoom= CLAMPIS(rv3d->camzoom, -30, 300); -} - - -static void drawviewborder_flymode(ARegion *ar) -{ - /* draws 4 edge brackets that frame the safe area where the - mouse can move during fly mode without spinning the view */ - float x1, x2, y1, y2; - - x1= 0.45*(float)ar->winx; - y1= 0.45*(float)ar->winy; - x2= 0.55*(float)ar->winx; - y2= 0.55*(float)ar->winy; - cpack(0); - - - glBegin(GL_LINES); - /* bottom left */ - glVertex2f(x1,y1); - glVertex2f(x1,y1+5); - - glVertex2f(x1,y1); - glVertex2f(x1+5,y1); - - /* top right */ - glVertex2f(x2,y2); - glVertex2f(x2,y2-5); - - glVertex2f(x2,y2); - glVertex2f(x2-5,y2); - - /* top left */ - glVertex2f(x1,y2); - glVertex2f(x1,y2-5); - - glVertex2f(x1,y2); - glVertex2f(x1+5,y2); - - /* bottom right */ - glVertex2f(x2,y1); - glVertex2f(x2,y1+5); - - glVertex2f(x2,y1); - glVertex2f(x2-5,y1); - glEnd(); -} - - static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) { - extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad); // interface_panel.c float fac, a; float x1, x2, y1, y2; float x1i, x2i, y1i, y2i; @@ -991,7 +932,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if(v3d->camera->type==OB_CAMERA) ca = v3d->camera->data; - view3d_calc_camera_border(scene, ar, rv3d, v3d, &viewborder); + view3d_calc_camera_border(scene, ar, rv3d, v3d, &viewborder, FALSE); /* the offsets */ x1= viewborder.xmin; y1= viewborder.ymin; @@ -1064,7 +1005,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 0.25, 0); uiSetRoundBox(15); - gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); + uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); } setlinestyle(0); @@ -1073,7 +1014,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) /* camera name - draw in highlighted text color */ if (ca && (ca->flag & CAM_SHOWNAME)) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(x1i, y1i-15, 0.0f, v3d->camera->id.name+2); + BLF_draw_default(x1i, y1i-15, 0.0f, v3d->camera->id.name+2, sizeof(v3d->camera->id.name)-2); UI_ThemeColor(TH_WIRE); } } @@ -1190,7 +1131,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, if(ymax >= vc->ar->winy) ymaxc= vc->ar->winy-1; else ymaxc= ymax; if(yminc > ymaxc) return NULL; - ibuf= IMB_allocImBuf((xmaxc-xminc+1), (ymaxc-yminc+1), 32, IB_rect,0); + ibuf= IMB_allocImBuf((xmaxc-xminc+1), (ymaxc-yminc+1), 32, IB_rect); view3d_validate_backbuf(vc); @@ -1210,7 +1151,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, if(xminc==xmin && xmaxc==xmax && yminc==ymin && ymaxc==ymax) return ibuf; - ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect,0); + ibuf1= IMB_allocImBuf( (xmax-xmin+1),(ymax-ymin+1),32,IB_rect); rd= ibuf->rect; dr= ibuf1->rect; @@ -1328,7 +1269,7 @@ static void draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d) if(rv3d->persp==RV3D_CAMOB) { rctf vb; - view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb); + view3d_calc_camera_border(scene, ar, rv3d, v3d, &vb, FALSE); x1= vb.xmin; y1= vb.ymin; @@ -1458,26 +1399,26 @@ static void view3d_draw_transp(Scene *scene, ARegion *ar, View3D *v3d) static void view3d_draw_xray(Scene *scene, ARegion *ar, View3D *v3d, int clear) { View3DAfter *v3da, *next; - + if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); - - v3d->xray= TRUE; + + v3d->xray= TRUE; for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { - next= v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + next= v3da->next; + draw_object(scene, ar, v3d, v3da->base, v3da->flag); BLI_remlink(&v3d->afterdraw_xray, v3da); - MEM_freeN(v3da); - } - v3d->xray= FALSE; + MEM_freeN(v3da); } + v3d->xray= FALSE; +} /* clears zbuffer and draws it over */ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int clear) { View3DAfter *v3da, *next; - + if(clear && v3d->zbuf) glClear(GL_DEPTH_BUFFER_BIT); @@ -1486,14 +1427,14 @@ static void view3d_draw_xraytransp(Scene *scene, ARegion *ar, View3D *v3d, int c for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { next= v3da->next; - draw_object(scene, ar, v3d, v3da->base, v3da->flag); + draw_object(scene, ar, v3d, v3da->base, v3da->flag); BLI_remlink(&v3d->afterdraw_xraytransp, v3da); - MEM_freeN(v3da); - } + MEM_freeN(v3da); + } v3d->transp= FALSE; v3d->xray= FALSE; - + } /* *********************** */ @@ -1528,7 +1469,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas { RegionView3D *rv3d= ar->regiondata; ListBase *lb; - DupliObject *dob_prev= NULL, *dob, *dob_next; + DupliObject *dob_prev= NULL, *dob, *dob_next= NULL; Base tbase; BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ GLuint displist=0; @@ -1638,8 +1579,62 @@ static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *bas draw_dupli_objects_color(scene, ar, v3d, base, color); } +void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) +{ + int x, y, w, h; + rcti r; + /* clamp rect by area */ + + r.xmin= 0; + r.xmax= ar->winx-1; + r.ymin= 0; + r.ymax= ar->winy-1; + + /* Constrain rect to depth bounds */ + BLI_isect_rcti(&r, rect, rect); + + /* assign values to compare with the ViewDepths */ + x= rect->xmin; + y= rect->ymin; -void view3d_update_depths(ARegion *ar, View3D *v3d) + w= rect->xmax - rect->xmin; + h= rect->ymax - rect->ymin; + + if(w <= 0 || h <= 0) { + if(d->depths) + MEM_freeN(d->depths); + d->depths= NULL; + + d->damaged= FALSE; + } + else if( d->w != w || + d->h != h || + d->x != x || + d->y != y || + d->depths==NULL + ) { + d->x= x; + d->y= y; + d->w= w; + d->h= h; + + if(d->depths) + MEM_freeN(d->depths); + + d->depths= MEM_mallocN(sizeof(float)*d->w*d->h,"View depths Subset"); + + d->damaged= TRUE; + } + + if(d->damaged) { + glReadPixels(ar->winrct.xmin+d->x,ar->winrct.ymin+d->y, d->w,d->h, GL_DEPTH_COMPONENT,GL_FLOAT, d->depths); + glGetDoublev(GL_DEPTH_RANGE,d->depth_range); + d->damaged= FALSE; + } +} + +/* note, with nouveau drivers the glReadPixels() is very slow. [#24339] */ +void view3d_update_depths(ARegion *ar) { RegionView3D *rv3d= ar->regiondata; @@ -1669,6 +1664,30 @@ void view3d_update_depths(ARegion *ar, View3D *v3d) } } +/* utility function to find the closest Z value, use for autodepth */ +float view3d_depth_near(ViewDepths *d) +{ + /* convert to float for comparisons */ + const float near= (float)d->depth_range[0]; + const float far_real= (float)d->depth_range[1]; + float far= far_real; + + const float *depths= d->depths; + float depth= FLT_MAX; + int i= (int)d->w * (int)d->h; /* cast to avoid short overflow */ + + /* far is both the starting 'far' value + * and the closest value found. */ + while(i--) { + depth= *depths++; + if((depth < far) && (depth > near)) { + far= depth; + } + } + + return far == far_real ? FLT_MAX : far; +} + void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) { short zbuf= v3d->zbuf; @@ -1698,7 +1717,6 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) { RegionView3D *rv3d= ar->regiondata; Base *base; - Scene *sce; short zbuf= v3d->zbuf; short flag= v3d->flag; float glalphaclip= U.glalphaclip; @@ -1731,7 +1749,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { if (func == NULL || func(base)) { draw_object(scene, ar, v3d, base, 0); @@ -1770,9 +1789,9 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) if(v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) { - glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ + glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */ for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { - next= v3da->next; + next= v3da->next; draw_object(scene, ar, v3d, v3da->base, 0); } glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */ @@ -1787,7 +1806,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) BLI_remlink(&v3d->afterdraw_transp, v3da); MEM_freeN(v3da); } - + v3d->xray= TRUE; v3d->transp= FALSE; for(v3da= v3d->afterdraw_xray.first; v3da; v3da= next) { @@ -1795,8 +1814,8 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (* func)(void *)) draw_object(scene, ar, v3d, v3da->base, 0); BLI_remlink(&v3d->afterdraw_xray, v3da); MEM_freeN(v3da); - } - + } + v3d->xray= TRUE; v3d->transp= TRUE; for(v3da= v3d->afterdraw_xraytransp.first; v3da; v3da= next) { @@ -1853,16 +1872,14 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) { ListBase shadows; View3DShadow *shadow; - Scene *sce; + Scene *sce_iter; Base *base; Object *ob; - ARegion ar; - RegionView3D rv3d; shadows.first= shadows.last= NULL; /* update lamp transform and gather shadow lamps */ - for(SETLOOPER(scene, base)) { + for(SETLOOPER(scene, sce_iter, base)) { ob= base->object; if(ob->type == OB_LAMP) @@ -1886,6 +1903,8 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) /* this needs to be done better .. */ float viewmat[4][4], winmat[4][4]; int drawtype, lay, winsize, flag2=v3d->flag2; + ARegion ar= {0}; + RegionView3D rv3d= {{{0}}}; drawtype= v3d->drawtype; lay= v3d->lay; @@ -1897,9 +1916,6 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat); - memset(&ar, 0, sizeof(ar)); - memset(&rv3d, 0, sizeof(rv3d)); - ar.regiondata= &rv3d; ar.regiontype= RGN_TYPE_WINDOW; rv3d.persp= RV3D_CAMOB; @@ -1923,8 +1939,10 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) /* *********************** customdata **************** */ /* goes over all modes and view3d settings */ -static CustomDataMask get_viewedit_datamask(bScreen *screen, Scene *scene, Object *ob) +CustomDataMask ED_viewedit_datamask(bScreen *screen) { + Scene *scene= screen->scene; + Object *ob= scene->basact ? scene->basact->object : NULL; CustomDataMask mask = CD_MASK_BAREMESH; ScrArea *sa; @@ -1974,29 +1992,34 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, if(viewmat) copy_m4_m4(rv3d->viewmat, viewmat); else - setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ + setviewmatrixview3d(scene, v3d, rv3d); /* note: calls where_is_object for camera... */ /* update utilitity matrices */ mul_m4_m4m4(rv3d->persmat, rv3d->viewmat, rv3d->winmat); invert_m4_m4(rv3d->persinv, rv3d->persmat); invert_m4_m4(rv3d->viewinv, rv3d->viewmat); - + /* calculate pixelsize factor once, is used for lamps and obcenters */ { - float len1, len2, vec[3]; - - copy_v3_v3(vec, rv3d->persinv[0]); - len1= normalize_v3(vec); - copy_v3_v3(vec, rv3d->persinv[1]); - len2= normalize_v3(vec); - - rv3d->pixsize= 2.0f*(len1>len2?len1:len2); + /* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])' + * because of float point precision problems at large values [#23908] */ + float v1[3], v2[3]; + float len1, len2; + + v1[0]= rv3d->persmat[0][0]; + v1[1]= rv3d->persmat[1][0]; + v1[2]= rv3d->persmat[2][0]; + + v2[0]= rv3d->persmat[0][1]; + v2[1]= rv3d->persmat[1][1]; + v2[2]= rv3d->persmat[2][1]; - /* correct for window size */ - if(ar->winx > ar->winy) rv3d->pixsize/= (float)ar->winx; - else rv3d->pixsize/= (float)ar->winy; + len1= 1.0f / len_v3(v1); + len2= 1.0f / len_v3(v2); + + rv3d->pixsize = (2.0f * MAX2(len1, len2)) / (float)MAX2(ar->winx, ar->winy); } - + /* set for opengl */ glMatrixMode(GL_PROJECTION); glLoadMatrixf(rv3d->winmat); @@ -2006,7 +2029,6 @@ static void view3d_main_area_setup_view(Scene *scene, View3D *v3d, ARegion *ar, void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, float viewmat[][4], float winmat[][4]) { - Scene *sce; Base *base; float backcol[3]; int bwinx, bwiny; @@ -2020,7 +2042,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, brect= ar->winrct; ar->winx= winx; - ar->winy= winy; + ar->winy= winy; ar->winrct.xmin= 0; ar->winrct.ymin= 0; ar->winrct.xmax= winx; @@ -2033,6 +2055,10 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* free images which can have changed on frame-change * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); + + /* shadow buffers, before we setup matrices */ + if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) + gpu_update_lamps_shadows(scene, v3d); /* set background color, fallback on the view background color */ if(scene->world) { @@ -2061,14 +2087,15 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f); draw_object(scene, ar, v3d, base, DRAW_CONSTCOLOR|DRAW_SCENESET); - + if(base->object->transflag & OB_DUPLI) draw_dupli_objects_color(scene, ar, v3d, base, TH_WIRE); - } + } } } @@ -2123,9 +2150,12 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in RegionView3D *rv3d= ar->regiondata; ImBuf *ibuf; GPUOffScreen *ofs; + + /* state changes make normal drawing go weird otherwise */ + glPushAttrib(GL_LIGHTING_BIT); /* bind */ - ofs= GPU_offscreen_create(sizex, sizey); + ofs= GPU_offscreen_create(&sizex, &sizey); if(ofs == NULL) return NULL; @@ -2146,13 +2176,13 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in } /* read in pixels & stamp */ - ibuf= IMB_allocImBuf(sizex, sizey, 32, flag, 0); + ibuf= IMB_allocImBuf(sizex, sizey, 32, flag); if(ibuf->rect_float) glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_FLOAT, ibuf->rect_float); else if(ibuf->rect) - glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); - + glReadPixels(0, 0, sizex, sizey, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + //if((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) // BKE_stamp_buf(scene, NULL, rr->rectf, rr->rectx, rr->recty, 4); @@ -2160,6 +2190,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); + glPopAttrib(); + if(ibuf->rect_float && ibuf->rect) IMB_rect_from_float(ibuf); @@ -2169,13 +2201,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, in /* creates own 3d views, used by the sequencer */ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, int width, int height, unsigned int flag, int drawtype) { - View3D v3d; - ARegion ar; - RegionView3D rv3d; - - memset(&v3d, 0, sizeof(v3d)); - memset(&ar, 0, sizeof(ar)); - memset(&rv3d, 0, sizeof(rv3d)); + View3D v3d= {0}; + ARegion ar= {0}; + RegionView3D rv3d= {{{0}}}; /* connect data */ v3d.regionbase.first= v3d.regionbase.last= &ar; @@ -2256,24 +2284,20 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps+0.5)); } - BLF_draw_default(22, ar->winy-17, 0.0f, printable); + BLF_draw_default(22, ar->winy-17, 0.0f, printable, sizeof(printable)-1); } +/* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ void view3d_main_area_draw(const bContext *C, ARegion *ar) { Scene *scene= CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); - Scene *sce; Base *base; Object *ob; float backcol[3]; - int retopo= 0, sculptparticle= 0; - Object *obact = OBACT; - char *grid_unit= NULL; - - /* from now on all object derived meshes check this */ - v3d->customdata_mask= get_viewedit_datamask(CTX_wm_screen(C), scene, obact); + unsigned int lay_used; + const char *grid_unit= NULL; /* shadow buffers, before we setup matrices */ if(draw_glsl_material(scene, NULL, v3d, v3d->drawtype)) @@ -2320,22 +2344,25 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) // needs to be done always, gridview is adjusted in drawgrid() now rv3d->gridview= v3d->grid; - - if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { - if(rv3d->view==0 || rv3d->persp != RV3D_ORTHO) { - drawfloor(scene, v3d); - if(rv3d->persp==RV3D_CAMOB) { - if(scene->world) { - if(scene->world->mode & WO_STARS) { - RE_make_stars(NULL, scene, star_stuff_init_func, star_stuff_vertex_func, - star_stuff_term_func); - } + if(rv3d->view==0 || rv3d->persp != RV3D_ORTHO) { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { + drawfloor(scene, v3d, &grid_unit); + } + if(rv3d->persp==RV3D_CAMOB) { + if(scene->world) { + if(scene->world->mode & WO_STARS) { + RE_make_stars(NULL, scene, star_stuff_init_func, star_stuff_vertex_func, + star_stuff_term_func); } + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { if(v3d->flag & V3D_DISPBGPICS) draw_bgpic(scene, ar, v3d); } } - else { + } + else { + if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { ED_region_pixelspace(ar); drawgrid(&scene->unit, ar, v3d, &grid_unit); /* XXX make function? replaces persp(1) */ @@ -2355,7 +2382,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* draw set first */ if(scene->set) { - for(SETLOOPER(scene->set, base)) { + Scene *sce_iter; + for(SETLOOPER(scene->set, sce_iter, base)) { if(v3d->lay & base->lay) { @@ -2370,9 +2398,13 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* Transp and X-ray afterdraw stuff for sets is done later */ } - + + lay_used= 0; + /* then draw not selected and the duplis, but skip editmode object */ for(base= scene->base.first; base; base= base->next) { + lay_used |= base->lay & ((1<<20)-1); + if(v3d->lay & base->lay) { /* dupli drawing */ @@ -2386,11 +2418,20 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) } } -// retopo= retopo_mesh_check() || retopo_curve_check(); - sculptparticle= (obact && obact->mode & (OB_MODE_PARTICLE_EDIT)) && !scene->obedit; - if(retopo) - view3d_update_depths(ar, v3d); - + if(v3d->lay_used != lay_used) { /* happens when loading old files or loading with UI load */ + ARegion *ar_iter; + ScrArea *sa= CTX_wm_area(C); + + /* find header and force tag redraw */ + for(ar_iter= sa->regionbase.first; ar_iter; ar_iter= ar_iter->next) + if(ar_iter->regiontype==RGN_TYPE_HEADER) { + ED_region_tag_redraw(ar_iter); + break; + } + + v3d->lay_used= lay_used; + } + /* draw selected and editmode */ for(base= scene->base.first; base; base= base->next) { if(v3d->lay & base->lay) { @@ -2398,11 +2439,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) draw_object(scene, ar, v3d, base, 0); } } - - if(!retopo && sculptparticle && !(obact && (obact->dtx & OB_DRAWXRAY))) { - view3d_update_depths(ar, v3d); - } - + // REEB_draw(); /* Transp and X-ray afterdraw stuff */ @@ -2411,11 +2448,7 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) if(v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(scene, ar, v3d, 1); ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - - if(!retopo && sculptparticle && (obact && (OBACT->dtx & OB_DRAWXRAY))) { - view3d_update_depths(ar, v3d); - } - + if(rv3d->rflag & RV3D_CLIPPING) view3d_clr_clipping(); @@ -2446,8 +2479,8 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) /* Draw particle edit brush XXX (removed) */ - if(rv3d->persp==RV3D_CAMOB) drawviewborder(scene, ar, v3d); - if(rv3d->rflag & RV3D_FLYMODE) drawviewborder_flymode(ar); + if(rv3d->persp==RV3D_CAMOB) + drawviewborder(scene, ar, v3d); if ((v3d->flag2 & V3D_RENDER_OVERRIDE)==0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -2469,8 +2502,14 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) draw_viewport_name(ar, v3d); } if (grid_unit) { /* draw below the viewport name */ + char tstr[32]= ""; + UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, grid_unit); + if(v3d->grid != 1.0f) { + BLI_snprintf(tstr, sizeof(tstr), "%s x %.4g", grid_unit, v3d->grid); + } + + BLF_draw_default(22, ar->winy-(USER_SHOW_VIEWPORTNAME?40:20), 0.0f, tstr[0]?tstr : grid_unit, sizeof(tstr)); /* XXX, use real length */ } ob= OBACT; |