diff options
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_draw.c')
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 699 |
1 files changed, 474 insertions, 225 deletions
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index a2e16efadd4..66047b6e8f4 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -75,7 +75,9 @@ #include "BIF_glutil.h" #include "WM_api.h" + #include "BLF_api.h" +#include "BLF_translation.h" #include "ED_armature.h" #include "ED_keyframing.h" @@ -217,25 +219,22 @@ void ED_view3d_clipping_enable(void) } } -static int view3d_clipping_test(const float vec[3], float clip[6][4]) +static bool view3d_clipping_test(const float co[3], float clip[6][4]) { - float view[3]; - copy_v3_v3(view, vec); - - if (0.0f < clip[0][3] + dot_v3v3(view, clip[0])) - if (0.0f < clip[1][3] + dot_v3v3(view, clip[1])) - if (0.0f < clip[2][3] + dot_v3v3(view, clip[2])) - if (0.0f < clip[3][3] + dot_v3v3(view, clip[3])) - return 0; + if (0.0f < clip[0][3] + dot_v3v3(co, clip[0])) + if (0.0f < clip[1][3] + dot_v3v3(co, clip[1])) + if (0.0f < clip[2][3] + dot_v3v3(co, clip[2])) + if (0.0f < clip[3][3] + dot_v3v3(co, clip[3])) + return false; - return 1; + return true; } /* for 'local' ED_view3d_clipping_local must run first * then all comparisons can be done in localspace */ -int ED_view3d_clipping_test(RegionView3D *rv3d, const float vec[3], const int is_local) +bool ED_view3d_clipping_test(RegionView3D *rv3d, const float co[3], const bool is_local) { - return view3d_clipping_test(vec, is_local ? rv3d->clip_local : rv3d->clip); + return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip); } /* ********* end custom clipping *********** */ @@ -315,7 +314,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** UI_ThemeColor(TH_GRID); if (unit->system) { - /* Use GRID_MIN_PX*2 for units because very very small grid + /* Use GRID_MIN_PX * 2 for units because very very small grid * items are less useful when dealing with units */ void *usys; int len, i; @@ -345,7 +344,7 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** CLAMP(blend_fac, 0.3f, 1.0f); - UI_ThemeColorBlend(TH_BACK, TH_GRID, blend_fac); + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, blend_fac); drawgrid_draw(ar, wx, wy, x, y, dx_scalar); } @@ -374,15 +373,15 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** } } else { /* start blending out */ - UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, sublines * dx); } } - else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX*10)) */ - UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); + else { /* start blending out (GRID_MIN_PX < dx < (GRID_MIN_PX * 10)) */ + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); UI_ThemeColor(TH_GRID); @@ -401,21 +400,21 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** drawgrid_draw(ar, wx, wy, x, y, dx); } else { - UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx * sublines); } } else { - UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx * sublines); } } else { - UI_ThemeColorBlend(TH_BACK, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); + UI_ThemeColorBlend(TH_HIGH_GRAD, TH_GRID, dx / (GRID_MIN_PX_D * 6.0)); drawgrid_draw(ar, wx, wy, x, y, dx); UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx * sublines); @@ -563,41 +562,49 @@ static void drawfloor(Scene *scene, View3D *v3d, const char **grid_unit) if (v3d->zbuf && scene->obedit) glDepthMask(1); } + static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) { int co[2]; /* we don't want the clipping for cursor */ if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + const float f5 = 0.25f * U.widget_unit; + const float f10 = 0.5f * U.widget_unit; + const float f20 = U.widget_unit; + setlinestyle(0); cpack(0xFF); - circ((float)co[0], (float)co[1], 10.0); - setlinestyle(4); + circ((float)co[0], (float)co[1], f10); + setlinestyle(4); cpack(0xFFFFFF); - circ((float)co[0], (float)co[1], 10.0); + circ((float)co[0], (float)co[1], f10); setlinestyle(0); cpack(0x0); - sdrawline(co[0] - 20, co[1], co[0] - 5, co[1]); - sdrawline(co[0] + 5, co[1], co[0] + 20, co[1]); - sdrawline(co[0], co[1] - 20, co[0], co[1] - 5); - sdrawline(co[0], co[1] + 5, co[0], co[1] + 20); + sdrawline(co[0] - f20, co[1], co[0] - f5, co[1]); + sdrawline(co[0] + f5, co[1], co[0] + f20, co[1]); + sdrawline(co[0], co[1] - f20, co[0], co[1] - f5); + sdrawline(co[0], co[1] + f5, co[0], co[1] + f20); } } /* 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) +static void draw_view_axis(RegionView3D *rv3d, rcti *rect) { 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.0f; /* axis center in screen coordinates, x=y */ + float startx = k + 1.0f; /* axis center in screen coordinates, x=y */ + float starty = k + 1.0f; float ydisp = 0.0; /* vertical displacement to allow obj info text */ - int bright = 25 * (float)U.rvibright + 5; /* axis alpha (rvibright has range 0-10) */ - + int bright = - 20 * (10 - U.rvibright); /* axis alpha offset (rvibright has range 0-10) */ float vec[3]; float dx, dy; + startx += rect->xmin; + starty += rect->ymin; + /* thickness of lines is proportional to k */ glLineWidth(2); @@ -613,12 +620,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_X, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "x", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "x", 1); } /* BLF_draw_default disables blending */ @@ -633,12 +640,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Y, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "y", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "y", 1); } glEnable(GL_BLEND); @@ -652,12 +659,12 @@ static void draw_view_axis(RegionView3D *rv3d) UI_ThemeColorShadeAlpha(TH_AXIS_Z, 0, bright); glBegin(GL_LINES); - glVertex2f(start, start + ydisp); - glVertex2f(start + dx, start + dy + ydisp); + glVertex2f(startx, starty + ydisp); + glVertex2f(startx + dx, starty + dy + ydisp); glEnd(); if (fabsf(dx) > toll || fabsf(dy) > toll) { - BLF_draw_default_ascii(start + dx + 2, start + dy + ydisp + 2, 0.0f, "z", 1); + BLF_draw_default_ascii(startx + dx + 2, starty + dy + ydisp + 2, 0.0f, "z", 1); } /* restore line-width */ @@ -770,7 +777,7 @@ static void draw_rotation_guide(RegionView3D *rv3d) glDepthMask(1); } -static void draw_view_icon(RegionView3D *rv3d) +static void draw_view_icon(RegionView3D *rv3d, rcti *rect) { BIFIconID icon; @@ -785,7 +792,7 @@ static void draw_view_icon(RegionView3D *rv3d) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - UI_icon_draw(5.0, 5.0, icon); + UI_icon_draw(5.0 + rect->xmin, 5.0 + rect->ymin, icon); glDisable(GL_BLEND); } @@ -796,28 +803,28 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) switch (rv3d->view) { case RV3D_VIEW_FRONT: - if (rv3d->persp == RV3D_ORTHO) name = "Front Ortho"; - else name = "Front Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Front Ortho"); + else name = IFACE_("Front Persp"); break; case RV3D_VIEW_BACK: - if (rv3d->persp == RV3D_ORTHO) name = "Back Ortho"; - else name = "Back Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Back Ortho"); + else name = IFACE_("Back Persp"); break; case RV3D_VIEW_TOP: - if (rv3d->persp == RV3D_ORTHO) name = "Top Ortho"; - else name = "Top Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Top Ortho"); + else name = IFACE_("Top Persp"); break; case RV3D_VIEW_BOTTOM: - if (rv3d->persp == RV3D_ORTHO) name = "Bottom Ortho"; - else name = "Bottom Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Bottom Ortho"); + else name = IFACE_("Bottom Persp"); break; case RV3D_VIEW_RIGHT: - if (rv3d->persp == RV3D_ORTHO) name = "Right Ortho"; - else name = "Right Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Right Ortho"); + else name = IFACE_("Right Persp"); break; case RV3D_VIEW_LEFT: - if (rv3d->persp == RV3D_ORTHO) name = "Left Ortho"; - else name = "Left Persp"; + if (rv3d->persp == RV3D_ORTHO) name = IFACE_("Left Ortho"); + else name = IFACE_("Left Persp"); break; default: @@ -825,14 +832,14 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) if ((v3d->camera) && (v3d->camera->type == OB_CAMERA)) { Camera *cam; cam = v3d->camera->data; - name = (cam->type != CAM_ORTHO) ? "Camera Persp" : "Camera Ortho"; + name = (cam->type != CAM_ORTHO) ? IFACE_("Camera Persp") : IFACE_("Camera Ortho"); } else { - name = "Object as Camera"; + name = IFACE_("Object as Camera"); } } else { - name = (rv3d->persp == RV3D_ORTHO) ? "User Ortho" : "User Persp"; + name = (rv3d->persp == RV3D_ORTHO) ? IFACE_("User Ortho") : IFACE_("User Persp"); } break; } @@ -840,30 +847,39 @@ static const char *view3d_get_name(View3D *v3d, RegionView3D *rv3d) return name; } -static void draw_viewport_name(ARegion *ar, View3D *v3d) +static void draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect) { RegionView3D *rv3d = ar->regiondata; const char *name = view3d_get_name(v3d, rv3d); + /* XXX 24 may be a bit small for unicode languages (Chinese in utf-8...) */ +#ifdef WITH_INTERNATIONAL + char tmpstr[32]; +#else char tmpstr[24]; - +#endif + if (v3d->localvd) { - BLI_snprintf(tmpstr, sizeof(tmpstr), "%s (Local)", name); + BLI_snprintf(tmpstr, sizeof(tmpstr), IFACE_("%s (Local)"), name); name = tmpstr; } if (name) { UI_ThemeColor(TH_TEXT_HI); - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, name, sizeof(tmpstr)); +#ifdef WITH_INTERNATIONAL + BLF_draw_default(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr)); +#else + BLF_draw_default_ascii(U.widget_unit + rect->xmin, rect->ymax - U.widget_unit, 0.0f, name, sizeof(tmpstr)); +#endif } } /* draw info beside axes in bottom left-corner: * framenum, object name, bone name (if available), marker name (if available) */ -static void draw_selected_name(Scene *scene, Object *ob) +static void draw_selected_name(Scene *scene, Object *ob, rcti *rect) { char info[256], *markern; - short offset = 30; + short offset = 1.5f * UI_UNIT_X + rect->xmin; /* get name of marker on current frame (if available) */ markern = BKE_scene_find_marker_name(scene, CFRA); @@ -910,7 +926,7 @@ static void draw_selected_name(Scene *scene, Object *ob) if (kb) { BLI_snprintf(shapes, sizeof(shapes), ": %s ", kb->name); if (ob->shapeflag == OB_SHAPE_LOCK) { - strcat(shapes, " (Pinned)"); + strcat(shapes, IFACE_(" (Pinned)")); } } } @@ -929,7 +945,7 @@ static void draw_selected_name(Scene *scene, Object *ob) } /* color depends on whether there is a keyframe */ - if (id_frame_has_keyframe((ID *)ob, /*BKE_scene_frame_get(scene)*/ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) + if (id_frame_has_keyframe((ID *)ob, /* BKE_scene_frame_get(scene) */ (float)(CFRA), ANIMFILTER_KEYS_LOCAL)) UI_ThemeColor(TH_VERTEX_SELECT); else UI_ThemeColor(TH_TEXT_HI); @@ -946,13 +962,13 @@ static void draw_selected_name(Scene *scene, Object *ob) } if (U.uiflag & USER_SHOW_ROTVIEWICON) - offset = 14 + (U.rvisize * 2); + offset = U.widget_unit + (U.rvisize * 2) + rect->xmin; - BLF_draw_default(offset, 10, 0.0f, info, sizeof(info)); + BLF_draw_default(offset, 0.5f * U.widget_unit, 0.0f, info, sizeof(info)); } static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, - rctf *viewborder_r, short no_shift, short no_zoom) + rctf *r_viewborder, const bool no_shift, const bool no_zoom) { CameraParams params; rctf rect_view, rect_camera; @@ -976,25 +992,25 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV rect_camera = params.viewplane; /* get camera border within viewport */ - viewborder_r->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; - viewborder_r->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; - viewborder_r->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; - viewborder_r->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; + r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; + r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx; + r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; + r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy; } -void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float size_r[2]) +void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2]) { rctf viewborder; - view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, TRUE, TRUE); - size_r[0] = BLI_rctf_size_x(&viewborder); - size_r[1] = BLI_rctf_size_y(&viewborder); + view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, true, true); + r_size[0] = BLI_rctf_size_x(&viewborder); + r_size[1] = BLI_rctf_size_y(&viewborder); } void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, - rctf *viewborder_r, short no_shift) + rctf *r_viewborder, const bool no_shift) { - view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, FALSE); + view3d_camera_border(scene, ar, v3d, rv3d, r_viewborder, no_shift, false); } static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac) @@ -1083,7 +1099,7 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) if (v3d->camera->type == OB_CAMERA) ca = v3d->camera->data; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false); /* the offsets */ x1 = viewborder.xmin; y1 = viewborder.ymin; @@ -1134,10 +1150,10 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d) glRectf(x1i, y1i, x2i, y2i); #ifdef VIEW3D_CAMERA_BORDER_HACK - if (view3d_camera_border_hack_test == TRUE) { + if (view3d_camera_border_hack_test == true) { glColor3ubv(view3d_camera_border_hack_col); glRectf(x1i + 1, y1i + 1, x2i - 1, y2i - 1); - view3d_camera_border_hack_test = FALSE; + view3d_camera_border_hack_test = false; } #endif @@ -1289,7 +1305,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) RegionView3D *rv3d = ar->regiondata; struct Base *base = scene->basact; int multisample_enabled; - rcti winrct; BLI_assert(ar->regiontype == RGN_TYPE_WINDOW); @@ -1298,11 +1313,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) { /* do nothing */ } - else if ((base && (base->object->mode & OB_MODE_TEXTURE_PAINT)) && - scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE)) - { - /* do nothing */ - } else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) && v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT)) { @@ -1338,8 +1348,35 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (multisample_enabled) glDisable(GL_MULTISAMPLE_ARB); - region_scissor_winrct(ar, &winrct); - glScissor(winrct.xmin, winrct.ymin, BLI_rcti_size_x(&winrct), BLI_rcti_size_y(&winrct)); + if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { + /* for multisample we use an offscreen FBO. multisample drawing can fail + * with color coded selection drawing, and reading back depths from such + * a buffer can also cause a few seconds freeze on OS X / NVidia. */ + int w = BLI_rcti_size_x(&ar->winrct); + int h = BLI_rcti_size_y(&ar->winrct); + char error[256]; + + if (rv3d->gpuoffscreen) { + if (GPU_offscreen_width(rv3d->gpuoffscreen) != w || + GPU_offscreen_height(rv3d->gpuoffscreen) != h) + { + GPU_offscreen_free(rv3d->gpuoffscreen); + rv3d->gpuoffscreen = NULL; + } + } + + if (!rv3d->gpuoffscreen) { + rv3d->gpuoffscreen = GPU_offscreen_create(w, h, error); + + if (!rv3d->gpuoffscreen) + fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error); + } + } + + if (rv3d->gpuoffscreen) + GPU_offscreen_bind(rv3d->gpuoffscreen); + else + glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct)); glClearColor(0.0, 0.0, 0.0, 0.0); if (v3d->zbuf) { @@ -1358,9 +1395,13 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) if (base && (base->lay & v3d->lay)) draw_object_backbufsel(scene, v3d, rv3d, base->object); + + if (rv3d->gpuoffscreen) + GPU_offscreen_unbind(rv3d->gpuoffscreen); + else + ar->swap = 0; /* mark invalid backbuf for wm draw */ v3d->flag &= ~V3D_INVALID_BACKBUF; - ar->swap = 0; /* mark invalid backbuf for wm draw */ G.f &= ~G_BACKBUFSEL; v3d->zbuf = FALSE; @@ -1377,6 +1418,28 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d) } +void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->gpuoffscreen) { + GPU_offscreen_bind(rv3d->gpuoffscreen); + glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); + glReadPixels(x, y, w, h, format, type, data); + GPU_offscreen_unbind(rv3d->gpuoffscreen); + } + else { + glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); + } +} + +/* XXX depth reading exception, for code not using gpu offscreen */ +static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data) +{ + + glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data); +} + void view3d_validate_backbuf(ViewContext *vc) { if (vc->v3d->flag & V3D_INVALID_BACKBUF) @@ -1392,12 +1455,9 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y) return 0; } - x += vc->ar->winrct.xmin; - y += vc->ar->winrct.ymin; - view3d_validate_backbuf(vc); - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); + view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col); glReadBuffer(GL_BACK); if (ENDIAN_ORDER == B_ENDIAN) { @@ -1428,8 +1488,8 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, view3d_validate_backbuf(vc); - glReadPixels(vc->ar->winrct.xmin + xminc, - vc->ar->winrct.ymin + yminc, + view3d_opengl_read_pixels(vc->ar, + xminc, yminc, (xmaxc - xminc + 1), (ymaxc - yminc + 1), GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); @@ -1537,7 +1597,7 @@ exit: /* ************************************************************* */ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, - const short do_foreground, const short do_camera_frame) + const bool do_foreground, const bool do_camera_frame) { RegionView3D *rv3d = ar->regiondata; BGpic *bgpic; @@ -1556,7 +1616,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, float fac, asp, zoomx, zoomy; float x1, y1, x2, y2; - ImBuf *ibuf = NULL, *freeibuf; + ImBuf *ibuf = NULL, *freeibuf, *releaseibuf; Image *ima; MovieClip *clip; @@ -1566,6 +1626,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, continue; freeibuf = NULL; + releaseibuf = NULL; if (bgpic->source == V3D_BGPIC_IMAGE) { ima = bgpic->ima; if (ima == NULL) @@ -1576,7 +1637,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, } else { ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL); - freeibuf = ibuf; + releaseibuf = ibuf; } image_aspect[0] = ima->aspx; @@ -1591,7 +1652,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if (scene->camera) clip = BKE_object_movieclip_get(scene, scene->camera, 1); } - else clip = bgpic->clip; + else { + clip = bgpic->clip; + } if (clip == NULL) continue; @@ -1619,6 +1682,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */ if (freeibuf) IMB_freeImBuf(freeibuf); + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); continue; } @@ -1630,7 +1695,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if (do_camera_frame) { rctf vb; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, false); x1 = vb.xmin; y1 = vb.ymin; x2 = vb.xmax; @@ -1691,10 +1756,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, float tvec[3]; float sco[2]; const float mval_f[2] = {1.0f, 0.0f}; + const float co_zero[3] = {0}; + float zfac; /* calc window coord */ - initgrabz(rv3d, 0.0, 0.0, 0.0); - ED_view3d_win_to_delta(ar, mval_f, tvec); + zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL); + ED_view3d_win_to_delta(ar, mval_f, tvec, zfac); fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */ fac = 1.0f / fac; @@ -1714,6 +1781,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, if (x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) { if (freeibuf) IMB_freeImBuf(freeibuf); + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); continue; } @@ -1757,7 +1826,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, glPixelZoom(zoomx, zoomy); glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend); - glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect); + + /* could not use glaDrawPixelsAuto because it could fallback to + * glaDrawPixelsSafe in some cases, which will end up in misssing + * alpha transparency for the background image (sergey) + */ + glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect); glPixelZoom(1.0, 1.0); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); @@ -1772,15 +1846,16 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, glDepthMask(1); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); - if (freeibuf) { + if (freeibuf) IMB_freeImBuf(freeibuf); - } + if (releaseibuf) + BKE_image_release_ibuf(ima, releaseibuf, NULL); } } } static void view3d_draw_bgpic_test(Scene *scene, ARegion *ar, View3D *v3d, - const short do_foreground, const short do_camera_frame) + const bool do_foreground, const bool do_camera_frame) { RegionView3D *rv3d = ar->regiondata; @@ -1921,12 +1996,13 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ GLuint displist = 0; short transflag, use_displist = -1; /* -1 is initialize */ - char dt, dtx; + char dt; + short dtx; if (base->object->restrictflag & OB_RESTRICT_VIEW) return; tbase.flag = OB_FROMDUPLI | base->flag; - lb = object_duplilist(scene, base->object, FALSE); + lb = object_duplilist(scene, base->object, false); // BLI_sortlist(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */ dob = dupli_step(lb->first); @@ -1956,7 +2032,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas /* generate displist, test for new object */ if (dob_prev && dob_prev->ob != dob->ob) { - if (use_displist == TRUE) + if (use_displist == true) glDeleteLists(displist, 1); use_displist = -1; @@ -1977,11 +2053,11 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas (dob->type == OB_DUPLIGROUP && dob->animated) || !(bb_tmp = BKE_object_boundbox_get(dob->ob))) { - // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name+2); - use_displist = FALSE; + // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2); + use_displist = false; } else { - // printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name+2); + // printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name + 2); bb = *bb_tmp; /* must make a copy */ /* disable boundbox check for list creation */ @@ -1994,7 +2070,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas draw_object(scene, ar, v3d, &tbase, DRAW_CONSTCOLOR); glEndList(); - use_displist = TRUE; + use_displist = true; BKE_object_boundbox_flag(dob->ob, OB_BB_DISABLED, 0); } } @@ -2035,6 +2111,7 @@ static void draw_dupli_objects(Scene *scene, ARegion *ar, View3D *v3d, Base *bas draw_dupli_objects_color(scene, ar, v3d, base, color); } +/* XXX warning, not using gpu offscreen here */ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) { int x, y, w, h; @@ -2061,7 +2138,7 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) MEM_freeN(d->depths); d->depths = NULL; - d->damaged = FALSE; + d->damaged = false; } else if (d->w != w || d->h != h || @@ -2080,13 +2157,14 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths Subset"); - d->damaged = TRUE; + 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); + /* XXX using special function here, it doesn't use the gpu offscreen system */ + view3d_opengl_read_Z_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); glGetDoublev(GL_DEPTH_RANGE, d->depth_range); - d->damaged = FALSE; + d->damaged = false; } } @@ -2108,16 +2186,14 @@ void ED_view3d_depth_update(ARegion *ar) if (d->depths) MEM_freeN(d->depths); d->depths = MEM_mallocN(sizeof(float) * d->w * d->h, "View depths"); - d->damaged = 1; + d->damaged = true; } if (d->damaged) { - glReadPixels(ar->winrct.xmin, ar->winrct.ymin, d->w, d->h, - GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); - + view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths); glGetDoublev(GL_DEPTH_RANGE, d->depth_range); - d->damaged = 0; + d->damaged = false; } } } @@ -2165,13 +2241,15 @@ void draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d) v3d->zbuf = TRUE; glEnable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + draw_gpencil_view3d(scene, v3d, ar, true); + } v3d->zbuf = zbuf; } -void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *)) +void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *), bool alphaoverride) { RegionView3D *rv3d = ar->regiondata; Base *base; @@ -2183,7 +2261,7 @@ void draw_depth(Scene *scene, ARegion *ar, View3D *v3d, int (*func)(void *)) /* Setting these temporarily is not nice */ v3d->flag &= ~V3D_SELECT_OUTLINE; - U.glalphaclip = 0.5; /* not that nice but means we wont zoom into billboards */ + U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */ U.obcenter_dia = 0; setwinmatrixview3d(ar, v3d, NULL); @@ -2346,7 +2424,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) if (ob->transflag & OB_DUPLI) { DupliObject *dob; - ListBase *lb = object_duplilist(scene, ob, FALSE); + ListBase *lb = object_duplilist(scene, ob, false); for (dob = lb->first; dob; dob = dob->next) if (dob->ob->type == OB_LAMP) @@ -2385,7 +2463,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d) invert_m4_m4(rv3d.persinv, rv3d.viewinv); /* no need to call ED_view3d_draw_offscreen_init since shadow buffers were already updated */ - ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, FALSE, FALSE); + ED_view3d_draw_offscreen(scene, v3d, &ar, winsize, winsize, viewmat, winmat, false); GPU_lamp_shadow_buffer_unbind(shadow->lamp); v3d->drawtype = drawtype; @@ -2532,13 +2610,11 @@ void ED_view3d_draw_offscreen_init(Scene *scene, View3D *v3d) /* ED_view3d_draw_offscreen_init should be called before this to initialize * stuff like shadow buffers */ -void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, - int winx, int winy, float viewmat[4][4], float winmat[4][4], - int do_bgpic, int colormanage_background) +void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, int winx, int winy, + float viewmat[4][4], float winmat[4][4], bool do_bgpic) { RegionView3D *rv3d = ar->regiondata; Base *base; - float backcol[3]; int bwinx, bwiny; rcti brect; @@ -2566,34 +2642,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, * warning! can be slow so only free animated images - campbell */ GPU_free_images_anim(); - /* set background color, fallback on the view background color - * (if active clip is set but frame is failed to load fallback to horizon color as background) */ - if (scene->world) { - /* NOTE: currently OpenGL is supposed to always work in sRGB space and do not - * apply any tonemaps since it's really tricky to support for all features (GLSL, textures, etc) - * but due to compatibility issues background is being affected display transform, so we can - * emulate behavior of disabled color management - * but this function is also used for sequencer's scene strips which shouldn't be affected by - * tonemaps now and should be purely sRGB, that's why we've got this colormanage_background - * we can drop this flag in cost of some compatibility loss -- background wouldn't be - * color managed in 3d viewport - * same goes to opengl rendering, where color profile should be applied as very final step - */ - - if (colormanage_background) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - } - else { - linearrgb_to_srgb_v3_v3(backcol, &scene->world->horr); - } - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else { - UI_ThemeClearColor(TH_BACK); - } - + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -2613,7 +2662,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, /* important to do before clipping */ if (do_bgpic) { - view3d_draw_bgpic_test(scene, ar, v3d, FALSE, FALSE); + view3d_draw_bgpic_test(scene, ar, v3d, false, false); } if (rv3d->rflag & RV3D_CLIPPING) @@ -2645,9 +2694,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, } /* must be before xray draw which clears the depth buffer */ - if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); - if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + if (v3d->zbuf) glDisable(GL_DEPTH_TEST); + draw_gpencil_view3d(scene, v3d, ar, true); + if (v3d->zbuf) glEnable(GL_DEPTH_TEST); + } /* transp and X-ray afterdraw stuff */ if (v3d->afterdraw_transp.first) view3d_draw_transp(scene, ar, v3d); @@ -2659,7 +2710,7 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, /* important to do after clipping */ if (do_bgpic) { - view3d_draw_bgpic_test(scene, ar, v3d, TRUE, FALSE); + view3d_draw_bgpic_test(scene, ar, v3d, true, false); } /* cleanup */ @@ -2671,8 +2722,11 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, /* draw grease-pencil stuff */ ED_region_pixelspace(ar); - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - draw_gpencil_view3d(scene, v3d, ar, 0); + + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, false); + } /* freeing the images again here could be done after the operator runs, leaving for now */ GPU_free_images_anim(); @@ -2690,10 +2744,30 @@ void ED_view3d_draw_offscreen(Scene *scene, View3D *v3d, ARegion *ar, G.f &= ~G_RENDER_OGL; } +/* get a color used for offscreen sky, returns color in sRGB space */ +void ED_view3d_offscreen_sky_color_get(Scene *scene, float sky_color[3]) +{ + if (scene->world) + linearrgb_to_srgb_v3_v3(sky_color, &scene->world->horr); + else + UI_GetThemeColor3fv(TH_BACK, sky_color); +} + +static void offscreen_imbuf_add_sky(ImBuf *ibuf, Scene *scene) +{ + float sky_color[3]; + + ED_view3d_offscreen_sky_color_get(scene, sky_color); + + if (ibuf->rect_float) + IMB_alpha_under_color_float(ibuf->rect_float, ibuf->x, ibuf->y, sky_color); + else + IMB_alpha_under_color_byte((unsigned char *) ibuf->rect, ibuf->x, ibuf->y, sky_color); +} + /* utility func for ED_view3d_draw_offscreen */ -ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, - int sizex, int sizey, unsigned int flag, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, int sizex, int sizey, unsigned int flag, + bool draw_background, int alpha_mode, char err_out[256]) { RegionView3D *rv3d = ar->regiondata; ImBuf *ibuf; @@ -2720,10 +2794,10 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, BKE_camera_params_compute_viewplane(¶ms, sizex, sizey, scene->r.xasp, scene->r.yasp); BKE_camera_params_compute_matrix(¶ms); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, params.winmat, draw_background); } else { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background, colormanage_background); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, NULL, draw_background); } /* read in pixels & stamp */ @@ -2734,6 +2808,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, else if (ibuf->rect) GPU_offscreen_read_pixels(ofs, GL_UNSIGNED_BYTE, ibuf->rect); + if (alpha_mode == R_ADDSKY) + offscreen_imbuf_add_sky(ibuf, scene); + /* unbind */ GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); @@ -2747,9 +2824,8 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(Scene *scene, View3D *v3d, ARegion *ar, } /* creates own 3d views, used by the sequencer */ -ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, - unsigned int flag, int drawtype, int draw_background, - int colormanage_background, char err_out[256]) +ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int width, int height, unsigned int flag, int drawtype, + bool use_solid_tex, bool draw_background, int alpha_mode, char err_out[256]) { View3D v3d = {NULL}; ARegion ar = {NULL}; @@ -2765,6 +2841,9 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w v3d.drawtype = drawtype; v3d.flag2 = V3D_RENDER_OVERRIDE; + if (use_solid_tex) + v3d.flag2 |= V3D_SOLID_TEX; + rv3d.persp = RV3D_CAMOB; copy_m4_m4(rv3d.viewinv, v3d.camera->obmat); @@ -2789,7 +2868,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w invert_m4_m4(rv3d.persinv, rv3d.viewinv); return ED_view3d_draw_offscreen_imbuf(scene, &v3d, &ar, width, height, flag, - draw_background, colormanage_background, err_out); + draw_background, alpha_mode, err_out); // seq_view3d_cb(scene, cfra, render_size, seqrectx, seqrecty); } @@ -2798,7 +2877,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf_simple(Scene *scene, Object *camera, int w /* NOTE: the info that this uses is updated in ED_refresh_viewport_fps(), * which currently gets called during SCREEN_OT_animation_step. */ -static void draw_viewport_fps(Scene *scene, ARegion *ar) +static void draw_viewport_fps(Scene *scene, rcti *rect) { ScreenFrameRateInfo *fpsi = scene->fps_info; float fps; @@ -2836,19 +2915,23 @@ static void draw_viewport_fps(Scene *scene, ARegion *ar) /* is this more then half a frame behind? */ if (fps + 0.5f < (float)(FPS)) { UI_ThemeColor(TH_REDALERT); - BLI_snprintf(printable, sizeof(printable), "fps: %.2f", fps); + BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %.2f"), fps); } else { UI_ThemeColor(TH_TEXT_HI); - BLI_snprintf(printable, sizeof(printable), "fps: %i", (int)(fps + 0.5f)); + BLI_snprintf(printable, sizeof(printable), IFACE_("fps: %i"), (int)(fps + 0.5f)); } - - BLF_draw_default_ascii(22, ar->winy - 17, 0.0f, printable, sizeof(printable)); + +#ifdef WITH_INTERNATIONAL + BLF_draw_default(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable)); +#else + BLF_draw_default_ascii(rect->xmin + U.widget_unit, rect->ymax - U.widget_unit, 0.0f, printable, sizeof(printable)); +#endif } static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit); -static int view3d_main_area_do_render_draw(const bContext *C) +static bool view3d_main_area_do_render_draw(const bContext *C) { Scene *scene = CTX_data_scene(C); RenderEngineType *type = RE_engines_find(scene->r.engine); @@ -2856,7 +2939,7 @@ static int view3d_main_area_do_render_draw(const bContext *C) return (type && type->view_update && type->view_draw); } -static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw_border) +static bool view3d_main_area_draw_engine(const bContext *C, ARegion *ar, const bool draw_border) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -2871,9 +2954,9 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw type = RE_engines_find(scene->r.engine); if (!(type->view_update && type->view_draw)) - return 0; + return false; - engine = RE_engine_create(type); + engine = RE_engine_create_ex(type, true); engine->tile_x = scene->r.tilex; engine->tile_y = scene->r.tiley; @@ -2895,7 +2978,7 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw rcti cliprct; if (rv3d->persp == RV3D_CAMOB) { - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, false); cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); @@ -2923,15 +3006,16 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw glGetIntegerv(GL_SCISSOR_BOX, scissor); glScissor(cliprct.xmin, cliprct.ymin, BLI_rcti_size_x(&cliprct), BLI_rcti_size_y(&cliprct)); } - else - return 0; + else { + return false; + } } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (v3d->flag & V3D_DISPBGPICS) - view3d_draw_bgpic(scene, ar, v3d, FALSE, TRUE); + view3d_draw_bgpic(scene, ar, v3d, false, true); else fdrawcheckerboard(0, 0, ar->winx, ar->winy); @@ -2940,14 +3024,14 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw type->view_draw(rv3d->render_engine, C); if (v3d->flag & V3D_DISPBGPICS) - view3d_draw_bgpic(scene, ar, v3d, TRUE, TRUE); + view3d_draw_bgpic(scene, ar, v3d, true, true); if (draw_border) { /* restore scissor as it was before */ glScissor(scissor[0], scissor[1], scissor[2], scissor[3]); } - return 1; + return true; } static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar) @@ -2958,6 +3042,177 @@ static void view3d_main_area_draw_engine_info(RegionView3D *rv3d, ARegion *ar) ED_region_info_draw(ar, rv3d->render_engine->text, 1, 0.25); } +/* + * Function to clear the view + */ +static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar) +{ + /* clear background */ + if (scene->world && (v3d->flag2 & V3D_RENDER_OVERRIDE)) { /* clear with solid color */ + if (scene->world->skytype & WO_SKYBLEND) { /* blend sky */ + int x, y; + float col_hor[3]; + float col_zen[3]; + +#define VIEWGRAD_RES_X 16 +#define VIEWGRAD_RES_Y 16 + + GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4]; + static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3]; + static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4]; + static bool buf_calculated = false; + + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings, + &scene->display_settings); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glShadeModel(GL_SMOOTH); + + /* calculate buffers the first time only */ + if (!buf_calculated) { + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + + /* -1..1 range */ + grid_pos[x][y][0] = (xf - 0.5f) * 2.0f; + grid_pos[x][y][1] = (yf - 0.5f) * 2.0f; + grid_pos[x][y][2] = 1.0; + } + } + + for (x = 0; x < VIEWGRAD_RES_X - 1; x++) { + for (y = 0; y < VIEWGRAD_RES_Y - 1; y++) { + indices[x][y][0] = x * VIEWGRAD_RES_X + y; + indices[x][y][1] = x * VIEWGRAD_RES_X + y + 1; + indices[x][y][2] = (x + 1) * VIEWGRAD_RES_X + y + 1; + indices[x][y][3] = (x + 1) * VIEWGRAD_RES_X + y; + } + } + + buf_calculated = true; + } + + for (x = 0; x < VIEWGRAD_RES_X; x++) { + for (y = 0; y < VIEWGRAD_RES_Y; y++) { + const float xf = (float)x / (float)(VIEWGRAD_RES_X - 1); + const float yf = (float)y / (float)(VIEWGRAD_RES_Y - 1); + const float mval[2] = {xf * (float)ar->winx, yf * ar->winy}; + const float z_up[3] = {0.0f, 0.0f, 1.0f}; + float out[3]; + GLubyte *col_ub = grid_col[x][y]; + + float col_fac; + float col_fl[3]; + + ED_view3d_win_to_vector(ar, mval, out); + + if (scene->world->skytype & WO_SKYPAPER) { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf(((float)y / (float)VIEWGRAD_RES_Y) - 0.5f) * 2.0f; + } + else { + col_fac = (float)y / (float)VIEWGRAD_RES_Y; + } + } + else { + if (scene->world->skytype & WO_SKYREAL) { + col_fac = fabsf((angle_normalized_v3v3(z_up, out) / (float)M_PI) - 0.5f) * 2.0f; + } + else { + col_fac = 1.0f - (angle_normalized_v3v3(z_up, out) / (float)M_PI); + } + } + + interp_v3_v3v3(col_fl, col_hor, col_zen, col_fac); + + rgb_float_to_uchar(col_ub, col_fl); + col_ub[3] = 0; + } + } + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, grid_pos); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col); + + glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glShadeModel(GL_FLAT); + +#undef VIEWGRAD_RES_X +#undef VIEWGRAD_RES_Y + } + else { /* solid sky */ + float col_hor[3]; + IMB_colormanagement_pixel_to_display_space_v3(col_hor, &scene->world->horr, &scene->view_settings, + &scene->display_settings); + + glClearColor(col_hor[0], col_hor[1], col_hor[2], 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } + else { + if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + glShadeModel(GL_SMOOTH); + glBegin(GL_QUADS); + UI_ThemeColor(TH_LOW_GRAD); + glVertex3f(-1.0, -1.0, 1.0); + glVertex3f(1.0, -1.0, 1.0); + UI_ThemeColor(TH_HIGH_GRAD); + glVertex3f(1.0, 1.0, 1.0); + glVertex3f(-1.0, 1.0, 1.0); + glEnd(); + glShadeModel(GL_FLAT); + + glDepthFunc(GL_LEQUAL); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + else { + UI_ThemeClearColor(TH_HIGH_GRAD); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + } +} + /* warning: this function has duplicate drawing in ED_view3d_draw_offscreen() */ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const char **grid_unit) { @@ -2965,7 +3220,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); Base *base; - float backcol[3]; unsigned int lay_used; /* shadow buffers, before we setup matrices */ @@ -2978,21 +3232,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const GPU_default_lights(); } - /* clear background */ - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) && scene->world) { - IMB_colormanagement_pixel_to_display_space_v3(backcol, &scene->world->horr, &scene->view_settings, - &scene->display_settings); - - glClearColor(backcol[0], backcol[1], backcol[2], 0.0); - } - else - UI_ThemeClearColor(TH_BACK); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - /* setup view matrices */ view3d_main_area_setup_view(scene, v3d, ar, NULL, NULL); + /* clear the background */ + view3d_main_area_clear(scene, v3d, ar); + ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); if (rv3d->rflag & RV3D_CLIPPING) @@ -3008,7 +3253,6 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const /* enables anti-aliasing for 3D view drawing */ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { - // if (!(U.gameflags & USER_DISABLE_AA)) glEnable(GL_MULTISAMPLE_ARB); } @@ -3041,7 +3285,7 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const } } - view3d_draw_bgpic_test(scene, ar, v3d, FALSE, TRUE); + view3d_draw_bgpic_test(scene, ar, v3d, false, true); if (rv3d->rflag & RV3D_CLIPPING) ED_view3d_clipping_set(rv3d); @@ -3102,10 +3346,10 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const // REEB_draw(); - if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { + if (v3d->flag2 & V3D_SHOW_GPENCIL) { /* must be before xray draw which clears the depth buffer */ if (v3d->zbuf) glDisable(GL_DEPTH_TEST); - draw_gpencil_view3d(scene, v3d, ar, 1); + draw_gpencil_view3d(scene, v3d, ar, true); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } @@ -3120,13 +3364,12 @@ static void view3d_main_area_draw_objects(const bContext *C, ARegion *ar, const ED_view3d_clipping_disable(); /* important to do after clipping */ - view3d_draw_bgpic_test(scene, ar, v3d, TRUE, TRUE); + view3d_draw_bgpic_test(scene, ar, v3d, true, true); BIF_draw_manipulator(C); /* Disable back anti-aliasing */ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) { - // if (!(U.gameflags & USER_DISABLE_AA)) glDisable(GL_MULTISAMPLE_ARB); } @@ -3152,6 +3395,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); + rcti rect; + + /* local coordinate visible rect inside region, to accomodate overlapping ui */ + ED_region_visible_rect(ar, &rect); if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); @@ -3168,23 +3415,24 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } + if (v3d->flag2 & V3D_SHOW_GPENCIL) { + /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ + draw_gpencil_view3d(scene, v3d, ar, false); + } + if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { Object *ob; - /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ - // if (v3d->flag2 & V3D_DISPGP) - draw_gpencil_view3d(scene, v3d, ar, 0); - drawcursor(scene, ar, v3d); if (U.uiflag & USER_SHOW_ROTVIEWICON) - draw_view_axis(rv3d); + draw_view_axis(rv3d, &rect); else - draw_view_icon(rv3d); + draw_view_icon(rv3d, &rect); ob = OBACT; if (U.uiflag & USER_DRAWVIEWINFO) - draw_selected_name(scene, ob); + draw_selected_name(scene, ob, &rect); } if (rv3d->render_engine) { @@ -3194,10 +3442,10 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_playing(wm)) { - draw_viewport_fps(scene, ar); + draw_viewport_fps(scene, &rect); } else if (U.uiflag & USER_SHOW_VIEWPORTNAME) { - draw_viewport_name(ar, v3d); + draw_viewport_name(ar, v3d, &rect); } if (grid_unit) { /* draw below the viewport name */ @@ -3208,7 +3456,8 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha BLI_snprintf(numstr, sizeof(numstr), "%s x %.4g", grid_unit, v3d->grid); } - BLF_draw_default_ascii(22, ar->winy - (USER_SHOW_VIEWPORTNAME ? 40 : 20), 0.0f, + BLF_draw_default_ascii(rect.xmin + U.widget_unit, + rect.ymax - (USER_SHOW_VIEWPORTNAME ? 2 * U.widget_unit : U.widget_unit), 0.0f, numstr[0] ? numstr : grid_unit, sizeof(numstr)); } } @@ -3220,12 +3469,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; - int draw_border = FALSE; + bool draw_border = false; if (rv3d->persp == RV3D_CAMOB) - draw_border = scene->r.mode & R_BORDER; + draw_border = (scene->r.mode & R_BORDER) != 0; else - draw_border = v3d->flag2 & V3D_RENDER_BORDER; + draw_border = (v3d->flag2 & V3D_RENDER_BORDER) != 0; /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { @@ -3290,14 +3539,14 @@ static void bl_debug_draw(void) if (_bl_debug_draw_quads_tot) { int i; cpack(0x00FF0000); - glBegin(GL_LINE_LOOP); for (i = 0; i < _bl_debug_draw_quads_tot; i ++) { + glBegin(GL_LINE_LOOP); glVertex3fv(_bl_debug_draw_quads[i][0]); glVertex3fv(_bl_debug_draw_quads[i][1]); glVertex3fv(_bl_debug_draw_quads[i][2]); glVertex3fv(_bl_debug_draw_quads[i][3]); + glEnd(); } - glEnd(); } if (_bl_debug_draw_edges_tot) { int i; |