📄 geometry_stacks.c
字号:
DrawableContext *ctx; M_Curve2D *c2D = (M_Curve2D *)node; Drawable *cs = (Drawable *)gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { DestroyDrawableNode(node); return; } if (eff->traversing_mode==TRAVERSE_DRAW) { drawable_draw(eff); return; } else if (eff->traversing_mode==TRAVERSE_PICK) { drawable_pick(eff); return; } if (!c2D->point) return; if (gf_node_dirty_get(node)) { drawable_reset_path(cs); cs->path->fineness = c2D->fineness; if (eff->surface->render->compositor->high_speed) cs->path->fineness /= 2; build_curve2D(cs, c2D); gf_node_dirty_clear(node, 0); cs->flags |= DRAWABLE_HAS_CHANGED; } ctx = drawable_init_context(cs, eff); if (!ctx) return; drawable_finalize_render(ctx, eff, NULL);}void R2D_InitCurve2D(Render2D *sr, GF_Node *node){ drawable_stack_new(sr, node); gf_node_set_callback_function(node, RenderCurve2D);}typedef struct _bitmap_stack{ /*rendering node*/ Drawable *graph;} BitmapStack;static void Bitmap_BuildGraph(BitmapStack *st, DrawableContext *ctx, RenderEffect2D *eff, GF_Rect *out_rc){ Fixed w, h; M_Bitmap *bmp = (M_Bitmap *)ctx->drawable->node; w = INT2FIX(ctx->h_texture->width); /*if we have a PAR update it!!*/ if (ctx->h_texture->pixel_ar) { u32 n = (ctx->h_texture->pixel_ar>>16) & 0xFFFF; u32 d = (ctx->h_texture->pixel_ar) & 0xFFFF; w = INT2FIX((ctx->h_texture->width * n) / d); } h = INT2FIX(ctx->h_texture->height); /*the spec says STRICTLY positive or -1, but some content use 0...*/ w = gf_mulfix(w, ((bmp->scale.x>=0) ? bmp->scale.x : FIX_ONE) ); h = gf_mulfix(h, ((bmp->scale.y>=0) ? bmp->scale.y : FIX_ONE) ); /*reverse meterMetrics conversion*/ if (!eff->is_pixel_metrics) { w = gf_divfix(w, eff->min_hsize); h = gf_divfix(h, eff->min_hsize); } /*get size with scale*/ drawable_reset_path(st->graph); gf_path_add_rect_center(st->graph->path, 0, 0, w, h); *out_rc = gf_rect_center(w, h);}static void DrawBitmap(GF_Node *node, RenderEffect2D *eff){ u8 alpha; u32 keyColor; Render2D *sr; Bool use_blit, has_key; DrawableContext *ctx = eff->ctx; BitmapStack *st = (BitmapStack *) gf_node_get_private(node); sr = eff->surface->render; /*bitmaps are NEVER rotated (forbidden in spec). In case a rotation was done we still display (reset the skew components)*/ ctx->transform.m[1] = ctx->transform.m[3] = 0; use_blit = 1; alpha = GF_COL_A(ctx->aspect.fill_color); /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/ if (!alpha) alpha = GF_COL_A(ctx->aspect.line_color); if (ctx->transform.m[0] || ctx->transform.m[4]<0) use_blit = 0; /*materialKey*/ has_key = 0; if (ctx->appear) { M_Appearance *app = (M_Appearance *)ctx->appear; if ( app->material && (gf_node_get_tag((GF_Node *)app->material)==TAG_MPEG4_MaterialKey) ) { if (((M_MaterialKey*)app->material)->isKeyed && ((M_MaterialKey*)app->material)->transparency) { SFColor col = ((M_MaterialKey*)app->material)->keyColor; has_key = 1; keyColor = GF_COL_ARGB_FIXED( FIX_ONE - ((M_MaterialKey*)app->material)->transparency, col.red, col.green, col.blue); } } } /*this is not a native texture, use graphics*/ if (!ctx->h_texture->data) { use_blit = 0; } else { if (!eff->surface->SupportsFormat || !eff->surface->DrawBitmap ) use_blit = 0; /*format not supported directly, try with brush*/ else if (!eff->surface->SupportsFormat(eff->surface, ctx->h_texture->pixelformat) ) use_blit = 0; } /*no HW, fall back to the graphics driver*/ if (!use_blit) { GF_Matrix2D _mat; GF_Rect rc = gf_rect_center(ctx->bi->unclip.width, ctx->bi->unclip.height); gf_mx2d_copy(_mat, ctx->transform); gf_mx2d_inverse(&_mat); gf_mx2d_apply_rect(&_mat, &rc); drawable_reset_path(st->graph); gf_path_add_rect_center(st->graph->path, 0, 0, rc.width, rc.height); ctx->flags |= CTX_NO_ANTIALIAS; VS2D_TexturePath(eff->surface, st->graph->path, ctx); return; } /*direct rendering, render without clippers */ if (eff->surface->render->top_effect->trav_flags & TF_RENDER_DIRECT) { eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &ctx->bi->clip, &ctx->bi->unclip, alpha, has_key ? &keyColor : NULL, ctx->col_mat); } /*render bitmap for all dirty rects*/ else { u32 i; GF_IRect clip; for (i=0; i<eff->surface->to_redraw.count; i++) { /*there's an opaque region above, don't draw*/#ifdef TRACK_OPAQUE_REGIONS if (eff->surface->draw_node_index < eff->surface->to_redraw.opaque_node_index[i]) continue;#endif clip = ctx->bi->clip; gf_irect_intersect(&clip, &eff->surface->to_redraw.list[i]); if (clip.width && clip.height) { eff->surface->DrawBitmap(eff->surface, ctx->h_texture, &clip, &ctx->bi->unclip, alpha, has_key ? &keyColor : NULL, ctx->col_mat); } } }}static void RenderBitmap(GF_Node *node, void *rs, Bool is_destroy){ GF_Rect rc; DrawableContext *ctx; BitmapStack *st = (BitmapStack *)gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { drawable_del(st->graph); free(st); return; } if (eff->traversing_mode==TRAVERSE_DRAW) { DrawBitmap(node, eff); return; } else if (eff->traversing_mode==TRAVERSE_PICK) { eff->is_over = 1; return; } /*we never cache anything with bitmap...*/ gf_node_dirty_clear(node, 0); ctx = drawable_init_context(st->graph, eff); if (!ctx || !ctx->h_texture ) { VS2D_RemoveLastContext(eff->surface); return; } /*always build the path*/ Bitmap_BuildGraph(st, ctx, eff, &rc); /*even if set this is not true*/ ctx->aspect.pen_props.width = 0; ctx->flags |= CTX_NO_ANTIALIAS; ctx->flags &= ~CTX_IS_TRANSPARENT; /*if clipper then transparent*/ if (ctx->h_texture->transparent) { ctx->flags |= CTX_IS_TRANSPARENT; } else { M_Appearance *app = (M_Appearance *)ctx->appear; if ( app->material && (gf_node_get_tag((GF_Node *)app->material)==TAG_MPEG4_MaterialKey) ) { if (((M_MaterialKey*)app->material)->isKeyed && ((M_MaterialKey*)app->material)->transparency) ctx->flags |= CTX_IS_TRANSPARENT; } else if (!eff->color_mat.identity) { ctx->flags |= CTX_IS_TRANSPARENT; } else { u8 alpha = GF_COL_A(ctx->aspect.fill_color); /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/ if (!alpha) alpha = GF_COL_A(ctx->aspect.line_color); if (alpha < 0xFF) ctx->flags |= CTX_IS_TRANSPARENT; } } /*bounds are stored when building graph*/ drawable_finalize_render(ctx, eff, &rc);}void R2D_InitBitmap(Render2D *sr, GF_Node *node){ BitmapStack *st = (BitmapStack *)malloc(sizeof(BitmapStack)); st->graph = drawable_new(); st->graph->node = node; gf_node_set_private(node, st); gf_node_set_callback_function(node, RenderBitmap);}/* Note on point set 2D: this is a very bad node and should be avoided in DEF/USE, since the size of the rectangle representing the pixel shall always be 1 pixel w/h on the final surface, therefore the path object is likely not the same depending on transformation context...*/static void get_point_size(GF_Matrix2D *mat, Fixed *w, Fixed *h){ GF_Point2D pt; pt.x = mat->m[0] + mat->m[1]; pt.y = mat->m[3] + mat->m[4]; *w = *h = gf_divfix(FLT2FIX(1.41421356f) , gf_v2d_len(&pt));}static void build_graph(Drawable *cs, GF_Matrix2D *mat, M_PointSet2D *ps2D){ u32 i; Fixed w, h; M_Coordinate2D *coord = (M_Coordinate2D *)ps2D->coord; get_point_size(mat, &w, &h); /*for PS2D don't add to avoid too much antialiasing, just try to fill the given pixel*/ for (i=0; i < coord->point.count; i++) gf_path_add_rect(cs->path, coord->point.vals[i].x, coord->point.vals[i].y, w, h); cs->path->flags |= GF_PATH_FILL_ZERO_NONZERO;}static void PointSet2D_Draw(GF_Node *node, RenderEffect2D *eff){ GF_Path *path; Fixed alpha, w, h; u32 i; SFColor col; DrawableContext *ctx = eff->ctx; M_PointSet2D *ps2D = (M_PointSet2D *)node; M_Coordinate2D *coord = (M_Coordinate2D*) ps2D->coord; M_Color *color = (M_Color *) ps2D->color; /*never outline PS2D*/ ctx->flags |= CTX_PATH_STROKE; if (!color || color->color.count<coord->point.count) { /*no texturing*/ VS2D_DrawPath(eff->surface, ctx->drawable->path, ctx, NULL, NULL); return; } get_point_size(&ctx->transform, &w, &h); path = gf_path_new(); alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; for (i = 0; i < coord->point.count; i++) { col = color->color.vals[i]; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); gf_path_add_rect_center(path, coord->point.vals[i].x, coord->point.vals[i].y, w, h); VS2D_DrawPath(eff->surface, path, ctx, NULL, NULL); gf_path_reset(path); ctx->flags &= ~CTX_PATH_FILLED; } gf_path_del(path);}static void RenderPointSet2D(GF_Node *node, void *rs, Bool is_destroy){ DrawableContext *ctx; M_PointSet2D *ps2D = (M_PointSet2D *)node; Drawable *cs = (Drawable *)gf_node_get_private(node); RenderEffect2D *eff = (RenderEffect2D *)rs; if (is_destroy) { DestroyDrawableNode(node); return; } if (eff->traversing_mode==TRAVERSE_DRAW) { PointSet2D_Draw(node, eff); return; } else if (eff->traversing_mode==TRAVERSE_PICK) { return; } if (!ps2D->coord) return; if (gf_node_dirty_get(node)) { drawable_reset_path(cs); build_graph(cs, &eff->transform, ps2D); gf_node_dirty_clear(node, 0); cs->flags |= DRAWABLE_HAS_CHANGED; } ctx = drawable_init_context(cs, eff); if (!ctx) return; drawable_finalize_render(ctx, eff, NULL);}void R2D_InitPointSet2D(Render2D *sr, GF_Node *node){ drawable_stack_new(sr, node); gf_node_set_callback_function(node, RenderPointSet2D);}static void RenderPathExtrusion(GF_Node *node, void *rs, Bool is_destroy){ GF_FieldInfo field; GF_Node *geom; if (is_destroy) return; if (gf_node_get_field(node, 0, &field) != GF_OK) return; if (field.fieldType != GF_SG_VRML_SFNODE) return; geom = * (GF_Node **) field.far_ptr; if (geom) gf_node_render(geom, rs);}void R2D_InitPathExtrusion(Render2D *sr, GF_Node *node){ gf_node_set_callback_function(node, RenderPathExtrusion);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -