void render_view3d_draw(RenderEngine *engine, const bContext *C)
{
	Render *re = engine->re;
	RenderResult rres;
	int keep_data = render_view3d_changed(engine, C);
	
	if (engine->flag & RE_ENGINE_DO_UPDATE)
		render_view3d_do(engine, C, keep_data);

	if (re == NULL) return;
	
	RE_AcquireResultImage(re, &rres);
	
	if (rres.rectf) {
		Scene *scene = CTX_data_scene(C);
		bool force_fallback = false;
		bool need_fallback = true;
		float dither = scene->r.dither_intensity;

		/* Dithering is not supported on GLSL yet */
		force_fallback |= dither != 0.0f;

		/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
		force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);

		/* Try using GLSL display transform. */
		if (force_fallback == false) {
			if (IMB_colormanagement_setup_glsl_draw(NULL, &scene->display_settings, TRUE)) {
				glEnable(GL_BLEND);
				glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
				glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT,
				                 GL_LINEAR, rres.rectf);
				glDisable(GL_BLEND);

				IMB_colormanagement_finish_glsl_draw();
				need_fallback = false;
			}
		}

		/* If GLSL failed, use old-school CPU-based transform. */
		if (need_fallback) {
			unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char),
			                                            "render_view3d_draw");

			IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty,
			                                              4, dither, NULL, &scene->display_settings);

			glEnable(GL_BLEND);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glaDrawPixelsAuto(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_UNSIGNED_BYTE,
			                  GL_LINEAR, display_buffer);
			glDisable(GL_BLEND);

			MEM_freeN(display_buffer);
		}
	}

	RE_ReleaseResultImage(re);
}
Esempio n. 2
0
/* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */
void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect)
{
	if (U.image_draw_method != IMAGE_DRAW_METHOD_DRAWPIXELS) {
		glColor4f(1.0, 1.0, 1.0, 1.0);
		glaDrawPixelsTex(x, y, img_w, img_h, format, type, zoomfilter, rect);
	}
	else {
		glaDrawPixelsSafe(x, y, img_w, img_h, img_w, format, type, rect);
	}
}
Esempio n. 3
0
/* 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;
}
Esempio n. 4
0
/* Draw given image buffer on a screen using GLSL for display transform */
void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
                       ColorManagedViewSettings *view_settings,
                       ColorManagedDisplaySettings *display_settings)
{
	bool force_fallback = false;
	bool need_fallback = true;

	/* Early out */
	if (ibuf->rect == NULL && ibuf->rect_float == NULL)
		return;

	/* Dithering is not supported on GLSL yet */
	force_fallback |= ibuf->dither != 0.0f;

	/* Single channel images could not be transformed using GLSL yet */
	force_fallback |= ibuf->channels == 1;

	/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
	force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);

	/* This is actually lots of crap, but currently not sure about
	 * more clear way to bypass partial buffer update crappyness
	 * while rendering.
	 *
	 * The thing is -- render engines are only updating byte and
	 * display buffers for active render result opened in image
	 * editor. This works fine to show render progress without
	 * switching render layers in image editor user, but this is
	 * completely useless for GLSL display, where we need to have
	 * original buffer which we could color manage.
	 *
	 * For the time of rendering, we'll stick back to slower CPU
	 * display buffer update. GLSL could be used as soon as some
	 * fixes (?) are done in render itself, so we'll always have
	 * image buffer with relevant float buffer opened while
	 * rendering.
	 *
	 * On the other hand, when using Cycles, stressing GPU with
	 * GLSL could backfire on a performance.
	 *                                         - sergey -
	 */
	if (G.is_rendering) {
		/* Try to detect whether we're drawing render result,
		 * other images could have both rect and rect_float
		 * but they'll be synchronized
		 */
		if (ibuf->rect_float && ibuf->rect &&
		    ((ibuf->mall & IB_rectfloat) == 0))
		{
			force_fallback = true;
		}
	}

	/* Try to draw buffer using GLSL display transform */
	if (force_fallback == false) {
		int ok;

		if (ibuf->rect_float) {
			if (ibuf->float_colorspace) {
				ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
				                                                    ibuf->float_colorspace, TRUE);
			}
			else {
				ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, TRUE);
			}
		}
		else {
			ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
			                                                    ibuf->rect_colorspace, FALSE);
		}

		if (ok) {
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glColor4f(1.0, 1.0, 1.0, 1.0);

			if (ibuf->rect_float) {
				int format = 0;

				if (ibuf->channels == 3)
					format = GL_RGB;
				else if (ibuf->channels == 4)
					format = GL_RGBA;
				else
					BLI_assert(!"Incompatible number of channels for GLSL display");

				if (format != 0) {
					glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
					                 zoomfilter, ibuf->rect_float);
				}
			}
			else if (ibuf->rect) {
				/* ibuf->rect is always RGBA */
				glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
				                 zoomfilter, ibuf->rect);
			}

			IMB_colormanagement_finish_glsl_draw();

			need_fallback = false;
		}
	}

	/* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */
	if (need_fallback) {
		unsigned char *display_buffer;
		void *cache_handle;

		display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);

		if (display_buffer)
			glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
			                  zoomfilter, display_buffer);

		IMB_display_buffer_release(cache_handle);
	}
}
Esempio n. 5
0
void render_view3d_draw(RenderEngine *engine, const bContext *C)
{
	Render *re = engine->re;
	RenderResult rres;
	char name[32];
	
	render_view3d_do(engine, C);
	
	if (re == NULL) {
		sprintf(name, "View3dPreview %p", (void *)CTX_wm_region(C));
		re = RE_GetRender(name);
	
		if (re == NULL) return;
	}
	
	/* Viewport render preview doesn't support multiview, view hardcoded to 0 */
	RE_AcquireResultImage(re, &rres, 0);
	
	if (rres.rectf) {
		RegionView3D *rv3d = CTX_wm_region_view3d(C);
		View3D *v3d = CTX_wm_view3d(C);
		Scene *scene = CTX_data_scene(C);
		ARegion *ar = CTX_wm_region(C);
		bool force_fallback = false;
		bool need_fallback = true;
		float dither = scene->r.dither_intensity;
		float scale_x, scale_y;
		rcti clip_rect;
		int xof, yof;

		if (render_view3d_disprect(scene, ar, v3d, rv3d, &clip_rect)) {
			scale_x = (float) BLI_rcti_size_x(&clip_rect) / rres.rectx;
			scale_y = (float) BLI_rcti_size_y(&clip_rect) / rres.recty;
			xof = clip_rect.xmin;
			yof = clip_rect.ymin;
		}
		else {
			scale_x = (float) ar->winx / rres.rectx;
			scale_y = (float) ar->winy / rres.recty;
			xof = rres.xof;
			yof = rres.yof;
		}

		/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
		force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);

		/* Try using GLSL display transform. */
		if (force_fallback == false) {
			if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, dither, true)) {
				glEnable(GL_BLEND);
				glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
				glPixelZoom(scale_x, scale_y);
				glaDrawPixelsTex(xof, yof, rres.rectx, rres.recty,
				                 GL_RGBA, GL_FLOAT, GL_NEAREST, rres.rectf);
				glPixelZoom(1.0f, 1.0f);
				glDisable(GL_BLEND);

				IMB_colormanagement_finish_glsl_draw();
				need_fallback = false;
			}
		}

		/* If GLSL failed, use old-school CPU-based transform. */
		if (need_fallback) {
			unsigned char *display_buffer = MEM_mallocN(4 * rres.rectx * rres.recty * sizeof(char),
			                                            "render_view3d_draw");

			IMB_colormanagement_buffer_make_display_space(rres.rectf, display_buffer, rres.rectx, rres.recty,
			                                              4, dither, &scene->view_settings, &scene->display_settings);

			glEnable(GL_BLEND);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			glPixelZoom(scale_x, scale_y);
			glaDrawPixelsAuto(xof, yof, rres.rectx, rres.recty,
			                  GL_RGBA, GL_UNSIGNED_BYTE,
			                  GL_NEAREST, display_buffer);
			glPixelZoom(1.0f, 1.0f);
			glDisable(GL_BLEND);

			MEM_freeN(display_buffer);
		}
	}

	RE_ReleaseResultImage(re);
}
Esempio n. 6
0
/* sets up the opengl context.
 * width, height are to match the values from ED_mask_get_size() */
void ED_mask_draw_region(Mask *mask, ARegion *ar,
                         const char draw_flag, const char draw_type, const char overlay_mode,
                         const int width_i, const int height_i,  /* convert directly into aspect corrected vars */
                         const float aspx, const float aspy,
                         const bool do_scale_applied, const bool do_draw_cb,
                         float stabmat[4][4], /* optional - only used by clip */
                         const bContext *C    /* optional - only used when do_post_draw is set or called from clip editor */
                         )
{
	struct View2D *v2d = &ar->v2d;

	/* aspect always scales vertically in movie and image spaces */
	const float width = width_i, height = (float)height_i * (aspy / aspx);

	int x, y;
	/* int w, h; */
	float zoomx, zoomy;

	/* frame image */
	float maxdim;
	float xofs, yofs;

	/* find window pixel coordinates of origin */
	UI_view2d_view_to_region(&ar->v2d, 0.0f, 0.0f, &x, &y);


	/* w = BLI_rctf_size_x(&v2d->tot); */
	/* h = BLI_rctf_size_y(&v2d->tot); */


	zoomx = (float)(BLI_rcti_size_x(&ar->winrct) + 1) / BLI_rctf_size_x(&ar->v2d.cur);
	zoomy = (float)(BLI_rcti_size_y(&ar->winrct) + 1) / BLI_rctf_size_y(&ar->v2d.cur);

	if (do_scale_applied) {
		zoomx /= width;
		zoomy /= height;
	}

	x += v2d->tot.xmin * zoomx;
	y += v2d->tot.ymin * zoomy;

	/* frame the image */
	maxdim = max_ff(width, height);
	if (width == height) {
		xofs = yofs = 0;
	}
	else if (width < height) {
		xofs = ((height - width) / -2.0f) * zoomx;
		yofs = 0.0f;
	}
	else { /* (width > height) */
		xofs = 0.0f;
		yofs = ((width - height) / -2.0f) * zoomy;
	}

	if (draw_flag & MASK_DRAWFLAG_OVERLAY) {
		float *buffer = threaded_mask_rasterize(mask, width, height);
		int format;

		if (overlay_mode == MASK_OVERLAY_ALPHACHANNEL) {
			glColor3f(1.0f, 1.0f, 1.0f);
			format = GL_LUMINANCE;
		}
		else {
			/* More blending types could be supported in the future. */
			glEnable(GL_BLEND);
			glBlendFunc(GL_DST_COLOR, GL_SRC_ALPHA);
			format = GL_ALPHA;
		}

		glPushMatrix();
		glTranslatef(x, y, 0);
		glScalef(zoomx, zoomy, 0);
		if (stabmat) {
			glMultMatrixf(stabmat);
		}
		glaDrawPixelsTex(0.0f, 0.0f, width, height, format, GL_FLOAT, GL_NEAREST, buffer);
		glPopMatrix();

		if (overlay_mode != MASK_OVERLAY_ALPHACHANNEL) {
			glDisable(GL_BLEND);
		}

		MEM_freeN(buffer);
	}

	/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
	glPushMatrix();

	if (stabmat) {
		glMultMatrixf(stabmat);
	}

	glTranslatef(x + xofs, y + yofs, 0);
	glScalef(maxdim * zoomx, maxdim * zoomy, 0);

	if (do_draw_cb) {
		ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
	}

	/* draw! */
	draw_masklays(C, mask, draw_flag, draw_type, width, height, maxdim * zoomx, maxdim * zoomy);

	if (do_draw_cb) {
		ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
	}

	glPopMatrix();
}
Esempio n. 7
0
/* Draw given image buffer on a screen using GLSL for display transform */
void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
                       ColorManagedViewSettings *view_settings,
                       ColorManagedDisplaySettings *display_settings)
{
	bool force_fallback = false;
	bool need_fallback = true;

	/* Early out */
	if (ibuf->rect == NULL && ibuf->rect_float == NULL)
		return;

	/* Single channel images could not be transformed using GLSL yet */
	force_fallback |= ibuf->channels == 1;

	/* If user decided not to use GLSL, fallback to glaDrawPixelsAuto */
	force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);

	/* Try to draw buffer using GLSL display transform */
	if (force_fallback == false) {
		int ok;

		if (ibuf->rect_float) {
			if (ibuf->float_colorspace) {
				ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
				                                                    ibuf->float_colorspace,
				                                                    ibuf->dither, true);
			}
			else {
				ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings,
				                                         ibuf->dither, true);
			}
		}
		else {
			ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
			                                                    ibuf->rect_colorspace,
			                                                    ibuf->dither, false);
		}

		if (ok) {
			glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
			glColor4f(1.0, 1.0, 1.0, 1.0);

			if (ibuf->rect_float) {
				int format = 0;

				if (ibuf->channels == 3)
					format = GL_RGB;
				else if (ibuf->channels == 4)
					format = GL_RGBA;
				else
					BLI_assert(!"Incompatible number of channels for GLSL display");

				if (format != 0) {
					glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
					                 zoomfilter, ibuf->rect_float);
				}
			}
			else if (ibuf->rect) {
				/* ibuf->rect is always RGBA */
				glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
				                 zoomfilter, ibuf->rect);
			}

			IMB_colormanagement_finish_glsl_draw();

			need_fallback = false;
		}
	}

	/* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */
	if (need_fallback) {
		unsigned char *display_buffer;
		void *cache_handle;

		display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle);

		if (display_buffer)
			glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
			                  zoomfilter, display_buffer);

		IMB_display_buffer_release(cache_handle);
	}
}