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

📄 visual_surface.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
	VS3D_SetViewport(eff->surface, eff->camera->vp);	/*setup projection*/	VS_SetupProjection(eff);	/*turn off depth buffer in 2D*/	VS3D_SetDepthBuffer(eff->surface, eff->camera->is_3D);	/*set headlight if any*/	VS3D_SetHeadlight(eff->surface, (eff->camera->navigation_flags & NAV_HEADLIGHT) ? 1 : 0, eff->camera);	/*setup background*/	mode = eff->traversing_mode;	eff->traversing_mode = TRAVERSE_RENDER_BINDABLE;	bindable = (GF_Node*) gf_list_get(eff->backgrounds, 0);	/*if in layer clear z buffer (even if background)*/	if (in_layer) VS3D_ClearDepth(eff->surface);	if (Bindable_GetIsBound(bindable)) {		gf_node_render(bindable, eff);	}	/*clear if not in layer*/	else if (!in_layer) {		SFColor col;		col.red = INT2FIX((eff->surface->render->compositor->back_color>>16)&0xFF) / 255;		col.green = INT2FIX((eff->surface->render->compositor->back_color>>8)&0xFF) / 255;		col.blue = INT2FIX((eff->surface->render->compositor->back_color)&0xFF) / 255;		/*if composite surface, clear with alpha = 0*/		VS3D_ClearSurface(eff->surface, col, (eff->surface==eff->surface->render->surface) ? FIX_ONE : 0);	}	eff->traversing_mode = mode;}void VS_SetupEffects(VisualSurface *surface, RenderEffect3D *eff){	eff->surface = surface;	eff->camera = &surface->camera;	eff->backgrounds = surface->back_stack;	eff->viewpoints = surface->view_stack;	eff->fogs = surface->fog_stack;	eff->navigations = surface->navigation_stack;	eff->color_mat.identity = 1;	eff->camera->vp.x = eff->camera->vp.y = 0;	eff->min_hsize = INT2FIX(MIN(surface->width, surface->height) / 2);	if (!eff->min_hsize) eff->min_hsize = FIX_ONE;	/*main surface, set AR*/	if (surface->render->surface==surface) {		if (eff->surface->render->compositor->has_size_info) {			eff->camera->vp.x = INT2FIX(eff->surface->render->out_x); 			eff->camera->vp.y = INT2FIX(eff->surface->render->out_y);			eff->camera->vp.width = INT2FIX(eff->surface->render->out_width);			eff->camera->vp.height = INT2FIX(eff->surface->render->out_height);			eff->camera->width = INT2FIX(eff->surface->width);			eff->camera->height = INT2FIX(eff->surface->height);		} else {			Fixed sw, sh;			sw = INT2FIX(eff->surface->render->out_width);			sh = INT2FIX(eff->surface->render->out_height);			/*AR changed, rebuild camera*/			if ((sw!=eff->camera->vp.width) || (sh!=eff->camera->vp.height)) { 				eff->camera->width = eff->camera->vp.width = INT2FIX(eff->surface->render->out_width);				eff->camera->height = eff->camera->vp.height = INT2FIX(eff->surface->render->out_height);				eff->camera->flags |= CAM_IS_DIRTY;			}		}	}	/*composite surface, no AR*/	else {		eff->camera->vp.width = eff->camera->width = INT2FIX(surface->width);		eff->camera->vp.height = eff->camera->height = INT2FIX(surface->height);	}	if (!eff->is_pixel_metrics) {		if (eff->camera->height > eff->camera->width) {			eff->camera->height = 2*gf_divfix(eff->camera->height , eff->camera->width);			eff->camera->width = 2*FIX_ONE;		} else {			eff->camera->width = 2 * gf_divfix(eff->camera->width, eff->camera->height);			eff->camera->height = 2 * FIX_ONE;		}	}	/*setup surface bounds*/	eff->bbox.max_edge.x = eff->camera->width / 2;	eff->bbox.min_edge.x = -eff->bbox.max_edge.x;	eff->bbox.max_edge.y = eff->camera->height / 2;	eff->bbox.min_edge.y = -eff->bbox.max_edge.y;	eff->bbox.max_edge.z = eff->bbox.min_edge.z = 0;	eff->bbox.is_set = 1;}void VS_NodeRender(RenderEffect3D *eff, GF_Node *root_node){	GF_Node *fog;	if (!eff->camera || !eff->surface) return;	VS_InitRender(eff);	/*main surface, handle collisions*/	if ((eff->surface==eff->surface->render->surface) && eff->camera->is_3D) 		VS_DoCollisions(eff, NULL);		/*setup fog*/	fog = (GF_Node*) gf_list_get(eff->surface->fog_stack, 0);	eff->traversing_mode = TRAVERSE_RENDER_BINDABLE;	if (Bindable_GetIsBound(fog)) gf_node_render(fog, eff);	/*turn global lights on*/	eff->traversing_mode = TRAVERSE_LIGHTING;	gf_node_render(root_node, eff);		/*sort graph*/	eff->traversing_mode = TRAVERSE_SORT;	gf_node_render(root_node, eff);	/*and draw*/	VS_FlushContexts(eff->surface, eff);	/*and turn off lights*/	VS3D_ClearAllLights(eff->surface);}void VS_RootRenderChildren(RenderEffect3D *eff, GF_ChildNodeItem *children){	GF_ChildNodeItem *l;	GF_Matrix mx;	GF_Node *child;	if (!eff->camera || !eff->surface) return;	/*don't reset given matrix (used by compositeTexture2D when rescaling to POW2 sizes)*/	gf_mx_copy(mx, eff->model_matrix);	VS_InitRender(eff);		/**/	gf_mx_copy(eff->model_matrix, mx);	VS3D_MultMatrix(eff->surface, mx.m);	l = children;	eff->traversing_mode = TRAVERSE_LIGHTING;	while (l) {		gf_node_render(l->node, eff);		l = l->next;	}	l = children;	eff->traversing_mode = TRAVERSE_SORT;	while (l) {		gf_node_render(l->node, eff);		l = l->next;	}	/*setup fog*/	child = (GF_Node*) gf_list_get(eff->fogs, 0);	eff->traversing_mode = TRAVERSE_RENDER_BINDABLE;	if (Bindable_GetIsBound(child)) gf_node_render(child, eff);	/*and draw*/	VS_FlushContexts(eff->surface, eff);	/*and turn off lights*/	VS3D_ClearAllLights(eff->surface);}static GFINLINE Bool appear_has_alpha(RenderEffect3D *eff, GF_Node *node_to_draw){	u32 tag;	Bool is_mat3D;	DrawableStack *stack;	GF_Node *mat = eff->appear ? ((M_Appearance *)eff->appear)->material : NULL;	is_mat3D = 0;	if (mat) {		tag = gf_node_get_tag(mat);		switch (tag) {		/*for M2D: if filled & transparent we're transparent - otherwise we must check texture*/		case TAG_MPEG4_Material2D:			if (((M_Material2D *)mat)->filled && ((M_Material2D *)mat)->transparency) return 1;			break;		case TAG_MPEG4_Material:		case TAG_X3D_Material:			is_mat3D = 1;			if ( ((M_Material *)mat)->transparency) return 1;			break;		case TAG_MPEG4_MaterialKey:			return 1;			break;		}	} else if (eff->camera->is_3D && eff->appear) {		GF_TextureHandler *txh = R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture);		if (txh && txh->transparent) return 1;	}	/*check alpha texture in3D or with bitmap*/	if (is_mat3D || (gf_node_get_tag(((M_Shape *)node_to_draw)->geometry)==TAG_MPEG4_Bitmap)) {		GF_TextureHandler *txh = R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture);		if (txh && txh->transparent) return 1;	}	/*TODO - FIXME check alpha only...*/	if (!eff->color_mat.identity) return 1;	stack = (DrawableStack*)gf_node_get_private(((M_Shape *)node_to_draw)->geometry);	if (stack && (stack->mesh->flags & MESH_HAS_ALPHA)) return 1;	return 0;}void VS_RegisterContext(RenderEffect3D *eff, GF_Node *node_to_draw, GF_BBox *bounds, Bool is_shape){	u32 i, count;	GF_BBox b;	DLightContext *nl, *ol;	Draw3DContext *ctx;	assert(eff->traversing_mode == TRAVERSE_SORT);	/*if 2D draw in declared order. Otherwise, if no alpha or node is a layer, draw directly*/	if (!eff->camera->is_3D || !is_shape || !appear_has_alpha(eff, node_to_draw)) {		eff->traversing_mode = TRAVERSE_RENDER;		/*layout/form clipper, set it in world coords only*/		if (eff->has_clip) {			VS3D_PushMatrix(eff->surface);			VS3D_ResetMatrix(eff->surface);			VS3D_SetClipper2D(eff->surface, eff->clipper);			VS3D_PopMatrix(eff->surface);		}				gf_node_render(node_to_draw, eff);			/*back to SORT*/		eff->traversing_mode = TRAVERSE_SORT;		if (eff->has_clip) VS3D_ResetClipper2D(eff->surface);		return;	}	GF_SAFEALLOC(ctx, Draw3DContext);	ctx->directional_lights = gf_list_new();	ctx->node_to_draw = node_to_draw;	memcpy(&ctx->model_matrix, &eff->model_matrix, sizeof(GF_Matrix));	ctx->color_mat.identity = eff->color_mat.identity;	if (!eff->color_mat.identity) memcpy(&ctx->color_mat, &eff->color_mat, sizeof(GF_ColorMatrix));	ctx->is_pixel_metrics = eff->is_pixel_metrics;	ctx->split_text_idx = eff->split_text_idx;		i=0;	while ((ol = (DLightContext*)gf_list_enum(eff->local_lights, &i))) {		nl = (DLightContext*)malloc(sizeof(DLightContext));		memcpy(nl, ol, sizeof(DLightContext));		gf_list_add(ctx->directional_lights, nl);	}	ctx->clipper = eff->clipper;	ctx->has_clipper = eff->has_clip;	ctx->cull_flag = eff->cull_flag;	if ((ctx->num_clip_planes = eff->num_clip_planes))		memcpy(ctx->clip_planes, eff->clip_planes, sizeof(GF_Plane)*MAX_USER_CLIP_PLANES);	/*and insert from further to closest*/	b = *bounds;	gf_mx_apply_bbox(&ctx->model_matrix, &b);	gf_mx_apply_bbox(&eff->camera->modelview, &b);	ctx->zmax = b.max_edge.z;	/*we don't need an exact sorting, as long as we keep transparent nodes above  -note that for	speed purposes we store in reverse-z transparent nodes*/	count = gf_list_count(eff->surface->alpha_nodes_to_draw);	for (i=0; i<count; i++) {		Draw3DContext *next = (Draw3DContext *)gf_list_get(eff->surface->alpha_nodes_to_draw, i);		if (next->zmax>ctx->zmax) {			gf_list_insert(eff->surface->alpha_nodes_to_draw, ctx, i);			return;		}	}	gf_list_add(eff->surface->alpha_nodes_to_draw, ctx);}void VS_FlushContexts(VisualSurface *surf, RenderEffect3D *eff){	u32 i, idx, count;	eff->traversing_mode = TRAVERSE_RENDER;	count = gf_list_count(surf->alpha_nodes_to_draw);	for (idx=0; idx<count; idx++) {		DLightContext *dl;		Draw3DContext *ctx = (Draw3DContext *)gf_list_get(surf->alpha_nodes_to_draw, idx);		VS3D_PushMatrix(surf);		/*apply directional lights*/		eff->local_light_on = 1;		i=0;		while ((dl = (DLightContext*)gf_list_enum(ctx->directional_lights, &i))) {			VS3D_PushMatrix(surf);			VS3D_MultMatrix(surf, dl->light_matrix.m);			gf_node_render(dl->dlight, eff);			VS3D_PopMatrix(surf);		}				/*clipper, set it in world coords only*/		if (ctx->has_clipper) {			VS3D_PushMatrix(surf);			VS3D_ResetMatrix(surf);			VS3D_SetClipper2D(surf, ctx->clipper);			VS3D_PopMatrix(surf);		}		/*clip planes, set it in world coords only*/		for (i=0; i<ctx->num_clip_planes; i++)			VS3D_SetClipPlane(surf, ctx->clip_planes[i]);		/*restore effect*/		VS3D_MultMatrix(surf, ctx->model_matrix.m);		memcpy(&eff->model_matrix, &ctx->model_matrix, sizeof(GF_Matrix));		eff->color_mat.identity = ctx->color_mat.identity;		if (!eff->color_mat.identity) memcpy(&eff->color_mat, &ctx->color_mat, sizeof(GF_ColorMatrix));		eff->split_text_idx = ctx->split_text_idx;		eff->is_pixel_metrics = ctx->is_pixel_metrics;		/*restore cull flag in case we're completely inside (avoids final frustum/AABB tree culling)*/		eff->cull_flag = ctx->cull_flag;		gf_node_render(ctx->node_to_draw, eff);				/*reset directional lights*/		eff->local_light_on = 0;		for (i=gf_list_count(ctx->directional_lights); i>0; i--) {			DLightContext *dl = (DLightContext*)gf_list_get(ctx->directional_lights, i-1);			gf_node_render(dl->dlight, eff);			free(dl);		}		if (ctx->has_clipper) VS3D_ResetClipper2D(surf);		for (i=0; i<ctx->num_clip_planes; i++) VS3D_ResetClipPlane(surf);		VS3D_PopMatrix(surf);		/*and destroy*/		gf_list_del(ctx->directional_lights);		free(ctx);	}	gf_list_reset(eff->surface->alpha_nodes_to_draw);}static void reset_collide_cursor(Render3D *sr){	if (sr->last_cursor == GF_CURSOR_COLLIDE) {		GF_Event evt;		sr->last_cursor = evt.cursor.cursor_type = GF_CURSOR_NORMAL;		evt.type = GF_EVENT_SET_CURSOR;		sr->compositor->video_out->ProcessEvent(sr->compositor->video_out, &evt);	}}Bool VS_ExecuteEvent(VisualSurface *surf, RenderEffect3D *eff, GF_Event *ev, GF_ChildNodeItem *node_list){	Fixed x, y;	SFVec3f start, end;	SensorHandler *hs, *hs_grabbed;	SFVec4f res;	Fixed in_x, in_y;	GF_List *tmp;	u32 i, count, stype;	Render3D *sr = surf->render;	count = 0;	if ((ev->type > GF_EVENT_MOUSEMOVE) || sr->nav_is_grabbed) return 0;	eff->camera = &surf->camera;	eff->surface = surf;	eff->backgrounds = surf->back_stack;	eff->viewpoints = surf->view_stack;	eff->fogs = surf->fog_stack;	eff->navigations = surf->navigation_stack;	eff->min_hsize = INT2FIX(MIN(surf->width, surf->height)) / 2;	/*setup projection*/	VS_SetupProjection(eff);	eff->traversing_mode = TRAVERSE_PICK;	eff->collect_layer = NULL;	sr->hit_info.appear = NULL;	x = INT2FIX(ev->mouse.x); y = INT2FIX(ev->mouse.y);	/*main surface with AR*/	if ((sr->surface == surf) && sr->compositor->has_size_info) {		Fixed scale = gf_divfix(INT2FIX(surf->width), INT2FIX(sr->out_width));		x = gf_mulfix(x, scale);		scale = gf_divfix(INT2FIX(surf->height), INT2FIX(sr->out_height));		y = gf_mulfix(y, scale);	}	start.z = surf->camera.z_near;	end.z = surf->camera.z_far;	if (!eff->camera->is_3D && !eff->is_pixel_metrics) {		start.x = end.x = gf_divfix(x, eff->min_hsize); 		start.y = end.y = gf_divfix(y, eff->min_hsize);	} else {		start.x = end.x = x;		start.y = end.y = y;	}	/*unproject to world coords*/	in_x = 2*x/ (s32) surf->width;	in_y = 2*y/ (s32) surf->height;		res.x = in_x; res.y = in_y; res.z = -FIX_ONE; res.q = FIX_ONE;	gf_mx_apply_vec_4x4(&surf->camera.unprojection, &res);	if (!res.q) return 0;	start.x = gf_divfix(res.x, res.q); start.y = gf_divfix(res.y, res.q); start.z = gf_divfix(res.z, res.q);	res.x = in_x; res.y = in_y; res.z = FIX_ONE; res.q = FIX_ONE;	gf_mx_apply_vec_4x4(&surf->camera.unprojection, &res);	if (!res.q) return 0;	end.x = gf_divfix(res.x, res.q); end.y = gf_divfix(res.y, res.q); end.z = gf_divfix(res.z, res.q);	eff->ray = gf_ray(start, end);	/*also update hit info world ray in case we have a grabbed sensor with mouse off*/	sr->hit_info.world_ray = eff->ray;#ifndef GPAC_DISABLE_LOG	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] cast ray\n\tOrigin %.4f %.4f %.4f - End %.4f %.4f %.4f\n\tDir %.4f %.4f %.4f\n", 		FIX2FLT(eff->ray.orig.x), FIX2FLT(eff->ray.orig.y), FIX2FLT(eff->ray.orig.z),		FIX2FLT(end.x), FIX2FLT(end.y), FIX2FLT(end.z),

⌨️ 快捷键说明

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