Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_draw_legacy.c
| Show First 20 Lines • Show All 434 Lines • ▼ Show 20 Lines | for (int nr = 1; nr <= height; nr++) { | ||||
| } | } | ||||
| } | } | ||||
| exit: | exit: | ||||
| MEM_freeN(buf); | MEM_freeN(buf); | ||||
| return index; | return index; | ||||
| } | } | ||||
| /* ************************************************************* */ | |||||
| static void view3d_stereo_bgpic_setup(Scene *scene, View3D *v3d, Image *ima, ImageUser *iuser) | |||||
| { | |||||
| if (BKE_image_is_stereo(ima)) { | |||||
| iuser->flag |= IMA_SHOW_STEREO; | |||||
| if ((scene->r.scemode & R_MULTIVIEW) == 0) { | |||||
| iuser->multiview_eye = STEREO_LEFT_ID; | |||||
| } | |||||
| else if (v3d->stereo3d_camera != STEREO_3D_ID) { | |||||
| /* show only left or right camera */ | |||||
| iuser->multiview_eye = v3d->stereo3d_camera; | |||||
| } | |||||
| BKE_image_multiview_index(ima, iuser); | |||||
| } | |||||
| else { | |||||
| iuser->flag &= ~IMA_SHOW_STEREO; | |||||
| } | |||||
| } | |||||
| static void view3d_draw_bgpic(Scene *scene, Depsgraph *depsgraph, | |||||
| ARegion *ar, View3D *v3d, | |||||
| const bool do_foreground, const bool do_camera_frame) | |||||
| { | |||||
| RegionView3D *rv3d = ar->regiondata; | |||||
| int fg_flag = do_foreground ? CAM_BGIMG_FLAG_FOREGROUND : 0; | |||||
| if (v3d->camera == NULL || v3d->camera->type != OB_CAMERA) { | |||||
| return; | |||||
| } | |||||
| Camera *cam = v3d->camera->data; | |||||
| for (CameraBGImage *bgpic = cam->bg_images.first; bgpic; bgpic = bgpic->next) { | |||||
| if ((bgpic->flag & CAM_BGIMG_FLAG_FOREGROUND) != fg_flag) { | |||||
| continue; | |||||
| } | |||||
| { | |||||
| float image_aspect[2]; | |||||
| float x1, y1, x2, y2, centx, centy; | |||||
| void *lock; | |||||
| Image *ima = NULL; | |||||
| /* disable individual images */ | |||||
| if ((bgpic->flag & CAM_BGIMG_FLAG_DISABLED)) { | |||||
| continue; | |||||
| } | |||||
| ImBuf *ibuf = NULL; | |||||
| ImBuf *freeibuf = NULL; | |||||
| ImBuf *releaseibuf = NULL; | |||||
| if (bgpic->source == CAM_BGIMG_SOURCE_IMAGE) { | |||||
| ima = bgpic->ima; | |||||
| if (ima == NULL) { | |||||
| continue; | |||||
| } | |||||
| ImageUser iuser = bgpic->iuser; | |||||
| iuser.scene = scene; /* Needed for render results. */ | |||||
| BKE_image_user_frame_calc(&iuser, (int)DEG_get_ctime(depsgraph)); | |||||
| if (ima->source == IMA_SRC_SEQUENCE && !(iuser.flag & IMA_USER_FRAME_IN_RANGE)) { | |||||
| ibuf = NULL; /* frame is out of range, dont show */ | |||||
| } | |||||
| else { | |||||
| view3d_stereo_bgpic_setup(scene, v3d, ima, &iuser); | |||||
| ibuf = BKE_image_acquire_ibuf(ima, &iuser, &lock); | |||||
| releaseibuf = ibuf; | |||||
| } | |||||
| image_aspect[0] = ima->aspx; | |||||
| image_aspect[1] = ima->aspy; | |||||
| } | |||||
| else if (bgpic->source == CAM_BGIMG_SOURCE_MOVIE) { | |||||
| /* TODO: skip drawing when out of frame range (as image sequences do above) */ | |||||
| MovieClip *clip = NULL; | |||||
| if (bgpic->flag & CAM_BGIMG_FLAG_CAMERACLIP) { | |||||
| if (scene->camera) { | |||||
| clip = BKE_object_movieclip_get(scene, scene->camera, true); | |||||
| } | |||||
| } | |||||
| else { | |||||
| clip = bgpic->clip; | |||||
| } | |||||
| if (clip == NULL) { | |||||
| continue; | |||||
| } | |||||
| BKE_movieclip_user_set_frame(&bgpic->cuser, (int)DEG_get_ctime(depsgraph)); | |||||
| ibuf = BKE_movieclip_get_ibuf(clip, &bgpic->cuser); | |||||
| image_aspect[0] = clip->aspx; | |||||
| image_aspect[1] = clip->aspy; | |||||
| /* working with ibuf from image and clip has got different workflow now. | |||||
| * ibuf acquired from clip is referenced by cache system and should | |||||
| * be dereferenced after usage. */ | |||||
| freeibuf = ibuf; | |||||
| } | |||||
| else { | |||||
| /* perhaps when loading future files... */ | |||||
| BLI_assert(0); | |||||
| copy_v2_fl(image_aspect, 1.0f); | |||||
| } | |||||
| if (ibuf == NULL) { | |||||
| continue; | |||||
| } | |||||
| 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, lock); | |||||
| } | |||||
| continue; | |||||
| } | |||||
| if (ibuf->rect == NULL) { | |||||
| IMB_rect_from_float(ibuf); | |||||
| } | |||||
| BLI_assert(rv3d->persp == RV3D_CAMOB); | |||||
| { | |||||
| if (do_camera_frame) { | |||||
| rctf vb; | |||||
| ED_view3d_calc_camera_border(scene, depsgraph, ar, v3d, rv3d, &vb, false); | |||||
| x1 = vb.xmin; | |||||
| y1 = vb.ymin; | |||||
| x2 = vb.xmax; | |||||
| y2 = vb.ymax; | |||||
| } | |||||
| else { | |||||
| x1 = ar->winrct.xmin; | |||||
| y1 = ar->winrct.ymin; | |||||
| x2 = ar->winrct.xmax; | |||||
| y2 = ar->winrct.ymax; | |||||
| } | |||||
| /* apply offset last - camera offset is different to offset in blender units */ | |||||
| /* so this has some sane way of working - this matches camera's shift _exactly_ */ | |||||
| { | |||||
| const float max_dim = max_ff(x2 - x1, y2 - y1); | |||||
| const float xof_scale = bgpic->offset[0] * max_dim; | |||||
| const float yof_scale = bgpic->offset[1] * max_dim; | |||||
| x1 += xof_scale; | |||||
| y1 += yof_scale; | |||||
| x2 += xof_scale; | |||||
| y2 += yof_scale; | |||||
| } | |||||
| centx = (x1 + x2) * 0.5f; | |||||
| centy = (y1 + y2) * 0.5f; | |||||
| /* aspect correction */ | |||||
| if (bgpic->flag & CAM_BGIMG_FLAG_CAMERA_ASPECT) { | |||||
| /* apply aspect from clip */ | |||||
| const float w_src = ibuf->x * image_aspect[0]; | |||||
| const float h_src = ibuf->y * image_aspect[1]; | |||||
| /* destination aspect is already applied from the camera frame */ | |||||
| const float w_dst = x1 - x2; | |||||
| const float h_dst = y1 - y2; | |||||
| const float asp_src = w_src / h_src; | |||||
| const float asp_dst = w_dst / h_dst; | |||||
| if (fabsf(asp_src - asp_dst) >= FLT_EPSILON) { | |||||
| if ((asp_src > asp_dst) == ((bgpic->flag & CAM_BGIMG_FLAG_CAMERA_CROP) != 0)) { | |||||
| /* fit X */ | |||||
| const float div = asp_src / asp_dst; | |||||
| x1 = ((x1 - centx) * div) + centx; | |||||
| x2 = ((x2 - centx) * div) + centx; | |||||
| } | |||||
| else { | |||||
| /* fit Y */ | |||||
| const float div = asp_dst / asp_src; | |||||
| y1 = ((y1 - centy) * div) + centy; | |||||
| y2 = ((y2 - centy) * div) + centy; | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| /* complete clip? */ | |||||
| rctf clip_rect; | |||||
| BLI_rctf_init(&clip_rect, x1, x2, y1, y2); | |||||
| if (bgpic->rotation) { | |||||
| BLI_rctf_rotate_expand(&clip_rect, &clip_rect, bgpic->rotation); | |||||
| } | |||||
| if (clip_rect.xmax < 0 || clip_rect.ymax < 0 || clip_rect.xmin > ar->winx || clip_rect.ymin > ar->winy) { | |||||
| if (freeibuf) { | |||||
| IMB_freeImBuf(freeibuf); | |||||
| } | |||||
| if (releaseibuf) { | |||||
| BKE_image_release_ibuf(ima, releaseibuf, lock); | |||||
| } | |||||
| continue; | |||||
| } | |||||
| float zoomx = (x2 - x1) / ibuf->x; | |||||
| float zoomy = (y2 - y1) / ibuf->y; | |||||
| /* for some reason; zoomlevels down refuses to use GL_ALPHA_SCALE */ | |||||
| if (zoomx < 1.0f || zoomy < 1.0f) { | |||||
| float tzoom = min_ff(zoomx, zoomy); | |||||
| int mip = 0; | |||||
| if ((ibuf->userflags & IB_MIPMAP_INVALID) != 0) { | |||||
| IMB_remakemipmap(ibuf, 0); | |||||
| ibuf->userflags &= ~IB_MIPMAP_INVALID; | |||||
| } | |||||
| else if (ibuf->mipmap[0] == NULL) { | |||||
| IMB_makemipmap(ibuf, 0); | |||||
| } | |||||
| while (tzoom < 1.0f && mip < 8 && ibuf->mipmap[mip]) { | |||||
| tzoom *= 2.0f; | |||||
| zoomx *= 2.0f; | |||||
| zoomy *= 2.0f; | |||||
| mip++; | |||||
| } | |||||
| if (mip > 0) { | |||||
| ibuf = ibuf->mipmap[mip - 1]; | |||||
| } | |||||
| } | |||||
| GPU_depth_test(!do_foreground); | |||||
| glDepthMask(GL_FALSE); | |||||
| GPU_blend(true); | |||||
| GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); | |||||
| GPU_matrix_push_projection(); | |||||
| GPU_matrix_push(); | |||||
| ED_region_pixelspace(ar); | |||||
| GPU_matrix_translate_2f(centx, centy); | |||||
| GPU_matrix_scale_1f(bgpic->scale); | |||||
| GPU_matrix_rotate_2d(RAD2DEGF(-bgpic->rotation)); | |||||
| if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_X) { | |||||
| zoomx *= -1.0f; | |||||
| x1 = x2; | |||||
| } | |||||
| if (bgpic->flag & CAM_BGIMG_FLAG_FLIP_Y) { | |||||
| zoomy *= -1.0f; | |||||
| y1 = y2; | |||||
| } | |||||
| float col[4] = {1.0f, 1.0f, 1.0f, bgpic->alpha}; | |||||
| IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); | |||||
| immDrawPixelsTex(&state, x1 - centx, y1 - centy, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect, | |||||
| zoomx, zoomy, col); | |||||
| GPU_matrix_pop_projection(); | |||||
| GPU_matrix_pop(); | |||||
| GPU_blend(false); | |||||
| glDepthMask(GL_TRUE); | |||||
| GPU_depth_test(true); | |||||
| if (freeibuf) { | |||||
| IMB_freeImBuf(freeibuf); | |||||
| } | |||||
| if (releaseibuf) { | |||||
| BKE_image_release_ibuf(ima, releaseibuf, lock); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| void ED_view3d_draw_bgpic_test( | |||||
| Scene *scene, Depsgraph *depsgraph, | |||||
| ARegion *ar, View3D *v3d, | |||||
| const bool do_foreground, const bool do_camera_frame) | |||||
| { | |||||
| RegionView3D *rv3d = ar->regiondata; | |||||
| if ((rv3d->persp == RV3D_CAMOB) && v3d->camera && (v3d->camera->type == OB_CAMERA)) { | |||||
| Camera *cam = v3d->camera->data; | |||||
| if ((cam->flag & CAM_SHOW_BG_IMAGE) == 0) { | |||||
| return; | |||||
| } | |||||
| } | |||||
| else { | |||||
| return; | |||||
| } | |||||
| /* disabled - mango request, since footage /w only render is quite useful | |||||
| * and this option is easy to disable all background images at once */ | |||||
| #if 0 | |||||
| if (v3d->flag2 & V3D_HIDE_OVERLAYS) { | |||||
| return; | |||||
| } | |||||
| #endif | |||||
| if ((rv3d->view == RV3D_VIEW_USER) || (rv3d->persp != RV3D_ORTHO)) { | |||||
| if (rv3d->persp == RV3D_CAMOB) { | |||||
| view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); | |||||
| } | |||||
| } | |||||
| else { | |||||
| view3d_draw_bgpic(scene, depsgraph, ar, v3d, do_foreground, do_camera_frame); | |||||
| } | |||||
| } | |||||
| /* *********************** */ | /* *********************** */ | ||||
| void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) | void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect) | ||||
| { | { | ||||
| /* clamp rect by region */ | /* clamp rect by region */ | ||||
| rcti r = { | rcti r = { | ||||
| .xmin = 0, | .xmin = 0, | ||||
| .xmax = ar->winx - 1, | .xmax = ar->winx - 1, | ||||
| ▲ Show 20 Lines • Show All 319 Lines • Show Last 20 Lines | |||||