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

📄 render3d.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.h"#include "visual_surface.h"#include "render3d_nodes.h"#include <gpac/options.h>void effect3d_reset(RenderEffect3D *eff){	GF_List *sbck = eff->sensors;	GF_List *dbck = eff->local_lights;	memset(eff, 0, sizeof(RenderEffect3D));	gf_mx_init(eff->model_matrix);	gf_cmx_init(&eff->color_mat);	eff->sensors = sbck;	eff->local_lights = dbck;	gf_list_reset(eff->sensors);	while (gf_list_count(eff->local_lights)) {		DLightContext *dl = (DLightContext *)gf_list_get(eff->local_lights, 0);		gf_list_rem(eff->local_lights, 0);		free(dl);	}}RenderEffect3D *effect3d_new(){	RenderEffect3D *eff;	GF_SAFEALLOC(eff, RenderEffect3D);	eff->sensors = gf_list_new();	eff->local_lights = gf_list_new();	return eff;}void effect3d_delete(RenderEffect3D *eff){	effect3d_reset(eff);	gf_list_del(eff->sensors);	gf_list_del(eff->local_lights);	free(eff);}GF_Rect R3D_UpdateClipper(RenderEffect3D *eff, GF_Rect this_clip, Bool *need_restore, GF_Rect *original, Bool for_layer){	GF_Rect clip, orig;	if (for_layer) {		orig = eff->layer_clipper;		*need_restore = eff->has_layer_clip;	} else {		orig = eff->clipper;		*need_restore = eff->has_clip;	}	*original = orig;	clip = this_clip;	if (*need_restore) {		GF_Matrix mx;		gf_mx_copy(mx, eff->model_matrix);		gf_mx_inverse(&mx);		gf_mx_apply_rect(&mx, &orig);		if (clip.x < orig.x) {			clip.width -= (orig.x - clip.x);			clip.x = orig.x;		}		if (clip.x + clip.width > orig.x + orig.width) {			clip.width = orig.x + orig.width - clip.x;		}		if (clip.y > orig.y) {			clip.height -= (clip.y - orig.y);			clip.y = orig.y;		}		if (clip.y - clip.height < orig.y - orig.height) {			clip.height = clip.y - orig.y + orig.height;		}	}	if (for_layer) {		eff->layer_clipper = clip;		eff->has_layer_clip = 1;	} else {		eff->clipper = clip;		/*retranslate to world coords*/		gf_mx_apply_rect(&eff->model_matrix, &eff->clipper);		/*if 2D, also update with user zoom and translation*/		if (!eff->camera->is_3D) gf_mx_apply_rect(&eff->camera->modelview, &eff->clipper);		eff->has_clip = 1;	}	return clip;}Bool R3D_GetSurfaceSizeInfo(RenderEffect3D *eff, Fixed *surf_width, Fixed *surf_height){	u32 w, h;	w = eff->surface->width;	h = eff->surface->height;	/*no size info, use main render output size*/	if (!w || !h) {		w = eff->surface->render->out_width;		h = eff->surface->render->out_height;	}	if (eff->is_pixel_metrics) {		*surf_width = INT2FIX(w);		*surf_height = INT2FIX(h);		return 1;	}	if (h > w) {		*surf_width = 2*FIX_ONE;		*surf_height = gf_divfix(2*INT2FIX(h), INT2FIX(w));	} else {		*surf_width = gf_divfix(2*INT2FIX(w), INT2FIX(h));		*surf_height = 2*FIX_ONE;	}	return 0;}SensorHandler *r3d_get_sensor_handler(GF_Node *n){	SensorHandler *hs;	if (!n) return NULL;	switch (gf_node_get_tag(n)) {	case TAG_MPEG4_DiscSensor: hs = r3d_ds_get_handler(n); break;	case TAG_MPEG4_PlaneSensor2D: hs = r3d_ps2D_get_handler(n); break;	case TAG_MPEG4_ProximitySensor2D: hs = r3d_prox2D_get_handler(n); break;	case TAG_MPEG4_Anchor: case TAG_X3D_Anchor: hs = r3d_anchor_get_handler(n); break;	case TAG_MPEG4_TouchSensor: case TAG_X3D_TouchSensor: hs = r3d_touch_sensor_get_handler(n); break;	case TAG_MPEG4_PlaneSensor: case TAG_X3D_PlaneSensor: hs = r3d_ps_get_handler(n); break;	case TAG_MPEG4_CylinderSensor: case TAG_X3D_CylinderSensor: hs = r3d_cs_get_handler(n); break;	case TAG_MPEG4_SphereSensor: case TAG_X3D_SphereSensor: hs = r3d_sphere_get_handler(n); break;	default: return NULL;	}	if (hs && hs->IsEnabled(n)) return hs;	return NULL;}void R3D_SensorDeleted(GF_Renderer *rend, SensorHandler *hdl){	Render3D *sr = (Render3D *)rend->visual_renderer->user_priv;	gf_list_del_item(sr->prev_sensors, hdl);	if (rend->interaction_sensors) rend->interaction_sensors--;}void R3D_SetGrabbed(GF_Renderer *rend, Bool bOn) {	((Render3D *)rend->visual_renderer->user_priv)->is_grabbed = bOn; }GF_Node *R3D_PickNode(GF_VisualRenderer *vr, s32 X, s32 Y){	return NULL;}static void DestroyLineProps(GF_Node *n, void *rs, Bool is_destroy){	StrikeInfo *si;	u32 i;	LinePropStack *st = (LinePropStack *)gf_node_get_private(n);	Render3D *sr = (Render3D *)st->sr;		if (!is_destroy) return;	i=0;	while ((si = (StrikeInfo*)gf_list_enum(sr->strike_bank, &i))) {		if (si->lineProps == n) {			/*remove from node*/			if (si->node2D) {				stack2D *st = (stack2D *) gf_node_get_private(si->node2D);				gf_list_del_item(st->strike_list, si);			}			i--;			gf_list_rem(sr->strike_bank, i);			delete_strikeinfo(si);		}	}	free(st);}void R3D_InitLineProps(Render3D *sr, GF_Node *node){	LinePropStack *st = (LinePropStack *)malloc(sizeof(LinePropStack));	st->sr = sr;	st->last_mod_time = 1;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyLineProps);}u32 R3D_LP_GetLastUpdateTime(GF_Node *node){	LinePropStack *st = (LinePropStack *)gf_node_get_private(node);	if (!st) return 0;	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		st->last_mod_time ++;		gf_node_dirty_clear(node, 0);	}	return st->last_mod_time;}void R3D_DrawScene(GF_VisualRenderer *vr){	u32 i, tag;	GF_SceneGraph *sg;	RenderEffect3D static_eff;	Render3D *sr = (Render3D *)vr->user_priv;	GF_Node *top_node = NULL;		if (sr->compositor->scene) top_node = gf_sg_get_root_node(sr->compositor->scene);	/*setup GL*/	VS3D_Setup(sr->surface);	memcpy(&static_eff, sr->top_effect, sizeof(RenderEffect3D));	if (top_node) {		if (!sr->main_surface_setup) {			tag = gf_node_get_tag(top_node);			if (!sr->compositor->has_size_info) {				sr->surface->width = sr->out_width;				sr->surface->height = sr->out_height;			} else {				sr->surface->width = sr->compositor->scene_width;				sr->surface->height = sr->compositor->scene_height;			}			if ((tag>=GF_NODE_RANGE_FIRST_X3D) && (tag<=GF_NODE_RANGE_LAST_X3D)) {				sr->surface->camera.is_3D = 1;				sr->root_is_3D = 2;			} else {				sr->surface->camera.is_3D = sr->root_is_3D = ((tag==TAG_MPEG4_Group) || (tag==TAG_MPEG4_Layer3D) ) ? 1 : 0;			}			camera_invalidate(&sr->surface->camera);			sr->main_surface_setup = 1;		}		sr->top_effect->is_pixel_metrics = gf_sg_use_pixel_metrics(sr->compositor->scene);		/*setup our effects*/		VS_SetupEffects(sr->surface, sr->top_effect);		VS_NodeRender(sr->top_effect, top_node);		sr->top_effect->surface = NULL;	}	i=0; 	while ((sg = (GF_SceneGraph*)gf_list_enum(sr->compositor->extra_scenes, &i))) {		GF_Node *n = gf_sg_get_root_node(sg);		if (!n) continue;				tag = gf_node_get_tag(n);		if (!sr->main_surface_setup) {			sr->surface->width = sr->compositor->scene_width;			sr->surface->height = sr->compositor->scene_height;		}/*		if ((tag>=GF_NODE_RANGE_FIRST_X3D) && (tag<=GF_NODE_RANGE_LAST_X3D)) {			sr->surface->camera.is_3D = 1;		} else {			sr->surface->camera.is_3D = ((tag==TAG_MPEG4_Group) || (tag==TAG_MPEG4_Layer3D) ) ? 1 : 0;		}		sr->surface->camera.flags |= CAM_IS_DIRTY;*/		sr->top_effect->is_pixel_metrics = gf_sg_use_pixel_metrics(sg);		VS_SetupEffects(sr->surface, sr->top_effect);		//VS_NodeRender(sr->top_effect, n);		sr->top_effect->traversing_mode = TRAVERSE_SORT;		gf_node_render(n, sr->top_effect);	}	//if (i) sr->main_surface_setup = 0;	memcpy(sr->top_effect, &static_eff, sizeof(RenderEffect3D));		if (!i && !top_node) {		/*default color is VRML default background color*/		SFColor c;		c.red = c.green = c.blue = 0;		VS3D_ClearSurface(sr->surface, c, FIX_ONE);	}	sr->compositor->video_out->Flush(sr->compositor->video_out, NULL);}static Bool R3D_ExecuteEvent(GF_VisualRenderer *vr, GF_Event *event){	GF_Event evt;	Render3D *sr = (Render3D *)vr->user_priv;	/*revert to BIFS like*/	evt = *event;	if (evt.type<=GF_EVENT_MOUSEMOVE) {		evt.mouse.x = event->mouse.x - sr->compositor->width/2;		evt.mouse.y = sr->compositor->height/2 - event->mouse.y;	}	sr->top_effect->is_pixel_metrics = gf_sg_use_pixel_metrics(sr->compositor->scene);	/*process regular events*/	if ((sr->compositor->interaction_level & GF_INTERACT_NORMAL) && VS_ExecuteEvent(sr->surface, sr->top_effect, &evt, NULL)) 		return 1;	/*remember active layer on mouse click - may be NULL*/	if ((event->type==GF_EVENT_MOUSEDOWN) && (event->mouse.button==GF_MOUSE_LEFT)) sr->active_layer = sr->top_effect->collect_layer;	/*process navigation events*/	if (sr->compositor->interaction_level & GF_INTERACT_NAVIGATION) return R3D_HandleUserEvent(sr, &evt);	return 0;}static void R3D_SetScaling(Render3D *sr, Fixed sx, Fixed sy){	sr->scale_x = sx;	sr->scale_y = sy;}GF_Err R3D_RecomputeAR(GF_VisualRenderer *vr){	Double ratio;	Fixed scaleX, scaleY;	Render3D *sr = (Render3D *)vr->user_priv;	sr->surface->camera.flags |= CAM_IS_DIRTY;	if (!sr->compositor->height || !sr->compositor->width) return GF_OK;	/*we're inside a resetup of the window, indocate HW reset */	if (sr->compositor->new_width || sr->compositor->new_height) {		GF_Event evt;		evt.type = GF_EVENT_VIDEO_SETUP;		evt.size.width = sr->compositor->width;		evt.size.height = sr->compositor->height;		sr->compositor->video_out->ProcessEvent(sr->compositor->video_out, &evt);	}	sr->out_width = sr->compositor->width;	sr->out_height = sr->compositor->height;	sr->out_x = 0;	sr->out_y = 0;	if (!sr->compositor->has_size_info) {		R3D_SetScaling(sr, FIX_ONE, FIX_ONE);		sr->surface->width = sr->out_width;		sr->surface->height = sr->out_height;		return GF_OK;	}	switch (sr->compositor->aspect_ratio) {	case GF_ASPECT_RATIO_FILL_SCREEN:		break;	case GF_ASPECT_RATIO_16_9:		sr->out_height = 9 * sr->out_width  / 16;		break;	case GF_ASPECT_RATIO_4_3:		sr->out_height = 3 * sr->out_width / 4;		break;	default:		ratio = sr->compositor->scene_height;		ratio /= sr->compositor->scene_width;		if (sr->out_width * ratio > sr->out_height) {			sr->out_width = sr->out_height * sr->compositor->scene_width;			sr->out_width /= sr->compositor->scene_height;		}		else {			sr->out_height = sr->out_width * sr->compositor->scene_height;			sr->out_height /= sr->compositor->scene_width;		}		break;	}	sr->out_x = (sr->compositor->width - sr->out_width) / 2;	sr->out_y = (sr->compositor->height - sr->out_height) / 2;	/*update size info for main surface*/	if (sr->surface) {		sr->surface->width = sr->compositor->scene_width;		sr->surface->height = sr->compositor->scene_height;	}

⌨️ 快捷键说明

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