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

📄 viewport.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"#include <gpac/options.h>/*for default viewport*/#include <gpac/internal/terminal_dev.h>GF_Err R3D_GetViewpoint(GF_VisualRenderer *vr, u32 viewpoint_idx, const char **outName, Bool *is_bound){	u32 count;	GF_Node *n;	Render3D *sr = (Render3D *) vr->user_priv;	if (!sr->surface) return GF_BAD_PARAM;	count = gf_list_count(sr->surface->view_stack);	if (!viewpoint_idx) return GF_BAD_PARAM;	if (viewpoint_idx>count) return GF_EOS;	n = (GF_Node*)gf_list_get(sr->surface->view_stack, viewpoint_idx-1);	switch (gf_node_get_tag(n)) {	case TAG_MPEG4_Viewport: *outName = ((M_Viewport*)n)->description.buffer; *is_bound = ((M_Viewport*)n)->isBound;return GF_OK;	case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: *outName = ((M_Viewpoint*)n)->description.buffer; *is_bound = ((M_Viewpoint*)n)->isBound; return GF_OK;	default: *outName = NULL; return GF_OK;	}}GF_Err R3D_SetViewpoint(GF_VisualRenderer *vr, u32 viewpoint_idx, const char *viewpoint_name){	u32 count, i;	GF_Node *n;	Render3D *sr = (Render3D *) vr->user_priv;	if (!sr->surface) return GF_BAD_PARAM;	count = gf_list_count(sr->surface->view_stack);	if (viewpoint_idx>count) return GF_BAD_PARAM;	if (!viewpoint_idx && !viewpoint_name) return GF_BAD_PARAM;	if (viewpoint_idx) {		Bool bind;		n = (GF_Node*)gf_list_get(sr->surface->view_stack, viewpoint_idx-1);		bind = Bindable_GetIsBound(n);		Bindable_SetSetBind(n, !bind);		return GF_OK;	}	for (i=0; i<count;i++) {		char *name = NULL;		n = (GF_Node*)gf_list_get(sr->surface->view_stack, viewpoint_idx-1);		switch (gf_node_get_tag(n)) {		case TAG_MPEG4_Viewport: name = ((M_Viewport*)n)->description.buffer; break;		case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: name = ((M_Viewpoint*)n)->description.buffer; break;		default: break;		}		if (name && !stricmp(name, viewpoint_name)) {			Bool bind = Bindable_GetIsBound(n);			Bindable_SetSetBind(n, !bind);			return GF_OK;		}	}	return GF_BAD_PARAM;}#define VPCHANGED(__comp) { GF_Event evt; evt.type = GF_EVENT_VIEWPOINTS; GF_USER_SENDEVENT(__comp->user, &evt); }static void DestroyViewStack(GF_Node *node){	ViewStack *st = (ViewStack *) gf_node_get_private(node);	PreDestroyBindable(node, st->reg_stacks);	gf_list_del(st->reg_stacks);	VPCHANGED(st->compositor);	free(st);}static void viewport_set_bind(GF_Node *node){	ViewStack *st = (ViewStack *) gf_node_get_private(node);	Bindable_OnSetBind(node, st->reg_stacks);	gf_sr_invalidate(st->compositor, NULL);	/*notify change of vp stack*/	VPCHANGED(st->compositor);	/*and dirty ourselves to force frustrum update*/	gf_node_dirty_set(node, 0, 0);}static void RenderViewport(GF_Node *node, void *rs, Bool is_destroy){	Fixed ar, sx, sy, w, h, tx, ty;	GF_Matrix2D mat;	GF_Matrix mx;	GF_Rect rc, rc_bckup;	Bool is_layer;	RenderEffect3D *eff = (RenderEffect3D *)rs;	M_Viewport *vp = (M_Viewport*) node;	ViewStack *st = (ViewStack *) gf_node_get_private(node);	if (is_destroy) {		DestroyViewStack(node);		return;	}	assert(eff->viewpoints);	if (eff->camera->is_3D) return;	/*first traverse, bound if needed*/	if (gf_list_find(eff->viewpoints, node) < 0) {		gf_list_add(eff->viewpoints, node);		assert(gf_list_find(st->reg_stacks, eff->viewpoints)==-1);		gf_list_add(st->reg_stacks, eff->viewpoints);		if (gf_list_get(eff->viewpoints, 0) == vp) {			if (!vp->isBound) Bindable_SetIsBound(node, 1);		} else {			if (gf_is_default_scene_viewpoint(node)) Bindable_SetSetBind(node, 1);		}		VPCHANGED(st->compositor);		/*in any case don't draw the first time (since the viewport could have been declared last)*/		gf_sr_invalidate(st->compositor, NULL);		return;	}	/*not bound ignore*/	if (!vp->isBound) return;	if (eff->traversing_mode != TRAVERSE_RENDER_BINDABLE) return;		is_layer = (eff->viewpoints == eff->surface->view_stack) ? 0 : 1;	/*if no parent this is the main viewport, don't update if not changed*/	if (!is_layer && !gf_node_dirty_get(node)) return;	gf_node_dirty_clear(node, 0);	gf_mx2d_init(mat);	gf_mx2d_add_translation(&mat, vp->position.x, vp->position.y);	gf_mx2d_add_rotation(&mat, 0, 0, vp->orientation);	//compute scaling ratio	rc = gf_rect_center(vp->size.x, vp->size.y);	gf_mx2d_apply_rect(&mat, &rc);	w = eff->bbox.max_edge.x - eff->bbox.min_edge.x;	h = eff->bbox.max_edge.y - eff->bbox.min_edge.y;	ar = gf_divfix(h, w);	rc_bckup = rc;	switch (vp->fit) {	/*covers all area and respect aspect ratio*/	case 2:		if (gf_divfix(rc.width, w) > gf_divfix(rc.height, h)) {			rc.width = gf_muldiv(rc.width, h, rc.height);			rc.height = h;		} else {			rc.height = gf_muldiv(rc.height , w, rc.width);			rc.width = w;		}		break;	/*fits inside the area and respect AR*/	case 1:		if (gf_divfix(rc.width, w)> gf_divfix(rc.height, h)) {			rc.height = gf_muldiv(rc.height, w, rc.width);			rc.width = w;		} else {			rc.width = gf_muldiv(rc.width, h, rc.height);			rc.height = h;		}		break;	/*fit entirely: nothing to change*/	case 0:		rc.width = w;		rc.height = h;		break;	default:		return;	}	sx = gf_divfix(rc_bckup.width , rc.width);	sy = gf_divfix(rc_bckup.height , rc.height);	rc.x = - rc.width/2;	rc.y = rc.height/2;	tx = ty = 0;	if (vp->fit) {		/*left alignment*/		if (vp->alignment.vals[0] == -1) tx = rc.width/2 - w/2;		else if (vp->alignment.vals[0] == 1) tx = w/2 - rc.width/2;		/*top-alignment*/		if (vp->alignment.vals[1]==-1) ty = rc.height/2 - h/2;		else if (vp->alignment.vals[1]==1) ty = h/2 - rc.height/2;	}		gf_mx_from_mx2d(&mx, &mat);	gf_mx_add_scale(&mx, sx, sy, FIX_ONE);	gf_mx_add_translation(&mx, -tx, -ty, 0);	gf_mx_inverse(&mx);	/*in layers directly modify the model matrix*/	if (eff->viewpoints != eff->surface->view_stack) {		gf_mx_add_matrix(&eff->model_matrix, &mx);	} else {		gf_mx_copy(eff->camera->viewport, mx);		eff->camera->flags = (CAM_HAS_VIEWPORT | CAM_IS_DIRTY);	}}void R3D_InitViewport(Render3D *sr, GF_Node *node){	ViewStack *st;	GF_SAFEALLOC(st, ViewStack);	st->reg_stacks = gf_list_new();	gf_sr_traversable_setup(st, node, sr->compositor);	gf_node_set_private(node, st);	gf_node_set_callback_function(node, RenderViewport);	((M_Viewport*)node)->on_set_bind = viewport_set_bind;}static void viewpoint_set_bind(GF_Node *node){	ViewStack *st = (ViewStack *) gf_node_get_private(node);	if (!((M_Viewpoint*)node)->isBound ) 		st->prev_was_bound = 0;	Bindable_OnSetBind(node, st->reg_stacks);	gf_sr_invalidate(st->compositor, NULL);	/*notify change of vp stack*/	VPCHANGED(st->compositor);	/*and dirty ourselves to force frustrum update*/	gf_node_dirty_set(node, 0, 0);}static void RenderViewpoint(GF_Node *node, void *rs, Bool is_destroy){	SFVec3f pos, v1, v2;	SFRotation ori;	GF_Matrix mx;

⌨️ 快捷键说明

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