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

📄 grouping_stacks.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 "grouping.h"struct og_pos{	Fixed priority;	u32 position;};typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK	u32 *positions;} OrderedGroupStack;static s32 compare_priority(const void* elem1, const void* elem2){	struct og_pos *p1, *p2;	p1 = (struct og_pos *)elem1;	p2 = (struct og_pos *)elem2;	if (p1->priority < p2->priority) return -1;	if (p1->priority > p2->priority) return 1;	return 0;}static void RenderOrderedGroup(GF_Node *node, void *rs, Bool is_destroy){	u32 i, count;	struct og_pos *priorities;	OrderedGroupStack *ogs = (OrderedGroupStack *) gf_node_get_private(node);	M_OrderedGroup *og = (M_OrderedGroup *)node;	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		DeleteGroupingNode((GroupingNode *)ogs);		if (ogs->positions) free(ogs->positions);		free(ogs);		return;	}	if (!og->order.count) {		grouping_traverse((GroupingNode*)ogs, eff, NULL);		return;	}	/*check whether the OrderedGroup node has changed*/	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		if (ogs->positions) free(ogs->positions);		count = gf_node_list_get_count(og->children);		priorities = (struct og_pos*)malloc(sizeof(struct og_pos)*count);		for (i=0; i<count; i++) {			priorities[i].position = i;			priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0;		}		qsort(priorities, count, sizeof(struct og_pos), compare_priority);		ogs->positions = (u32*)malloc(sizeof(u32) * count);		for (i=0; i<count; i++) ogs->positions[i] = priorities[i].position;		free(priorities);	}	grouping_traverse((GroupingNode*)ogs, eff, ogs->positions);}void R3D_InitOrderedGroup(Render3D *sr, GF_Node *node){	OrderedGroupStack *ptr;	GF_SAFEALLOC(ptr, OrderedGroupStack);	SetupGroupingNode((GroupingNode*)ptr, sr->compositor, node, & ((M_OrderedGroup *)node)->children);	gf_node_set_private(node, ptr);	gf_node_set_callback_function(node, RenderOrderedGroup);}static void RenderSwitch(GF_Node *node, void *rs, Bool is_destroy){	u32 i;	GF_ChildNodeItem *children;	s32 whichChoice;	Bool prev_switch;	s32 *last_switch = (s32 *)gf_node_get_private(node);	RenderEffect3D *eff; 		if (is_destroy) {		free(last_switch);		return;	}	eff = (RenderEffect3D *)rs;	gf_node_dirty_clear(node, 0);	prev_switch = eff->trav_flags;	/*WARNING: X3D/MPEG4 NOT COMPATIBLE*/	if (gf_node_get_tag(node)==TAG_MPEG4_Switch) {		children = ((M_Switch *)node)->choice;		whichChoice = ((M_Switch *)node)->whichChoice;	} else {		children = ((X_Switch *)node)->children;		whichChoice = ((X_Switch *)node)->whichChoice;	}	/*check changes in choice field*/	if (*last_switch != whichChoice) {		GF_ChildNodeItem *l = children;		eff->trav_flags |= GF_SR_TRAV_SWITCHED_OFF;		/*deactivation must be signaled because switch may contain audio nodes (I hate this spec!!!)*/		i = 0;		while (l) {			if ((s32) i!=whichChoice) gf_node_render(l->node, eff);			i++;			l = l->next;		}		eff->trav_flags &= ~GF_SR_TRAV_SWITCHED_OFF;		*last_switch = whichChoice;	}	eff->trav_flags = prev_switch;	if (whichChoice>=0) {		gf_node_render( gf_node_list_get_child(children, whichChoice), eff);	}}void R3D_InitSwitch(Render3D *sr, GF_Node *node){	s32 *last_switch = (s32*)malloc(sizeof(s32));	*last_switch = -1;	gf_node_set_private(node, last_switch);	gf_node_set_callback_function(node, RenderSwitch);}typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK	GF_ColorMatrix cmat;} ColorTransformStack;/*ColorTransform*/static void RenderColorTransform(GF_Node *node, void *rs, Bool is_destroy){	M_ColorTransform *tr = (M_ColorTransform *)node;	ColorTransformStack *ptr = (ColorTransformStack  *)gf_node_get_private(node);	RenderEffect3D *eff;	if (is_destroy) {		DeleteGroupingNode((GroupingNode *)ptr);		free(ptr);		return;	}	eff = (RenderEffect3D *) rs;	if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) {		gf_cmx_set(&ptr->cmat, 			tr->mrr , tr->mrg, tr->mrb, tr->mra, tr->tr, 			tr->mgr , tr->mgg, tr->mgb, tr->mga, tr->tg, 			tr->mbr, tr->mbg, tr->mbb, tr->mba, tr->tb, 			tr->mar, tr->mag, tr->mab, tr->maa, tr->ta); 	}	/*note we don't clear dirty flag, this is done in traversing*/	if (ptr->cmat.identity) {		grouping_traverse((GroupingNode *) ptr, eff, NULL);	} else {		GF_ColorMatrix gf_cmx_bck;		Bool prev_cmat = !eff->color_mat.identity;		if (prev_cmat) {			gf_cmx_copy(&gf_cmx_bck, &eff->color_mat);			gf_cmx_multiply(&eff->color_mat, &ptr->cmat);		} else {			gf_cmx_copy(&eff->color_mat, &ptr->cmat);		}		grouping_traverse((GroupingNode *) ptr, eff, NULL);		/*restore effects*/		if (prev_cmat) gf_cmx_copy(&eff->color_mat, &gf_cmx_bck);		else eff->color_mat.identity = 1;	}}void R3D_InitColorTransform(Render3D *sr, GF_Node *node){	ColorTransformStack *stack = (ColorTransformStack *)malloc(sizeof(ColorTransformStack));	SetupGroupingNode((GroupingNode *)stack, sr->compositor, node, & ((M_ColorTransform *)node)->children);	gf_cmx_init(&stack->cmat);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderColorTransform);}static void RenderGroup(GF_Node *node, void *rs, Bool is_destroy){	GroupingNode *group = (GroupingNode *) gf_node_get_private(node);	if (is_destroy) {		DestroyBaseGrouping(node);	} else {		grouping_traverse(group, (RenderEffect3D*)rs, NULL);	}}void R3D_InitGroup(Render3D *sr, GF_Node *node){	GroupingNode *stack = (GroupingNode *)malloc(sizeof(GroupingNode));	SetupGroupingNode(stack, sr->compositor, node, & ((M_Group *)node)->children);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderGroup);}void RenderCollision(GF_Node *node, void *rs, Bool is_destroy){	u32 collide_flags;	SFVec3f last_point;	Fixed last_dist;	M_Collision *col = (M_Collision *)node;	RenderEffect3D *eff = (RenderEffect3D *)rs;	GroupingNode *group = (GroupingNode *) gf_node_get_private(node);	if (is_destroy) {		DestroyBaseGrouping(node);		return;	}	if (eff->traversing_mode != TRAVERSE_COLLIDE) {		grouping_traverse(group, eff, NULL);	} else if (col->collide) {		collide_flags = eff->camera->collide_flags;		last_dist = eff->camera->collide_dist;		eff->camera->collide_flags &= 0;		eff->camera->collide_dist = FIX_MAX;		last_point = eff->camera->collide_point;		if (col->proxy) {			/*always check bounds to update any dirty node*/			eff->traversing_mode = TRAVERSE_GET_BOUNDS;			gf_node_render(col->proxy, rs);			eff->traversing_mode = TRAVERSE_COLLIDE;			gf_node_render(col->proxy, rs);		} else {			grouping_traverse(group, (RenderEffect3D*)rs, NULL);		}		if (eff->camera->collide_flags & CF_COLLISION) {			col->collideTime = gf_node_get_scene_time(node);			gf_node_event_out_str(node, "collideTime");			/*if not closer restore*/			if (collide_flags && (last_dist<eff->camera->collide_dist)) {				eff->camera->collide_flags = collide_flags;				eff->camera->collide_dist = last_dist;				eff->camera->collide_point = last_point;			}		} else {			eff->camera->collide_flags = collide_flags;			eff->camera->collide_dist = last_dist;		}	}}void R3D_InitCollision(Render3D *sr, GF_Node *node){	GroupingNode *stack = (GroupingNode *)malloc(sizeof(GroupingNode));	SetupGroupingNode(stack, sr->compositor, node, & ((M_Group *)node)->children);	gf_node_set_private(node, stack);	gf_node_set_callback_function(node, RenderCollision);}/*for transform, transform2D & transformMatrix2D*/typedef struct{	GF_Node *owner;	GF_Renderer *compositor;	GROUPINGNODESTACK	GF_Matrix mx;	Bool has_scale;} TransformStack;static void DestroyTransform(GF_Node *n){	TransformStack *ptr = (TransformStack *)gf_node_get_private(n);	DeleteGroupingNode((GroupingNode *)ptr);	free(ptr);}static void NewTransformStack(Render3D *sr, GF_Node *node, GF_ChildNodeItem **children){	TransformStack *st;	GF_SAFEALLOC(st, TransformStack);	gf_mx_init(st->mx);	SetupGroupingNode((GroupingNode *)st, sr->compositor, node, children);	gf_node_set_private(node, st);}#define TRANS_PUSH_MX	\		if (eff->traversing_mode == TRAVERSE_SORT) {	\			VS3D_PushMatrix(eff->surface); \			VS3D_MultMatrix(eff->surface, st->mx.m);	\		}	\#define TRANS_POP_MX	if (eff->traversing_mode==TRAVERSE_SORT) VS3D_PopMatrix(eff->surface);static void RenderTransform(GF_Node *n, void *rs, Bool is_destroy){	GF_Matrix gf_mx_bckup;	TransformStack *st = (TransformStack *)gf_node_get_private(n);	M_Transform *tr = (M_Transform *)n;	RenderEffect3D *eff = (RenderEffect3D *)rs;	if (is_destroy) {		DestroyTransform(n);		return;	}

⌨️ 快捷键说明

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