⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 background.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005  *					All rights reserved * *  This file is part of GPAC / 3D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "render3d_nodes.h"/*for background textures - the offset is to prevent lines on cube map edges*/#define PLANE_HSIZE		FLT2FIX(0.5025f)#define PLANE_HSIZE_LOW		FLT2FIX(0.5f)static Bool back_use_texture(MFURL *url){	if (!url->count) return 0;	if (url->vals[0].OD_ID > 0) return 1;	if (url->vals[0].url && strlen(url->vals[0].url)) return 1;	return 0;}static void UpdateBackgroundTexture(GF_TextureHandler *txh){	gf_sr_texture_update_frame(txh, 0);	/*restart texture if needed (movie background controled by MediaControl)*/	if (txh->stream_finished && gf_mo_get_loop(txh->stream, 0)) gf_sr_texture_restart(txh);}static Bool back_gf_sr_texture_enabled(MFURL *url, GF_TextureHandler *txh){	Bool use_texture = back_use_texture(url);	if (use_texture) {		/*texture not ready*/		if (!txh->hwtx) {			use_texture = 0;			gf_sr_invalidate(txh->compositor, NULL);		}		tx_set_blend_mode(txh, tx_is_transparent(txh) ? TX_REPLACE : TX_DECAL);	}	return use_texture;}static void back_check_gf_sr_texture_change(GF_TextureHandler *txh, MFURL *url){	/*if open and changed, stop and play*/	if (txh->is_open) {		if (! gf_sr_texture_check_url_change(txh, url)) return;		gf_sr_texture_stop(txh);		gf_sr_texture_play(txh, url);		return;	}	/*if not open and changed play*/	if (url->count) gf_sr_texture_play(txh, url);}static void DestroyBackground2D(GF_Node *node){	Background2DStack *ptr;	ptr = (Background2DStack *) gf_node_get_private(node);	PreDestroyBindable(node, ptr->reg_stacks);	gf_list_del(ptr->reg_stacks);	gf_sr_texture_destroy(&ptr->txh);	mesh_free(ptr->mesh);	free(ptr);}static void RenderBackground2D(GF_Node *node, void *rs, Bool is_destroy){	M_Background2D *bck;	Bool use_texture;	Background2DStack *st;	GF_Matrix mx;	Bool is_layer;	RenderEffect3D *eff = (RenderEffect3D *)rs;	Render3D *sr;	if (is_destroy) {		DestroyBackground2D(node);		return;	}	gf_node_dirty_clear(node, 0);	bck = (M_Background2D *)node;	st = (Background2DStack *) gf_node_get_private(node);	sr = (Render3D*)st->compositor->visual_renderer->user_priv;	assert(eff->backgrounds);	/*first traverse, bound if needed*/	if (gf_list_find(eff->backgrounds, node) < 0) {		gf_list_add(eff->backgrounds, node);		assert(gf_list_find(st->reg_stacks, eff->backgrounds)==-1);		gf_list_add(st->reg_stacks, eff->backgrounds);		/*only bound if we're on top*/		if (gf_list_get(eff->backgrounds, 0) == bck) {			if (!bck->isBound) Bindable_SetIsBound(node, 1);		}		/*open the stream if any*/		if (back_use_texture(&bck->url) && !st->txh.is_open) gf_sr_texture_play(&st->txh, &bck->url);		/*in any case don't draw the first time (since the background could have been declared last)*/		gf_sr_invalidate(st->compositor, NULL);		return;	}	if (!bck->isBound) return;	if (eff->traversing_mode != TRAVERSE_RENDER_BINDABLE) return;	use_texture = back_gf_sr_texture_enabled(&bck->url, &st->txh);	/*no lights on background*/	VS3D_SetState(eff->surface, F3D_LIGHT | F3D_BLEND, 0);	VS3D_PushMatrix(eff->surface);	VS3D_SetMatrixMode(eff->surface, MAT_TEXTURE);	VS3D_ResetMatrix(eff->surface);	VS3D_SetMatrixMode(eff->surface, MAT_MODELVIEW);	is_layer = (eff->surface->back_stack == eff->backgrounds) ? 0 : 1;	/*little opt: if we clear the main surface clear it entirely */	if (!is_layer) {		VS3D_ClearSurface(eff->surface, bck->backColor, FIX_ONE);		if (!use_texture) {			VS3D_PopMatrix(eff->surface);			return;		}		/*we need a hack here because main vp is always rendered before main background, and in the case of a		2D viewport it modifies the modelview matrix, which we don't want ...*/		VS3D_ResetMatrix(eff->surface);	}	if (!use_texture || (!is_layer && st->txh.transparent) ) VS3D_SetMaterial2D(eff->surface, bck->backColor, FIX_ONE);	if (use_texture) {		VS3D_SetState(eff->surface, F3D_COLOR, !is_layer);		eff->mesh_has_texture = tx_enable(&st->txh, NULL);	}	gf_mx_init(mx);	if (eff->camera->is_3D) {		Fixed sx, sy;		/*reset matrix*/		VS3D_ResetMatrix(eff->surface);		sx = sy = 2 * gf_mulfix(gf_tan(eff->camera->fieldOfView/2), eff->camera->z_far);		if (eff->camera->width > eff->camera->height) {			sx = gf_muldiv(sx, eff->camera->width, eff->camera->height);		} else {			sy = gf_muldiv(sy, eff->camera->height, eff->camera->width);		}		gf_mx_add_scale(&mx, sx, sy, FIX_ONE);#ifdef GPAC_FIXED_POINT		gf_mx_add_translation(&mx, 0, 0, - (eff->camera->z_far/100)*99);#else		gf_mx_add_translation(&mx, 0, 0, -0.999f*eff->camera->z_far);#endif	} else {		gf_mx_add_scale(&mx, eff->bbox.max_edge.x - eff->bbox.min_edge.x, 							eff->bbox.max_edge.y - eff->bbox.min_edge.y,							FIX_ONE);		/*when in layer2D, DON'T MOVE BACKGROUND TO ZFAR*/#ifdef GPAC_FIXED_POINT		if (!is_layer) gf_mx_add_translation(&mx, 0, 0, -(eff->camera->z_far/100)*99);#else		if (!is_layer) gf_mx_add_translation(&mx, 0, 0, -0.999f*eff->camera->z_far);#endif	}	VS3D_MultMatrix(eff->surface, mx.m);	VS3D_DrawMesh(eff, st->mesh);	if (eff->mesh_has_texture) {		tx_disable(&st->txh);		eff->mesh_has_texture = 0;	}	VS3D_PopMatrix(eff->surface);}static void b2D_set_bind(GF_Node *node){	Background2DStack *st = (Background2DStack *)gf_node_get_private(node);	Bindable_OnSetBind(node, st->reg_stacks);	/*and redraw scene*/	gf_sr_invalidate(st->compositor, NULL);}void R3D_InitBackground2D(Render3D *sr, GF_Node *node){	Background2DStack *ptr;	GF_SAFEALLOC(ptr, Background2DStack);	gf_sr_traversable_setup(ptr, node, sr->compositor);	ptr->reg_stacks = gf_list_new();	((M_Background2D *)node)->on_set_bind = b2D_set_bind;	gf_sr_texture_setup(&ptr->txh, sr->compositor, node);	ptr->txh.update_texture_fcnt = UpdateBackgroundTexture;	gf_node_set_private(node, ptr);	gf_node_set_callback_function(node, RenderBackground2D);	ptr->mesh = new_mesh();	mesh_set_vertex(ptr->mesh, -PLANE_HSIZE, -PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, 0);	mesh_set_vertex(ptr->mesh,  PLANE_HSIZE, -PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, 0);	mesh_set_vertex(ptr->mesh,  PLANE_HSIZE,  PLANE_HSIZE, 0,  0,  0,  FIX_ONE, FIX_ONE, FIX_ONE);	mesh_set_vertex(ptr->mesh, -PLANE_HSIZE,  PLANE_HSIZE, 0,  0,  0,  FIX_ONE, 0, FIX_ONE);	mesh_set_triangle(ptr->mesh, 0, 1, 2); mesh_set_triangle(ptr->mesh, 0, 2, 3);	ptr->mesh->flags |= MESH_IS_2D;}void R3D_Background2DModified(GF_Node *node){	M_Background2D *bck = (M_Background2D *)node;	Background2DStack *st = (Background2DStack *) gf_node_get_private(node);	if (!st) return;	back_check_gf_sr_texture_change(&st->txh, &bck->url);		gf_sr_invalidate(st->txh.compositor, NULL);}static void DestroyBackground(GF_Node *node){	BackgroundStack *ptr = (BackgroundStack *) gf_node_get_private(node);	PreDestroyBindable(node, ptr->reg_stacks);	gf_list_del(ptr->reg_stacks);	if (ptr->sky_mesh) mesh_free(ptr->sky_mesh);	if (ptr->ground_mesh) mesh_free(ptr->ground_mesh);		gf_sg_vrml_mf_reset(&ptr->ground_ang, GF_SG_VRML_MFFLOAT);	gf_sg_vrml_mf_reset(&ptr->sky_ang, GF_SG_VRML_MFFLOAT);	gf_sg_vrml_mf_reset(&ptr->ground_col, GF_SG_VRML_MFCOLOR);	gf_sg_vrml_mf_reset(&ptr->sky_col, GF_SG_VRML_MFCOLOR);	mesh_free(ptr->front_mesh);	mesh_free(ptr->back_mesh);	mesh_free(ptr->top_mesh);	mesh_free(ptr->bottom_mesh);	mesh_free(ptr->left_mesh);	mesh_free(ptr->right_mesh);		gf_sr_texture_destroy(&ptr->txh_front);	gf_sr_texture_destroy(&ptr->txh_back);	gf_sr_texture_destroy(&ptr->txh_top);	gf_sr_texture_destroy(&ptr->txh_bottom);	gf_sr_texture_destroy(&ptr->txh_left);	gf_sr_texture_destroy(&ptr->txh_right);		free(ptr);}#define COL_TO_RGBA(res, col) { res.red = col.red; res.green = col.green; res.blue = col.blue; res.alpha = FIX_ONE; }#define DOME_STEP_V	32#define DOME_STEP_H	16static void back_build_dome(GF_Mesh *mesh, MFFloat *angles, MFColor *color, Bool ground_dome){	u32 i, j, last_idx, ang_idx, new_idx;	Bool pad;	u32 step_div_h;	GF_Vertex vx;	SFColorRGBA start_col, end_col;	Fixed start_angle, next_angle, angle, r, frac, first_angle;	start_angle = 0;	mesh_reset(mesh);	start_col.red = start_col.green = start_col.blue = 0;	end_col = start_col;	if (color->count) {		COL_TO_RGBA(start_col, color->vals[0]);		end_col = start_col;		if (color->count>1) COL_TO_RGBA(end_col, color->vals[1]);	}	start_col.alpha = end_col.alpha = FIX_ONE;	vx.texcoords.x = vx.texcoords.y = 0;	vx.color = start_col;	vx.pos.x = vx.pos.z = 0; vx.pos.y = FIX_ONE;	vx.normal.x = vx.normal.z = 0; vx.normal.y = -FIX_ONE;	mesh_set_vertex_vx(mesh, &vx);	last_idx = 0;	ang_idx = 0;		pad = 1;	next_angle = first_angle = 0;	if (angles->count) {		next_angle = angles->vals[0];		first_angle = 7*next_angle/8;		pad = 0;	}	step_div_h = DOME_STEP_H;	i=0;	if (ground_dome) {		step_div_h *= 2;		i=1;	} 		for (; i<DOME_STEP_V; i++) {		if (ground_dome) {	        angle = first_angle + (i * (GF_PI2-first_angle) / DOME_STEP_V);		} else {	        angle = (i * GF_PI / DOME_STEP_V);		}		/*switch cols*/		if (angle >= next_angle) {			if (ang_idx+1<=angles->count) {				start_angle = next_angle;				next_angle = angles->vals[ang_idx+1];				if (next_angle>GF_PI) next_angle=GF_PI;				start_col = end_col;				ang_idx++;				if (ang_idx+1<color->count) {					COL_TO_RGBA(end_col, color->vals[ang_idx+1]);				} else {					pad = 1;				}			} else {				if (ground_dome) break;				pad = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -