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

📄 visual_surface.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *			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 "visual_surface.h"#include "render3d_nodes.h"#include <gpac/options.h>VisualSurface *VS_New(){	VisualSurface *tmp;	GF_SAFEALLOC(tmp, VisualSurface);	tmp->back_stack = gf_list_new();	tmp->view_stack = gf_list_new();	tmp->alpha_nodes_to_draw = gf_list_new();	tmp->fog_stack = gf_list_new();	tmp->navigation_stack = gf_list_new();	return tmp;}void VS_Delete(VisualSurface *surf){	BindableStackDelete(surf->back_stack);	BindableStackDelete(surf->view_stack);	BindableStackDelete(surf->fog_stack);	BindableStackDelete(surf->navigation_stack);	gf_list_del(surf->alpha_nodes_to_draw);	free(surf);}DrawableStack *new_drawable(GF_Node *owner, GF_Renderer *compositor){	DrawableStack *tmp = (DrawableStack *)malloc(sizeof(DrawableStack));	if (tmp) stack_setup(tmp, owner, compositor);	return tmp;}void delete_drawable(DrawableStack*d){	drawablestack_predestroy(d);	free(d);}void drawable_node_destroy(GF_Node *n){	DrawableStack *d = (DrawableStack *)gf_node_get_private(n);	if (d) delete_drawable(d);}DrawableStack *BaseDrawableStack(GF_Renderer *sr, GF_Node *node){	DrawableStack *st = new_drawable(node, sr);	gf_node_set_private(node, st);	return st;}void delete_strikeinfo(StrikeInfo *info){	if (info->outline) mesh_free(info->outline);	free(info);}stack2D *new_stack2D(GF_Node *owner, GF_Renderer *compositor){	stack2D *tmp = (stack2D *)malloc(sizeof(stack2D));	if (tmp) {		stack_setup(tmp, owner, compositor);		tmp->path = gf_path_new();		tmp->strike_list = gf_list_new();	}	return tmp;}void stack2D_predestroy(stack2D *d){	Render3D *sr = (Render3D *)d->compositor->visual_renderer->user_priv;	if (d->mesh) mesh_free(d->mesh);	assert(d->path);	gf_path_del(d->path);	while (gf_list_count(d->strike_list)) {		StrikeInfo *si = (StrikeInfo *)gf_list_get(d->strike_list, 0);		gf_list_rem(d->strike_list, 0);		/*remove from main strike list*/		gf_list_del_item(sr->strike_bank, si);		delete_strikeinfo(si);	}	gf_list_del(d->strike_list);}void delete_stack2D(stack2D *d){	stack2D_predestroy(d);	free(d);}void stack2D_node_predestroy(GF_Node *n){	stack2D *d = (stack2D *)gf_node_get_private(n);	if (d) delete_stack2D(d);}stack2D *BaseStack2D(GF_Renderer *sr, GF_Node *node){	stack2D *st = new_stack2D(node, sr);	gf_node_set_private(node, st);	return st;}void stack2D_setup(stack2D *st, GF_Renderer *sr, GF_Node *node){	stack_setup(st, node, sr);	st->path = gf_path_new();	st->strike_list = gf_list_new();}void stack2D_reset(stack2D *d){	Render3D *sr = (Render3D *)d->compositor->visual_renderer->user_priv;	if (d->path) gf_path_reset(d->path);	while (gf_list_count(d->strike_list)) {		StrikeInfo *si = (StrikeInfo *)gf_list_get(d->strike_list, 0);		gf_list_rem(d->strike_list, 0);		gf_list_del_item(sr->strike_bank, si);		delete_strikeinfo(si);	}}Bool VS_GetAspect2D(RenderEffect3D *eff, Aspect2D *asp){	M_Material2D *mat;	Bool has_mat;	/*default values*/	memset(asp, 0, sizeof(Aspect2D));	asp->fill_color.red = asp->fill_color.green = asp->fill_color.blue = FLT2FIX(0.8f);	/*this is a bug in the spec: by default line width is 1.0, but in meterMetrics this means half of the screen :)*/	if (eff->is_pixel_metrics) 		asp->pen_props.width = FIX_ONE;	else		asp->pen_props.width = gf_invfix(2*eff->min_hsize);	asp->line_color = asp->fill_color;	asp->pen_props.cap = GF_LINE_CAP_FLAT;	asp->pen_props.join = GF_LINE_JOIN_MITER;	asp->pen_props.miterLimit = INT2FIX(4);	asp->line_alpha = asp->alpha = FIX_ONE;	has_mat = 1;	if (!eff->appear) goto exit;	mat = (M_Material2D *) ((M_Appearance *)eff->appear)->material;	/*according to the spec only Material2D shall be used with 2D primitives*/	if (!mat) goto exit;	switch (gf_node_get_tag((GF_Node *)mat)) {	/*we need to indicate to text if it shall use 2D or 3D material...*/	case TAG_MPEG4_Material:	case TAG_X3D_Material:		has_mat = 0;		asp->filled = 1;		asp->pen_props.width = 0;		asp->fill_color = ((M_Material*)mat)->diffuseColor;		goto exit;	case TAG_MPEG4_MaterialKey:		goto exit;	}	asp->line_color = asp->fill_color = mat->emissiveColor;	asp->line_alpha = asp->alpha = FIX_ONE - mat->transparency;	asp->filled = mat->filled;	if (mat->lineProps == NULL) {		if (asp->filled || (asp->alpha==0)) asp->pen_props.width =0;	} else {		asp->lp = mat->lineProps;		switch (gf_node_get_tag(mat->lineProps)) {		case TAG_MPEG4_LineProperties:		{			M_LineProperties *lp = (M_LineProperties *)mat->lineProps;			asp->pen_props.width = lp->width;			asp->pen_props.dash = (u8) lp->lineStyle;			asp->line_color = lp->lineColor;		}			break;		case TAG_MPEG4_XLineProperties:		{			M_XLineProperties *xlp = (M_XLineProperties *)mat->lineProps;			asp->pen_props.dash = (u8) xlp->lineStyle;			asp->line_color = xlp->lineColor;			asp->line_alpha = FIX_ONE - xlp->transparency;			asp->pen_props.width = xlp->width;			asp->is_scalable = xlp->isScalable;			asp->pen_props.align = xlp->isCenterAligned ? GF_PATH_LINE_CENTER : GF_PATH_LINE_INSIDE;			asp->pen_props.cap = (u8) xlp->lineCap;			asp->pen_props.join = (u8) xlp->lineJoin;			asp->pen_props.miterLimit = xlp->miterLimit;			asp->pen_props.dash_offset = xlp->dashOffset;			/*dash settings strutc is the same as MFFloat from XLP, typecast without storing*/			if (xlp->dashes.count) {				asp->pen_props.dash_set = (GF_DashSettings *) &xlp->dashes;			} else {				asp->pen_props.dash_set = NULL;			}			asp->txh = R3D_GetTextureHandler(xlp->texture);			asp->tx_trans = xlp->textureTransform;		}			break;		}	}exit:	if (!eff->color_mat.identity) 		gf_cmx_apply_fixed(&eff->color_mat, &asp->alpha, &asp->fill_color.red, &asp->fill_color.green, &asp->fill_color.blue);		/*update line width*/	if (asp->pen_props.width) {		/*if pen is not scalable, apply user/viewport transform so that original aspect is kept*/		if (!asp->is_scalable) {			GF_Rect rc;			rc.x = rc.y = 0;			rc.width = rc.height = FIX_ONE;			gf_mx_apply_rect(&eff->model_matrix, &rc);			asp->line_scale = MAX(rc.width, rc.height);		} else {			asp->line_scale = FIX_ONE;		}		if (!eff->color_mat.identity) 			gf_cmx_apply_fixed(&eff->color_mat, &asp->line_alpha, &asp->line_color.red, &asp->line_color.green, &asp->line_color.blue);	}	return has_mat;}StrikeInfo *VS_GetStrikeInfo(stack2D *st, Aspect2D *asp, RenderEffect3D *eff){	StrikeInfo *si;	u32 now, i;	Render3D *sr = (Render3D *)st->compositor->visual_renderer->user_priv;	Bool vect_outline = !sr->raster_outlines;	if (!asp->pen_props.width || !st->path) return NULL;	si = NULL;	i=0;	while ((si = (StrikeInfo *)gf_list_enum(st->strike_list, &i))) {		/*note this includes default LP (NULL)*/		if (si->lineProps == asp->lp) break;		si = NULL;	}	/*not found, add*/	if (!si) {		GF_SAFEALLOC(si, StrikeInfo);		si->lineProps = asp->lp;		si->node2D = st->owner;		gf_list_add(st->strike_list, si);		gf_list_add(sr->strike_bank, si);	}	if (vect_outline != si->is_vectorial) {		if (si->outline) mesh_free(si->outline);		si->outline = NULL;	}	/*node changed or outline not build*/	now = asp->lp ? (1 + R3D_LP_GetLastUpdateTime(asp->lp)) : si->last_update_time;	if (!si->outline 		|| (si->is_vectorial && ((now!=si->last_update_time) || (si->line_scale != asp->line_scale) )) ) {		si->last_update_time = now;		si->line_scale = asp->line_scale;		if (si->outline) mesh_free(si->outline);		si->outline = new_mesh();		si->is_vectorial = vect_outline;#ifndef GPAC_USE_OGL_ES		if (vect_outline) {			u32 i;			GF_Path *outline_path;			Fixed dash_o = asp->pen_props.dash_offset;			Fixed w = asp->pen_props.width;			asp->pen_props.width = gf_divfix(asp->pen_props.width, asp->line_scale);			asp->pen_props.dash_offset = gf_mulfix(asp->pen_props.dash_offset, asp->pen_props.width);			if (asp->pen_props.dash_set) {				for(i=0; i<asp->pen_props.dash_set->num_dash; i++) {					asp->pen_props.dash_set->dashes[i] = gf_mulfix(asp->pen_props.dash_set->dashes[i], asp->line_scale);				}			}						outline_path = gf_path_get_outline(st->path, asp->pen_props);			/*restore*/			asp->pen_props.width = w;			asp->pen_props.dash_offset = dash_o;			if (asp->pen_props.dash_set) {				for(i=0; i<asp->pen_props.dash_set->num_dash; i++) {					asp->pen_props.dash_set->dashes[i] = gf_divfix(asp->pen_props.dash_set->dashes[i], asp->line_scale);				}			}			TesselatePath(si->outline, outline_path, asp->txh ? 2 : 1);			gf_path_del(outline_path);		} else#endif			mesh_get_outline(si->outline, st->path);	}	return si;}StrikeInfo *VS_GetStrikeInfoIFS(stack2D *st, Aspect2D *asp, RenderEffect3D *eff){	StrikeInfo *si;	u32 now, i;	Render3D *sr = (Render3D *)st->compositor->visual_renderer->user_priv;	if (!asp->pen_props.width || !st->path) return NULL;	si = NULL;	i=0;	while ((si = (StrikeInfo *)gf_list_enum(st->strike_list, &i))) {		/*note this includes default LP (NULL)*/		if (si->lineProps == asp->lp) break;		si = NULL;	}	/*not found, add*/	if (!si) {		GF_SAFEALLOC(si, StrikeInfo);		si->lineProps = asp->lp;		si->node2D = st->owner;		gf_list_add(st->strike_list, si);		gf_list_add(sr->strike_bank, si);	}	/*for this func the strike is always raster*/	if (si->is_vectorial) {		if (si->outline) mesh_free(si->outline);		si->outline = NULL;	}	/*node changed or outline not build*/	now = asp->lp ? R3D_LP_GetLastUpdateTime(asp->lp) : si->last_update_time;	if ((now!=si->last_update_time) || (si->line_scale != asp->line_scale) ) {		si->last_update_time = now;		si->line_scale = asp->line_scale;		if (si->outline) mesh_free(si->outline);		si->outline = NULL;		si->is_vectorial = 0;	}	return si;}Fixed Aspect_GetLineWidth(Aspect2D *asp){	/*for raster outlines are already set to the proper width - note this may not work depending on GL...*/	Fixed width = asp->pen_props.width;	if (asp->is_scalable) 		width = gf_mulfix(width, asp->line_scale);	return width;}void VS_Set2DStrikeAspect(RenderEffect3D *eff, Aspect2D *asp){	if (asp->txh) {		/*We forgot to specify this in the spec ...*/		tx_set_blend_mode(asp->txh, TX_REPLACE);#if 0		if (asp->line_alpha != FIX_ONE) {			VS3D_SetMaterial2D(eff->surface, asp->line_color, asp->line_alpha);			tx_set_blend_mode(asp->txh, TX_MODULATE);		} else {			VS3D_SetState(eff->surface, F3D_BLEND, 0);			tx_set_blend_mode(asp->txh, TX_REPLACE);		}#endif		eff->mesh_has_texture = tx_enable(asp->txh, asp->tx_trans);		if (eff->mesh_has_texture) return;	}	/*no texture or not ready, use color*/	VS3D_SetMaterial2D(eff->surface, asp->line_color, asp->line_alpha);}static GF_TextureHandler *VS_setup_texture_2d(RenderEffect3D *eff, Aspect2D *asp){	GF_TextureHandler *txh;	if (!eff->appear) return NULL;	txh = R3D_GetTextureHandler(((M_Appearance *)eff->appear)->texture);	if (!txh) return NULL;	if (!asp->filled) {		if (asp->alpha!=FIX_ONE) {			VS3D_SetMaterial2D(eff->surface, asp->fill_color, asp->alpha);			tx_set_blend_mode(txh, TX_MODULATE);		} else {			VS3D_SetState(eff->surface, F3D_BLEND, 0);			tx_set_blend_mode(txh, TX_REPLACE);		}	}	eff->mesh_has_texture = tx_enable(txh, ((M_Appearance *)eff->appear)->textureTransform);	if (eff->mesh_has_texture) return txh;	return NULL;}void stack2D_draw(stack2D *st, RenderEffect3D *eff){	Aspect2D asp;	StrikeInfo *si;	GF_TextureHandler *fill_txh;	VS_GetAspect2D(eff, &asp);	if (!asp.alpha) {		fill_txh = NULL;	} else {		fill_txh = VS_setup_texture_2d(eff, &asp);	}	/*fill path*/	if (fill_txh || (asp.alpha && asp.filled) ) {

⌨️ 快捷键说明

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