Esempio n. 1
0
static void RenderOrderedGroup(GF_Node *node, void *rs, Bool is_destroy)
{
	u32 i, count;
	GF_Node *child;
	Bool split_text_backup, invalidate_backup;
	M_OrderedGroup *og;
	u32 count2;
	GF_List *sensor_backup;
	SensorHandler *hsens;
	OrderedGroupStack *ogs = (OrderedGroupStack *) gf_node_get_private(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	if (is_destroy) {
		DeleteGroupingNode2D((GroupingNode2D *)ogs);
		if (ogs->priorities) free(ogs->priorities);
		free(ogs);
		return;
	}
	og = (M_OrderedGroup *) ogs->owner;

	if (!og->order.count) {
		group2d_traverse((GroupingNode2D*)ogs, og->children, eff);
		return;
	}
	count = gf_node_list_get_count(og->children);
	invalidate_backup = eff->invalidate_all;

	/*check whether the OrderedGroup node has changed*/
	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {

		if (ogs->priorities) free(ogs->priorities);
		ogs->priorities = (struct og_pos*)malloc(sizeof(struct og_pos)*count);
		for (i=0; i<count; i++) {
			ogs->priorities[i].position = i;
			ogs->priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0;
		}
		qsort(ogs->priorities, count, sizeof(struct og_pos), compare_priority);
		eff->invalidate_all = 1;
	}

	sensor_backup = NULL;
	if (gf_node_dirty_get(node) & GF_SG_CHILD_DIRTY) {
		/*rebuild sensor list*/
		if (gf_list_count(ogs->sensors)) {
			gf_list_del(ogs->sensors);
			ogs->sensors = gf_list_new();
		}

		for (i=0; i<count; i++) {
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			if (!child || !is_sensor_node(child) ) continue;
			hsens = get_sensor_handler(child);
			if (hsens) gf_list_add(ogs->sensors, hsens);
		}
	}

	/*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/
	count2 = gf_list_count(ogs->sensors);
	if (count2) {
		sensor_backup = eff->sensors;
		eff->sensors = gf_list_new();
		/*add sensor to effects*/	
		for (i=0; i <count2; i++) {
			SensorHandler *hsens = (SensorHandler *)gf_list_get(ogs->sensors, i);
			effect_add_sensor(eff, hsens, &eff->transform);
		}
	}
	gf_node_dirty_clear(node, 0);

	if (eff->parent == (GroupingNode2D *) ogs) {
		for (i=0; i<count; i++) {
			group2d_start_child((GroupingNode2D *) ogs);
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			gf_node_render(child, eff);
			group2d_end_child((GroupingNode2D *) ogs);
		}
	} else {
		split_text_backup = eff->text_split_mode;
		if (count>1) eff->text_split_mode = 0;
		for (i=0; i<count; i++) {
			child = (GF_Node*)gf_node_list_get_child(og->children, ogs->priorities[i].position);
			gf_node_render(child, eff);
		}
		eff->text_split_mode = split_text_backup;
	}

	/*restore effect*/
	invalidate_backup = eff->invalidate_all;
	if (count2) {
		/*destroy current effect list and restore previous*/
		effect_reset_sensors(eff);
		gf_list_del(eff->sensors);
		eff->sensors = sensor_backup;
	}
}
Esempio n. 2
0
static void UpdateComposite2D(GF_TextureHandler *txh)
{
	GF_Err e;
	u32 i;
	SensorHandler *hsens;
	RenderEffect2D *eff;

	M_CompositeTexture2D *ct2D = (M_CompositeTexture2D *)txh->owner;
	Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner);
	GF_Raster2D *r2d = st->surf->render->compositor->r2d;

	if (!gf_node_dirty_get(txh->owner)) {
		txh->needs_refresh = 0;
		return;
	}
	/*rebuild stencil*/
	if (!st->surf->the_surface || !txh->hwtx || ((s32) st->width != ct2D->pixelWidth) || ( (s32) st->height != ct2D->pixelHeight) ) {
		if (txh->hwtx) r2d->stencil_delete(txh->hwtx);
		txh->hwtx = NULL;

		if (ct2D->pixelWidth<=0) return;
		if (ct2D->pixelHeight<=0) return;
		st->width = ct2D->pixelWidth;
		st->height = ct2D->pixelHeight;

		txh->hwtx = r2d->stencil_new(r2d, GF_STENCIL_TEXTURE);
		e = r2d->stencil_create_texture(txh->hwtx, st->width, st->height, GF_PIXEL_ARGB);
		if (e) {
			if (txh->hwtx) r2d->stencil_delete(txh->hwtx);
			txh->hwtx = NULL;
		}
	}
	if (!txh->hwtx) return;

	GF_SAFEALLOC(eff, RenderEffect2D);
	eff->sensors = gf_list_new();
	eff->surface = st->surf;

	if (st->surf->render->top_effect->trav_flags & TF_RENDER_DIRECT) {
		eff->trav_flags = TF_RENDER_DIRECT;
	}


	gf_mx2d_init(eff->transform);
	gf_cmx_init(&eff->color_mat);
	st->surf->width = st->width;
	st->surf->height = st->height;
	eff->back_stack = st->surf->back_stack;
	eff->view_stack = st->surf->view_stack;
	eff->is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(st->txh.owner));
	eff->min_hsize = INT2FIX( MIN(st->width, st->height) ) / 2;

	Composite_CheckBindables(st->txh.owner, eff, st->first);
	st->first = 0;
	
	
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Entering CompositeTexture2D Render Cycle\n"));
	e = VS2D_InitDraw(st->surf, eff);
	if (e) {
		effect_delete(eff);
		return;
	}

	/*render children*/
	if (gf_node_dirty_get(st->txh.owner) & GF_SG_NODE_DIRTY) {
		GF_ChildNodeItem *l = ct2D->children;
		/*rebuild sensor list */
		if (gf_list_count(st->sensors)) {
			gf_list_del(st->sensors);
			st->sensors = gf_list_new();
		}
		while (l) {
			if (l->node && is_sensor_node(l->node) ) {
				hsens = get_sensor_handler(l->node);
				if (hsens) gf_list_add(st->sensors, hsens);
			}
			l = l->next;
		}

		/*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/
		if (gf_list_count(st->sensors)) {
			effect_reset_sensors(eff);
		}
	}

	/*add sensor to effects*/	
	i=0; 
	while ((hsens = (SensorHandler*)gf_list_enum(st->sensors, &i))) {
		effect_add_sensor(eff, hsens, &eff->transform);
	}

	gf_node_dirty_clear(st->txh.owner, 0);

	/*render*/
	gf_node_render_children(st->txh.owner, eff);

	/*finalize draw*/
	txh->needs_refresh = VS2D_TerminateDraw(st->surf, eff);
	st->txh.transparent = st->surf->last_had_back ? 0 : 1;
/*
	st->txh.active_window.x = 0;
	st->txh.active_window.y = 0;
	st->txh.active_window.width = st->width;
	st->txh.active_window.height = st->height;
*/
	st->txh.width = st->width;
	st->txh.height = st->height;

	/*set active viewport in image coordinates top-left=(0, 0), not in BIFS*/
	if (gf_list_count(st->surf->view_stack)) {
		M_Viewport *vp = (M_Viewport *)gf_list_get(st->surf->view_stack, 0);

		if (vp->isBound) {
			SFVec2f size = vp->size;
			if (size.x >=0 && size.y>=0) {
/*
				st->txh.active_window.width = size.x;
				st->txh.active_window.height = size.y;
				st->txh.active_window.x = (st->width - size.x) / 2;
				st->txh.active_window.y = (st->height - size.y) / 2;
*/
				/*FIXME - we need tracking of VP changes*/
				txh->needs_refresh = 1;
			}
		}
	} 

	if (txh->needs_refresh) {
		if (r2d->stencil_texture_modified) r2d->stencil_texture_modified(st->txh.hwtx); 
		gf_sr_invalidate(st->txh.compositor, NULL);
	}
	effect_delete(eff);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Leaving CompositeTexture2D Render Cycle\n"));
}