コード例 #1
0
ファイル: background2d.c プロジェクト: DmitrySigaev/DSMedia
static void DrawBackground(DrawableContext *ctx)
{
	Background2DStack *bcks = (Background2DStack *) Node_GetPrivate(ctx->node->owner);

	if (m4_rect_is_empty(ctx->clip) ) return;

	ctx->path_filled = 0;

	if ( back_use_texture(b2D_getnode(bcks)) ) {

		if (!ctx->surface->DrawBitmap) {
			/*set target rect*/
			m4_path_reset(bcks->node->path);
			m4_path_add_rectangle(bcks->node->path, 
								ctx->unclip.x + ctx->unclip.width/2,
								ctx->unclip.y - ctx->unclip.height/2,
								ctx->unclip.width, ctx->unclip.height);

			ctx->original = ctx->unclip;

			/*draw texture*/
			VS2D_TexturePath(ctx->surface, bcks->node->path, ctx);

		} else {

			ctx->original = ctx->unclip;
			ctx->clip = m4_rect_pixelize(&ctx->unclip);

			/*direct rendering, render without clippers */
			if (ctx->surface->render->top_effect->trav_flags & TF_RENDER_DIRECT) {
				ctx->surface->DrawBitmap(ctx->surface, ctx->h_texture, &ctx->clip, &ctx->unclip);
			}
			/*render bitmap for all dirty rects*/
			else {
				u32 i;
				M4IRect clip;
				for (i=0; i<ctx->surface->to_redraw.count; i++) {
					/*there's an opaque region above, don't draw*/
					if (ctx->surface->draw_node_index<ctx->surface->to_redraw.opaque_node_index[i]) continue;
					clip = ctx->clip;
					m4_irect_intersect(&clip, &ctx->surface->to_redraw.list[i]);
					if (clip.width && clip.height) {
						ctx->surface->DrawBitmap(ctx->surface, ctx->h_texture, &clip, &ctx->unclip);
					}
				}
			}
		}		
		ctx->redraw_flags = bcks->txh.hwtx ? 0 : CTX_APP_DIRTY;
	} else {
		/*directly clear with specified color*/
		VS2D_Clear(ctx->surface, &ctx->clip, ctx->aspect.fill_color);
		ctx->redraw_flags = 0;
	}
}
コード例 #2
0
ファイル: mpeg4_background2d.c プロジェクト: bigbensk/gpac
static Bool back_texture_enabled(M_Background2D *bck, GF_TextureHandler *txh)
{
	Bool use_texture = back_use_texture(bck);
	if (use_texture) {
		/*texture not ready*/
		if (!txh->tx_io) {
			use_texture = 0;
			gf_sc_invalidate(txh->compositor, NULL);
		}
		gf_sc_texture_set_blend_mode(txh, gf_sc_texture_is_transparent(txh) ? TX_REPLACE : TX_DECAL);
	}
	return use_texture;
}
コード例 #3
0
ファイル: mpeg4_background2d.c プロジェクト: bigbensk/gpac
static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state)
{
	Background2DStack *stack;
	if (!ctx || !ctx->drawable || !ctx->drawable->node) return;
	stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node);

	if (!ctx->bi->clip.width || !ctx->bi->clip.height) return;

	stack->flags &= ~CTX_PATH_FILLED;

	if (back_use_texture((M_Background2D *)ctx->drawable->node)) {

		if (!tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx, NULL)) {
			/*set target rect*/
			gf_path_reset(stack->drawable->path);
			gf_path_add_rect_center(stack->drawable->path, 
								ctx->bi->unclip.x + ctx->bi->unclip.width/2,
								ctx->bi->unclip.y - ctx->bi->unclip.height/2,
								ctx->bi->unclip.width, ctx->bi->unclip.height);

			/*draw texture*/
			visual_2d_texture_path(tr_state->visual, stack->drawable->path, ctx, tr_state);
		}
		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	} else {
		
		/*direct drawing, draw without clippers */
		if (tr_state->immediate_draw) {
			/*directly clear with specified color*/
			tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, ctx->aspect.fill_color);
		} else {
			u32 i;
			GF_IRect clip;
			for (i=0; i<tr_state->visual->to_redraw.count; i++) {
				/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
				if (tr_state->visual->draw_node_index<tr_state->visual->to_redraw.opaque_node_index[i]) continue;
#endif
				clip = ctx->bi->clip;
				gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i]);
				if (clip.width && clip.height) {
					tr_state->visual->ClearSurface(tr_state->visual, &clip, ctx->aspect.fill_color);
				}
			}
		}
		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	}
	tr_state->visual->has_modif = 1;
}
コード例 #4
0
ファイル: mpeg4_background2d.c プロジェクト: bigbensk/gpac
static void TraverseBackground2D(GF_Node *node, void *rs, Bool is_destroy)
{
	u32 col;
	BackgroundStatus *status;
	M_Background2D *bck;
	Background2DStack *stack = (Background2DStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		DestroyBackground2D(node);
		return;
	}

	bck = (M_Background2D *)node;

	/*special case for background in Layer2D: the background is seen as a regular drawable, so 
	RENDER_BINDABLE is not used*/
	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_2D:
		DrawBackground2D_2D(tr_state->ctx, tr_state);
		return;
	case  TRAVERSE_PICK:
	case TRAVERSE_GET_BOUNDS:
		return;
	}

	/*first traverse, bound if needed*/
	if (gf_list_find(tr_state->backgrounds, node) < 0) {
		M_Background2D *top_bck = (M_Background2D *)node;
		gf_list_add(tr_state->backgrounds, node);
		assert(gf_list_find(stack->reg_stacks, tr_state->backgrounds)==-1);
		gf_list_add(stack->reg_stacks, tr_state->backgrounds);
		b2D_new_status(stack, bck);

		/*only bound if we're on top*/
		top_bck = gf_list_get(tr_state->backgrounds, 0);
		if (!bck->isBound) {
			if (top_bck== bck) {
				Bindable_SetIsBound(node, 1);
			} else if (!top_bck->isBound) {
				bck->set_bind = 1;
				bck->on_set_bind(node, NULL);
			}
		}
		/*open the stream if any*/
		if (back_use_texture(bck) && !stack->txh.is_open) gf_sc_texture_play(&stack->txh, &bck->url);
		/*in any case don't draw the first time (since the background could have been declared last)*/
		gf_sc_invalidate(stack->txh.compositor, NULL);
		return;
	}
	if (!bck->isBound) return;

	status = b2d_get_status(stack, tr_state->backgrounds);
	if (!status) return;

	if (gf_node_dirty_get(node)) {
		stack->flags |= CTX_APP_DIRTY;
		gf_node_dirty_clear(node, 0);


		col = GF_COL_ARGB_FIXED(FIX_ONE, bck->backColor.red, bck->backColor.green, bck->backColor.blue);
		if (col != status->ctx.aspect.fill_color) {
			status->ctx.aspect.fill_color = col;
			stack->flags |= CTX_APP_DIRTY;
		}
	} 

	if (back_use_texture(bck) ) {
		if (stack->txh.tx_io && !(status->ctx.flags & CTX_APP_DIRTY) && stack->txh.needs_refresh) 
			stack->flags |= CTX_TEXTURE_DIRTY;
	}
	status->ctx.flags = stack->flags;


	if (tr_state->traversing_mode != TRAVERSE_BINDABLE) return;

	/*3D mode*/
#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d) {
		DrawBackground2D_3D(bck, stack, tr_state);
	} else
#endif
		DrawBackground2D_2D(&status->ctx, tr_state);
}
コード例 #5
0
ファイル: background2d.c プロジェクト: DmitrySigaev/DSMedia
static void RenderBackground2D(SFNode *node, void *rs)
{
	u32 col;
	BackgroundStatus *status;
	M_Background2D *bck;
	Background2DStack *bcks = (Background2DStack *) Node_GetPrivate(node);
	RenderEffect2D *eff = (RenderEffect2D *)rs;

	status = b2D_GetStatus(bcks, eff);
	if (!status) return;

	status->ctx.redraw_flags = 0;
	if (Node_GetDirty(node)) {
		status->ctx.redraw_flags = CTX_APP_DIRTY;
		Node_ClearDirty(node);
	}

	bck = b2D_getnode(bcks);

	if (bcks->first_render) {
		bcks->first_render = 0;
		if (ChainGetEntry(status->bind_stack, 0) == node) {
			if (!bck->isBound) {
				bck->isBound = 1;
				Node_OnEventOutSTR((SFNode *)bck, "isBound");
			}
		}
		/*open the stream if any*/
		if (back_use_texture(bck) && !bcks->txh.is_open) {
			texture_play(&bcks->txh, &bck->url);
		}

		/*we're in direct rendering and we missed background drawing - reset*/
		if (bck->isBound && (eff->trav_flags & TF_RENDER_DIRECT) && !eff->draw_background) {
			SR_Invalidate(bcks->compositor, NULL);
			return;
		}
	}

	if (!bck->isBound) return;
	if (!eff->draw_background && (eff->trav_flags & TF_RENDER_DIRECT)) return;

	/*background context bounds are always setup by parent group/surface*/
	if (back_use_texture(bck) ) {
		if (bcks->txh.hwtx) {
			if (!status->ctx.redraw_flags && bcks->txh.needs_refresh) status->ctx.redraw_flags |= CTX_TEXTURE_DIRTY;
		} else {
			SR_Invalidate(bcks->compositor, NULL);
			status->ctx.redraw_flags = CTX_APP_DIRTY;
		}
	} else {
		col = MAKE_ARGB_FLOAT(1.0, bck->backColor.red, bck->backColor.green, bck->backColor.blue);
		if (col != status->ctx.aspect.fill_color) {
			status->ctx.aspect.fill_color = col;
			status->ctx.redraw_flags = CTX_APP_DIRTY;
		}
	}

	if (!eff->draw_background) return;

	if (eff->back_stack == eff->surface->back_stack)
		eff->surface->render->back_color = MAKE_ARGB_FLOAT(1.0, bck->backColor.red, bck->backColor.green, bck->backColor.blue);

	if (eff->parent) {
		group2d_add_to_context_list(eff->parent, &status->ctx);
	} else if (eff->trav_flags & TF_RENDER_DIRECT) {
		bcks->node->Draw(&status->ctx);
	}
}
コード例 #6
0
ファイル: mpeg4_background2d.c プロジェクト: HungMingWu/gpac
static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state)
{
	Bool clear_all = GF_TRUE;
	u32 color;
	Bool use_texture;
	Bool is_offscreen = GF_FALSE;
	Background2DStack *stack;
	if (!ctx || !ctx->drawable || !ctx->drawable->node) return;
	stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node);

	if (!ctx->bi->clip.width || !ctx->bi->clip.height) return;

	stack->flags &= ~CTX_PATH_FILLED;
	color = ctx->aspect.fill_color;

	use_texture = back_use_texture((M_Background2D *)ctx->drawable->node);
	if (!use_texture && !tr_state->visual->is_attached) {
		use_texture = 1;
		stack->txh.data = stack->col_tx;
		stack->txh.width = 2;
		stack->txh.height = 2;
		stack->txh.stride = 6;
		stack->txh.pixelformat = GF_PIXEL_RGB_24;
	}

	if (use_texture) {

		if (!tr_state->visual->DrawBitmap(tr_state->visual, tr_state, ctx)) {
			/*set target rect*/
			gf_path_reset(stack->drawable->path);
			gf_path_add_rect_center(stack->drawable->path,
			                        ctx->bi->unclip.x + ctx->bi->unclip.width/2,
			                        ctx->bi->unclip.y - ctx->bi->unclip.height/2,
			                        ctx->bi->unclip.width, ctx->bi->unclip.height);

			/*draw texture*/
			visual_2d_texture_path(tr_state->visual, stack->drawable->path, ctx, tr_state);
		}
		//a quick hack, if texture not ready return (we don't have direct notification of this through the above functions
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->compositor->hybrid_opengl && !stack->txh.tx_io) 
			return;
#endif

		stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
		tr_state->visual->has_modif = 1;
#ifndef GPAC_DISABLE_3D
		//in opengl auto mode we still have to clear the canvas
		if (!tr_state->immediate_draw && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) {
			clear_all = GF_FALSE;
			is_offscreen = GF_TRUE;
			color &= 0x00FFFFFF;
		} else
#endif
			return;
	}


#ifndef GPAC_DISABLE_3D
	if (ctx->flags & CTX_BACKROUND_NOT_LAYER) {
		if (clear_all && !tr_state->visual->offscreen && tr_state->visual->compositor->hybrid_opengl) {
			compositor_2d_hybgl_clear_surface(tr_state->visual, NULL, color, GF_FALSE);
			is_offscreen = GF_TRUE;
			color &= 0x00FFFFFF;
			//we may need to clear the canvas for immediate mode
		}
	} else {
		is_offscreen = GF_TRUE;
	}
#endif
	/*direct drawing, draw without clippers */
	if (tr_state->immediate_draw
	   ) {
		/*directly clear with specified color*/
		if (clear_all)
			tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, color, is_offscreen);
	} else {
		u32 i;
		GF_IRect clip;
		for (i=0; i<tr_state->visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (tr_state->visual->draw_node_index < tr_state->visual->to_redraw.list[i].opaque_node_index) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i].rect);
			if (clip.width && clip.height) {
				tr_state->visual->ClearSurface(tr_state->visual, &clip, color, is_offscreen);
			}
		}
	}
	stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY);
	tr_state->visual->has_modif = 1;
}
コード例 #7
0
ファイル: mpeg4_background.c プロジェクト: Bevara/GPAC
static void TraverseBackground(GF_Node *node, void *rs, Bool is_destroy)
{
	M_Background *bck;
	BackgroundStack *st;
	SFColor bcol;
	SFVec4f res;
	Fixed scale;
	Bool has_sky, has_ground, front_tx, back_tx, top_tx, bottom_tx, right_tx, left_tx;
	GF_Matrix mx;
	GF_Compositor *compositor;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		DestroyBackground(node);
		return;
	}

	gf_node_dirty_clear(node, 0);
	bck = (M_Background *)node;
	st = (BackgroundStack *) gf_node_get_private(node);
	compositor = (GF_Compositor*)st->compositor;


	/*may happen in get_bounds*/
	if (!tr_state->backgrounds) return;

	/*first traverse, bound if needed*/
	if (gf_list_find(tr_state->backgrounds, node) < 0) {
		gf_list_add(tr_state->backgrounds, node);
		assert(gf_list_find(st->reg_stacks, tr_state->backgrounds)==-1);
		gf_list_add(st->reg_stacks, tr_state->backgrounds);
		/*only bound if we're on top*/
		if (gf_list_get(tr_state->backgrounds, 0) == bck) {
			if (!bck->isBound) Bindable_SetIsBound(node, 1);
		}

		/*check streams*/
		if (back_use_texture(&bck->frontUrl) && !st->txh_front.is_open) gf_sc_texture_play(&st->txh_front, &bck->frontUrl);
		if (back_use_texture(&bck->bottomUrl) && !st->txh_bottom.is_open) gf_sc_texture_play(&st->txh_bottom, &bck->bottomUrl);
		if (back_use_texture(&bck->backUrl) && !st->txh_back.is_open) gf_sc_texture_play(&st->txh_back, &bck->backUrl);
		if (back_use_texture(&bck->topUrl) && !st->txh_top.is_open) gf_sc_texture_play(&st->txh_top, &bck->topUrl);
		if (back_use_texture(&bck->rightUrl) && !st->txh_right.is_open) gf_sc_texture_play(&st->txh_right, &bck->rightUrl);
		if (back_use_texture(&bck->leftUrl) && !st->txh_left.is_open) gf_sc_texture_play(&st->txh_left, &bck->leftUrl);

		/*in any case don't draw the first time (since the background could have been declared last)*/
		gf_sc_invalidate(st->compositor, NULL);
		return;
	}
	if (!bck->isBound) return;

	if (tr_state->traversing_mode != TRAVERSE_BINDABLE) {
		if (tr_state->traversing_mode == TRAVERSE_SORT) {
			gf_mx_copy(st->current_mx, tr_state->model_matrix);
		}
		return;
	}

	front_tx = back_gf_sc_texture_enabled(&bck->frontUrl, &st->txh_front);
	back_tx = back_gf_sc_texture_enabled(&bck->backUrl, &st->txh_back);
	top_tx = back_gf_sc_texture_enabled(&bck->topUrl, &st->txh_top);
	bottom_tx = back_gf_sc_texture_enabled(&bck->bottomUrl, &st->txh_bottom);
	right_tx = back_gf_sc_texture_enabled(&bck->rightUrl, &st->txh_right);
	left_tx = back_gf_sc_texture_enabled(&bck->leftUrl, &st->txh_left);

	has_sky = ((bck->skyColor.count>1) && bck->skyAngle.count) ? 1 : 0;
	has_ground = ((bck->groundColor.count>1) && bck->groundAngle.count) ? 1 : 0;
	bcol.red = bcol.green = bcol.blue = 0;
	if (bck->skyColor.count) bcol = bck->skyColor.vals[0];

	/*if we clear the main visual clear it entirely - ONLY IF NOT IN LAYER*/
	if ((tr_state->visual == compositor->visual) && (tr_state->visual->back_stack == tr_state->backgrounds)) {
		visual_3d_clear(tr_state->visual, bcol, FIX_ONE);
		if (!has_sky && !has_ground && !front_tx && !back_tx && !top_tx && !bottom_tx && !left_tx && !right_tx) {
			return;
		}
	}

	/*undo translation*/
	res.x = res.y = res.z = 0;
	res.q = FIX_ONE;
	gf_mx_apply_vec_4x4(&tr_state->camera->unprojection, &res);
	assert(res.q);
	res.x = gf_divfix(res.x, res.q);
	res.y = gf_divfix(res.y, res.q);
	res.z = gf_divfix(res.z, res.q);
	/*NB: we don't support local rotation of the background ...*/

	/*enable background state (turn off all quality options)*/
	visual_3d_set_background_state(tr_state->visual, 1);

	if (has_sky) {
		GF_Matrix bck_mx;
		gf_mx_copy(bck_mx, tr_state->model_matrix);
		gf_mx_copy(tr_state->model_matrix, st->current_mx);

		if (!st->sky_mesh) {
			st->sky_mesh = new_mesh();
			back_build_dome(st->sky_mesh, &bck->skyAngle, &bck->skyColor, 0);
		}

		gf_mx_init(mx);
		gf_mx_add_translation(&mx, res.x, res.y, res.z);

		/*CHECKME - not sure why, we need to scale less in fixed point otherwise z-far clipping occur - probably some
		rounding issues...*/
#ifdef GPAC_FIXED_POINT
		scale = (tr_state->camera->z_far/10)*8;
#else
		scale = 9*tr_state->camera->z_far/10;
#endif
		gf_mx_add_scale(&mx, scale, scale, scale);

		gf_mx_add_matrix(&tr_state->model_matrix, &mx);

		visual_3d_mesh_paint(tr_state, st->sky_mesh);

		gf_mx_copy(tr_state->model_matrix, bck_mx);
	}

	if (has_ground) {
		GF_Matrix bck_mx;
		gf_mx_copy(bck_mx, tr_state->model_matrix);
		gf_mx_copy(tr_state->model_matrix, st->current_mx);

		if (!st->ground_mesh) {
			st->ground_mesh = new_mesh();
			back_build_dome(st->ground_mesh, &bck->groundAngle, &bck->groundColor, 1);
		}

		gf_mx_init(mx);
		gf_mx_add_translation(&mx, res.x, res.y, res.z);
		/*cf above*/
#ifdef GPAC_FIXED_POINT
		scale = (tr_state->camera->z_far/100)*70;
#else
		scale = 85*tr_state->camera->z_far/100;
#endif
		gf_mx_add_scale(&mx, scale, -scale, scale);

		gf_mx_add_matrix(&tr_state->model_matrix, &mx);
		visual_3d_mesh_paint(tr_state, st->ground_mesh);
		gf_mx_copy(tr_state->model_matrix, bck_mx);
	}

	if (front_tx || back_tx || left_tx || right_tx || top_tx || bottom_tx) {
		GF_Matrix bck_mx;
		gf_mx_copy(bck_mx, tr_state->model_matrix);
		gf_mx_copy(tr_state->model_matrix, st->current_mx);

		gf_mx_init(mx);
		gf_mx_add_translation(&mx, res.x, res.y, res.z);
#ifdef GPAC_FIXED_POINT
		scale = (tr_state->camera->z_far/100)*99;
		gf_mx_add_scale(&mx, scale, scale, scale);
#else
		gf_mx_add_scale(&mx, tr_state->camera->z_far, tr_state->camera->z_far, tr_state->camera->z_far);
#endif
		visual_3d_enable_antialias(tr_state->visual, 1);

		gf_mx_add_matrix(&tr_state->model_matrix, &mx);

		if (front_tx) back_draw_texture(tr_state, &st->txh_front, st->front_mesh);
		if (back_tx) back_draw_texture(tr_state, &st->txh_back, st->back_mesh);
		if (top_tx) back_draw_texture(tr_state, &st->txh_top, st->top_mesh);
		if (bottom_tx) back_draw_texture(tr_state, &st->txh_bottom, st->bottom_mesh);
		if (left_tx) back_draw_texture(tr_state, &st->txh_left, st->left_mesh);
		if (right_tx) back_draw_texture(tr_state, &st->txh_right, st->right_mesh);

		gf_mx_copy(tr_state->model_matrix, bck_mx);
	}

	/*enable background state (turn off all quality options)*/
	visual_3d_set_background_state(tr_state->visual, 0);
}