/** Save the current OpenGL state and initialize OpenGL for 2D * rendering. glaEnd2DDraw should be called on the returned structure * to free it and to return OpenGL to its previous state. The * scissor rectangle is set to match the viewport. * * See glaDefine2DArea for an explanation of why this function uses integers. * * \param screen_rect The screen rectangle to be used for 2D drawing. * \param world_rect The world rectangle that the 2D area represented * by \a screen_rect is supposed to represent. If NULL it is assumed the * world has a 1 to 1 mapping to the screen. */ gla2DDrawInfo *glaBegin2DDraw(rcti *screen_rect, rctf *world_rect) { gla2DDrawInfo *di = MEM_mallocN(sizeof(*di), "gla2DDrawInfo"); int sc_w, sc_h; float wo_w, wo_h; glGetIntegerv(GL_VIEWPORT, (GLint *)di->orig_vp); glGetIntegerv(GL_SCISSOR_BOX, (GLint *)di->orig_sc); glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)di->orig_projmat); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)di->orig_viewmat); di->screen_rect = *screen_rect; if (world_rect) { di->world_rect = *world_rect; } else { di->world_rect.xmin = di->screen_rect.xmin; di->world_rect.ymin = di->screen_rect.ymin; di->world_rect.xmax = di->screen_rect.xmax; di->world_rect.ymax = di->screen_rect.ymax; } sc_w = BLI_rcti_size_x(&di->screen_rect); sc_h = BLI_rcti_size_y(&di->screen_rect); wo_w = BLI_rcti_size_x(&di->world_rect); wo_h = BLI_rcti_size_y(&di->world_rect); di->wo_to_sc[0] = sc_w / wo_w; di->wo_to_sc[1] = sc_h / wo_h; glaDefine2DArea(&di->screen_rect); return di; }
/* Transform buffer from role to scene linear space using GLSL OCIO conversion * * See IMB_colormanagement_setup_transform_from_role_glsl description for * some more details * * NOTE: this only works for RGBA buffers! */ int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role) { GPUOffScreen *ofs; char err_out[256]; rcti display_rect; ofs = GPU_offscreen_create(width, height, err_out); if (!ofs) return FALSE; GPU_offscreen_bind(ofs); if (!IMB_colormanagement_setup_transform_from_role_glsl(role, TRUE)) { GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); return FALSE; } BLI_rcti_init(&display_rect, 0, width, 0, height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glaDefine2DArea(&display_rect); glaDrawPixelsTex(0, 0, width, height, GL_RGBA, GL_FLOAT, GL_NEAREST, buffer); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); GPU_offscreen_read_pixels(ofs, GL_FLOAT, buffer); IMB_colormanagement_finish_glsl_transform(); /* unbind */ GPU_offscreen_unbind(ofs); GPU_offscreen_free(ofs); return TRUE; }
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); }