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

📄 visual_surface.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (asp.filled) VS3D_SetMaterial2D(eff->surface, asp.fill_color, asp.alpha);		VS3D_DrawMesh(eff, st->mesh);		/*reset texturing in case of line texture*/		if (eff->mesh_has_texture) {			tx_disable(fill_txh);			eff->mesh_has_texture = 0;		}	}	/*strike path*/	if (!asp.line_alpha) return;	si = VS_GetStrikeInfo(st, &asp, eff);	if (si) {		VS_Set2DStrikeAspect(eff, &asp);//		if (asp.txh) eff->mesh_has_texture = 1;		if (!si->is_vectorial) {			VS3D_StrikeMesh(eff, si->outline, Aspect_GetLineWidth(&asp), asp.pen_props.dash);		} else {			VS3D_DrawMesh(eff, si->outline);		}		if (asp.txh) {			tx_disable(asp.txh);			eff->mesh_has_texture = 0;		}			}}static GFINLINE Bool VS_setup_material(RenderEffect3D *eff, u32 mesh_type){	SFColor def;	GF_Node *__mat;	def.red = def.green = def.blue = FIX_ONE;	/*temp storage of diffuse alpha*/	eff->ray.orig.x = FIX_ONE;	if (!eff->appear) {		/*use material2D to disable lighting*/		VS3D_SetMaterial2D(eff->surface, def, FIX_ONE);		return 1;	}	if (gf_node_get_tag(eff->appear)==TAG_X3D_Appearance) {		X_FillProperties *fp = (X_FillProperties *) ((X_Appearance*)eff->appear)->fillProperties;		if (fp && !fp->filled) return 0;	}	__mat = ((M_Appearance *)eff->appear)->material;	if (!__mat) {		/*use material2D to disable lighting (cf VRML specs)*/		VS3D_SetMaterial2D(eff->surface, def, FIX_ONE);		return 1;	} 		switch (gf_node_get_tag((GF_Node *)__mat)) {	case TAG_MPEG4_Material:	case TAG_X3D_Material:	{		SFColor diff, spec, emi;		Fixed diff_a, spec_a, emi_a;		Fixed vec[4];		Bool has_alpha;		u32 flag = F3D_LIGHT /*| F3D_COLOR*/;		M_Material *mat = (M_Material *)__mat;		diff = mat->diffuseColor;		diff_a = FIX_ONE - mat->transparency;		/*if drawing in 2D context or special meshes (lines, points) disable lighting*/		if (mesh_type || !eff->camera->is_3D) {			if (eff->camera->is_3D) diff = mat->emissiveColor;			if (!eff->color_mat.identity) gf_cmx_apply_fixed(&eff->color_mat, &diff_a, &diff.red, &diff.green, &diff.blue);			VS3D_SetMaterial2D(eff->surface, diff, diff_a);			return 1;		}		spec = mat->specularColor;		emi = mat->emissiveColor;		spec_a = emi_a = FIX_ONE - mat->transparency;		if (!eff->color_mat.identity) {			gf_cmx_apply_fixed(&eff->color_mat, &diff_a, &diff.red, &diff.green, &diff.blue);			gf_cmx_apply_fixed(&eff->color_mat, &spec_a, &spec.red, &spec.green, &spec.blue);			gf_cmx_apply_fixed(&eff->color_mat, &emi_a, &emi.red, &emi.green, &emi.blue);			if ((diff_a+FIX_EPSILON<FIX_ONE) || (spec_a+FIX_EPSILON<FIX_ONE) || (emi_a+FIX_EPSILON<FIX_ONE )) {				has_alpha = 1;			} else {				has_alpha = 0;			}		} else {			has_alpha = (mat->transparency>FIX_EPSILON) ? 1 : 0;			/*100% transparent DON'T DRAW*/			if (mat->transparency+FIX_EPSILON>=FIX_ONE) return 0;		}		/*using antialiasing with alpha usually gives bad results (non-edge face segments are visible)*/		VS3D_SetAntiAlias(eff->surface, !has_alpha);		if (has_alpha) {			flag |= F3D_BLEND;			eff->mesh_is_transparent = 1;		}		VS3D_SetState(eff->surface, flag, 1);		vec[0] = gf_mulfix(diff.red, mat->ambientIntensity);		vec[1] = gf_mulfix(diff.green, mat->ambientIntensity);		vec[2] = gf_mulfix(diff.blue, mat->ambientIntensity);		vec[3] = diff_a;		VS3D_SetMaterial(eff->surface, MATERIAL_AMBIENT, vec);		vec[0] = diff.red;		vec[1] = diff.green;		vec[2] = diff.blue;		vec[3] = diff_a;		VS3D_SetMaterial(eff->surface, MATERIAL_DIFFUSE, vec);		vec[0] = spec.red;		vec[1] = spec.green;		vec[2] = spec.blue;		vec[3] = spec_a;		VS3D_SetMaterial(eff->surface, MATERIAL_SPECULAR, vec);				vec[0] = emi.red;		vec[1] = emi.green;		vec[2] = emi.blue;		vec[3] = emi_a;		VS3D_SetMaterial(eff->surface, MATERIAL_EMISSIVE, vec);		VS3D_SetShininess(eff->surface, mat->shininess);		eff->ray.orig.x = diff_a;	}		break;	case TAG_MPEG4_Material2D:	{		SFColor emi;		Fixed emi_a;		M_Material2D *mat = (M_Material2D *)__mat;		emi = mat->emissiveColor;		emi_a = FIX_ONE - mat->transparency;		if (!eff->color_mat.identity) gf_cmx_apply_fixed(&eff->color_mat, &emi_a, &emi.red, &emi.green, &emi.blue);		/*100% transparent DON'T DRAW*/		if (emi_a<FIX_EPSILON) return 0;		else if (emi_a+FIX_EPSILON<FIX_ONE) VS3D_SetState(eff->surface, F3D_BLEND, 1);		/*this is an extra feature: if material2D.filled is FALSE on 3D objects, switch to TX_REPLACE mode		and enable lighting*/		if (!mat->filled) {			GF_TextureHandler *txh = R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture);			if (txh) {				tx_set_blend_mode(txh, TX_REPLACE);				VS3D_SetState(eff->surface, F3D_COLOR, 0);				VS3D_SetState(eff->surface, F3D_LIGHT, 1);				return 1;			}		}		/*regular mat 2D*/		VS3D_SetState(eff->surface, F3D_LIGHT | F3D_COLOR, 0);		VS3D_SetMaterial2D(eff->surface, emi, emi_a);	}			break;	default:		break;	}	return 1;}Bool VS_setup_texture(RenderEffect3D *eff){	GF_TextureHandler *txh;	eff->mesh_has_texture = 0;	if (!eff->appear) return 0;	txh = R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture);	if (txh) {		tx_set_blend_mode(txh, tx_is_transparent(txh) ? TX_MODULATE : TX_REPLACE);		eff->mesh_has_texture = tx_enable(txh, ((M_Appearance *)eff->appear)->textureTransform);		if (eff->mesh_has_texture) {			Fixed v[4];			switch (txh->pixelformat) {			/*override diffuse color with full intensity, but keep material alpha (cf VRML lighting)*/			case GF_PIXEL_RGB_24:				v[0] = v[1] = v[2] = 1; v[3] = eff->ray.orig.x;				VS3D_SetMaterial(eff->surface, MATERIAL_DIFFUSE, v);				break;			/*override diffuse color AND material alpha (cf VRML lighting)*/			case GF_PIXEL_RGBA:				v[0] = v[1] = v[2] = v[3] = 1;				VS3D_SetMaterial(eff->surface, MATERIAL_DIFFUSE, v);				break;			case GF_PIXEL_GREYSCALE:				eff->mesh_has_texture = 2;				break;			}		}		return eff->mesh_has_texture;	}	return 0;}void VS_disable_texture(RenderEffect3D *eff){	if (eff->mesh_has_texture) {		tx_disable(R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture) );		eff->mesh_has_texture = 0;	}}Bool VS_SetupAppearance(RenderEffect3D *eff){	/*setup material and check if 100% transparent - in which case don't draw*/	if (!VS_setup_material(eff, 0)) return 0;	/*setup texture*/	VS_setup_texture(eff);	return 1;}void VS_DrawMesh(RenderEffect3D *eff, GF_Mesh *mesh){	if (mesh->mesh_type) {		if (VS_setup_material(eff, mesh->mesh_type)) {			VS3D_DrawMesh(eff, mesh);		}	} else if (VS_SetupAppearance(eff)) {		VS3D_DrawMesh(eff, mesh);		VS_disable_texture(eff);	#ifndef GPAC_USE_OGL_ES		if (eff->appear && gf_node_get_tag(eff->appear)==TAG_X3D_Appearance) {			X_Appearance *ap = (X_Appearance *)eff->appear;			X_FillProperties *fp = ap->fillProperties ? (X_FillProperties *) ap->fillProperties : NULL;			if (fp && fp->hatched) VS3D_HatchMesh(eff, mesh, fp->hatchStyle, fp->hatchColor);		}#endif	}}/*uncomment to disable frustum cull*///#define DISABLE_VIEW_CULL#ifndef GPAC_DISABLE_LOGstatic const char *szPlaneNames [] = {	"Near", "Far", "Left", "Right", "Bottom", "Top"};#endifBool node_cull(RenderEffect3D *eff, GF_BBox *bbox, Bool skip_near) {	GF_BBox b;	Fixed irad, rad;	GF_Camera *cam;	Bool do_sphere;	u32 i, p_idx;	SFVec3f cdiff, vertices[8];	if (eff->cull_flag == CULL_INSIDE) return 1;	assert(eff->cull_flag != CULL_OUTSIDE);#ifdef DISABLE_VIEW_CULL	eff->cull_flag = CULL_INSIDE;	return 1;#endif	/*empty bounds*/	if (!bbox->is_set) {		eff->cull_flag = CULL_OUTSIDE;		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node out (bbox not set)\n"));		return 0;	}	/*get bbox in world space*/	b = *bbox;	gf_mx_apply_bbox(&eff->model_matrix, &b);	cam = eff->camera;	/*if camera is inside bbox consider we intersect*/	if (gf_bbox_point_inside(&b, &cam->position)) {		eff->cull_flag = CULL_INTERSECTS;		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node intersect (camera in box test)\n"));		return 1;	}	/*first check: sphere vs frustum sphere intersection, this will discard far objects quite fast*/	gf_vec_diff(cdiff, cam->center, b.center);	rad = b.radius + cam->radius;	if (gf_vec_len(cdiff) > rad) {		eff->cull_flag = CULL_OUTSIDE;		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node out (sphere-sphere test)\n"));		return 0;	}	/*second check: sphere vs frustum planes intersection, if any intersection is detected switch 	to n/p vertex check.*/	rad = b.radius;	irad = -b.radius;	do_sphere = 1;	/*skip near/far tests in ortho mode, and near in 3D*/	i = (eff->camera->is_3D) ? (skip_near ? 1 : 0) : 2;	for (; i<6; i++) {		if (do_sphere) {			Fixed d = gf_plane_get_distance(&cam->planes[i], &b.center);			if (d<irad) {				eff->cull_flag = CULL_OUTSIDE;				GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node out (sphere-planes test) plane %s\n", szPlaneNames[i]));				return 0;			}			/*intersect, move to n-p vertex test*/			if (d<rad) {				/*get box vertices*/				gf_bbox_get_vertices(b.min_edge, b.max_edge, vertices);				do_sphere = 0;			} else {				continue;			}		}		p_idx = cam->p_idx[i];		/*check p-vertex: if not in plane, we're out (since p-vertex is the closest point to the plane)*/		if (gf_plane_get_distance(&cam->planes[i], &vertices[p_idx])<0) {			eff->cull_flag = CULL_OUTSIDE;			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node out (p-vertex test) plane %s\n", szPlaneNames[i]));			return 0;		}		/*check n-vertex: if not in plane, we're intersecting*/		if (gf_plane_get_distance(&cam->planes[i], &vertices[7-p_idx])<0) {			eff->cull_flag = CULL_INTERSECTS;			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node intersect (n-vertex test) plane %s\n", szPlaneNames[i]));			return 1;		}	}	eff->cull_flag = CULL_INSIDE;	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 3D] Culling: Node inside (%s test)\n", do_sphere ? "sphere-planes" : "n-p vertex"));	return 1;}void VS_SetupProjection(RenderEffect3D *eff){	GF_Node *bindable;	u32 mode = eff->traversing_mode;	eff->traversing_mode = TRAVERSE_RENDER_BINDABLE;	/*setup viewpoint (this directly modifies the frustum)*/	bindable = (GF_Node*)gf_list_get(eff->viewpoints, 0);	if (Bindable_GetIsBound(bindable)) {		gf_node_render(bindable, eff);		eff->camera->had_viewpoint = 1;	} else if (eff->camera->had_viewpoint) {		if (eff->camera->is_3D) {			SFVec3f pos, center;			SFRotation r;			Fixed fov = GF_PI/4;			/*default viewpoint*/			pos.x = pos.y = 0; pos.z = 10 * FIX_ONE;			center.x = center.y = center.z = 0;			r.q = r.x = r.z = 0; r.y = FIX_ONE;			/*this takes care of pixelMetrics*/			VS_ViewpointChange(eff, NULL, 0, fov, pos, r, center);			/*initial vp compute, don't animate*/			if (eff->camera->had_viewpoint == 2) {				camera_stop_anim(eff->camera);				camera_reset_viewpoint(eff->camera, 0);			}		} else {			eff->camera->zoom = FIX_ONE;			eff->camera->trans.x = eff->camera->trans.y = eff->camera->rot.x = eff->camera->rot.y = 0;			eff->camera->flags &= ~CAM_HAS_VIEWPORT;			eff->camera->flags |= CAM_IS_DIRTY;		}		eff->camera->had_viewpoint = 0;	}	camera_update(eff->camera);	/*setup projection/modelview*/	VS3D_SetMatrixMode(eff->surface, MAT_PROJECTION);	VS3D_LoadMatrix(eff->surface, eff->camera->projection.m);	VS3D_SetMatrixMode(eff->surface, MAT_MODELVIEW);	VS3D_LoadMatrix(eff->surface, eff->camera->modelview.m);	gf_mx_init(eff->model_matrix);	eff->traversing_mode = mode;}void VS_InitRender(RenderEffect3D *eff){	Bool in_layer;	u32 mode;	GF_Node *bindable;	in_layer = (eff->backgrounds != eff->surface->back_stack) ? 1 : 0;	/*if not in layer, render navigation	FIXME: we should update the nav info according to the world transform at the current viewpoint (vrml)*/	eff->traversing_mode = TRAVERSE_RENDER_BINDABLE;	bindable = eff->navigations ? (GF_Node*) gf_list_get(eff->navigations, 0) : NULL;	if (Bindable_GetIsBound(bindable)) {		gf_node_render(bindable, eff);		eff->camera->had_nav_info = 1;	} else if (eff->camera->had_nav_info) {		/*if no navigation specified, use default VRML one*/		eff->camera->avatar_size.x = FLT2FIX(0.25f); eff->camera->avatar_size.y = FLT2FIX(1.6f); eff->camera->avatar_size.z = FLT2FIX(0.75f);		eff->camera->visibility = 0;		eff->camera->speed = FIX_ONE;		/*not specified in the spec, but by default we forbid navigation in layer*/		if (in_layer) {			eff->camera->navigation_flags = NAV_HEADLIGHT;			eff->camera->navigate_mode = GF_NAVIGATE_NONE;		} else {			eff->camera->navigation_flags = NAV_ANY | NAV_HEADLIGHT;			if (eff->camera->is_3D) {				/*X3D is by default examine, VRML/MPEG4 is WALK*/				eff->camera->navigate_mode = (eff->surface->render->root_is_3D==2) ? GF_NAVIGATE_EXAMINE : GF_NAVIGATE_WALK;			} else {				eff->camera->navigate_mode = GF_NAVIGATE_NONE;			}		}		eff->camera->had_nav_info = 0;		if (eff->is_pixel_metrics) {			eff->camera->visibility = gf_mulfix(eff->camera->visibility, eff->min_hsize);			eff->camera->avatar_size.x = gf_mulfix(eff->camera->avatar_size.x, eff->min_hsize);			eff->camera->avatar_size.y = gf_mulfix(eff->camera->avatar_size.y, eff->min_hsize);			eff->camera->avatar_size.z = gf_mulfix(eff->camera->avatar_size.z, eff->min_hsize);		}	}	/*animate current camera - if returns TRUE draw next frame*/	if (camera_animate(eff->camera)) 		gf_sr_invalidate(eff->surface->render->compositor, NULL);

⌨️ 快捷键说明

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