示例#1
0
static void DrawBackground2D_3D(M_Background2D *bck, Background2DStack *st, GF_TraverseState *tr_state)
{
	GF_Matrix mx;
	Bool use_texture;

	use_texture = back_texture_enabled(bck, &st->txh);

	visual_3d_set_background_state(tr_state->visual, 1);

	visual_3d_matrix_push(tr_state->visual);

/*	visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_TEXTURE);
	gf_sc_texture_get_transform(&st->txh, NULL, &mx, 0);
	visual_3d_matrix_load(tr_state->visual, mx.m);
*/	
	visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW);

	/*little opt: if we clear the main visual clear it entirely */
	if (! tr_state->is_layer) {
		visual_3d_clear(tr_state->visual, bck->backColor, FIX_ONE);
		if (!use_texture) {
			visual_3d_matrix_pop(tr_state->visual);
			visual_3d_set_background_state(tr_state->visual, 0);
			return;
		}
		/*we need a hack here because main vp is always traversed before main background, and in the case of a
		2D viewport it modifies the modelview matrix, which we don't want ...*/
		visual_3d_matrix_reset(tr_state->visual);
	}
	if (!use_texture || (!tr_state->is_layer && st->txh.transparent) ) visual_3d_set_material_2d(tr_state->visual, bck->backColor, FIX_ONE);
	if (use_texture) {
		visual_3d_set_state(tr_state->visual, V3D_STATE_COLOR, ! tr_state->is_layer);
		tr_state->mesh_num_textures = gf_sc_texture_enable(&st->txh, NULL);
		if (!tr_state->mesh_num_textures) visual_3d_set_material_2d(tr_state->visual, bck->backColor, FIX_ONE);
	}

	/*create mesh object if needed*/
	if (!st->mesh) {
		st->mesh = new_mesh();
		mesh_set_vertex(st->mesh, -B2D_PLANE_HSIZE, -B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, 0);
		mesh_set_vertex(st->mesh,  B2D_PLANE_HSIZE, -B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, 0);
		mesh_set_vertex(st->mesh,  B2D_PLANE_HSIZE,  B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);
		mesh_set_vertex(st->mesh, -B2D_PLANE_HSIZE,  B2D_PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, FIX_ONE);
		mesh_set_triangle(st->mesh, 0, 1, 2); mesh_set_triangle(st->mesh, 0, 2, 3);
		st->mesh->flags |= MESH_IS_2D;
	}

	gf_mx_init(mx);
	if (tr_state->camera->is_3D) {
		Fixed sx, sy;
		/*reset matrix*/
		visual_3d_matrix_reset(tr_state->visual);
		sx = sy = 2 * gf_mulfix(gf_tan(tr_state->camera->fieldOfView/2), tr_state->camera->z_far);
		if (tr_state->camera->width > tr_state->camera->height) {
			sx = gf_muldiv(sx, tr_state->camera->width, tr_state->camera->height);
		} else {
			sy = gf_muldiv(sy, tr_state->camera->height, tr_state->camera->width);
		}
		gf_mx_add_scale(&mx, sx, sy, FIX_ONE);
#ifdef GPAC_FIXED_POINT
		gf_mx_add_translation(&mx, 0, 0, - (tr_state->camera->z_far/100)*99);
#else
		gf_mx_add_translation(&mx, 0, 0, -0.995f*tr_state->camera->z_far);
#endif
	} else {
		gf_mx_add_scale(&mx, tr_state->bbox.max_edge.x - tr_state->bbox.min_edge.x, 
							tr_state->bbox.max_edge.y - tr_state->bbox.min_edge.y,
							FIX_ONE);
		/*when in layer2D, DON'T MOVE BACKGROUND TO ZFAR*/
		if (!tr_state->is_layer) {
			Fixed tr;
#ifdef GPAC_FIXED_POINT
			tr = -(tr_state->camera->z_far/100)*99;
#else
			tr = -0.999f*tr_state->camera->z_far;
#endif
			if (!tr_state->camera->is_3D) tr = -tr;
			gf_mx_add_translation(&mx, 0, 0, tr);
		}
	}
	visual_3d_matrix_add(tr_state->visual, mx.m);
	visual_3d_mesh_paint(tr_state, st->mesh);
	if (tr_state->mesh_num_textures) {
		gf_sc_texture_disable(&st->txh);
		tr_state->mesh_num_textures = 0;
	}

	visual_3d_matrix_pop(tr_state->visual);
	visual_3d_set_background_state(tr_state->visual, 0);
}
示例#2
0
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);
}