static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) { int x, y; /* set zoom */ glPixelZoom(zoomx, zoomy); /* find window pixel coordinates of origin */ UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y); /* this part is generic image display */ if (sima->flag & SI_SHOW_ALPHA) { if (ibuf->rect) sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect); else if (ibuf->rect_float && ibuf->channels == 4) sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float); } else if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) { if (ibuf->zbuf) sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf); else if (ibuf->zbuf_float) sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float); else if (ibuf->channels == 1) sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float); } else { unsigned char *display_buffer; void *cache_handle; glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (sima->flag & SI_USE_ALPHA) { fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); } else { glColor4f(0.0f, 0.0f, 0.0f, 1.0f); glRecti(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); } display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); if (display_buffer) glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); #if 0 else glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float); #endif IMB_display_buffer_release(cache_handle); glDisable(GL_BLEND); } /* reset zoom */ glPixelZoom(1.0f, 1.0f); }
/* draws checkerboard background for transparent content */ static void sequencer_draw_background(const SpaceSeq *sseq, View2D *v2d, const float viewrect[2]) { /* setting up the view */ UI_view2d_totRect_set(v2d, viewrect[0] + 0.5f, viewrect[1] + 0.5f); UI_view2d_curRect_validate(v2d); UI_view2d_view_ortho(v2d); /* only draw alpha for main buffer */ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { if (sseq->flag & SEQ_USE_ALPHA) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); glColor4f(1.0, 1.0, 1.0, 1.0); } } }
static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar, Scene *scene, ImBuf *ibuf, float fx, float fy, float zoomx, float zoomy) { int x, y; /* set zoom */ glPixelZoom(zoomx, zoomy); glaDefine2DArea(&ar->winrct); /* find window pixel coordinates of origin */ UI_view2d_view_to_region(&ar->v2d, fx, fy, &x, &y); /* this part is generic image display */ if (sima->flag & SI_SHOW_ALPHA) { if (ibuf->rect) sima_draw_alpha_pixels(x, y, ibuf->x, ibuf->y, ibuf->rect); else if (ibuf->rect_float && ibuf->channels == 4) sima_draw_alpha_pixelsf(x, y, ibuf->x, ibuf->y, ibuf->rect_float); } else if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) { if (ibuf->zbuf) sima_draw_zbuf_pixels(x, y, ibuf->x, ibuf->y, ibuf->zbuf); else if (ibuf->zbuf_float) sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->zbuf_float); else if (ibuf->channels == 1) sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float); } else { if (sima->flag & SI_USE_ALPHA) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy); } glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST); if (sima->flag & SI_USE_ALPHA) glDisable(GL_BLEND); } /* reset zoom */ glPixelZoom(1.0f, 1.0f); }
static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf, int width, int height, float zoomx, float zoomy) { MovieClip *clip = ED_space_clip_get_clip(sc); int filter = GL_LINEAR; int x, y; /* find window pixel coordinates of origin */ UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y); /* checkerboard for case alpha */ if (ibuf->planes == 32) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); } /* non-scaled proxy shouldn't use filtering */ if ((clip->flag & MCLIP_USE_PROXY) == 0 || ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) { filter = GL_NEAREST; } /* set zoom */ glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y); glaDrawImBuf_glsl_ctx(C, ibuf, x, y, filter); /* reset zoom */ glPixelZoom(1.0f, 1.0f); if (sc->flag & SC_SHOW_METADATA) { rctf frame; BLI_rctf_init(&frame, 0.0f, ibuf->x, 0.0f, ibuf->y); ED_region_image_metadata_draw(x, y, ibuf, &frame, zoomx * width / ibuf->x, zoomy * height / ibuf->y); } if (ibuf->planes == 32) glDisable(GL_BLEND); }
static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { float offsx, offsy; if (ibuf == NULL) { printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>"); return; } if (ibuf->rect == NULL && ibuf->rect_float) { IMB_rect_from_float(ibuf); imb_freerectfloatImBuf(ibuf); } if (ibuf->rect == NULL) return; GHOST_ActivateWindowDrawingContext(g_WS.ghost_window); /* offset within window */ offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x); offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y); CLAMP(offsx, 0.0f, 1.0f); CLAMP(offsy, 0.0f, 1.0f); glRasterPos2f(offsx, offsy); glClearColor(0.1, 0.1, 0.1, 0.0); glClear(GL_COLOR_BUFFER_BIT); /* checkerboard for case alpha */ if (ibuf->planes == 32) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y); } glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); glDisable(GL_BLEND); pupdate_time(); if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) { int sizex, sizey; float fsizex_inv, fsizey_inv; char str[32 + FILE_MAX]; cpack(-1); BLI_snprintf(str, sizeof(str), "%s | %.2f frames/s", picture->name, fstep / swaptime); playanim_window_get_size(&sizex, &sizey); fsizex_inv = 1.0f / sizex; fsizey_inv = 1.0f / sizey; BLF_enable(fontid, BLF_ASPECT); BLF_aspect(fontid, fsizex_inv, fsizey_inv, 1.0f); BLF_position(fontid, 10.0f * fsizex_inv, 10.0f * fsizey_inv, 0.0f); BLF_draw(fontid, str, sizeof(str)); } GHOST_SwapWindowBuffers(g_WS.ghost_window); }
void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, int draw_overlay) { struct Main *bmain = CTX_data_main(C); struct ImBuf *ibuf = NULL; struct ImBuf *scope = NULL; struct View2D *v2d = &ar->v2d; /* int rectx, recty; */ /* UNUSED */ float viewrectx, viewrecty; float render_size = 0.0; float proxy_size = 100.0; float col[3]; GLuint texid; GLuint last_texid; void *display_buffer; void *cache_handle = NULL; const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); int format, type; bool glsl_used = false; if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* stop all running jobs, except screen one. currently previews frustrate Render * needed to make so sequencer's rendering doesn't conflict with compositor */ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_COMPOSITE); if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* in case of final rendering used for preview, kill all previews, * otherwise threading conflict will happen in rendering module */ WM_jobs_kill_type(CTX_wm_manager(C), WM_JOB_TYPE_RENDER_PREVIEW); } } render_size = sseq->render_size; if (render_size == 0) { render_size = scene->r.size; } else { proxy_size = render_size; } if (render_size < 0) { return; } viewrectx = (render_size * (float)scene->r.xsch) / 100.0f; viewrecty = (render_size * (float)scene->r.ysch) / 100.0f; /* rectx = viewrectx + 0.5f; */ /* UNUSED */ /* recty = viewrecty + 0.5f; */ /* UNUSED */ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { viewrectx *= scene->r.xasp / scene->r.yasp; viewrectx /= proxy_size / 100.0f; viewrecty /= proxy_size / 100.0f; } if (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) { UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col); glClearColor(col[0], col[1], col[2], 0.0); glClear(GL_COLOR_BUFFER_BIT); } /* without this colors can flicker from previous opengl state */ glColor4ub(255, 255, 255, 255); UI_view2d_totRect_set(v2d, viewrectx + 0.5f, viewrecty + 0.5f); UI_view2d_curRect_validate(v2d); /* only initialize the preview if a render is in progress */ if (G.is_rendering) return; ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs); if (ibuf == NULL) return; if (ibuf->rect == NULL && ibuf->rect_float == NULL) return; if (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0) { SequencerScopes *scopes = &sseq->scopes; sequencer_check_scopes(scopes, ibuf); switch (sseq->mainb) { case SEQ_DRAW_IMG_IMBUF: if (!scopes->zebra_ibuf) { ImBuf *display_ibuf = IMB_dupImBuf(ibuf); if (display_ibuf->rect_float) { IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings, &scene->display_settings); } scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra); IMB_freeImBuf(display_ibuf); } scope = scopes->zebra_ibuf; break; case SEQ_DRAW_IMG_WAVEFORM: if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) { if (!scopes->sep_waveform_ibuf) scopes->sep_waveform_ibuf = sequencer_make_scope(scene, ibuf, make_sep_waveform_view_from_ibuf); scope = scopes->sep_waveform_ibuf; } else { if (!scopes->waveform_ibuf) scopes->waveform_ibuf = sequencer_make_scope(scene, ibuf, make_waveform_view_from_ibuf); scope = scopes->waveform_ibuf; } break; case SEQ_DRAW_IMG_VECTORSCOPE: if (!scopes->vector_ibuf) scopes->vector_ibuf = sequencer_make_scope(scene, ibuf, make_vectorscope_view_from_ibuf); scope = scopes->vector_ibuf; break; case SEQ_DRAW_IMG_HISTOGRAM: if (!scopes->histogram_ibuf) scopes->histogram_ibuf = sequencer_make_scope(scene, ibuf, make_histogram_view_from_ibuf); scope = scopes->histogram_ibuf; break; } scopes->reference_ibuf = ibuf; } /* setting up the view - actual drawing starts here */ UI_view2d_view_ortho(v2d); /* only draw alpha for main buffer */ if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { if (sseq->flag & SEQ_USE_ALPHA) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); glColor4f(1.0, 1.0, 1.0, 1.0); } } if (scope) { IMB_freeImBuf(ibuf); ibuf = scope; if (ibuf->rect_float && ibuf->rect == NULL) { IMB_rect_from_float(ibuf); } display_buffer = (unsigned char *)ibuf->rect; format = GL_RGBA; type = GL_UNSIGNED_BYTE; } else { bool force_fallback = false; force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL); force_fallback |= (ibuf->dither != 0.0f); if (force_fallback) { /* Fallback to CPU based color space conversion */ glsl_used = false; format = GL_RGBA; type = GL_UNSIGNED_BYTE; display_buffer = NULL; } else if (ibuf->rect_float) { display_buffer = ibuf->rect_float; if (ibuf->channels == 4) { format = GL_RGBA; } else if (ibuf->channels == 3) { format = GL_RGB; } else { BLI_assert(!"Incompatible number of channels for float buffer in sequencer"); format = GL_RGBA; display_buffer = NULL; } type = GL_FLOAT; if (ibuf->float_colorspace) { glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->float_colorspace, true); } else { glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, true); } } else if (ibuf->rect) { display_buffer = ibuf->rect; format = GL_RGBA; type = GL_UNSIGNED_BYTE; glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, false); } else { format = GL_RGBA; type = GL_UNSIGNED_BYTE; display_buffer = NULL; } /* there's a data to be displayed, but GLSL is not initialized * properly, in this case we fallback to CPU-based display transform */ if ((ibuf->rect || ibuf->rect_float) && !glsl_used) { display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); format = GL_RGBA; type = GL_UNSIGNED_BYTE; } } glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1.0, 1.0, 1.0, 1.0); last_texid = glaGetOneInteger(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D); glGenTextures(1, (GLuint *)&texid); glBindTexture(GL_TEXTURE_2D, texid); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); if (type == GL_FLOAT) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, ibuf->x, ibuf->y, 0, format, type, display_buffer); else glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer); glBegin(GL_QUADS); if (draw_overlay) { if (sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) { rctf tot_clip; tot_clip.xmin = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmin); tot_clip.ymin = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymin); tot_clip.xmax = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmax); tot_clip.ymax = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymax); glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmin, tot_clip.ymin); glTexCoord2f(scene->ed->over_border.xmin, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmin, tot_clip.ymax); glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymax); glVertex2f(tot_clip.xmax, tot_clip.ymax); glTexCoord2f(scene->ed->over_border.xmax, scene->ed->over_border.ymin); glVertex2f(tot_clip.xmax, tot_clip.ymin); } else if (sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) { glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin); glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax); glTexCoord2f(1.0f, 1.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymax); glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } } else { glTexCoord2f(0.0f, 0.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymin); glTexCoord2f(0.0f, 1.0f); glVertex2f(v2d->tot.xmin, v2d->tot.ymax); glTexCoord2f(1.0f, 1.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymax); glTexCoord2f(1.0f, 0.0f); glVertex2f(v2d->tot.xmax, v2d->tot.ymin); } glEnd(); glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) glDisable(GL_BLEND); glDeleteTextures(1, &texid); if (glsl_used) IMB_colormanagement_finish_glsl_draw(); if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { float x1 = v2d->tot.xmin; float y1 = v2d->tot.ymin; float x2 = v2d->tot.xmax; float y2 = v2d->tot.ymax; /* border */ setlinestyle(3); UI_ThemeColorBlendShade(TH_WIRE, TH_BACK, 1.0, 0); glBegin(GL_LINE_LOOP); glVertex2f(x1 - 0.5f, y1 - 0.5f); glVertex2f(x1 - 0.5f, y2 + 0.5f); glVertex2f(x2 + 0.5f, y2 + 0.5f); glVertex2f(x2 + 0.5f, y1 - 0.5f); glEnd(); /* safety border */ if ((sseq->flag & SEQ_DRAW_SAFE_MARGINS) != 0) { float fac = 0.1; float a = fac * (x2 - x1); x1 += a; x2 -= a; a = fac * (y2 - y1); y1 += a; y2 -= a; glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); uiSetRoundBox(UI_CNR_ALL); uiDrawBox(GL_LINE_LOOP, x1, y1, x2, y2, 12.0); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } setlinestyle(0); } if (sseq->flag & SEQ_SHOW_GPENCIL) { if (is_imbuf) { /* draw grease-pencil (image aligned) */ draw_gpencil_2dimage(C); } } if (!scope) IMB_freeImBuf(ibuf); /* ortho at pixel level */ UI_view2d_view_restore(C); if (sseq->flag & SEQ_SHOW_GPENCIL) { if (is_imbuf) { /* draw grease-pencil (screen aligned) */ draw_gpencil_view2d(C, 0); } } /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not, * for now just disable drawing since the strip frame will likely be offset */ //if (sc->mode == SC_MODE_MASKEDIT) { if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) { Mask *mask = BKE_sequencer_mask_get(scene); if (mask) { int width, height; float aspx = 1.0f, aspy = 1.0f; // ED_mask_get_size(C, &width, &height); //Scene *scene = CTX_data_scene(C); width = (scene->r.size * scene->r.xsch) / 100; height = (scene->r.size * scene->r.ysch) / 100; ED_mask_draw_region(mask, ar, 0, 0, /* TODO */ width, height, aspx, aspy, FALSE, TRUE, NULL, C); } } if (cache_handle) IMB_display_buffer_release(cache_handle); }