Esempio n. 1
0
static int view_all_exec(bContext *C, wmOperator *UNUSED(op))
{
	Scene *scene = CTX_data_scene(C);
	ARegion *ar = CTX_wm_region(C);
	SpaceClip *sc = CTX_wm_space_clip(C);
	View2D *v2d = &ar->v2d;
	ViewAllUserData userdata;
	float extra;

	userdata.max = -FLT_MAX;
	userdata.min = FLT_MAX;

	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &userdata, view_all_cb, NULL, NULL);

	/* set extents of view to start/end frames */
	v2d->cur.xmin = (float) SFRA;
	v2d->cur.xmax = (float) EFRA;

	if (userdata.min < userdata.max) {
		v2d->cur.ymin = userdata.min;
		v2d->cur.ymax = userdata.max;
	}
	else {
		v2d->cur.ymin = -10;
		v2d->cur.ymax = 10;
	}

	/* we need an extra "buffer" factor on either side so that the endpoints are visible */
	extra = 0.01f * BLI_rctf_size_x(&v2d->cur);
	v2d->cur.xmin -= extra;
	v2d->cur.xmax += extra;

	extra = 0.01f * BLI_rctf_size_y(&v2d->cur);
	v2d->cur.ymin -= extra;
	v2d->cur.ymax += extra;

	ED_region_tag_redraw(ar);

	return OPERATOR_FINISHED;
}
Esempio n. 2
0
/* Convert Grease Pencil points to screen-space values
 * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
 */
void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
                    int *r_x, int *r_y)
{
	ARegion *ar = gsc->ar;
	View2D *v2d = gsc->v2d;
	rctf *subrect = gsc->subrect;
	int xyval[2];
	
	/* sanity checks */
	BLI_assert(!(gps->flag & GP_STROKE_3DSPACE) || (gsc->sa->spacetype == SPACE_VIEW3D));
	BLI_assert(!(gps->flag & GP_STROKE_2DSPACE) || (gsc->sa->spacetype != SPACE_VIEW3D));
	
	
	if (gps->flag & GP_STROKE_3DSPACE) {
		if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
			*r_x = xyval[0];
			*r_y = xyval[1];
		}
		else {
			*r_x = V2D_IS_CLIPPED;
			*r_y = V2D_IS_CLIPPED;
		}
	}
	else if (gps->flag & GP_STROKE_2DSPACE) {
		float vec[3] = {pt->x, pt->y, 0.0f};
		mul_m4_v3(gsc->mat, vec);
		UI_view2d_view_to_region_clip(v2d, vec[0], vec[1], r_x, r_y);
	}
	else {
		if (subrect == NULL) {
			/* normal 3D view (or view space) */
			*r_x = (int)(pt->x / 100 * ar->winx);
			*r_y = (int)(pt->y / 100 * ar->winy);
		}
		else {
			/* camera view, use subrect */
			*r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin;
			*r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin;
		}
	}
}
Esempio n. 3
0
static void drawWalkPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg)
{
	/* draws an aim/cross in the center */
	WalkInfo *walk = arg;

	const int outter_length = 24;
	const int inner_length = 14;
	int xoff, yoff;
	rctf viewborder;

	if (walk->scene->camera) {
		ED_view3d_calc_camera_border(walk->scene, ar, walk->v3d, walk->rv3d, &viewborder, false);
		xoff = viewborder.xmin + BLI_rctf_size_x(&viewborder) * 0.5f;
		yoff = viewborder.ymin + BLI_rctf_size_y(&viewborder) * 0.5f;
	}
	else {
		xoff = walk->ar->winx / 2;
		yoff = walk->ar->winy / 2;
	}

	cpack(0);

	glBegin(GL_LINES);
	/* North */
	glVertex2i(xoff, yoff + inner_length);
	glVertex2i(xoff, yoff + outter_length);

	/* East */
	glVertex2i(xoff + inner_length, yoff);
	glVertex2i(xoff + outter_length, yoff);

	/* South */
	glVertex2i(xoff, yoff - inner_length);
	glVertex2i(xoff, yoff - outter_length);

	/* West */
	glVertex2i(xoff - inner_length, yoff);
	glVertex2i(xoff - outter_length, yoff);
	glEnd();
}
Esempio n. 4
0
/* convert the coordinates from the given stroke point into 3d-coordinates 
 *	- assumes that the active space is the 3D-View
 */
static void gp_strokepoint_convertcoords(bContext *C, bGPDstroke *gps, bGPDspoint *pt, float p3d[3], rctf *subrect)
{
	Scene *scene = CTX_data_scene(C);
	View3D *v3d = CTX_wm_view3d(C);
	ARegion *ar = CTX_wm_region(C);
	
	if (gps->flag & GP_STROKE_3DSPACE) {
		/* directly use 3d-coordinates */
		copy_v3_v3(p3d, &pt->x);
	}
	else {
		const float *fp = give_cursor(scene, v3d);
		float mvalf[2];
		
		/* get screen coordinate */
		if (gps->flag & GP_STROKE_2DSPACE) {
			int mvali[2];
			View2D *v2d = &ar->v2d;
			UI_view2d_view_to_region(v2d, pt->x, pt->y, mvali, mvali + 1);
			VECCOPY2D(mvalf, mvali);
		}
		else {
			if (subrect) {
				mvalf[0] = (((float)pt->x / 100.0f) * BLI_rctf_size_x(subrect)) + subrect->xmin;
				mvalf[1] = (((float)pt->y / 100.0f) * BLI_rctf_size_y(subrect)) + subrect->ymin;
			}
			else {
				mvalf[0] = (float)pt->x / 100.0f * ar->winx;
				mvalf[1] = (float)pt->y / 100.0f * ar->winy;
			}
		}
		
		/* convert screen coordinate to 3d coordinates 
		 *	- method taken from editview.c - mouse_cursor() 
		 */
		ED_view3d_win_to_3d(ar, fp, mvalf, p3d);
	}
}
Esempio n. 5
0
static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
{
	wmWindow *win = CTX_wm_window(C);
	rctf viewborder;

	float upvec[3]; /* tmp */
	float mat[3][3];

	fly->rv3d = CTX_wm_region_view3d(C);
	fly->v3d = CTX_wm_view3d(C);
	fly->ar = CTX_wm_region(C);
	fly->scene = CTX_data_scene(C);

#ifdef NDOF_FLY_DEBUG
	puts("\n-- fly begin --");
#endif

	/* sanity check: for rare but possible case (if lib-linking the camera fails) */
	if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) {
		fly->rv3d->persp = RV3D_PERSP;
	}

	if (fly->rv3d->persp == RV3D_CAMOB && ID_IS_LINKED(fly->v3d->camera)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library");
		return false;
	}

	if (ED_view3d_offset_lock_check(fly->v3d, fly->rv3d)) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly when the view offset is locked");
		return false;
	}

	if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->constraints.first) {
		BKE_report(op->reports, RPT_ERROR, "Cannot fly an object with constraints");
		return false;
	}

	fly->state = FLY_RUNNING;
	fly->speed = 0.0f;
	fly->axis = 2;
	fly->pan_view = false;
	fly->xlock = FLY_AXISLOCK_STATE_OFF;
	fly->zlock = FLY_AXISLOCK_STATE_OFF;
	fly->xlock_momentum = 0.0f;
	fly->zlock_momentum = 0.0f;
	fly->grid = 1.0f;
	fly->use_precision = false;
	fly->use_freelook = false;

#ifdef NDOF_FLY_DRAW_TOOMUCH
	fly->redraw = 1;
#endif
	zero_v3(fly->dvec_prev);

	fly->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f);

	copy_v2_v2_int(fly->mval, event->mval);

#ifdef WITH_INPUT_NDOF
	fly->ndof = NULL;
#endif

	fly->time_lastdraw = fly->time_lastwheel = PIL_check_seconds_timer();

	fly->draw_handle_pixel = ED_region_draw_cb_activate(fly->ar->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);

	fly->rv3d->rflag |= RV3D_NAVIGATING;

	/* detect whether to start with Z locking */
	copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f);
	copy_m3_m4(mat, fly->rv3d->viewinv);
	mul_m3_v3(mat, upvec);
	if (fabsf(upvec[2]) < 0.1f) {
		fly->zlock = FLY_AXISLOCK_STATE_IDLE;
	}

	fly->v3d_camera_control = ED_view3d_cameracontrol_acquire(
	        fly->scene, fly->v3d, fly->rv3d,
	        (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0);

	/* calculate center */
	if (fly->scene->camera) {
		ED_view3d_calc_camera_border(fly->scene, fly->ar, fly->v3d, fly->rv3d, &viewborder, false);

		fly->width = BLI_rctf_size_x(&viewborder);
		fly->height = BLI_rctf_size_y(&viewborder);

		fly->center_mval[0] = viewborder.xmin + fly->width / 2;
		fly->center_mval[1] = viewborder.ymin + fly->height / 2;
	}
	else {
		fly->width = fly->ar->winx;
		fly->height = fly->ar->winy;

		fly->center_mval[0] = fly->width / 2;
		fly->center_mval[1] = fly->height / 2;
	}

	/* center the mouse, probably the UI mafia are against this but without its quite annoying */
	WM_cursor_warp(win, fly->ar->winrct.xmin + fly->center_mval[0], fly->ar->winrct.ymin + fly->center_mval[1]);

	fly_update_header(C, op, fly);
	return 1;
}
Esempio n. 6
0
void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
{
	const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
	Scopes *scopes = (Scopes *)but->poin;
	rctf rect;
	int i, j;
	float w, h, centerx, centery, diam;
	float alpha;
	const float colors[6][3] = {
	    {0.75, 0.0, 0.0},  {0.75, 0.75, 0.0}, {0.0, 0.75, 0.0},
	    {0.0, 0.75, 0.75}, {0.0, 0.0, 0.75},  {0.75, 0.0, 0.75}};
	GLint scissor[4];
	
	rect.xmin = (float)recti->xmin + 1;
	rect.xmax = (float)recti->xmax - 1;
	rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
	rect.ymax = (float)recti->ymax - 1;
	
	w = BLI_rctf_size_x(&rect);
	h = BLI_rctf_size_y(&rect);
	centerx = rect.xmin + w / 2;
	centery = rect.ymin + h / 2;
	diam = (w < h) ? w : h;
	
	alpha = scopes->vecscope_alpha * scopes->vecscope_alpha * scopes->vecscope_alpha;
			
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	glColor4f(0.f, 0.f, 0.f, 0.3f);
	uiSetRoundBox(UI_CNR_ALL);
	uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);

	/* need scissor test, hvectorscope can draw outside of boundary */
	glGetIntegerv(GL_VIEWPORT, scissor);
	glScissor(ar->winrct.xmin + (rect.xmin - 1),
	          ar->winrct.ymin + (rect.ymin - 1),
	          (rect.xmax + 1) - (rect.xmin - 1),
	          (rect.ymax + 1) - (rect.ymin - 1));
	
	glColor4f(1.f, 1.f, 1.f, 0.08f);
	/* draw grid elements */
	/* cross */
	fdrawline(centerx - (diam / 2) - 5, centery, centerx + (diam / 2) + 5, centery);
	fdrawline(centerx, centery - (diam / 2) - 5, centerx, centery + (diam / 2) + 5);
	/* circles */
	for (j = 0; j < 5; j++) {
		glBegin(GL_LINE_STRIP);
		for (i = 0; i <= 360; i = i + 15) {
			const float a = DEG2RADF((float)i);
			const float r = (j + 1) / 10.0f;
			glVertex2f(polar_to_x(centerx, diam, r, a), polar_to_y(centery, diam, r, a));
		}
		glEnd();
	}
	/* skin tone line */
	glColor4f(1.f, 0.4f, 0.f, 0.2f);
	fdrawline(polar_to_x(centerx, diam, 0.5f, skin_rad), polar_to_y(centery, diam, 0.5, skin_rad),
	          polar_to_x(centerx, diam, 0.1f, skin_rad), polar_to_y(centery, diam, 0.1, skin_rad));
	/* saturation points */
	for (i = 0; i < 6; i++)
		vectorscope_draw_target(centerx, centery, diam, colors[i]);
	
	if (scopes->ok && scopes->vecscope != NULL) {
		/* pixel point cloud */
		glBlendFunc(GL_ONE, GL_ONE);
		glColor3f(alpha, alpha, alpha);

		glPushMatrix();
		glEnableClientState(GL_VERTEX_ARRAY);

		glTranslatef(centerx, centery, 0.f);
		glScalef(diam, diam, 0.f);

		glVertexPointer(2, GL_FLOAT, 0, scopes->vecscope);
		glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
		
		glDisableClientState(GL_VERTEX_ARRAY);
		glPopMatrix();
	}

	/* outline, scale gripper */
	draw_scope_end(&rect, scissor);
		
	glDisable(GL_BLEND);
}
Esempio n. 7
0
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
{
	Scopes *scopes = (Scopes *)but->poin;
	rctf rect;
	int i, c;
	float w, w3, h, alpha, yofs;
	GLint scissor[4];
	float colors[3][3] = MAT3_UNITY;
	float colorsycc[3][3] = {{1, 0, 1}, {1, 1, 0}, {0, 1, 1}};
	float colors_alpha[3][3], colorsycc_alpha[3][3]; /* colors  pre multiplied by alpha for speed up */
	float min, max;
	
	if (scopes == NULL) return;
	
	rect.xmin = (float)recti->xmin + 1;
	rect.xmax = (float)recti->xmax - 1;
	rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
	rect.ymax = (float)recti->ymax - 1;

	if (scopes->wavefrm_yfac < 0.5f)
		scopes->wavefrm_yfac = 0.98f;
	w = BLI_rctf_size_x(&rect) - 7;
	h = BLI_rctf_size_y(&rect) * scopes->wavefrm_yfac;
	yofs = rect.ymin + (BLI_rctf_size_y(&rect) - h) / 2.0f;
	w3 = w / 3.0f;
	
	/* log scale for alpha */
	alpha = scopes->wavefrm_alpha * scopes->wavefrm_alpha;
	
	for (c = 0; c < 3; c++) {
		for (i = 0; i < 3; i++) {
			colors_alpha[c][i] = colors[c][i] * alpha;
			colorsycc_alpha[c][i] = colorsycc[c][i] * alpha;
		}
	}
			
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	glColor4f(0.f, 0.f, 0.f, 0.3f);
	uiSetRoundBox(UI_CNR_ALL);
	uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);
	

	/* need scissor test, waveform can draw outside of boundary */
	glGetIntegerv(GL_VIEWPORT, scissor);
	glScissor(ar->winrct.xmin + (rect.xmin - 1),
	          ar->winrct.ymin + (rect.ymin - 1),
	          (rect.xmax + 1) - (rect.xmin - 1),
	          (rect.ymax + 1) - (rect.ymin - 1));

	glColor4f(1.f, 1.f, 1.f, 0.08f);
	/* draw grid lines here */
	for (i = 0; i < 6; i++) {
		char str[4];
		BLI_snprintf(str, sizeof(str), "%-3d", i * 20);
		str[3] = '\0';
		fdrawline(rect.xmin + 22, yofs + (i / 5.f) * h, rect.xmax + 1, yofs + (i / 5.f) * h);
		BLF_draw_default(rect.xmin + 1, yofs - 5 + (i / 5.f) * h, 0, str, sizeof(str) - 1);
		/* in the loop because blf_draw reset it */
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	/* 3 vertical separation */
	if (scopes->wavefrm_mode != SCOPES_WAVEFRM_LUMA) {
		for (i = 1; i < 3; i++) {
			fdrawline(rect.xmin + i * w3, rect.ymin, rect.xmin + i * w3, rect.ymax);
		}
	}
	
	/* separate min max zone on the right */
	fdrawline(rect.xmin + w, rect.ymin, rect.xmin + w, rect.ymax);
	/* 16-235-240 level in case of ITU-R BT601/709 */
	glColor4f(1.f, 0.4f, 0.f, 0.2f);
	if (ELEM(scopes->wavefrm_mode, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709)) {
		fdrawline(rect.xmin + 22, yofs + h * 16.0f / 255.0f, rect.xmax + 1, yofs + h * 16.0f / 255.0f);
		fdrawline(rect.xmin + 22, yofs + h * 235.0f / 255.0f, rect.xmin + w3, yofs + h * 235.0f / 255.0f);
		fdrawline(rect.xmin + 3 * w3, yofs + h * 235.0f / 255.0f, rect.xmax + 1, yofs + h * 235.0f / 255.0f);
		fdrawline(rect.xmin + w3, yofs + h * 240.0f / 255.0f, rect.xmax + 1, yofs + h * 240.0f / 255.0f);
	}
	/* 7.5 IRE black point level for NTSC */
	if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA)
		fdrawline(rect.xmin, yofs + h * 0.075f, rect.xmax + 1, yofs + h * 0.075f);

	if (scopes->ok && scopes->waveform_1 != NULL) {
		
		/* LUMA (1 channel) */
		glBlendFunc(GL_ONE, GL_ONE);
		glColor3f(alpha, alpha, alpha);
		if (scopes->wavefrm_mode == SCOPES_WAVEFRM_LUMA) {

			glBlendFunc(GL_ONE, GL_ONE);
			
			glPushMatrix();
			glEnableClientState(GL_VERTEX_ARRAY);
			
			glTranslatef(rect.xmin, yofs, 0.f);
			glScalef(w, h, 0.f);
			glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
			glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
					
			glDisableClientState(GL_VERTEX_ARRAY);
			glPopMatrix();

			/* min max */
			glColor3f(0.5f, 0.5f, 0.5f);
			min = yofs + scopes->minmax[0][0] * h;
			max = yofs + scopes->minmax[0][1] * h;
			CLAMP(min, rect.ymin, rect.ymax);
			CLAMP(max, rect.ymin, rect.ymax);
			fdrawline(rect.xmax - 3, min, rect.xmax - 3, max);
		}

		/* RGB / YCC (3 channels) */
		else if (ELEM4(scopes->wavefrm_mode,
		               SCOPES_WAVEFRM_RGB,
		               SCOPES_WAVEFRM_YCC_601,
		               SCOPES_WAVEFRM_YCC_709,
		               SCOPES_WAVEFRM_YCC_JPEG))
		{
			int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB);
			
			glBlendFunc(GL_ONE, GL_ONE);
			
			glPushMatrix();
			glEnableClientState(GL_VERTEX_ARRAY);
			
			glTranslatef(rect.xmin, yofs, 0.f);
			glScalef(w3, h, 0.f);
			
			glColor3fv((rgb) ? colors_alpha[0] : colorsycc_alpha[0]);
			glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_1);
			glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);

			glTranslatef(1.f, 0.f, 0.f);
			glColor3fv((rgb) ? colors_alpha[1] : colorsycc_alpha[1]);
			glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_2);
			glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
			
			glTranslatef(1.f, 0.f, 0.f);
			glColor3fv((rgb) ? colors_alpha[2] : colorsycc_alpha[2]);
			glVertexPointer(2, GL_FLOAT, 0, scopes->waveform_3);
			glDrawArrays(GL_POINTS, 0, scopes->waveform_tot);
			
			glDisableClientState(GL_VERTEX_ARRAY);
			glPopMatrix();

			
			/* min max */
			for (c = 0; c < 3; c++) {
				if (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB)
					glColor3f(colors[c][0] * 0.75f, colors[c][1] * 0.75f, colors[c][2] * 0.75f);
				else
					glColor3f(colorsycc[c][0] * 0.75f, colorsycc[c][1] * 0.75f, colorsycc[c][2] * 0.75f);
				min = yofs + scopes->minmax[c][0] * h;
				max = yofs + scopes->minmax[c][1] * h;
				CLAMP(min, rect.ymin, rect.ymax);
				CLAMP(max, rect.ymin, rect.ymax);
				fdrawline(rect.xmin + w + 2 + c * 2, min, rect.xmin + w + 2 + c * 2, max);
			}
		}
		
	}
	
	/* outline, scale gripper */
	draw_scope_end(&rect, scissor);
}
Esempio n. 8
0
void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
{
	Histogram *hist = (Histogram *)but->poin;
	int res = hist->x_resolution;
	rctf rect;
	int i;
	float w, h;
	const short is_line = (hist->flag & HISTO_FLAG_LINE) != 0;
	//float alpha;
	GLint scissor[4];
	
	rect.xmin = (float)recti->xmin + 1;
	rect.xmax = (float)recti->xmax - 1;
	rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
	rect.ymax = (float)recti->ymax - 1;
	
	w = BLI_rctf_size_x(&rect);
	h = BLI_rctf_size_y(&rect) * hist->ymax;
	
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	glColor4f(0.f, 0.f, 0.f, 0.3f);
	uiSetRoundBox(UI_CNR_ALL);
	uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin - 1, rect.xmax + 1, rect.ymax + 1, 3.0f);

	/* need scissor test, histogram can draw outside of boundary */
	glGetIntegerv(GL_VIEWPORT, scissor);
	glScissor(ar->winrct.xmin + (rect.xmin - 1),
	          ar->winrct.ymin + (rect.ymin - 1),
	          (rect.xmax + 1) - (rect.xmin - 1),
	          (rect.ymax + 1) - (rect.ymin - 1));

	glColor4f(1.f, 1.f, 1.f, 0.08f);
	/* draw grid lines here */
	for (i = 1; i <= HISTOGRAM_TOT_GRID_LINES; i++) {
		const float fac = (float)i / (float)HISTOGRAM_TOT_GRID_LINES;

		/* so we can tell the 1.0 color point */
		if (i == HISTOGRAM_TOT_GRID_LINES) {
			glColor4f(1.0f, 1.0f, 1.0f, 0.5f);
		}

		fdrawline(rect.xmin, rect.ymin + fac * h, rect.xmax, rect.ymin + fac * h);
		fdrawline(rect.xmin + fac * w, rect.ymin, rect.xmin + fac * w, rect.ymax);
	}
	
	if (hist->mode == HISTO_MODE_LUMA) {
		histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_luma, res, is_line);
	}
	else if (hist->mode == HISTO_MODE_ALPHA) {
		histogram_draw_one(1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line);
	}
	else {
		if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R)
			histogram_draw_one(1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line);
		if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G)
			histogram_draw_one(0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line);
		if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B)
			histogram_draw_one(0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line);
	}
	
	/* outline, scale gripper */
	draw_scope_end(&rect, scissor);
}
/* note; only does current curvemap! */
void curvemapping_changed(CurveMapping *cumap, const bool rem_doubles)
{
	CurveMap *cuma = cumap->cm + cumap->cur;
	CurveMapPoint *cmp = cuma->curve;
	rctf *clipr = &cumap->clipr;
	float thresh = 0.01f * BLI_rctf_size_x(clipr);
	float dx = 0.0f, dy = 0.0f;
	int a;

	cumap->changed_timestamp++;

	/* clamp with clip */
	if (cumap->flag & CUMA_DO_CLIP) {
		for (a = 0; a < cuma->totpoint; a++) {
			if (cmp[a].flag & CUMA_SELECT) {
				if (cmp[a].x < clipr->xmin)
					dx = min_ff(dx, cmp[a].x - clipr->xmin);
				else if (cmp[a].x > clipr->xmax)
					dx = max_ff(dx, cmp[a].x - clipr->xmax);
				if (cmp[a].y < clipr->ymin)
					dy = min_ff(dy, cmp[a].y - clipr->ymin);
				else if (cmp[a].y > clipr->ymax)
					dy = max_ff(dy, cmp[a].y - clipr->ymax);
			}
		}
		for (a = 0; a < cuma->totpoint; a++) {
			if (cmp[a].flag & CUMA_SELECT) {
				cmp[a].x -= dx;
				cmp[a].y -= dy;
			}
		}

		/* ensure zoom-level respects clipping */
		if (BLI_rctf_size_x(&cumap->curr) > BLI_rctf_size_x(&cumap->clipr)) {
			cumap->curr.xmin = cumap->clipr.xmin;
			cumap->curr.xmax = cumap->clipr.xmax;
		}
		if (BLI_rctf_size_y(&cumap->curr) > BLI_rctf_size_y(&cumap->clipr)) {
			cumap->curr.ymin = cumap->clipr.ymin;
			cumap->curr.ymax = cumap->clipr.ymax;
		}
	}
	
	
	qsort(cmp, cuma->totpoint, sizeof(CurveMapPoint), sort_curvepoints);
	
	/* remove doubles, threshold set on 1% of default range */
	if (rem_doubles && cuma->totpoint > 2) {
		for (a = 0; a < cuma->totpoint - 1; a++) {
			dx = cmp[a].x - cmp[a + 1].x;
			dy = cmp[a].y - cmp[a + 1].y;
			if (sqrtf(dx * dx + dy * dy) < thresh) {
				if (a == 0) {
					cmp[a + 1].flag |= CUMA_VECTOR;
					if (cmp[a + 1].flag & CUMA_SELECT)
						cmp[a].flag |= CUMA_SELECT;
				}
				else {
					cmp[a].flag |= CUMA_VECTOR;
					if (cmp[a].flag & CUMA_SELECT)
						cmp[a + 1].flag |= CUMA_SELECT;
				}
				break;  /* we assume 1 deletion per edit is ok */
			}
		}
		if (a != cuma->totpoint - 1)
			curvemap_remove(cuma, 2);
	}
	curvemap_make_table(cuma, clipr);
}
Esempio n. 10
0
static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
{
	MemArena *arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 16), __func__);

	const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds);
	const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds);

	layer->buckets_x = (unsigned int)((bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);
	layer->buckets_y = (unsigned int)((bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL);

//		printf("bucket size %ux%u\n", layer->buckets_x, layer->buckets_y);

	CLAMP(layer->buckets_x, 8, 512);
	CLAMP(layer->buckets_y, 8, 512);

	layer->buckets_xy_scalar[0] = (1.0f / (bucket_dim_x + FLT_EPSILON)) * (float)layer->buckets_x;
	layer->buckets_xy_scalar[1] = (1.0f / (bucket_dim_y + FLT_EPSILON)) * (float)layer->buckets_y;

	{
		/* width and height of each bucket */
		const float bucket_size_x = (bucket_dim_x + FLT_EPSILON) / (float)layer->buckets_x;
		const float bucket_size_y = (bucket_dim_y + FLT_EPSILON) / (float)layer->buckets_y;
		const float bucket_max_rad = (max_ff(bucket_size_x, bucket_size_y) * (float)M_SQRT2) + FLT_EPSILON;
		const float bucket_max_rad_squared = bucket_max_rad * bucket_max_rad;

		unsigned int *face = &layer->face_array[0][0];
		float (*cos)[3] = layer->face_coords;

		const unsigned int  bucket_tot = layer->buckets_x * layer->buckets_y;
		LinkNode     **bucketstore     = MEM_callocN(bucket_tot * sizeof(LinkNode *),  __func__);
		unsigned int  *bucketstore_tot = MEM_callocN(bucket_tot * sizeof(unsigned int), __func__);

		unsigned int face_index;

		for (face_index = 0; face_index < layer->face_tot; face_index++, face += 4) {
			float xmin;
			float xmax;
			float ymin;
			float ymax;

			if (face[3] == TRI_VERT) {
				const float *v1 = cos[face[0]];
				const float *v2 = cos[face[1]];
				const float *v3 = cos[face[2]];

				xmin = min_ff(v1[0], min_ff(v2[0], v3[0]));
				xmax = max_ff(v1[0], max_ff(v2[0], v3[0]));
				ymin = min_ff(v1[1], min_ff(v2[1], v3[1]));
				ymax = max_ff(v1[1], max_ff(v2[1], v3[1]));
			}
			else {
				const float *v1 = cos[face[0]];
				const float *v2 = cos[face[1]];
				const float *v3 = cos[face[2]];
				const float *v4 = cos[face[3]];

				xmin = min_ff(v1[0], min_ff(v2[0], min_ff(v3[0], v4[0])));
				xmax = max_ff(v1[0], max_ff(v2[0], max_ff(v3[0], v4[0])));
				ymin = min_ff(v1[1], min_ff(v2[1], min_ff(v3[1], v4[1])));
				ymax = max_ff(v1[1], max_ff(v2[1], max_ff(v3[1], v4[1])));
			}


			/* not essential but may as will skip any faces outside the view */
			if (!((xmax < 0.0f) || (ymax < 0.0f) || (xmin > 1.0f) || (ymin > 1.0f))) {

				CLAMP(xmin, 0.0f,  1.0f);
				CLAMP(ymin, 0.0f,  1.0f);
				CLAMP(xmax, 0.0f,  1.0f);
				CLAMP(ymax, 0.0f,  1.0f);

				{
					unsigned int xi_min = (unsigned int) ((xmin - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
					unsigned int xi_max = (unsigned int) ((xmax - layer->bounds.xmin) * layer->buckets_xy_scalar[0]);
					unsigned int yi_min = (unsigned int) ((ymin - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
					unsigned int yi_max = (unsigned int) ((ymax - layer->bounds.ymin) * layer->buckets_xy_scalar[1]);
					void *face_index_void = SET_UINT_IN_POINTER(face_index);

					unsigned int xi, yi;

					/* this should _almost_ never happen but since it can in extreme cases,
					 * we have to clamp the values or we overrun the buffer and crash */
					if (xi_min >= layer->buckets_x) xi_min = layer->buckets_x - 1;
					if (xi_max >= layer->buckets_x) xi_max = layer->buckets_x - 1;
					if (yi_min >= layer->buckets_y) yi_min = layer->buckets_y - 1;
					if (yi_max >= layer->buckets_y) yi_max = layer->buckets_y - 1;

					for (yi = yi_min; yi <= yi_max; yi++) {
						unsigned int bucket_index = (layer->buckets_x * yi) + xi_min;
						for (xi = xi_min; xi <= xi_max; xi++, bucket_index++) {
							// unsigned int bucket_index = (layer->buckets_x * yi) + xi; /* correct but do in outer loop */

							BLI_assert(xi < layer->buckets_x);
							BLI_assert(yi < layer->buckets_y);
							BLI_assert(bucket_index < bucket_tot);

							/* check if the bucket intersects with the face */
							/* note: there is a trade off here since checking box/tri intersections isn't
							 * as optimal as it could be, but checking pixels against faces they will never intersect
							 * with is likely the greater slowdown here - so check if the cell intersects the face */
							if (layer_bucket_isect_test(layer, face_index,
							                            xi, yi,
							                            bucket_size_x, bucket_size_y,
							                            bucket_max_rad_squared))
							{
								BLI_linklist_prepend_arena(&bucketstore[bucket_index], face_index_void, arena);
								bucketstore_tot[bucket_index]++;
							}
						}
					}
				}
			}
		}

		if (1) {
			/* now convert linknodes into arrays for faster per pixel access */
			unsigned int  **buckets_face = MEM_mallocN(bucket_tot * sizeof(*buckets_face), __func__);
			unsigned int bucket_index;

			for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
				if (bucketstore_tot[bucket_index]) {
					unsigned int  *bucket = MEM_mallocN((bucketstore_tot[bucket_index] + 1) * sizeof(unsigned int),
					                                    __func__);
					LinkNode *bucket_node;

					buckets_face[bucket_index] = bucket;

					for (bucket_node = bucketstore[bucket_index]; bucket_node; bucket_node = bucket_node->next) {
						*bucket = GET_UINT_FROM_POINTER(bucket_node->link);
						bucket++;
					}
					*bucket = TRI_TERMINATOR_ID;
				}
				else {
					buckets_face[bucket_index] = NULL;
				}
			}

			layer->buckets_face = buckets_face;
		}

		MEM_freeN(bucketstore);
		MEM_freeN(bucketstore_tot);
	}

	BLI_memarena_free(arena);
}
Esempio n. 11
0
void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop)
{
	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 viewrect[2];
	float col[3];
	GLuint texid;
	GLuint last_texid;
	void *display_buffer;
	void *cache_handle = NULL;
	const bool is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
	int format, type;
	bool glsl_used = false;
	const bool draw_gpencil = ((sseq->flag & SEQ_SHOW_GPENCIL) && sseq->gpd);
	const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
	bool draw_metadata = 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), NULL, 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), NULL, WM_JOB_TYPE_RENDER_PREVIEW);
		}
	}

	if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) {
		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);

	/* only initialize the preview if a render is in progress */
	if (G.is_rendering)
		return;

	if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
		return;
	}

	/* for now we only support Left/Right */
	ibuf = sequencer_ibuf_get(bmain, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]);

	if ((ibuf == NULL) ||
	    (ibuf->rect == NULL && ibuf->rect_float == NULL))
	{
		/* gpencil can also be drawn without a valid imbuf */
		if (draw_gpencil && is_imbuf) {
			sequencer_display_size(scene, sseq, viewrect);

			sequencer_draw_background(sseq, v2d, viewrect);
			sequencer_draw_borders(sseq, v2d, scene);

			sequencer_draw_gpencil(C);
		}
		return;
	}

	sequencer_display_size(scene, sseq, viewrect);

	if (!draw_backdrop && (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;
		}

		/* future files may have new scopes we don't catch above */
		if (scope) {
			scopes->reference_ibuf = ibuf;
			if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
				/* scopes drawn in image preview use viewrect from orig ibuf - currently that's only zebra */
			}
			else {
				viewrect[0] = scope->x;
				viewrect[1] = scope->y;
			}
		}
		else {
			scopes->reference_ibuf = NULL;
		}
	}

	if (!draw_backdrop) {
		sequencer_draw_background(sseq, v2d, viewrect);
	}

	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, ibuf->dither, true);
			}
			else {
				glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, 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, ibuf->dither, 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);

	if (draw_backdrop) {
		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();
	}
	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 if (draw_backdrop) {
		float aspect;
		float image_aspect = viewrect[0] / viewrect[1];
		float imagex, imagey;

		aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct);

		if (aspect >= image_aspect) {
			imagex = image_aspect / aspect;
			imagey = 1.0f;
		}
		else {
			imagex = 1.0f;
			imagey = aspect / image_aspect;
		}

		glTexCoord2f(0.0f, 0.0f); glVertex2f(-imagex, -imagey);
		glTexCoord2f(0.0f, 1.0f); glVertex2f(-imagex, imagey);
		glTexCoord2f(1.0f, 1.0f); glVertex2f(imagex, imagey);
		glTexCoord2f(1.0f, 0.0f); glVertex2f(imagex, -imagey);
	}
	else {
		draw_metadata = ((sseq->flag & SEQ_SHOW_METADATA) != 0);

		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 (cache_handle)
		IMB_display_buffer_release(cache_handle);

	if (!scope)
		IMB_freeImBuf(ibuf);

	if (draw_metadata) {
		ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
	}

	if (draw_backdrop) {
		glPopMatrix();
		glMatrixMode(GL_PROJECTION);
		glPopMatrix();
		glMatrixMode(GL_MODELVIEW);
		return;
	}

	if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
		sequencer_draw_borders(sseq, v2d, scene);
	}

	if (draw_gpencil && is_imbuf) {
		sequencer_draw_gpencil(C);
	}
	else {
		/* ortho at pixel level */
		UI_view2d_view_restore(C);
	}


	/* 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, 0,  /* TODO */
			                    width, height,
			                    aspx, aspy,
			                    false, true,
			                    NULL, C);
		}
	}
}
Esempio n. 12
0
/* position block relative to but, result is in window space */
static void ui_popup_block_position(wmWindow *window,
                                    ARegion *butregion,
                                    uiBut *but,
                                    uiBlock *block)
{
  uiPopupBlockHandle *handle = block->handle;

  /* Compute button position in window coordinates using the source
   * button region/block, to position the popup attached to it. */
  rctf butrct;

  if (!handle->refresh) {
    ui_block_to_window_rctf(butregion, but->block, &butrct, &but->rect);

    /* widget_roundbox_set has this correction too, keep in sync */
    if (but->type != UI_BTYPE_PULLDOWN) {
      if (but->drawflag & UI_BUT_ALIGN_TOP) {
        butrct.ymax += U.pixelsize;
      }
      if (but->drawflag & UI_BUT_ALIGN_LEFT) {
        butrct.xmin -= U.pixelsize;
      }
    }

    handle->prev_butrct = butrct;
  }
  else {
    /* For refreshes, keep same button position so popup doesn't move. */
    butrct = handle->prev_butrct;
  }

  /* Compute block size in window space, based on buttons contained in it. */
  if (block->rect.xmin == 0.0f && block->rect.xmax == 0.0f) {
    if (block->buttons.first) {
      BLI_rctf_init_minmax(&block->rect);

      for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
        if (block->content_hints & UI_BLOCK_CONTAINS_SUBMENU_BUT) {
          bt->rect.xmax += UI_MENU_SUBMENU_PADDING;
        }
        BLI_rctf_union(&block->rect, &bt->rect);
      }
    }
    else {
      /* we're nice and allow empty blocks too */
      block->rect.xmin = block->rect.ymin = 0;
      block->rect.xmax = block->rect.ymax = 20;
    }
  }

  ui_block_to_window_rctf(butregion, but->block, &block->rect, &block->rect);

  /* Compute direction relative to button, based on available space. */
  const int size_x = BLI_rctf_size_x(&block->rect) + 0.2f * UI_UNIT_X; /* 4 for shadow */
  const int size_y = BLI_rctf_size_y(&block->rect) + 0.2f * UI_UNIT_Y;
  const int center_x = (block->direction & UI_DIR_CENTER_X) ? size_x / 2 : 0;
  const int center_y = (block->direction & UI_DIR_CENTER_Y) ? size_y / 2 : 0;

  short dir1 = 0, dir2 = 0;

  if (!handle->refresh) {
    bool left = 0, right = 0, top = 0, down = 0;

    const int win_x = WM_window_pixels_x(window);
    const int win_y = WM_window_pixels_y(window);

    /* Take into account maximum size so we don't have to flip on refresh. */
    const float max_size_x = max_ff(size_x, handle->max_size_x);
    const float max_size_y = max_ff(size_y, handle->max_size_y);

    /* check if there's space at all */
    if (butrct.xmin - max_size_x + center_x > 0.0f) {
      left = 1;
    }
    if (butrct.xmax + max_size_x - center_x < win_x) {
      right = 1;
    }
    if (butrct.ymin - max_size_y + center_y > 0.0f) {
      down = 1;
    }
    if (butrct.ymax + max_size_y - center_y < win_y) {
      top = 1;
    }

    if (top == 0 && down == 0) {
      if (butrct.ymin - max_size_y < win_y - butrct.ymax - max_size_y) {
        top = 1;
      }
      else {
        down = 1;
      }
    }

    dir1 = (block->direction & UI_DIR_ALL);

    /* Secondary directions. */
    if (dir1 & (UI_DIR_UP | UI_DIR_DOWN)) {
      if (dir1 & UI_DIR_LEFT) {
        dir2 = UI_DIR_LEFT;
      }
      else if (dir1 & UI_DIR_RIGHT) {
        dir2 = UI_DIR_RIGHT;
      }
      dir1 &= (UI_DIR_UP | UI_DIR_DOWN);
    }

    if ((dir2 == 0) && (dir1 == UI_DIR_LEFT || dir1 == UI_DIR_RIGHT)) {
      dir2 = UI_DIR_DOWN;
    }
    if ((dir2 == 0) && (dir1 == UI_DIR_UP || dir1 == UI_DIR_DOWN)) {
      dir2 = UI_DIR_LEFT;
    }

    /* no space at all? don't change */
    if (left || right) {
      if (dir1 == UI_DIR_LEFT && left == 0) {
        dir1 = UI_DIR_RIGHT;
      }
      if (dir1 == UI_DIR_RIGHT && right == 0) {
        dir1 = UI_DIR_LEFT;
      }
      /* this is aligning, not append! */
      if (dir2 == UI_DIR_LEFT && right == 0) {
        dir2 = UI_DIR_RIGHT;
      }
      if (dir2 == UI_DIR_RIGHT && left == 0) {
        dir2 = UI_DIR_LEFT;
      }
    }
    if (down || top) {
      if (dir1 == UI_DIR_UP && top == 0) {
        dir1 = UI_DIR_DOWN;
      }
      if (dir1 == UI_DIR_DOWN && down == 0) {
        dir1 = UI_DIR_UP;
      }
      BLI_assert(dir2 != UI_DIR_UP);
      //          if (dir2 == UI_DIR_UP   && top == 0)  { dir2 = UI_DIR_DOWN; }
      if (dir2 == UI_DIR_DOWN && down == 0) {
        dir2 = UI_DIR_UP;
      }
    }

    handle->prev_dir1 = dir1;
    handle->prev_dir2 = dir2;
  }
  else {
    /* For refreshes, keep same popup direct so popup doesn't move
     * to a totally different position while editing in it. */
    dir1 = handle->prev_dir1;
    dir2 = handle->prev_dir2;
  }

  /* Compute offset based on direction. */
  float offset_x = 0, offset_y = 0;

  /* Ensure buttons don't come between the parent button and the popup, see: T63566. */
  const float offset_overlap = max_ff(U.pixelsize, 1.0f);

  if (dir1 == UI_DIR_LEFT) {
    offset_x = (butrct.xmin - block->rect.xmax) + offset_overlap;
    if (dir2 == UI_DIR_UP) {
      offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING;
    }
    else {
      offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING;
    }
  }
  else if (dir1 == UI_DIR_RIGHT) {
    offset_x = (butrct.xmax - block->rect.xmin) - offset_overlap;
    if (dir2 == UI_DIR_UP) {
      offset_y = butrct.ymin - block->rect.ymin - center_y - UI_MENU_PADDING;
    }
    else {
      offset_y = butrct.ymax - block->rect.ymax + center_y + UI_MENU_PADDING;
    }
  }
  else if (dir1 == UI_DIR_UP) {
    offset_y = (butrct.ymax - block->rect.ymin) - offset_overlap;
    if (dir2 == UI_DIR_RIGHT) {
      offset_x = butrct.xmax - block->rect.xmax + center_x;
    }
    else {
      offset_x = butrct.xmin - block->rect.xmin - center_x;
    }
    /* changed direction? */
    if ((dir1 & block->direction) == 0) {
      /* TODO: still do */
      UI_block_order_flip(block);
    }
  }
  else if (dir1 == UI_DIR_DOWN) {
    offset_y = (butrct.ymin - block->rect.ymax) + offset_overlap;
    if (dir2 == UI_DIR_RIGHT) {
      offset_x = butrct.xmax - block->rect.xmax + center_x;
    }
    else {
      offset_x = butrct.xmin - block->rect.xmin - center_x;
    }
    /* changed direction? */
    if ((dir1 & block->direction) == 0) {
      /* TODO: still do */
      UI_block_order_flip(block);
    }
  }

  /* Center over popovers for eg. */
  if (block->direction & UI_DIR_CENTER_X) {
    offset_x += BLI_rctf_size_x(&butrct) / ((dir2 == UI_DIR_LEFT) ? 2 : -2);
  }

  /* Apply offset, buttons in window coords. */
  for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
    ui_block_to_window_rctf(butregion, but->block, &bt->rect, &bt->rect);

    BLI_rctf_translate(&bt->rect, offset_x, offset_y);

    /* ui_but_update recalculates drawstring size in pixels */
    ui_but_update(bt);
  }

  BLI_rctf_translate(&block->rect, offset_x, offset_y);

  /* Safety calculus. */
  {
    const float midx = BLI_rctf_cent_x(&butrct);
    const float midy = BLI_rctf_cent_y(&butrct);

    /* when you are outside parent button, safety there should be smaller */

    /* parent button to left */
    if (midx < block->rect.xmin) {
      block->safety.xmin = block->rect.xmin - 3;
    }
    else {
      block->safety.xmin = block->rect.xmin - 40;
    }
    /* parent button to right */
    if (midx > block->rect.xmax) {
      block->safety.xmax = block->rect.xmax + 3;
    }
    else {
      block->safety.xmax = block->rect.xmax + 40;
    }

    /* parent button on bottom */
    if (midy < block->rect.ymin) {
      block->safety.ymin = block->rect.ymin - 3;
    }
    else {
      block->safety.ymin = block->rect.ymin - 40;
    }
    /* parent button on top */
    if (midy > block->rect.ymax) {
      block->safety.ymax = block->rect.ymax + 3;
    }
    else {
      block->safety.ymax = block->rect.ymax + 40;
    }

    /* exception for switched pulldowns... */
    if (dir1 && (dir1 & block->direction) == 0) {
      if (dir2 == UI_DIR_RIGHT) {
        block->safety.xmax = block->rect.xmax + 3;
      }
      if (dir2 == UI_DIR_LEFT) {
        block->safety.xmin = block->rect.xmin - 3;
      }
    }
    block->direction = dir1;
  }

  /* keep a list of these, needed for pulldown menus */
  uiSafetyRct *saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
  saferct->parent = butrct;
  saferct->safety = block->safety;
  BLI_freelistN(&block->saferct);
  BLI_duplicatelist(&block->saferct, &but->block->saferct);
  BLI_addhead(&block->saferct, saferct);
}
Esempio n. 13
0
/**
 * Called for creating new popups and refreshing existing ones.
 */
uiBlock *ui_popup_block_refresh(bContext *C,
                                uiPopupBlockHandle *handle,
                                ARegion *butregion,
                                uiBut *but)
{
  const int margin = UI_POPUP_MARGIN;
  wmWindow *window = CTX_wm_window(C);
  ARegion *ar = handle->region;

  uiBlockCreateFunc create_func = handle->popup_create_vars.create_func;
  uiBlockHandleCreateFunc handle_create_func = handle->popup_create_vars.handle_create_func;
  void *arg = handle->popup_create_vars.arg;

  uiBlock *block_old = ar->uiblocks.first;
  uiBlock *block;

  handle->refresh = (block_old != NULL);

  BLI_assert(!handle->refresh || handle->can_refresh);

#ifdef DEBUG
  wmEvent *event_back = window->eventstate;
#endif

  /* create ui block */
  if (create_func) {
    block = create_func(C, ar, arg);
  }
  else {
    block = handle_create_func(C, handle, arg);
  }

  /* callbacks _must_ leave this for us, otherwise we can't call UI_block_update_from_old */
  BLI_assert(!block->endblock);

  /* ensure we don't use mouse coords here! */
#ifdef DEBUG
  window->eventstate = NULL;
#endif

  if (block->handle) {
    memcpy(block->handle, handle, sizeof(uiPopupBlockHandle));
    MEM_freeN(handle);
    handle = block->handle;
  }
  else {
    block->handle = handle;
  }

  ar->regiondata = handle;

  /* set UI_BLOCK_NUMSELECT before UI_block_end() so we get alphanumeric keys assigned */
  if (but == NULL) {
    block->flag |= UI_BLOCK_POPUP;
  }

  block->flag |= UI_BLOCK_LOOP;
  UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);

  /* defer this until blocks are translated (below) */
  block->oldblock = NULL;

  if (!block->endblock) {
    UI_block_end_ex(
        C, block, handle->popup_create_vars.event_xy, handle->popup_create_vars.event_xy);
  }

  /* if this is being created from a button */
  if (but) {
    block->aspect = but->block->aspect;
    ui_popup_block_position(window, butregion, but, block);
    handle->direction = block->direction;
  }
  else {
    uiSafetyRct *saferct;
    /* keep a list of these, needed for pulldown menus */
    saferct = MEM_callocN(sizeof(uiSafetyRct), "uiSafetyRct");
    saferct->safety = block->safety;
    BLI_addhead(&block->saferct, saferct);
  }

  if (block->flag & UI_BLOCK_RADIAL) {
    int win_width = UI_SCREEN_MARGIN;
    int winx, winy;

    int x_offset = 0, y_offset = 0;

    winx = WM_window_pixels_x(window);
    winy = WM_window_pixels_y(window);

    copy_v2_v2(block->pie_data.pie_center_init, block->pie_data.pie_center_spawned);

    /* only try translation if area is large enough */
    if (BLI_rctf_size_x(&block->rect) < winx - (2.0f * win_width)) {
      if (block->rect.xmin < win_width) {
        x_offset += win_width - block->rect.xmin;
      }
      if (block->rect.xmax > winx - win_width) {
        x_offset += winx - win_width - block->rect.xmax;
      }
    }

    if (BLI_rctf_size_y(&block->rect) < winy - (2.0f * win_width)) {
      if (block->rect.ymin < win_width) {
        y_offset += win_width - block->rect.ymin;
      }
      if (block->rect.ymax > winy - win_width) {
        y_offset += winy - win_width - block->rect.ymax;
      }
    }
    /* if we are offsetting set up initial data for timeout functionality */

    if ((x_offset != 0) || (y_offset != 0)) {
      block->pie_data.pie_center_spawned[0] += x_offset;
      block->pie_data.pie_center_spawned[1] += y_offset;

      UI_block_translate(block, x_offset, y_offset);

      if (U.pie_initial_timeout > 0) {
        block->pie_data.flags |= UI_PIE_INITIAL_DIRECTION;
      }
    }

    ar->winrct.xmin = 0;
    ar->winrct.xmax = winx;
    ar->winrct.ymin = 0;
    ar->winrct.ymax = winy;

    ui_block_calc_pie_segment(block, block->pie_data.pie_center_init);

    /* lastly set the buttons at the center of the pie menu, ready for animation */
    if (U.pie_animation_timeout > 0) {
      for (uiBut *but_iter = block->buttons.first; but_iter; but_iter = but_iter->next) {
        if (but_iter->pie_dir != UI_RADIAL_NONE) {
          BLI_rctf_recenter(&but_iter->rect, UNPACK2(block->pie_data.pie_center_spawned));
        }
      }
    }
  }
  else {
    /* clip block with window boundary */
    ui_popup_block_clip(window, block);

    /* Avoid menu moving down and losing cursor focus by keeping it at
     * the same height. */
    if (handle->refresh && handle->prev_block_rect.ymax > block->rect.ymax) {
      float offset = handle->prev_block_rect.ymax - block->rect.ymax;
      UI_block_translate(block, 0, offset);
      block->rect.ymin = handle->prev_block_rect.ymin;
    }

    handle->prev_block_rect = block->rect;

    /* the block and buttons were positioned in window space as in 2.4x, now
     * these menu blocks are regions so we bring it back to region space.
     * additionally we add some padding for the menu shadow or rounded menus */
    ar->winrct.xmin = block->rect.xmin - margin;
    ar->winrct.xmax = block->rect.xmax + margin;
    ar->winrct.ymin = block->rect.ymin - margin;
    ar->winrct.ymax = block->rect.ymax + UI_POPUP_MENU_TOP;

    UI_block_translate(block, -ar->winrct.xmin, -ar->winrct.ymin);

    /* apply scroll offset */
    if (handle->scrolloffset != 0.0f) {
      for (uiBut *bt = block->buttons.first; bt; bt = bt->next) {
        bt->rect.ymin += handle->scrolloffset;
        bt->rect.ymax += handle->scrolloffset;
      }
    }
  }

  if (block_old) {
    block->oldblock = block_old;
    UI_block_update_from_old(C, block);
    UI_blocklist_free_inactive(C, &ar->uiblocks);
  }

  /* checks which buttons are visible, sets flags to prevent draw (do after region init) */
  ui_popup_block_scrolltest(block);

  /* adds subwindow */
  ED_region_init(ar);

  /* get winmat now that we actually have the subwindow */
  wmGetProjectionMatrix(block->winmat, &ar->winrct);

  /* notify change and redraw */
  ED_region_tag_redraw(ar);

  ED_region_update_rect(ar);

#ifdef DEBUG
  window->eventstate = event_back;
#endif

  return block;
}
Esempio n. 14
0
void print_rctf(const char *str, const rctf *rect)
{
	printf("%s: xmin %.8f, xmax %.8f, ymin %.8f, ymax %.8f (%.12fx%.12f)\n", str,
	       rect->xmin, rect->xmax, rect->ymin, rect->ymax, BLI_rctf_size_x(rect), BLI_rctf_size_y(rect));
}
Esempio n. 15
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. 16
0
static void draw_seq_extensions(Scene *scene, ARegion *ar, Sequence *seq)
{
	float x1, x2, y1, y2, pixely, a;
	unsigned char col[3], blendcol[3];
	View2D *v2d = &ar->v2d;
	
	if (seq->type >= SEQ_TYPE_EFFECT) return;

	x1 = seq->startdisp;
	x2 = seq->enddisp;
	
	y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
	y2 = seq->machine + SEQ_STRIP_OFSTOP;

	pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
	
	if (pixely <= 0) return;  /* can happen when the view is split/resized */
	
	blendcol[0] = blendcol[1] = blendcol[2] = 120;

	if (seq->startofs) {
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		get_seq_color3ubv(scene, seq, col);
		
		if (seq->flag & SELECT) {
			UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
			glColor4ub(col[0], col[1], col[2], 170);
		}
		else {
			UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
			glColor4ub(col[0], col[1], col[2], 110);
		}
		
		glRectf((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);
		
		if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
		else glColor4ub(col[0], col[1], col[2], 160);

		fdrawbox((float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM, x1, y1);  //outline
		
		glDisable(GL_BLEND);
	}
	if (seq->endofs) {
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		get_seq_color3ubv(scene, seq, col);
		
		if (seq->flag & SELECT) {
			UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.3, -40);
			glColor4ub(col[0], col[1], col[2], 170);
		}
		else {
			UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.6, 0);
			glColor4ub(col[0], col[1], col[2], 110);
		}
		
		glRectf(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
		
		if (seq->flag & SELECT) glColor4ub(col[0], col[1], col[2], 255);
		else glColor4ub(col[0], col[1], col[2], 160);

		fdrawbox(x2, y2, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM); //outline
		
		glDisable(GL_BLEND);
	}
	if (seq->startstill) {
		get_seq_color3ubv(scene, seq, col);
		UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
		glColor3ubv((GLubyte *)col);
		
		draw_shadedstrip(seq, col, x1, y1, (float)(seq->start), y2);
		
		/* feint pinstripes, helps see exactly which is extended and which isn't,
		 * especially when the extension is very small */ 
		if (seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 24);
		else UI_GetColorPtrShade3ubv(col, col, -16);
		
		glColor3ubv((GLubyte *)col);
		
		for (a = y1; a < y2; a += pixely * 2.0f) {
			fdrawline(x1,  a,  (float)(seq->start),  a);
		}
	}
	if (seq->endstill) {
		get_seq_color3ubv(scene, seq, col);
		UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.75, 40);
		glColor3ubv((GLubyte *)col);
		
		draw_shadedstrip(seq, col, (float)(seq->start + seq->len), y1, x2, y2);
		
		/* feint pinstripes, helps see exactly which is extended and which isn't,
		 * especially when the extension is very small */ 
		if (seq->flag & SELECT) UI_GetColorPtrShade3ubv(col, col, 24);
		else UI_GetColorPtrShade3ubv(col, col, -16);
		
		glColor3ubv((GLubyte *)col);
		
		for (a = y1; a < y2; a += pixely * 2.0f) {
			fdrawline((float)(seq->start + seq->len),  a,  x2,  a);
		}
	}
}
Esempio n. 17
0
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);
}
Esempio n. 18
0
int space_node_view_flag(bContext *C, SpaceNode *snode, ARegion *ar,
                         const int node_flag, const int smooth_viewtx)
{
    bNode *node;
    rctf cur_new;
    float oldwidth, oldheight, width, height;
    float oldasp, asp;
    int tot = 0;
    bool has_frame = false;

    oldwidth  = BLI_rctf_size_x(&ar->v2d.cur);
    oldheight = BLI_rctf_size_y(&ar->v2d.cur);

    oldasp = oldwidth / oldheight;

    BLI_rctf_init_minmax(&cur_new);

    if (snode->edittree) {
        for (node = snode->edittree->nodes.first; node; node = node->next) {
            if ((node->flag & node_flag) == node_flag) {
                BLI_rctf_union(&cur_new, &node->totr);
                tot++;

                if (node->type == NODE_FRAME) {
                    has_frame = TRUE;
                }
            }
        }
    }

    if (tot) {
        width  = BLI_rctf_size_x(&cur_new);
        height = BLI_rctf_size_y(&cur_new);
        asp = width / height;

        /* for single non-frame nodes, don't zoom in, just pan view,
         * but do allow zooming out, this allows for big nodes to be zoomed out */
        if ((tot == 1) &&
                (has_frame == FALSE) &&
                ((oldwidth * oldheight) > (width * height)))
        {
            /* center, don't zoom */
            BLI_rctf_resize(&cur_new, oldwidth, oldheight);
        }
        else {
            if (oldasp < asp) {
                const float height_new = width / oldasp;
                cur_new.ymin = cur_new.ymin - height_new / 2.0f;
                cur_new.ymax = cur_new.ymax + height_new / 2.0f;
            }
            else {
                const float width_new = height * oldasp;
                cur_new.xmin = cur_new.xmin - width_new / 2.0f;
                cur_new.xmax = cur_new.xmax + width_new / 2.0f;
            }

            /* add some padding */
            BLI_rctf_scale(&cur_new, 1.1f);
        }

        UI_view2d_smooth_view(C, ar, &cur_new, smooth_viewtx);
    }

    return (tot != 0);
}
Esempio n. 19
0
void ui_draw_but_CURVE(ARegion *ar, uiBut *but, uiWidgetColors *wcol, rcti *rect)
{
	CurveMapping *cumap;
	CurveMap *cuma;
	CurveMapPoint *cmp;
	float fx, fy, fac[2], zoomx, zoomy, offsx, offsy;
	GLint scissor[4];
	rcti scissor_new;
	int a;

	if (but->editcumap) {
		cumap = but->editcumap;
	}
	else {
		cumap = (CurveMapping *)but->poin;
	}

	cuma = &cumap->cm[cumap->cur];

	/* need scissor test, curve can draw outside of boundary */
	glGetIntegerv(GL_VIEWPORT, scissor);
	scissor_new.xmin = ar->winrct.xmin + rect->xmin;
	scissor_new.ymin = ar->winrct.ymin + rect->ymin;
	scissor_new.xmax = ar->winrct.xmin + rect->xmax;
	scissor_new.ymax = ar->winrct.ymin + rect->ymax;
	BLI_rcti_isect(&scissor_new, &ar->winrct, &scissor_new);
	glScissor(scissor_new.xmin,
	          scissor_new.ymin,
	          BLI_rcti_size_x(&scissor_new),
	          BLI_rcti_size_y(&scissor_new));

	/* calculate offset and zoom */
	zoomx = (BLI_rcti_size_x(rect) - 2.0f * but->aspect) / BLI_rctf_size_x(&cumap->curr);
	zoomy = (BLI_rcti_size_y(rect) - 2.0f * but->aspect) / BLI_rctf_size_y(&cumap->curr);
	offsx = cumap->curr.xmin - but->aspect / zoomx;
	offsy = cumap->curr.ymin - but->aspect / zoomy;
	
	/* backdrop */
	if (but->a1 == UI_GRAD_H) {
		/* magic trigger for curve backgrounds */
		rcti grid;
		float col[3] = {0.0f, 0.0f, 0.0f}; /* dummy arg */

		grid.xmin = rect->xmin + zoomx * (-offsx);
		grid.xmax = rect->xmax + zoomx * (-offsx);
		grid.ymin = rect->ymin + zoomy * (-offsy);
		grid.ymax = rect->ymax + zoomy * (-offsy);

		ui_draw_gradient(&grid, col, UI_GRAD_H, 1.0f);

		/* grid, hsv uses different grid */
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4ub(0, 0, 0, 48);
		ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.1666666f);
		glDisable(GL_BLEND);
	}
	else {
		if (cumap->flag & CUMA_DO_CLIP) {
			gl_shaded_color((unsigned char *)wcol->inner, -20);
			glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
			glColor3ubv((unsigned char *)wcol->inner);
			glRectf(rect->xmin + zoomx * (cumap->clipr.xmin - offsx),
			        rect->ymin + zoomy * (cumap->clipr.ymin - offsy),
			        rect->xmin + zoomx * (cumap->clipr.xmax - offsx),
			        rect->ymin + zoomy * (cumap->clipr.ymax - offsy));
		}
		else {
			glColor3ubv((unsigned char *)wcol->inner);
			glRectf(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
		}

		/* grid, every 0.25 step */
		gl_shaded_color((unsigned char *)wcol->inner, -16);
		ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 0.25f);
		/* grid, every 1.0 step */
		gl_shaded_color((unsigned char *)wcol->inner, -24);
		ui_draw_but_curve_grid(rect, zoomx, zoomy, offsx, offsy, 1.0f);
		/* axes */
		gl_shaded_color((unsigned char *)wcol->inner, -50);
		glBegin(GL_LINES);
		glVertex2f(rect->xmin, rect->ymin + zoomy * (-offsy));
		glVertex2f(rect->xmax, rect->ymin + zoomy * (-offsy));
		glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymin);
		glVertex2f(rect->xmin + zoomx * (-offsx), rect->ymax);
		glEnd();
	}

	/* cfra option */
	/* XXX 2.48 */
#if 0
	if (cumap->flag & CUMA_DRAW_CFRA) {
		glColor3ub(0x60, 0xc0, 0x40);
		glBegin(GL_LINES);
		glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymin);
		glVertex2f(rect->xmin + zoomx * (cumap->sample[0] - offsx), rect->ymax);
		glEnd();
	}
#endif
	/* sample option */

	if (cumap->flag & CUMA_DRAW_SAMPLE) {
		if (but->a1 == UI_GRAD_H) {
			float tsample[3];
			float hsv[3];
			linearrgb_to_srgb_v3_v3(tsample, cumap->sample);
			rgb_to_hsv_v(tsample, hsv);
			glColor3ub(240, 240, 240);

			glBegin(GL_LINES);
			glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymin);
			glVertex2f(rect->xmin + zoomx * (hsv[0] - offsx), rect->ymax);
			glEnd();
		}
		else if (cumap->cur == 3) {
			float lum = rgb_to_bw(cumap->sample);
			glColor3ub(240, 240, 240);
			
			glBegin(GL_LINES);
			glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymin);
			glVertex2f(rect->xmin + zoomx * (lum - offsx), rect->ymax);
			glEnd();
		}
		else {
			if (cumap->cur == 0)
				glColor3ub(240, 100, 100);
			else if (cumap->cur == 1)
				glColor3ub(100, 240, 100);
			else
				glColor3ub(100, 100, 240);
			
			glBegin(GL_LINES);
			glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymin);
			glVertex2f(rect->xmin + zoomx * (cumap->sample[cumap->cur] - offsx), rect->ymax);
			glEnd();
		}
	}

	/* the curve */
	glColor3ubv((unsigned char *)wcol->item);
	glEnable(GL_LINE_SMOOTH);
	glEnable(GL_BLEND);
	glBegin(GL_LINE_STRIP);
	
	if (cuma->table == NULL)
		curvemapping_changed(cumap, FALSE);
	cmp = cuma->table;
	
	/* first point */
	if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
		glVertex2f(rect->xmin, rect->ymin + zoomy * (cmp[0].y - offsy));
	}
	else {
		fx = rect->xmin + zoomx * (cmp[0].x - offsx + cuma->ext_in[0]);
		fy = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
		glVertex2f(fx, fy);
	}
	for (a = 0; a <= CM_TABLE; a++) {
		fx = rect->xmin + zoomx * (cmp[a].x - offsx);
		fy = rect->ymin + zoomy * (cmp[a].y - offsy);
		glVertex2f(fx, fy);
	}
	/* last point */
	if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
		glVertex2f(rect->xmax, rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy));
	}
	else {
		fx = rect->xmin + zoomx * (cmp[CM_TABLE].x - offsx - cuma->ext_out[0]);
		fy = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy - cuma->ext_out[1]);
		glVertex2f(fx, fy);
	}
	glEnd();
	glDisable(GL_LINE_SMOOTH);
	glDisable(GL_BLEND);

	/* the points, use aspect to make them visible on edges */
	cmp = cuma->curve;
	glPointSize(3.0f);
	bglBegin(GL_POINTS);
	for (a = 0; a < cuma->totpoint; a++) {
		if (cmp[a].flag & CUMA_SELECT)
			UI_ThemeColor(TH_TEXT_HI);
		else
			UI_ThemeColor(TH_TEXT);
		fac[0] = rect->xmin + zoomx * (cmp[a].x - offsx);
		fac[1] = rect->ymin + zoomy * (cmp[a].y - offsy);
		bglVertex2fv(fac);
	}
	bglEnd();
	glPointSize(1.0f);
	
	/* restore scissortest */
	glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);

	/* outline */
	glColor3ubv((unsigned char *)wcol->outline);
	fdrawbox(rect->xmin, rect->ymin, rect->xmax, rect->ymax);
}
Esempio n. 20
0
void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *recti)
{
	rctf rect;
	int ok = 0, width, height;
	GLint scissor[4];
	MovieClipScopes *scopes = (MovieClipScopes *)but->poin;

	rect.xmin = (float)recti->xmin + 1;
	rect.xmax = (float)recti->xmax - 1;
	rect.ymin = (float)recti->ymin + SCOPE_RESIZE_PAD + 2;
	rect.ymax = (float)recti->ymax - 1;

	width  = BLI_rctf_size_x(&rect) + 1;
	height = BLI_rctf_size_y(&rect);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/* need scissor test, preview image can draw outside of boundary */
	glGetIntegerv(GL_VIEWPORT, scissor);
	glScissor(ar->winrct.xmin + (rect.xmin - 1),
	          ar->winrct.ymin + (rect.ymin - 1),
	          (rect.xmax + 1) - (rect.xmin - 1),
	          (rect.ymax + 1) - (rect.ymin - 1));

	if (scopes->track_disabled) {
		glColor4f(0.7f, 0.3f, 0.3f, 0.3f);
		uiSetRoundBox(UI_CNR_ALL);
		uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);

		ok = 1;
	}
	else if ((scopes->track_search) &&
	         ((!scopes->track_preview) ||
	          (scopes->track_preview->x != width || scopes->track_preview->y != height)))
	{
		ImBuf *tmpibuf;

		if (scopes->track_preview)
			IMB_freeImBuf(scopes->track_preview);

		tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height,
		                                            scopes->track_search, scopes->track,
		                                            &scopes->undist_marker, TRUE, scopes->use_track_mask,
		                                            width, height, scopes->track_pos);

		if (tmpibuf) {
			if (tmpibuf->rect_float)
				IMB_rect_from_float(tmpibuf);

			if (tmpibuf->rect)
				scopes->track_preview = tmpibuf;
			else
				IMB_freeImBuf(tmpibuf);
		}
	}

	if (!ok && scopes->track_preview) {
		float track_pos[2];
		int a;
		ImBuf *drawibuf;

		glPushMatrix();

		track_pos[0] = scopes->track_pos[0];
		track_pos[1] = scopes->track_pos[1];

		/* draw content of pattern area */
		glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, scissor[2], scissor[3]);

		if (width > 0 && height > 0) {
			drawibuf = scopes->track_preview;

			if (scopes->use_track_mask) {
				glColor4f(0.0f, 0.0f, 0.0f, 0.3f);
				uiSetRoundBox(UI_CNR_ALL);
				uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
			}

			glaDrawPixelsSafe(rect.xmin, rect.ymin + 1, drawibuf->x, drawibuf->y,
			                  drawibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, drawibuf->rect);

			/* draw cross for pizel position */
			glTranslatef(rect.xmin + track_pos[0], rect.ymin + track_pos[1], 0.f);
			glScissor(ar->winrct.xmin + rect.xmin,
			          ar->winrct.ymin + rect.ymin,
			          BLI_rctf_size_x(&rect),
			          BLI_rctf_size_y(&rect));

			for (a = 0; a < 2; a++) {
				if (a == 1) {
					glLineStipple(3, 0xaaaa);
					glEnable(GL_LINE_STIPPLE);
					UI_ThemeColor(TH_SEL_MARKER);
				}
				else {
					UI_ThemeColor(TH_MARKER_OUTLINE);
				}

				glBegin(GL_LINES);
				glVertex2f(-10.0f, 0.0f);
				glVertex2f(10.0f, 0.0f);
				glVertex2f(0.0f, -10.0f);
				glVertex2f(0.0f, 10.0f);
				glEnd();
			}
		}

		glDisable(GL_LINE_STIPPLE);
		glPopMatrix();

		ok = 1;
	}

	if (!ok) {
		glColor4f(0.f, 0.f, 0.f, 0.3f);
		uiSetRoundBox(UI_CNR_ALL);
		uiDrawBox(GL_POLYGON, rect.xmin - 1, rect.ymin, rect.xmax + 1, rect.ymax + 1, 3.0f);
	}

	/* outline, scale gripper */
	draw_scope_end(&rect, scissor);

	glDisable(GL_BLEND);
}
Esempio n. 21
0
void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
{
	FileSelectParams *params = ED_fileselect_get_params(sfile);
	FileLayout *layout = NULL;
	View2D *v2d = &ar->v2d;
	int maxlen = 0;
	int numfiles;
	int textheight;

	if (sfile->layout == NULL) {
		sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout");
		sfile->layout->dirty = true;
	}
	else if (sfile->layout->dirty == false) {
		return;
	}

	numfiles = filelist_numfiles(sfile->files);
	textheight = (int)file_font_pointsize();
	layout = sfile->layout;
	layout->textheight = textheight;

	if (params->display == FILE_IMGDISPLAY) {
		layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
		layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
		layout->tile_border_x = 0.3f * UI_UNIT_X;
		layout->tile_border_y = 0.3f * UI_UNIT_X;
		layout->prv_border_x = 0.3f * UI_UNIT_X;
		layout->prv_border_y = 0.3f * UI_UNIT_Y;
		layout->tile_w = layout->prv_w + 2 * layout->prv_border_x;
		layout->tile_h = layout->prv_h + 2 * layout->prv_border_y + textheight;
		layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
		layout->columns = layout->width / (layout->tile_w + 2 * layout->tile_border_x);
		if (layout->columns > 0)
			layout->rows = numfiles / layout->columns + 1;  // XXX dirty, modulo is zero
		else {
			layout->columns = 1;
			layout->rows = numfiles + 1; // XXX dirty, modulo is zero
		}
		layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) + layout->tile_border_y * 2;
		layout->flag = FILE_LAYOUT_VER;
	}
	else {
		int column_space = 0.6f * UI_UNIT_X;
		int column_icon_space = 0.2f * UI_UNIT_X;

		layout->prv_w = 0;
		layout->prv_h = 0;
		layout->tile_border_x = 0.4f * UI_UNIT_X;
		layout->tile_border_y = 0.1f * UI_UNIT_Y;
		layout->prv_border_x = 0;
		layout->prv_border_y = 0;
		layout->tile_h = textheight * 3 / 2;
		layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y);
		layout->rows = layout->height / (layout->tile_h + 2 * layout->tile_border_y);

		column_widths(sfile->files, layout);

		if (params->display == FILE_SHORTDISPLAY) {
			maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
			         (int)layout->column_widths[COLUMN_NAME] + column_space +
			         (int)layout->column_widths[COLUMN_SIZE] + column_space;
		}
		else {
			maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
			         (int)layout->column_widths[COLUMN_NAME] + column_space +
#ifndef WIN32
			         (int)layout->column_widths[COLUMN_MODE1] + column_space +
			         (int)layout->column_widths[COLUMN_MODE2] + column_space +
			         (int)layout->column_widths[COLUMN_MODE3] + column_space +
			         (int)layout->column_widths[COLUMN_OWNER] + column_space +
#endif
			         (int)layout->column_widths[COLUMN_DATE] + column_space +
			         (int)layout->column_widths[COLUMN_TIME] + column_space +
			         (int)layout->column_widths[COLUMN_SIZE] + column_space;

		}
		layout->tile_w = maxlen;
		if (layout->rows > 0)
			layout->columns = numfiles / layout->rows + 1;  // XXX dirty, modulo is zero
		else {
			layout->rows = 1;
			layout->columns = numfiles + 1; // XXX dirty, modulo is zero
		}
		layout->width = sfile->layout->columns * (layout->tile_w + 2 * layout->tile_border_x) + layout->tile_border_x * 2;
		layout->flag = FILE_LAYOUT_HOR;
	}
	layout->dirty = false;
}
Esempio n. 22
0
static bool camera_frame_fit_calc_from_data(
        CameraParams *params, CameraViewFrameData *data, float r_co[3], float *r_scale)
{
	float plane_tx[CAMERA_VIEWFRAME_NUM_PLANES][3];
	unsigned int i;

	if (data->tot <= 1) {
		return false;
	}

	if (params->is_ortho) {
		const float *cam_axis_x = data->camera_rotmat[0];
		const float *cam_axis_y = data->camera_rotmat[1];
		const float *cam_axis_z = data->camera_rotmat[2];
		float dists[CAMERA_VIEWFRAME_NUM_PLANES];
		float scale_diff;

		/* apply the dist-from-plane's to the transformed plane points */
		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
			dists[i] = sqrtf_signed(data->dist_vals_sq[i]);
		}

		if ((dists[0] + dists[2]) > (dists[1] + dists[3])) {
			scale_diff = (dists[1] + dists[3]) *
			             (BLI_rctf_size_x(&params->viewplane) / BLI_rctf_size_y(&params->viewplane));
		}
		else {
			scale_diff = (dists[0] + dists[2]) *
			             (BLI_rctf_size_y(&params->viewplane) / BLI_rctf_size_x(&params->viewplane));
		}
		*r_scale = params->ortho_scale - scale_diff;

		zero_v3(r_co);
		madd_v3_v3fl(r_co, cam_axis_x, (dists[2] - dists[0]) * 0.5f + params->shiftx * scale_diff);
		madd_v3_v3fl(r_co, cam_axis_y, (dists[1] - dists[3]) * 0.5f + params->shifty * scale_diff);
		madd_v3_v3fl(r_co, cam_axis_z, -(data->dist_to_cam - 1.0f - params->clipsta));

		return true;
	}
	else {
		float plane_isect_1[3], plane_isect_1_no[3], plane_isect_1_other[3];
		float plane_isect_2[3], plane_isect_2_no[3], plane_isect_2_other[3];

		float plane_isect_pt_1[3], plane_isect_pt_2[3];

		/* apply the dist-from-plane's to the transformed plane points */
		for (i = 0; i < CAMERA_VIEWFRAME_NUM_PLANES; i++) {
			mul_v3_v3fl(plane_tx[i], data->normal_tx[i], sqrtf_signed(data->dist_vals_sq[i]));
		}

		if ((!isect_plane_plane_v3(plane_isect_1, plane_isect_1_no,
		                           plane_tx[0], data->normal_tx[0],
		                           plane_tx[2], data->normal_tx[2])) ||
		    (!isect_plane_plane_v3(plane_isect_2, plane_isect_2_no,
		                           plane_tx[1], data->normal_tx[1],
		                           plane_tx[3], data->normal_tx[3])))
		{
			return false;
		}

		add_v3_v3v3(plane_isect_1_other, plane_isect_1, plane_isect_1_no);
		add_v3_v3v3(plane_isect_2_other, plane_isect_2, plane_isect_2_no);

		if (isect_line_line_v3(plane_isect_1, plane_isect_1_other,
		                       plane_isect_2, plane_isect_2_other,
		                       plane_isect_pt_1, plane_isect_pt_2) != 0)
		{
			float cam_plane_no[3];
			float plane_isect_delta[3];
			float plane_isect_delta_len;

			float shift_fac = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y) /
			                  params->lens;

			/* we want (0, 0, -1) transformed by camera_rotmat, this is a quicker shortcut. */
			negate_v3_v3(cam_plane_no, data->camera_rotmat[2]);

			sub_v3_v3v3(plane_isect_delta, plane_isect_pt_2, plane_isect_pt_1);
			plane_isect_delta_len = len_v3(plane_isect_delta);

			if (dot_v3v3(plane_isect_delta, cam_plane_no) > 0.0f) {
				copy_v3_v3(r_co, plane_isect_pt_1);

				/* offset shift */
				normalize_v3(plane_isect_1_no);
				madd_v3_v3fl(r_co, plane_isect_1_no, params->shifty * plane_isect_delta_len * shift_fac);
			}
			else {
				copy_v3_v3(r_co, plane_isect_pt_2);

				/* offset shift */
				normalize_v3(plane_isect_2_no);
				madd_v3_v3fl(r_co, plane_isect_2_no, params->shiftx * plane_isect_delta_len * shift_fac);
			}

			return true;
		}
	}

	return false;
}