📄 texture_stacks.c
字号:
/* * GPAC - Multimedia Framework C SDK * * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / 2D 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 "stacks2d.h"#include "visualsurface2d.h"typedef struct _composite_2D{ GF_TextureHandler txh; u32 width, height; /*the surface object handling the texture*/ struct _visual_surface_2D *surf; GF_List *sensors; Bool first;} Composite2DStack;static void DestroyComposite2D(GF_Node *node, void *rs, Bool is_destroy){ if (is_destroy) { Composite2DStack *st = (Composite2DStack *) gf_node_get_private(node); /*unregister surface*/ R2D_UnregisterSurface(st->surf->render, st->surf); DeleteVisualSurface2D(st->surf); gf_list_del(st->sensors); /*destroy texture*/ gf_sr_texture_destroy(&st->txh); free(st); }}static Bool Composite_CheckBindables(GF_Node *n, RenderEffect2D *eff, Bool force_check){ GF_Node *btop; Bool ret = 0; M_CompositeTexture2D *c2d = (M_CompositeTexture2D *)n; if (force_check || gf_node_dirty_get(c2d->background)) { gf_node_render(c2d->background, eff); ret = 1; } btop = (GF_Node*)gf_list_get(eff->back_stack, 0); if (btop != c2d->background) { gf_node_unregister(c2d->background, n); gf_node_register(btop, n); c2d->background = btop; gf_node_event_out_str(n, "background"); ret = 1; } if (force_check || gf_node_dirty_get(c2d->viewport)) { gf_node_render(c2d->viewport, eff); ret = 1; } btop = (GF_Node*)gf_list_get(eff->view_stack, 0); if (btop != c2d->viewport) { gf_node_unregister(c2d->viewport, n); gf_node_register(btop, n); c2d->viewport = btop; gf_node_event_out_str(n, "viewport"); ret = 1; } return ret;}static void UpdateComposite2D(GF_TextureHandler *txh){ GF_Err e; u32 i; SensorHandler *hsens; RenderEffect2D *eff; M_CompositeTexture2D *ct2D = (M_CompositeTexture2D *)txh->owner; Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner); GF_Raster2D *r2d = st->surf->render->compositor->r2d; if (!gf_node_dirty_get(txh->owner)) { txh->needs_refresh = 0; return; } /*rebuild stencil*/ if (!st->surf->the_surface || !txh->hwtx || ((s32) st->width != ct2D->pixelWidth) || ( (s32) st->height != ct2D->pixelHeight) ) { if (txh->hwtx) r2d->stencil_delete(txh->hwtx); txh->hwtx = NULL; if (ct2D->pixelWidth<=0) return; if (ct2D->pixelHeight<=0) return; st->width = ct2D->pixelWidth; st->height = ct2D->pixelHeight; txh->hwtx = r2d->stencil_new(r2d, GF_STENCIL_TEXTURE); e = r2d->stencil_create_texture(txh->hwtx, st->width, st->height, GF_PIXEL_ARGB); if (e) { if (txh->hwtx) r2d->stencil_delete(txh->hwtx); txh->hwtx = NULL; } } if (!txh->hwtx) return; GF_SAFEALLOC(eff, RenderEffect2D); eff->sensors = gf_list_new(); eff->surface = st->surf; if (st->surf->render->top_effect->trav_flags & TF_RENDER_DIRECT) { eff->trav_flags = TF_RENDER_DIRECT; } gf_mx2d_init(eff->transform); gf_cmx_init(&eff->color_mat); st->surf->width = st->width; st->surf->height = st->height; eff->back_stack = st->surf->back_stack; eff->view_stack = st->surf->view_stack; eff->is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(st->txh.owner)); eff->min_hsize = INT2FIX( MIN(st->width, st->height) ) / 2; Composite_CheckBindables(st->txh.owner, eff, st->first); st->first = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Entering CompositeTexture2D Render Cycle\n")); e = VS2D_InitDraw(st->surf, eff); if (e) { effect_delete(eff); return; } /*render children*/ if (gf_node_dirty_get(st->txh.owner) & GF_SG_NODE_DIRTY) { GF_ChildNodeItem *l = ct2D->children; /*rebuild sensor list */ if (gf_list_count(st->sensors)) { gf_list_del(st->sensors); st->sensors = gf_list_new(); } while (l) { if (l->node && is_sensor_node(l->node) ) { hsens = get_sensor_handler(l->node); if (hsens) gf_list_add(st->sensors, hsens); } l = l->next; } /*if we have an active sensor at this level discard all sensors in current render context (cf VRML)*/ if (gf_list_count(st->sensors)) { effect_reset_sensors(eff); } } /*add sensor to effects*/ i=0; while ((hsens = (SensorHandler*)gf_list_enum(st->sensors, &i))) { effect_add_sensor(eff, hsens, &eff->transform); } gf_node_dirty_clear(st->txh.owner, 0); /*render*/ gf_node_render_children(st->txh.owner, eff); /*finalize draw*/ txh->needs_refresh = VS2D_TerminateDraw(st->surf, eff); st->txh.transparent = st->surf->last_had_back ? 0 : 1;/* st->txh.active_window.x = 0; st->txh.active_window.y = 0; st->txh.active_window.width = st->width; st->txh.active_window.height = st->height;*/ st->txh.width = st->width; st->txh.height = st->height; /*set active viewport in image coordinates top-left=(0, 0), not in BIFS*/ if (gf_list_count(st->surf->view_stack)) { M_Viewport *vp = (M_Viewport *)gf_list_get(st->surf->view_stack, 0); if (vp->isBound) { SFVec2f size = vp->size; if (size.x >=0 && size.y>=0) {/* st->txh.active_window.width = size.x; st->txh.active_window.height = size.y; st->txh.active_window.x = (st->width - size.x) / 2; st->txh.active_window.y = (st->height - size.y) / 2;*/ /*FIXME - we need tracking of VP changes*/ txh->needs_refresh = 1; } } } if (txh->needs_refresh) { if (r2d->stencil_texture_modified) r2d->stencil_texture_modified(st->txh.hwtx); gf_sr_invalidate(st->txh.compositor, NULL); } effect_delete(eff); GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render 2D] Leaving CompositeTexture2D Render Cycle\n"));}static GF_Err C2D_GetSurfaceAccess(VisualSurface2D *surf){ GF_Err e; if (!surf->composite->txh.hwtx || !surf->the_surface) return GF_BAD_PARAM; e = surf->render->compositor->r2d->surface_attach_to_texture(surf->the_surface, surf->composite->txh.hwtx); if (!e) surf->is_attached = 1; return e;}static void C2D_ReleaseSurfaceAccess(VisualSurface2D *surf){ surf->render->compositor->r2d->surface_detach(surf->the_surface);}void R2D_InitCompositeTexture2D(Render2D *sr, GF_Node *node){ M_CompositeTexture2D *c2d = (M_CompositeTexture2D *)node; Composite2DStack *st; GF_SAFEALLOC(st, Composite2DStack); gf_sr_texture_setup(&st->txh, sr->compositor, node); st->txh.update_texture_fcnt = UpdateComposite2D; st->txh.flags = GF_SR_TEXTURE_COMPOSITE; if ((c2d->repeatSandT==1) || (c2d->repeatSandT==3) ) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S; if (c2d->repeatSandT>1) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T; /*create composite surface*/ st->surf = NewVisualSurface2D(); st->surf->composite = st; st->surf->GetSurfaceAccess = C2D_GetSurfaceAccess; st->surf->ReleaseSurfaceAccess = C2D_ReleaseSurfaceAccess; /*Bitmap drawn with brush, not hardware since we don't know how the graphics driver handles the texture bytes*/ st->surf->DrawBitmap = NULL; st->surf->SupportsFormat = NULL; st->first = 1; st->surf->render = sr; st->sensors = gf_list_new(); gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyComposite2D); R2D_RegisterSurface(sr, st->surf);}GF_TextureHandler *ct2D_get_texture(GF_Node *node){ Composite2DStack *st = (Composite2DStack*) gf_node_get_private(node); return &st->txh;}Bool CT2D_has_sensors(GF_TextureHandler *txh){ Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner); assert(st->surf); return st->surf->has_sensors ? 1 : 0;}void get_gf_sr_texture_transform(GF_Node *__appear, GF_TextureHandler *txh, GF_Matrix2D *mat, Bool line_texture, Fixed final_width, Fixed final_height);DrawableContext *CT2D_FindNode(GF_TextureHandler *txh, DrawableContext *ctx, Fixed x, Fixed y){ GF_Rect orig; GF_Matrix2D mat, tx_trans; Fixed width, height; Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner); assert(st->surf); orig = ctx->bi->unclip; gf_mx2d_copy(mat, ctx->transform); gf_mx2d_inverse(&mat); gf_mx2d_apply_rect(&mat, &orig); gf_mx2d_init(mat); gf_mx2d_add_scale(&mat, orig.width / st->width, orig.height / st->height); get_gf_sr_texture_transform(ctx->appear, &st->txh, &tx_trans, (ctx->h_texture==&st->txh) ? 0 : 1, INT2FIX(orig.width), INT2FIX(orig.height)); gf_mx2d_add_matrix(&mat, &tx_trans); gf_mx2d_add_translation(&mat, (orig.x), (orig.y - orig.height)); gf_mx2d_add_matrix(&mat, &ctx->transform); gf_mx2d_inverse(&mat); gf_mx2d_apply_coords(&mat, &x, &y);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -