[vlc-devel] [PATCH 2/3] OpenGL: set the view frustum in function of the window size for 360 video

Adrien Maglo magsoft at videolan.org
Mon Nov 21 16:47:59 CET 2016


Previously, the frustum aspect ratio was set in function of the flat video
resolution, which is not related at all to the view frustum shape.
---
 modules/video_output/opengl.c | 53 +++++++++++++++++++++++++++++++++----------
 modules/video_output/opengl.h |  3 +++
 2 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/modules/video_output/opengl.c b/modules/video_output/opengl.c
index aefa63f..0cb67c4 100644
--- a/modules/video_output/opengl.c
+++ b/modules/video_output/opengl.c
@@ -212,6 +212,8 @@ struct vout_display_opengl_t {
     float f_fov;
     float f_zoom;
     float f_zoom_min;
+    float f_zoom_unscaled;
+    float f_sar;
 };
 
 static inline int GetAlignedSize(unsigned size)
@@ -788,6 +790,27 @@ void vout_display_opengl_Delete(vout_display_opengl_t *vgl)
     free(vgl);
 }
 
+
+static void UpdateZoom(vout_display_opengl_t *vgl)
+{
+    vgl->f_zoom = vgl->f_zoom_unscaled * (vgl->f_zoom_unscaled >= 0 ? 0.5 * SPHERE_RADIUS : vgl->f_zoom_min);
+}
+
+
+static void CalculateZoomMin(vout_display_opengl_t *vgl)
+{
+    /* Do trigonometry to calculate the minimal zoom value
+     * that will allow us to zoom out without seeing the outside of the
+     * sphere (black borders). */
+    float sar = vgl->f_sar;
+    float fovx = 2 * atanf(tanf(vgl->f_fov / 2) * sar);
+    float tan_fovx_2 = tanf(fovx / 2);
+    float tan_fovy_2 = tanf(vgl->f_fov / 2 );
+    vgl->f_zoom_min = SPHERE_RADIUS / sinf(atanf(sqrtf(
+                      tan_fovx_2 * tan_fovx_2 + tan_fovy_2 * tan_fovy_2)));
+}
+
+
 int vout_display_opengl_SetViewpoint(vout_display_opengl_t *vgl,
                                      const vlc_viewpoint_t *p_vp)
 {
@@ -803,24 +826,30 @@ int vout_display_opengl_SetViewpoint(vout_display_opengl_t *vgl,
 
     if (fabsf(f_fov - vgl->f_fov) >= 0.001f)
     {
-        /* The fov changed, do trigonometry to calculate the minimal zoom value
-         * that will allow us to zoom out without seeing the outside of the
-         * sphere (black borders). */
-        float sar = (float) vgl->fmt.i_visible_width / vgl->fmt.i_visible_height;
-        float fovx = 2 * atanf(tanf(f_fov / 2) * sar);
-        float tan_fovx_2 = tanf(fovx / 2);
-        float tan_fovy_2 = tanf(f_fov / 2 );
-        vgl->f_zoom_min = SPHERE_RADIUS / sinf(atanf(sqrtf(
-                          tan_fovx_2 * tan_fovx_2 + tan_fovy_2 * tan_fovy_2)));
+        vgl->f_fov  = f_fov;
+        CalculateZoomMin(vgl);
     }
 
-    vgl->f_fov  = f_fov;
-    vgl->f_zoom = p_vp->zoom * (p_vp->zoom >= 0 ? 0.5 * SPHERE_RADIUS : vgl->f_zoom_min);
+    vgl->f_zoom_unscaled = p_vp->zoom;
+    UpdateZoom(vgl);
 
     return VLC_SUCCESS;
 #undef RAD
 }
 
+
+void vout_display_opengl_SetWindowSize(vout_display_opengl_t *vgl,
+                                       unsigned i_win_width, unsigned i_win_height)
+{
+    /* Each time the window size changes, we must recompute the minimum zoom
+     * since the aspect ration changes.
+     * We must also set the new current zoom value. */
+    vgl->f_sar = (float)i_win_width / i_win_height;
+    CalculateZoomMin(vgl);
+    UpdateZoom(vgl);
+}
+
+
 picture_pool_t *vout_display_opengl_GetPool(vout_display_opengl_t *vgl, unsigned requested_count)
 {
     if (vgl->pool)
@@ -1601,7 +1630,7 @@ static void DrawWithShaders(vout_display_opengl_t *vgl,
     if (vgl->fmt.projection_mode == PROJECTION_MODE_EQUIRECTANGULAR
         || vgl->fmt.projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD)
     {
-        float sar = (float) vgl->fmt.i_visible_width / vgl->fmt.i_visible_height;
+        float sar = (float) vgl->f_sar;
         getProjectionMatrix(sar, vgl->f_fov, projectionMatrix);
         getYRotMatrix(vgl->f_teta, yRotMatrix);
         getXRotMatrix(vgl->f_phi, xRotMatrix);
diff --git a/modules/video_output/opengl.h b/modules/video_output/opengl.h
index 9aff95b..aa9ed51 100644
--- a/modules/video_output/opengl.h
+++ b/modules/video_output/opengl.h
@@ -99,6 +99,9 @@ picture_pool_t *vout_display_opengl_GetPool(vout_display_opengl_t *vgl, unsigned
 
 int vout_display_opengl_SetViewpoint(vout_display_opengl_t *vgl, const vlc_viewpoint_t*);
 
+void vout_display_opengl_SetWindowSize(vout_display_opengl_t *vgl,
+                                       unsigned i_win_width, unsigned i_win_height);
+
 int vout_display_opengl_Prepare(vout_display_opengl_t *vgl,
                                 picture_t *picture, subpicture_t *subpicture);
 int vout_display_opengl_Display(vout_display_opengl_t *vgl,
-- 
2.9.3



More information about the vlc-devel mailing list