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

📄 base_textures.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / Scene Rendering sub-project * *  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 "common_stacks.h"#include <gpac/nodes_mpeg4.h>#include <gpac/nodes_x3d.h>typedef struct{	GF_TextureHandler txh;	GF_TimeNode time_handle;	Bool fetch_first_frame, first_frame_fetched, is_vrml;	Double start_time;} MovieTextureStack;static void DestroyMovieTexture(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(node);		gf_sr_texture_destroy(&st->txh);		if (st->time_handle.is_registered) gf_sr_unregister_time_node(st->txh.compositor, &st->time_handle);		free(st);	}}static Fixed MT_GetSpeed(MovieTextureStack *stack, M_MovieTexture *mt){	return gf_mo_get_speed(stack->txh.stream, mt->speed);}static Bool MT_GetLoop(MovieTextureStack *stack, M_MovieTexture *mt){	return gf_mo_get_loop(stack->txh.stream, mt->loop);}static void MT_Activate(MovieTextureStack *stack, M_MovieTexture *mt, Double scene_time){	mt->isActive = 1;	gf_node_event_out_str((GF_Node*)mt, "isActive");	if (!stack->txh.is_open) {		scene_time -= mt->startTime;		gf_sr_texture_play_from_to(&stack->txh, &mt->url, scene_time, -1, gf_mo_get_loop(stack->txh.stream, mt->loop), 0);	}	gf_mo_set_speed(stack->txh.stream, mt->speed);}static void MT_Deactivate(MovieTextureStack *stack, M_MovieTexture *mt){	mt->isActive = 0;	gf_node_event_out_str((GF_Node*)mt, "isActive");	stack->time_handle.needs_unregister = 1;	if (stack->txh.is_open) {		gf_sr_texture_stop(&stack->txh);	}}static void UpdateMovieTexture(GF_TextureHandler *txh){	M_MovieTexture *txnode = (M_MovieTexture *) txh->owner;	MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(txh->owner);		/*setup texture if needed*/	if (!txh->is_open) return;	if (!txnode->isActive && st->first_frame_fetched) return;	/*when fetching the first frame disable resync*/	gf_sr_texture_update_frame(txh, !txnode->isActive);	if (txh->stream_finished) {		if (MT_GetLoop(st, txnode)) {			gf_sr_texture_restart(txh);		}		/*if active deactivate*/		else if (txnode->isActive && gf_mo_should_deactivate(st->txh.stream) ) {			MT_Deactivate(st, txnode);		}	}	/*first frame is fetched*/	if (!st->first_frame_fetched && (txh->needs_refresh) ) {		st->first_frame_fetched = 1;		txnode->duration_changed = gf_mo_get_duration(txh->stream);		gf_node_event_out_str(txh->owner, "duration_changed");		/*stop stream if needed*/		if (!txnode->isActive && txh->is_open) {			gf_sr_texture_stop(txh);			/*make sure the refresh flag is not cleared*/			txh->needs_refresh = 1;		}	}	if (txh->needs_refresh) 		gf_sr_invalidate(txh->compositor, NULL);}static void MT_UpdateTime(GF_TimeNode *st){	Double time;	M_MovieTexture *mt = (M_MovieTexture *)st->obj;	MovieTextureStack *stack = (MovieTextureStack *)gf_node_get_private(st->obj);		/*not active, store start time and speed*/	if ( ! mt->isActive) {		stack->start_time = mt->startTime;	}	time = gf_node_get_scene_time(st->obj);	if (time < stack->start_time ||		/*special case if we're getting active AFTER stoptime */		(!mt->isActive && (mt->stopTime > stack->start_time) && (time>=mt->stopTime))		|| (!stack->start_time && stack->is_vrml && !mt->loop)		) {		/*opens stream only at first access to fetch first frame*/		if (stack->fetch_first_frame) {			stack->fetch_first_frame = 0;			if (!stack->txh.is_open)				gf_sr_texture_play(&stack->txh, &mt->url);		}		return;	}	if (MT_GetSpeed(stack, mt) && mt->isActive) {		/*if stoptime is reached (>startTime) deactivate*/		if ((mt->stopTime > stack->start_time) && (time >= mt->stopTime) ) {			MT_Deactivate(stack, mt);			return;		}	}	/*we're (about to be) active: VRML:	"A time-dependent node is inactive until its startTime is reached. When time now becomes greater than or 	equal to startTime, an isActive TRUE event is generated and the time-dependent node becomes active 	*/	if (! mt->isActive) MT_Activate(stack, mt, time);}void InitMovieTexture(GF_Renderer *sr, GF_Node *node){	MovieTextureStack *st;	GF_SAFEALLOC(st, MovieTextureStack);	gf_sr_texture_setup(&st->txh, sr, node);	st->txh.update_texture_fcnt = UpdateMovieTexture;	st->time_handle.UpdateTimeNode = MT_UpdateTime;	st->time_handle.obj = node;	st->fetch_first_frame = 1;	st->txh.flags = 0;	if (((M_MovieTexture*)node)->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S;	if (((M_MovieTexture*)node)->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T;		st->is_vrml = (gf_node_get_tag(node)==TAG_X3D_MovieTexture) ? 1 : 0;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyMovieTexture);		gf_sr_register_time_node(sr, &st->time_handle);}GF_TextureHandler *mt_get_texture(GF_Node *node){	MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(node);	return &st->txh;}void MovieTextureModified(GF_Node *node){	M_MovieTexture *mt = (M_MovieTexture *)node;	MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(node);	if (!st) return;	/*if open and changed, stop and play*/	if (st->txh.is_open && gf_sr_texture_check_url_change(&st->txh, &mt->url)) {		gf_sr_texture_stop(&st->txh);		gf_sr_texture_play(&st->txh, &mt->url);	} 	/*update state if we're active*/	else if (mt->isActive) {		MT_UpdateTime(&st->time_handle);		if (!mt->isActive) return;	}	/*reregister if needed*/	st->time_handle.needs_unregister = 0;	if (!st->time_handle.is_registered) gf_sr_register_time_node(st->txh.compositor, &st->time_handle);}typedef struct{	GF_TextureHandler txh;} ImageTextureStack;static void DestroyImageTexture(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node);		gf_sr_texture_destroy(&st->txh);		free(st);	}}static void UpdateImageTexture(GF_TextureHandler *txh){	M_ImageTexture *txnode = (M_ImageTexture *) txh->owner;		/*setup texture if needed*/	if (!txh->is_open && txnode->url.count) {		gf_sr_texture_play(txh, &txnode->url);	}	gf_sr_texture_update_frame(txh, 0);	/*URL is present but not opened - redraw till fetch*/	if (txh->stream && !txh->hwtx) gf_sr_invalidate(txh->compositor, NULL);}void InitImageTexture(GF_Renderer *sr, GF_Node *node){	ImageTextureStack *st;	GF_SAFEALLOC(st, ImageTextureStack);	gf_sr_texture_setup(&st->txh, sr, node);	st->txh.update_texture_fcnt = UpdateImageTexture;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyImageTexture);	st->txh.flags = 0;	if (((M_ImageTexture*)node)->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S;	if (((M_ImageTexture*)node)->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T;}GF_TextureHandler *it_get_texture(GF_Node *node){	ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node);	return &st->txh;}void ImageTextureModified(GF_Node *node){	M_ImageTexture *im = (M_ImageTexture *)node;	ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node);	if (!st) return;	/*if open and changed, stop and play*/	if (st->txh.is_open) {		if (! gf_sr_texture_check_url_change(&st->txh, &im->url)) return;		gf_sr_texture_stop(&st->txh);		gf_sr_texture_play(&st->txh, &im->url);		return;	}	/*if not open and changed play*/	if (im->url.count) 		gf_sr_texture_play(&st->txh, &im->url);}typedef struct{	GF_TextureHandler txh;	char *pixels;} PixelTextureStack;static void DestroyPixelTexture(GF_Node *node, void *rs, Bool is_destroy){	if (is_destroy) {		PixelTextureStack *st = (PixelTextureStack *) gf_node_get_private(node);		if (st->pixels) free(st->pixels);		gf_sr_texture_destroy(&st->txh);		free(st);	}}static void UpdatePixelTexture(GF_TextureHandler *txh){	u32 pix_format, stride, i;	M_PixelTexture *pt = (M_PixelTexture *) txh->owner;	PixelTextureStack *st = (PixelTextureStack *) gf_node_get_private(txh->owner);	if (!gf_node_dirty_get(txh->owner)) return;	gf_node_dirty_clear(txh->owner, 0);		/*pixel texture doesn not use any media object but has data in the content. 	However we still use the same texture object, just be carefull not to use media funtcions*/	txh->transparent = 0;	stride = pt->image.width;	/*num_components are as in VRML (1->4) not as in BIFS bitstream (0->3)*/	switch (pt->image.numComponents) {	case 1:		pix_format = GF_PIXEL_GREYSCALE;		break;	case 2:		pix_format = GF_PIXEL_ALPHAGREY;		txh->transparent = 1;		stride *= 2;		break;	case 3:		pix_format = GF_PIXEL_RGB_24;		txh->transparent = 0;		stride *= 3;		break;	case 4:		pix_format = GF_PIXEL_RGBA;		txh->transparent = 1;		stride *= 4;		break;	default:		return;	}	if (!txh->hwtx) txh->compositor->visual_renderer->AllocTexture(txh);	if (!txh->hwtx) return;	if (st->pixels) free(st->pixels);	st->pixels = (char*)malloc(sizeof(char) * stride * pt->image.height);	if (txh->compositor->visual_renderer->bNeedsGL) {		for (i=0; i<pt->image.height; i++) {			memcpy(st->pixels + i * stride, pt->image.pixels + i * stride, stride);		}	} 	/*revert pixel ordering...*/	else {		for (i=0; i<pt->image.height; i++) {			memcpy(st->pixels + i * stride, pt->image.pixels + (pt->image.height - 1 - i) * stride, stride);		}	}	txh->width = pt->image.width;	txh->height = pt->image.height;	txh->stride = stride;	txh->pixelformat = pix_format;	txh->data = st->pixels;	txh->compositor->visual_renderer->SetTextureData(txh);}void InitPixelTexture(GF_Renderer *sr, GF_Node *node){	PixelTextureStack *st;	GF_SAFEALLOC(st, PixelTextureStack);	gf_sr_texture_setup(&st->txh, sr, node);	st->pixels = NULL;	st->txh.update_texture_fcnt = UpdatePixelTexture;	gf_node_set_private(node, st);	gf_node_set_callback_function(node, DestroyPixelTexture);	st->txh.flags = 0;	if (((M_PixelTexture*)node)->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S;	if (((M_PixelTexture*)node)->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T;}GF_TextureHandler *pt_get_texture(GF_Node *node){	PixelTextureStack *st = (PixelTextureStack *) gf_node_get_private(node);	return &st->txh;}GF_EXPORTGF_TextureHandler *gf_sr_texture_get_handler(GF_Node *n){	if (!n) return NULL;	switch (gf_node_get_tag(n)) {	case TAG_MPEG4_ImageTexture: case TAG_X3D_ImageTexture: return it_get_texture(n);	case TAG_MPEG4_MovieTexture: case TAG_X3D_MovieTexture: return mt_get_texture(n);	case TAG_MPEG4_PixelTexture: case TAG_X3D_PixelTexture: return pt_get_texture(n);	default: return NULL;	}}

⌨️ 快捷键说明

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