LCOV - code coverage report
Current view: top level - compositor - compositor_3d.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 78 103 75.7 %
Date: 2021-04-29 23:48:07 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :  *                      GPAC - Multimedia Framework C SDK
       3             :  *
       4             :  *                      Authors: Jean Le Feuvre
       5             :  *                      Copyright (c) Telecom ParisTech 2000-2020
       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 "visual_manager.h"
      29             : #include "texturing.h"
      30             : #include "nodes_stacks.h"
      31             : #include <gpac/options.h>
      32             : 
      33             : #ifndef GPAC_DISABLE_3D
      34             : 
      35             : #ifdef GPAC_USE_TINYGL
      36             : #include <GL/oscontext.h>
      37             : #endif
      38             : 
      39         126 : GF_Err compositor_3d_set_aspect_ratio(GF_Compositor *compositor)
      40             : {
      41             :         GF_Event evt;
      42             :         Double ratio;
      43             :         Fixed scaleX, scaleY;
      44             : 
      45         126 :         if (!compositor->display_height || !compositor->display_width) return GF_OK;
      46             : 
      47         126 :         compositor->visual->camera.flags |= CAM_IS_DIRTY;
      48             : 
      49         126 :         compositor->output_width = compositor->vp_width = compositor->display_width;
      50         126 :         compositor->output_height = compositor->vp_height = compositor->display_height;
      51         126 :         compositor->vp_x = 0;
      52         126 :         compositor->vp_y = 0;
      53             : 
      54             :         scaleX = scaleY = FIX_ONE;
      55         126 :         if (!compositor->has_size_info || compositor->inherit_type_3d) {
      56          23 :                 compositor->visual->width = compositor->vp_width;
      57          23 :                 compositor->visual->height = compositor->vp_height;
      58             :         } else {
      59         103 :                 switch (compositor->aspect_ratio) {
      60             :                 case GF_ASPECT_RATIO_FILL_SCREEN:
      61             :                         break;
      62           0 :                 case GF_ASPECT_RATIO_16_9:
      63           0 :                         compositor->vp_height = 9 * compositor->vp_width  / 16;
      64           0 :                         break;
      65           0 :                 case GF_ASPECT_RATIO_4_3:
      66           0 :                         compositor->vp_height = 3 * compositor->vp_width / 4;
      67           0 :                         break;
      68         103 :                 default:
      69         103 :                         ratio = compositor->scene_height;
      70         103 :                         ratio /= compositor->scene_width;
      71         103 :                         if (compositor->vp_width * ratio > compositor->vp_height) {
      72           0 :                                 compositor->vp_width = compositor->vp_height * compositor->scene_width;
      73           0 :                                 compositor->vp_width /= compositor->scene_height;
      74             :                         }
      75             :                         else {
      76         103 :                                 compositor->vp_height = compositor->vp_width * compositor->scene_height;
      77         103 :                                 compositor->vp_height /= compositor->scene_width;
      78             :                         }
      79             :                         break;
      80             :                 }
      81         103 :                 compositor->vp_x = (compositor->display_width - compositor->vp_width) / 2;
      82         103 :                 compositor->vp_y = (compositor->display_height - compositor->vp_height) / 2;
      83             :                 /*update size info for main visual*/
      84         103 :                 if (compositor->visual) {
      85         103 :                         compositor->visual->width = compositor->scene_width;
      86         103 :                         compositor->visual->height = compositor->scene_height;
      87             :                 }
      88             :                 /*scaling is still needed for bitmap*/
      89         103 :                 scaleX = gf_divfix(INT2FIX(compositor->vp_width), INT2FIX(compositor->scene_width));
      90         103 :                 scaleY = gf_divfix(INT2FIX(compositor->vp_height), INT2FIX(compositor->scene_height));
      91             :         }
      92             : 
      93         126 :         if (compositor->has_size_info) {
      94         103 :                 compositor->traverse_state->vp_size.x = INT2FIX(compositor->scene_width);
      95         103 :                 compositor->traverse_state->vp_size.y = INT2FIX(compositor->scene_height);
      96             :         } else {
      97          23 :                 compositor->traverse_state->vp_size.x = INT2FIX(compositor->output_width);
      98          23 :                 compositor->traverse_state->vp_size.y = INT2FIX(compositor->output_height);
      99             :         }
     100         126 :         compositor_set_ar_scale(compositor, scaleX, scaleY);
     101             : 
     102             : 
     103             :         /*and resetup OpenGL*/
     104         126 :         evt.type = GF_EVENT_VIDEO_SETUP;
     105         126 :         evt.setup.width = compositor->display_width;
     106         126 :         evt.setup.height = compositor->display_height;
     107         126 :         evt.setup.back_buffer = GF_TRUE;
     108         126 :         evt.setup.disable_vsync = compositor->bench_mode ? GF_TRUE : GF_FALSE;
     109             : #ifdef GPAC_USE_TINYGL
     110             :         evt.setup.use_opengl = GF_FALSE;
     111             : #else
     112         126 :         evt.setup.use_opengl = GF_TRUE;
     113         126 :         compositor->is_opengl = GF_TRUE;
     114             : #endif
     115             : 
     116         126 :         if (compositor->video_out->ProcessEvent(compositor->video_out, &evt)<0) {
     117           0 :                 gf_sc_reset_graphics(compositor);
     118           0 :                 return GF_OK;
     119             :         }
     120         126 :         if (evt.setup.use_opengl) {
     121         125 :                 gf_opengl_init();
     122             :         }
     123             : 
     124             : #if defined(GPAC_USE_TINYGL)
     125             :         {
     126             :                 u32 bpp;
     127             :                 GF_VideoSurface bb;
     128             :                 GF_Err e = compositor->video_out->LockBackBuffer(compositor->video_out, &bb, 1);
     129             :                 if (e==GF_OK) {
     130             :                         switch (bb.pixel_format) {
     131             :                         case GF_PIXEL_RGBX:
     132             :                         case GF_PIXEL_ARGB:
     133             :                                 bpp = 32;
     134             :                                 break;
     135             :                         case GF_PIXEL_RGB:
     136             :                         case GF_PIXEL_BGR:
     137             :                                 bpp = 24;
     138             :                                 break;
     139             :                         case GF_PIXEL_RGB_565:
     140             :                         case GF_PIXEL_RGB_555:
     141             :                                 bpp = 16;
     142             :                                 break;
     143             :                         default:
     144             :                                 e = GF_NOT_SUPPORTED;
     145             :                                 bpp = 0;
     146             :                                 break;
     147             :                         }
     148             :                         if (e==GF_OK) {
     149             :                                 compositor->tgl_ctx = ostgl_create_context(bb.width, bb.height, bpp, &bb.video_buffer, 1);
     150             :                                 if (compositor->tgl_ctx) ostgl_make_current(compositor->tgl_ctx, 0);
     151             :                         }
     152             :                         compositor->video_out->LockBackBuffer(compositor->video_out, &bb, 0);
     153             :                 }
     154             :         }
     155             : #endif
     156             : 
     157             :         return GF_OK;
     158             : }
     159             : 
     160             : 
     161          19 : GF_Camera *compositor_3d_get_camera(GF_Compositor *compositor)
     162             : {
     163             : #ifndef GPAC_DISABLE_VRML
     164          21 :         if (compositor->active_layer) {
     165           0 :                 return compositor_layer3d_get_camera(compositor->active_layer);
     166             :         }
     167             : #endif
     168          21 :         if (compositor->visual->type_3d)
     169          20 :                 return &compositor->visual->camera;
     170             :         return NULL;
     171             : }
     172             : 
     173           2 : void compositor_3d_reset_camera(GF_Compositor *compositor)
     174             : {
     175             :         GF_Camera *cam = compositor_3d_get_camera(compositor);
     176           1 :         if (cam) {
     177           1 :                 camera_reset_viewpoint(cam, GF_TRUE);
     178           1 :                 gf_sc_invalidate(compositor, NULL);
     179             :         }
     180           2 :         if (compositor->active_layer) gf_node_dirty_set(compositor->active_layer, 0, GF_TRUE);
     181           2 : }
     182             : 
     183         771 : void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseState *tr_state, Fixed width, Fixed height, Fixed bmp_scale_x, Fixed bmp_scale_y)
     184             : {
     185             :         u8 alpha;
     186             :         GF_TextureHandler *txh;
     187         771 :         GF_Compositor *compositor = tr_state->visual->compositor;
     188             : 
     189         771 :         if (!asp->fill_texture)
     190             :                 return;
     191             :         txh = asp->fill_texture;
     192         635 :         if (!txh || !txh->tx_io || !txh->width || !txh->height)
     193             :                 return;
     194             : 
     195         619 :         if (((txh->pixelformat==GF_PIXEL_RGBD) || (txh->pixelformat==GF_PIXEL_YUVD))) {
     196           0 :                 if (compositor->depth_gl_type) {
     197           0 :                         if (txh->data && gf_sc_texture_convert(txh) )
     198           0 :                                 visual_3d_point_sprite(tr_state->visual, stack, txh, tr_state);
     199             :                         return;
     200             :                 }
     201             :         }
     202             : 
     203         619 :         alpha = GF_COL_A(asp->fill_color);
     204             :         /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/
     205         619 :         if (!alpha) alpha = GF_COL_A(asp->line_color);
     206             : 
     207         619 :         visual_3d_set_state(tr_state->visual, V3D_STATE_LIGHT, GF_FALSE);
     208         619 :         visual_3d_enable_antialias(tr_state->visual, GF_FALSE);
     209             : 
     210         619 :         visual_3d_set_material_2d_argb(tr_state->visual, GF_COL_ARGB(alpha, 0xFF, 0xFF, 0xFF));
     211             :                 
     212         619 :         if (alpha && (alpha != 0xFF)) {
     213         142 :                 gf_sc_texture_set_blend_mode(txh, TX_MODULATE);
     214         477 :         } else if (gf_sc_texture_is_transparent(txh)) {
     215           3 :                 gf_sc_texture_set_blend_mode(txh, TX_REPLACE);
     216             :         } else {
     217         474 :                 visual_3d_set_state(tr_state->visual, V3D_STATE_BLEND, GF_FALSE);
     218             :         }
     219             :         /*ignore texture transform for bitmap*/
     220         619 :         tr_state->mesh_num_textures = gf_sc_texture_enable(txh, NULL);
     221         619 :         if (tr_state->mesh_num_textures) {
     222             :                 /*we must check the w & h passed are correct because of bitmap node initialization*/
     223         619 :                 if (width && height) {
     224         619 :                         if (!stack->mesh) {
     225             :                                 SFVec2f size;
     226          17 :                                 size.x = width;
     227          17 :                                 size.y = height;
     228             : 
     229          17 :                                 stack->mesh = new_mesh();
     230          17 :                                 mesh_new_rectangle(stack->mesh, size, NULL, GF_FALSE);
     231             :                         }
     232             :                 }
     233         619 :                 if (stack->mesh) {
     234             : #ifdef GF_SR_USE_DEPTH
     235         619 :                         if (tr_state->depth_offset) {
     236             :                                 GF_Matrix mx;
     237             :                                 Fixed offset;
     238           0 :                                 Fixed disp_depth = (compositor->dispdepth<0) ? INT2FIX(tr_state->visual->height) : INT2FIX(compositor->dispdepth);
     239           0 :                                 if (disp_depth) {
     240             :                                         GF_Matrix bck_mx;
     241           0 :                                         if (!tr_state->pixel_metrics) disp_depth = gf_divfix(disp_depth, tr_state->min_hsize);
     242           0 :                                         gf_mx_init(mx);
     243             :                                         /*add recalibration by the scene*/
     244             :                                         offset = tr_state->depth_offset;
     245           0 :                                         if (tr_state->visual->depth_vp_range) {
     246           0 :                                                 offset = gf_divfix(offset, tr_state->visual->depth_vp_range/2);
     247             :                                         }
     248           0 :                                         gf_mx_add_translation(&mx, 0, 0, gf_mulfix(offset, disp_depth/2) );
     249             : 
     250           0 :                                         gf_mx_copy(bck_mx, tr_state->model_matrix);
     251           0 :                                         gf_mx_add_matrix(&tr_state->model_matrix, &mx);
     252           0 :                                         visual_3d_mesh_paint(tr_state, stack->mesh);
     253             :                                         gf_mx_copy(tr_state->model_matrix, bck_mx);
     254             :                                 } else {
     255           0 :                                         visual_3d_mesh_paint(tr_state, stack->mesh);
     256             :                                 }
     257             :                         } else
     258             : #endif
     259         619 :                                 visual_3d_mesh_paint(tr_state, stack->mesh);
     260             :                 }
     261         619 :                 gf_sc_texture_disable(txh);
     262         619 :                 tr_state->mesh_num_textures = 0;
     263             :         }
     264             : }
     265             : 
     266             : #endif
     267             : 

Generated by: LCOV version 1.13