LCOV - code coverage report
Current view: top level - compositor - mpeg4_geometry_ils2d.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 111 150 74.0 %
Date: 2021-04-29 23:48:07 Functions: 4 6 66.7 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2012
       6             :  *                                      All rights reserved
       7             :  *
       8             :  *  This file is part of GPAC / Scene Compositor sub-project
       9             :  *
      10             :  *  GPAC is free software; you can redistribute it and/or modify
      11             :  *  it under the terms of the GNU Lesser General Public License as published by
      12             :  *  the Free Software Foundation; either version 2, or (at your option)
      13             :  *  any later version.
      14             :  *
      15             :  *  GPAC is distributed in the hope that it will be useful,
      16             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :  *  GNU Lesser General Public License for more details.
      19             :  *
      20             :  *  You should have received a copy of the GNU Lesser General Public
      21             :  *  License along with this library; see the file COPYING.  If not, write to
      22             :  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
      23             :  *
      24             :  */
      25             : 
      26             : 
      27             : 
      28             : #include "nodes_stacks.h"
      29             : #include "visual_manager.h"
      30             : 
      31             : #ifndef GPAC_DISABLE_VRML
      32             : 
      33        2338 : static void ils2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state)
      34             : {
      35             :         u32 i;
      36             :         Bool started;
      37             :         SFVec2f *pts;
      38             :         M_IndexedLineSet2D *ils2D;
      39             :         M_Coordinate2D *coord;
      40             : 
      41        2338 :         if (! gf_node_dirty_get(node)) return;
      42             : 
      43          49 :         drawable_reset_path(stack);
      44          49 :         gf_node_dirty_clear(node, 0);
      45          49 :         drawable_mark_modified(stack, tr_state);
      46             : 
      47             :         ils2D = (M_IndexedLineSet2D *)node;
      48          49 :         coord = (M_Coordinate2D *)ils2D->coord;
      49             : 
      50          49 :         pts = coord->point.vals;
      51          49 :         if (ils2D->coordIndex.count > 0) {
      52             :                 started = 0;
      53          99 :                 for (i=0; i < ils2D->coordIndex.count; i++) {
      54             :                         /*NO close on ILS2D*/
      55          99 :                         if (ils2D->coordIndex.vals[i] == -1) {
      56             :                                 started = 0;
      57          72 :                         } else if (!started) {
      58             :                                 started = 1;
      59          30 :                                 gf_path_add_move_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
      60             :                         } else {
      61          42 :                                 gf_path_add_line_to(stack->path, pts[ils2D->coordIndex.vals[i]].x, pts[ils2D->coordIndex.vals[i]].y);
      62             :                         }
      63             :                 }
      64          36 :         } else if (coord->point.count) {
      65          36 :                 gf_path_add_move_to(stack->path, pts[0].x, pts[0].y);
      66          95 :                 for (i=1; i < coord->point.count; i++) {
      67          59 :                         gf_path_add_line_to(stack->path, pts[i].x, pts[i].y);
      68             :                 }
      69             :         }
      70          49 :         stack->path->flags |= GF_PATH_FILL_ZERO_NONZERO;
      71             : }
      72             : 
      73         898 : static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state)
      74             : {
      75             :         GF_Path *path;
      76             :         SFVec2f *pts;
      77             :         SFColor col;
      78             :         Fixed alpha;
      79             :         u32 i, count, col_ind, ind, end_at;
      80             :         u32 linear[2];
      81             : #if 0 //unused
      82             :         u32 *colors, j;
      83             : #endif
      84             :         SFVec2f start, end;
      85             :         u32 num_col;
      86             :         GF_EVGStencil *grad;
      87         898 :         DrawableContext *ctx = tr_state->ctx;
      88             :         M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
      89         898 :         M_Coordinate2D *coord = (M_Coordinate2D*) ils2D->coord;
      90         898 :         M_Color *color = (M_Color *) ils2D->color;
      91             : 
      92             :         end.x = end.y = 0;
      93        1794 :         if (!coord->point.count) return;
      94             : 
      95         898 :         if (! ils2D->color) {
      96             :                 /*no texturing*/
      97         894 :                 visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state);
      98         894 :                 return;
      99             :         }
     100             : 
     101           4 :         alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255;
     102           4 :         pts = coord->point.vals;
     103             : 
     104           4 :         if (!ils2D->colorPerVertex || (color->color.count<2) ) {
     105             :                 count = 0;
     106           2 :                 end_at = ils2D->coordIndex.count;
     107           2 :                 if (!end_at) end_at = coord->point.count;
     108           2 :                 ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[0] : 0;
     109             :                 i=1;
     110           2 :                 path = gf_path_new();
     111           2 :                 gf_path_add_move_to(path, pts[ind].x, pts[ind].y);
     112             : 
     113          16 :                 for (; i<=end_at; i++) {
     114          16 :                         if ((i==end_at) || (ils2D->coordIndex.count && ils2D->coordIndex.vals[i] == -1)) {
     115             : 
     116             :                                 /*draw current*/
     117           4 :                                 col_ind = (ils2D->colorIndex.count && (ils2D->colorIndex.vals[count]>=0) ) ? (u32) ils2D->colorIndex.vals[count] : count;
     118           4 :                                 if (col_ind>=color->color.count) col_ind=color->color.count-1;
     119           4 :                                 col = color->color.vals[col_ind];
     120           4 :                                 ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     121             : 
     122           4 :                                 visual_2d_draw_path(tr_state->visual, path, ctx, NULL, NULL, tr_state);
     123             : 
     124           4 :                                 i++;
     125           4 :                                 if (i>=end_at) break;
     126           2 :                                 gf_path_reset(path);
     127             : 
     128           2 :                                 ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i;
     129           2 :                                 gf_path_add_move_to(path, pts[ind].x, pts[ind].y);
     130             : 
     131           2 :                                 if (ils2D->coordIndex.count) count++;
     132           2 :                                 continue;
     133             :                         } else {
     134          12 :                                 ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0) ) ? (u32) ils2D->coordIndex.vals[i] : i;
     135          12 :                                 gf_path_add_line_to(path, pts[ind].x, pts[ind].y);
     136             :                         }
     137             :                 }
     138           2 :                 gf_path_del(path);
     139           2 :                 return;
     140             :         }
     141             : 
     142           2 :         end_at = ils2D->coordIndex.count;
     143           2 :         if (!end_at) end_at = coord->point.count;
     144             : 
     145             :         col_ind = 0;
     146             :         i=0;
     147           2 :         path = gf_path_new();
     148             :         while (1) {
     149           6 :                 gf_path_reset(path);
     150           4 :                 ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i;
     151           4 :                 start = pts[ind];
     152             :                 num_col = 1;
     153           4 :                 i++;
     154           4 :                 gf_path_add_move_to(path, start.x, start.y);
     155             : 
     156           4 :                 if (ils2D->coordIndex.count) {
     157          14 :                         while (ils2D->coordIndex.vals[i] != -1) {
     158          12 :                                 end = pts[ils2D->coordIndex.vals[i]];
     159          12 :                                 gf_path_add_line_to(path, end.x, end.y);
     160          12 :                                 i++;
     161          12 :                                 num_col++;
     162          12 :                                 if (i >= ils2D->coordIndex.count) break;
     163             :                         }
     164             :                 } else {
     165           0 :                         while (i<end_at) {
     166           0 :                                 end = pts[i];
     167           0 :                                 gf_path_add_line_to(path, end.x, end.y);
     168           0 :                                 i++;
     169           0 :                                 num_col++;
     170             :                         }
     171             :                 }
     172             : 
     173             :                 /*use linear gradient*/
     174           4 :                 if (num_col==2) {
     175             :                         Fixed pos[2];
     176           0 :                         grad = gf_evg_stencil_new(GF_STENCIL_LINEAR_GRADIENT);
     177           0 :                         if (ils2D->colorIndex.count) {
     178           0 :                                 col = color->color.vals[ils2D->colorIndex.vals[col_ind]];
     179           0 :                                 linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     180           0 :                                 col = color->color.vals[ils2D->colorIndex.vals[col_ind+1]];
     181           0 :                                 linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     182           0 :                         } else if (ils2D->coordIndex.count) {
     183           0 :                                 col = color->color.vals[ils2D->coordIndex.vals[col_ind]];
     184           0 :                                 linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     185           0 :                                 col = color->color.vals[ils2D->coordIndex.vals[col_ind+1]];
     186           0 :                                 linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     187             :                         } else {
     188           0 :                                 col = color->color.vals[col_ind];
     189           0 :                                 linear[0] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     190           0 :                                 col = color->color.vals[col_ind+1];
     191           0 :                                 linear[1] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     192             :                         }
     193           0 :                         pos[0] = 0;
     194           0 :                         pos[1] = FIX_ONE;
     195           0 :                         gf_evg_stencil_set_linear_gradient(grad, start.x, start.y, end.x, end.y);
     196           0 :                         gf_evg_stencil_set_gradient_interpolation(grad, pos, linear, 2);
     197             :                 } else {
     198             :             grad = NULL;
     199             : #if 0 //unused
     200             :                         grad = gf_evg_stencil_new(GF_STENCIL_VERTEX_GRADIENT);
     201             :                         if (grad) {
     202             :                                 gf_evg_stencil_set_vertex_path(grad, path);
     203             : 
     204             :                                 colors = (u32*)gf_malloc(sizeof(u32) * num_col);
     205             :                                 for (j=0; j<num_col; j++) {
     206             :                                         if (ils2D->colorIndex.count>0) {
     207             :                                                 col = color->color.vals[ils2D->colorIndex.vals[col_ind+j]];
     208             :                                         } else if (ils2D->coordIndex.count) {
     209             :                                                 col = color->color.vals[ils2D->coordIndex.vals[col_ind+j]];
     210             :                                         } else {
     211             :                                                 col = color->color.vals[col_ind+j];
     212             :                                         }
     213             :                                         colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue);
     214             :                                 }
     215             :                                 gf_evg_stencil_set_vertex_colors(grad, colors, num_col);
     216             :                                 gf_free(colors);
     217             :                         }
     218             : #endif
     219             : 
     220             :                 }
     221           4 :                 gf_evg_stencil_set_matrix(grad, &ctx->transform);
     222           4 :                 visual_2d_draw_path(tr_state->visual, path, ctx, NULL, grad, tr_state);
     223           4 :                 if (grad) gf_evg_stencil_delete(grad);
     224             : 
     225           4 :                 i ++;
     226           4 :                 col_ind += num_col + 1;
     227           4 :                 if (i >= ils2D->coordIndex.count) break;
     228           2 :                 ctx->flags &= ~CTX_PATH_STROKE;
     229             :         }
     230           2 :         gf_path_del(path);
     231             : }
     232             : 
     233             : 
     234        2387 : static void TraverseILS2D(GF_Node *node, void *rs, Bool is_destroy)
     235             : {
     236             :         DrawableContext *ctx;
     237             :         M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
     238        2387 :         Drawable *stack = (Drawable *)gf_node_get_private(node);
     239             :         GF_TraverseState *tr_state = (GF_TraverseState *)rs;
     240             : 
     241        2387 :         if (is_destroy) {
     242          49 :                 drawable_node_del(node);
     243          49 :                 return;
     244             :         }
     245             : 
     246        2338 :         if (!ils2D->coord) return;
     247             : 
     248        2338 :         ils2d_check_changes(node, stack, tr_state);
     249             : 
     250        2338 :         switch (tr_state->traversing_mode) {
     251         898 :         case TRAVERSE_DRAW_2D:
     252         898 :                 ILS2D_Draw(node, tr_state);
     253         898 :                 return;
     254             : #ifndef GPAC_DISABLE_3D
     255         164 :         case TRAVERSE_DRAW_3D:
     256         164 :                 if (!stack->mesh) {
     257          13 :                         stack->mesh = new_mesh();
     258          13 :                         mesh_new_ils(stack->mesh, ils2D->coord, &ils2D->coordIndex, ils2D->color, &ils2D->colorIndex, ils2D->colorPerVertex, 0);
     259             :                 }
     260         164 :                 if (ils2D->color) {
     261             :                         DrawAspect2D asp;
     262             :                         memset(&asp, 0, sizeof(DrawAspect2D));
     263           0 :                         drawable_get_aspect_2d_mpeg4(node, &asp, tr_state);
     264             : 
     265           0 :                         visual_3d_mesh_strike(tr_state, stack->mesh, asp.pen_props.width, asp.line_scale, asp.pen_props.dash);
     266             :                 } else {
     267         164 :                         visual_3d_draw_2d(stack, tr_state);
     268             :                 }
     269             :                 return;
     270             : #endif
     271         372 :         case TRAVERSE_PICK:
     272         372 :                 vrml_drawable_pick(stack, tr_state);
     273         372 :                 return;
     274           0 :         case TRAVERSE_GET_BOUNDS:
     275           0 :                 gf_path_get_bounds(stack->path, &tr_state->bounds);
     276           0 :                 return;
     277         904 :         case TRAVERSE_SORT:
     278             : #ifndef GPAC_DISABLE_3D
     279         904 :                 if (tr_state->visual->type_3d) return;
     280             : #endif
     281             : 
     282         904 :                 ctx = drawable_init_context_mpeg4(stack, tr_state);
     283         904 :                 if (!ctx) return;
     284             :                 /*ILS2D are NEVER filled*/
     285         904 :                 ctx->aspect.fill_color &= 0x00FFFFFF;
     286         904 :                 drawable_finalize_sort(ctx, tr_state, NULL);
     287         904 :                 return;
     288             :         default:
     289             :                 return;
     290             :         }
     291             : }
     292             : 
     293           0 : static void ILS2D_SetColorIndex(GF_Node *node, GF_Route *route)
     294             : {
     295             :         M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
     296           0 :         if (node) {
     297           0 :                 gf_sg_vrml_field_copy(&ils2D->colorIndex, &ils2D->set_colorIndex, GF_SG_VRML_MFINT32);
     298           0 :                 gf_sg_vrml_mf_reset(&ils2D->set_colorIndex, GF_SG_VRML_MFINT32);
     299             :         }
     300           0 : }
     301             : 
     302           0 : static void ILS2D_SetCoordIndex(GF_Node *node, GF_Route *route)
     303             : {
     304             :         M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
     305           0 :         if (node) {
     306           0 :                 gf_sg_vrml_field_copy(&ils2D->coordIndex, &ils2D->set_coordIndex, GF_SG_VRML_MFINT32);
     307           0 :                 gf_sg_vrml_mf_reset(&ils2D->set_coordIndex, GF_SG_VRML_MFINT32);
     308             :         }
     309           0 : }
     310             : 
     311          49 : void compositor_init_indexed_line_set2d(GF_Compositor *compositor, GF_Node *node)
     312             : {
     313             :         M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
     314          49 :         Drawable *stack = drawable_stack_new(compositor, node);
     315          49 :         stack->flags = DRAWABLE_USE_TRAVERSE_DRAW;
     316          49 :         gf_node_set_callback_function(node, TraverseILS2D);
     317          49 :         ils2D->on_set_colorIndex = ILS2D_SetColorIndex;
     318          49 :         ils2D->on_set_coordIndex = ILS2D_SetCoordIndex;
     319             : 
     320             : #ifdef GPAC_ENABLE_COVERAGE
     321          49 :         if (gf_sys_is_cov_mode()) {
     322             :                 ILS2D_SetCoordIndex(NULL, NULL);
     323             :                 ILS2D_SetColorIndex(NULL, NULL);
     324             :         }
     325             : #endif
     326             : 
     327          49 : }
     328             : 
     329             : #endif /*GPAC_DISABLE_VRML*/

Generated by: LCOV version 1.13