Пример #1
0
static void DestroyLayer3D(GF_Node *node)
{
	Layer3DStack *st = (Layer3DStack *) gf_node_get_private(node);
	GF_Compositor *compositor = st->visual->compositor;

	drawable_del(st->drawable);

#ifdef GPAC_USE_TINYGL
	if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx);
#endif

	if (st->txh.data) gf_free(st->txh.data);
	/*destroy texture*/
	gf_sc_texture_destroy(&st->txh);

	BindableStackDelete(st->visual->back_stack);
	st->visual->back_stack = NULL;
	BindableStackDelete(st->visual->view_stack);
	st->visual->view_stack = NULL;
	BindableStackDelete(st->visual->navigation_stack);
	st->visual->navigation_stack = NULL;
	BindableStackDelete(st->visual->fog_stack);
	st->visual->fog_stack = NULL;
	visual_del(st->visual);


	if (compositor && compositor->active_layer == node) compositor->active_layer = NULL;
	gf_free(st);
}
Пример #2
0
void visual_del(GF_VisualManager *visual)
{
	ra_del(&visual->to_redraw);

	if (visual->raster_surface) visual->compositor->rasterizer->surface_delete(visual->raster_surface);
	visual->raster_surface = NULL;
	if (visual->raster_brush) visual->compositor->rasterizer->stencil_delete(visual->raster_brush);
	visual->raster_brush = NULL;

	while (visual->context) {
		DrawableContext *ctx = visual->context;
		visual->context = ctx->next;
		DeleteDrawableContext(ctx);
	}
	while (visual->prev_nodes) {
		struct _drawable_store *cur = visual->prev_nodes;
		visual->prev_nodes = cur->next;
		gf_free(cur);
	}

#ifndef GPAC_DISABLE_VRML
	if (visual->back_stack) BindableStackDelete(visual->back_stack);
	if (visual->view_stack) BindableStackDelete(visual->view_stack);
#endif /*GPAC_DISABLE_VRML*/

#ifndef GPAC_DISABLE_3D
	visual_3d_reset_graphics(visual);

#ifndef GPAC_DISABLE_VRML
	if (visual->navigation_stack) BindableStackDelete(visual->navigation_stack);
	if (visual->fog_stack) BindableStackDelete(visual->fog_stack);
#endif /*GPAC_DISABLE_VRML*/

	gf_list_del(visual->alpha_nodes_to_draw);
#endif
	gf_free(visual);
}
Пример #3
0
static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_List *oldb, *oldv;
	GF_Node *viewport;
	GF_Node *back;
	Bool prev_layer;
	GF_Matrix2D backup;
	GF_IRect prev_clip;
	GF_Rect rc;
	SFVec2f prev_vp;

#ifndef GPAC_DISABLE_3D
	GF_Matrix mx3d, prev_layer_mx;
	GF_List *oldf, *oldn;
	GF_List *node_list_backup;
	GF_Rect prev_clipper;
	Bool had_clip;
#endif

	M_Layer2D *l = (M_Layer2D *)node;
	Layer2DStack *st = (Layer2DStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;

	if (is_destroy) {
		BindableStackDelete(st->backs);
		BindableStackDelete(st->views);
		group_2d_destroy(node, (GroupingNode2D*)st);
		gf_free(st);
		return;
	}

	/*layers can only be used in a 2D context*/
#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d && tr_state->camera->is_3D) return;
#endif

	/*layer2D maintains its own stacks*/
	oldb = tr_state->backgrounds;
	oldv = tr_state->viewpoints;
	tr_state->backgrounds = st->backs;
	tr_state->viewpoints = st->views;
	prev_layer = tr_state->is_layer;
	tr_state->is_layer = 1;
#ifndef GPAC_DISABLE_3D
	oldf = tr_state->fogs;
	oldn = tr_state->navigations;
	tr_state->fogs = tr_state->navigations = NULL;
#endif

	l2d_CheckBindables(node, tr_state, st->first);

	back = (GF_Node*)gf_list_get(st->backs, 0);

	viewport = (GF_Node*)gf_list_get(st->views, 0);

	if ((tr_state->traversing_mode == TRAVERSE_SORT) || (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS)) {
		/*override group bounds*/
		visual_get_size_info(tr_state, &st->clip.width, &st->clip.height);
		/*setup bounds in local coord system*/
		if (l->size.x>=0) st->clip.width = l->size.x;
		if (l->size.y>=0) st->clip.height = l->size.y;
		st->clip = gf_rect_center(st->clip.width, st->clip.height);
		st->bounds = st->clip;
	}

	prev_vp = tr_state->vp_size;
	tr_state->vp_size.x = st->clip.width;
	tr_state->vp_size.y = st->clip.height;

	switch (tr_state->traversing_mode) {
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) {
			gf_mx_copy(prev_layer_mx, tr_state->layer_matrix);
			tr_state->layer_clipper = compositor_2d_update_clipper(tr_state, st->clip, &had_clip, &prev_clipper, 1);

			gf_mx_copy(mx3d, tr_state->model_matrix);

			/*setup clipping*/
			if (had_clip) {
				visual_3d_reset_clipper_2d(tr_state->visual);
			}
			visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper, &mx3d);

			/*apply background BEFORE viewport*/
			if (back) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				gf_bbox_from_rect(&tr_state->bbox, &st->clip);
				gf_node_traverse(back, tr_state);
			}

			/*apply viewport*/
			if (viewport) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				tr_state->bounds = st->clip;
				gf_node_traverse(viewport, tr_state);
			}


			node_list_backup = tr_state->visual->alpha_nodes_to_draw;
			tr_state->visual->alpha_nodes_to_draw = gf_list_new();
			tr_state->traversing_mode = TRAVERSE_SORT;
			/*reset cull flag*/
			tr_state->cull_flag = 0;
			group_2d_traverse(node, (GroupingNode2D *)st, tr_state);

			visual_3d_flush_contexts(tr_state->visual, tr_state);
			tr_state->traversing_mode = TRAVERSE_SORT;

			assert(!gf_list_count(tr_state->visual->alpha_nodes_to_draw));
			gf_list_del(tr_state->visual->alpha_nodes_to_draw);
			tr_state->visual->alpha_nodes_to_draw = node_list_backup;

			gf_mx_copy(tr_state->model_matrix, mx3d);

			visual_3d_reset_clipper_2d(tr_state->visual);

			tr_state->has_layer_clip = had_clip;
			if (had_clip) {
				tr_state->layer_clipper = prev_clipper;
				gf_mx_copy(tr_state->layer_matrix, prev_layer_mx);
				visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper, &prev_layer_mx);
			}
		} else
#endif
		{
			gf_mx2d_copy(backup, tr_state->transform);

			prev_clip = tr_state->visual->top_clipper;
			rc = st->clip;

			/*get clipper in world coordinate*/
			gf_mx2d_apply_rect(&tr_state->transform, &rc);

			if (viewport) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				tr_state->bounds = st->clip;
				gf_node_traverse(viewport, tr_state);
#if VIEWPORT_CLIPS
				/*move viewport box in world coordinate*/
				gf_mx2d_apply_rect(&backup, &tr_state->bounds);
				/*and intersect with layer clipper*/
				rect_intersect(&rc, &tr_state->bounds);
#endif
			}

			rc.x -= FIX_ONE;
			rc.width += 2*FIX_ONE;
			rc.y += FIX_ONE;
			rc.height += 2*FIX_ONE;
			tr_state->visual->top_clipper = gf_rect_pixelize(&rc);
			gf_irect_intersect(&tr_state->visual->top_clipper, &prev_clip);
			tr_state->traversing_mode = TRAVERSE_SORT;

			if (tr_state->visual->top_clipper.width && tr_state->visual->top_clipper.height) {
				if (back && Bindable_GetIsBound(back) ) {
					DrawableContext *ctx;

					ctx = b2d_get_context((M_Background2D*) back, st->backs);
					gf_mx2d_init(ctx->transform);
					ctx->bi->clip = tr_state->visual->top_clipper;
					ctx->bi->unclip = rc;

					if (tr_state->immediate_draw) {
						tr_state->ctx = ctx;
						tr_state->traversing_mode = TRAVERSE_DRAW_2D;
						gf_node_traverse(back, tr_state);
						tr_state->traversing_mode = TRAVERSE_SORT;
						tr_state->ctx = NULL;
					} else {
						DrawableContext *back_ctx = visual_2d_get_drawable_context(tr_state->visual);

						gf_node_traverse(back, tr_state);

						back_ctx->flags = ctx->flags;
						back_ctx->flags &= ~CTX_IS_TRANSPARENT;
						back_ctx->flags |= CTX_IS_BACKGROUND;
						back_ctx->aspect = ctx->aspect;
						back_ctx->drawable = ctx->drawable;
						drawable_check_bounds(back_ctx, tr_state->visual);
						back_ctx->bi->clip = ctx->bi->clip;
						back_ctx->bi->unclip = ctx->bi->unclip;
					}
					/*keep track of node drawn*/
					if (!(ctx->drawable->flags & DRAWABLE_REGISTERED_WITH_VISUAL) ) {
						struct _drawable_store *it;
						GF_SAFEALLOC(it, struct _drawable_store);
						it->drawable = ctx->drawable;
						if (tr_state->visual->last_prev_entry) {
							tr_state->visual->last_prev_entry->next = it;
							tr_state->visual->last_prev_entry = it;
						} else {
							tr_state->visual->prev_nodes = tr_state->visual->last_prev_entry = it;
						}
						GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer2D] Registering new drawn node %s on visual\n", gf_node_get_class_name(it->drawable->node)));
						ctx->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL;
					}
				}

				group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
			}
			tr_state->visual->top_clipper = prev_clip;
			gf_mx2d_copy(tr_state->transform, backup);
		}
		break;

	/*check picking - we must fall in our 2D clipper*/
	case TRAVERSE_PICK:
		if (gf_sc_pick_in_clipper(tr_state, &st->clip)) {

#ifndef GPAC_DISABLE_3D
			if (tr_state->visual->type_3d) {
				/*apply viewport*/
				if (viewport) {
					gf_mx_copy(mx3d, tr_state->model_matrix);
					tr_state->traversing_mode = TRAVERSE_BINDABLE;
					tr_state->bounds = st->clip;
					gf_node_traverse(viewport, tr_state);
					tr_state->traversing_mode = TRAVERSE_PICK;
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
					gf_mx_copy(tr_state->model_matrix, mx3d);
				} else {
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
				}
			} else
#endif
			{
				if (viewport) {
					gf_mx2d_copy(backup, tr_state->transform);
					tr_state->traversing_mode = TRAVERSE_BINDABLE;
					tr_state->bounds = st->clip;
					gf_node_traverse(viewport, tr_state);
					tr_state->traversing_mode = TRAVERSE_PICK;
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
					gf_mx2d_copy(tr_state->transform, backup);
				} else {
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
				}
			}
		}
		break;
	case TRAVERSE_GET_BOUNDS:
		if (tr_state->for_node) {
			group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
		} else {
			tr_state->bounds = st->clip;
#ifndef GPAC_DISABLE_3D
			gf_bbox_from_rect(&tr_state->bbox, &st->clip);
#endif
		}
		break;

	case TRAVERSE_DRAW_2D:
		group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
		break;

#ifndef GPAC_DISABLE_3D
	/*drawing a layer means drawing all sub-elements as a whole (no depth sorting with parents)*/
	case TRAVERSE_DRAW_3D:
		assert(0);
		break;
#endif
	}

	/*restore traversing state*/
	tr_state->vp_size = prev_vp;
	tr_state->backgrounds = oldb;
	tr_state->viewpoints = oldv;
	tr_state->is_layer = prev_layer;
#ifndef GPAC_DISABLE_3D
	tr_state->fogs = oldf;
	tr_state->navigations = oldn;
#endif

	/*in case we missed bindables*/
	if (st->first) {
		st->first = 0;
		gf_sc_invalidate(tr_state->visual->compositor, NULL);
	}
}