[vlc-commits] d3d11: support cubemap projection for 360 video

Adrien Maglo git at videolan.org
Mon Mar 19 13:36:06 CET 2018


vlc/vlc-3.0 | branch: master | Adrien Maglo <magsoft at videolan.org> | Thu Feb 15 16:57:44 2018 +0100| [1214fb41e8a5b542451458801443225f0efe85fc] | committer: Steve Lhomme

d3d11: support cubemap projection for 360 video

Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>
(cherry picked from commit 6d57f6cc5fe976d40606188152bbbfe96e21bbe8)

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=1214fb41e8a5b542451458801443225f0efe85fc
---

 modules/video_output/win32/direct3d11.c | 136 +++++++++++++++++++++++++++++---
 1 file changed, 125 insertions(+), 11 deletions(-)

diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index f61bfc9d56..9bf9e56bd8 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -2527,24 +2527,126 @@ static void SetupQuadSphere(d3d_vertex_t *dst_data, const RECT *output,
     }
 }
 
+
+static void SetupQuadCube(d3d_vertex_t *dst_data, const RECT *output,
+                          const d3d_quad_t *quad, WORD *triangle_pos)
+{
+    static const float coord[] = {
+        -1.0,    1.0,    -1.0f, // front
+        -1.0,    -1.0,   -1.0f,
+        1.0,     1.0,    -1.0f,
+        1.0,     -1.0,   -1.0f,
+
+        -1.0,    1.0,    1.0f, // back
+        -1.0,    -1.0,   1.0f,
+        1.0,     1.0,    1.0f,
+        1.0,     -1.0,   1.0f,
+
+        -1.0,    1.0,    -1.0f, // left
+        -1.0,    -1.0,   -1.0f,
+        -1.0,     1.0,    1.0f,
+        -1.0,     -1.0,   1.0f,
+
+        1.0f,    1.0,    -1.0f, // right
+        1.0f,   -1.0,    -1.0f,
+        1.0f,   1.0,     1.0f,
+        1.0f,   -1.0,    1.0f,
+
+        -1.0,    -1.0,    1.0f, // bottom
+        -1.0,    -1.0,   -1.0f,
+        1.0,     -1.0,    1.0f,
+        1.0,     -1.0,   -1.0f,
+
+        -1.0,    1.0,    1.0f, // top
+        -1.0,    1.0,   -1.0f,
+        1.0,     1.0,    1.0f,
+        1.0,     1.0,   -1.0f,
+    };
+
+    const float scaleX = (float)(output->right - output->left) / quad->i_width;
+    const float scaleY = (float)(output->bottom - output->top) / quad->i_height;
+
+    const float col[] = {0.f, scaleX / 3, scaleX * 2 / 3, scaleX};
+    const float row[] = {0.f, scaleY / 2, scaleY};
+
+    const float tex[] = {
+        col[1], row[1], // front
+        col[1], row[2],
+        col[2], row[1],
+        col[2], row[2],
+
+        col[3], row[1], // back
+        col[3], row[2],
+        col[2], row[1],
+        col[2], row[2],
+
+        col[2], row[0], // left
+        col[2], row[1],
+        col[1], row[0],
+        col[1], row[1],
+
+        col[0], row[0], // right
+        col[0], row[1],
+        col[1], row[0],
+        col[1], row[1],
+
+        col[0], row[2], // bottom
+        col[0], row[1],
+        col[1], row[2],
+        col[1], row[1],
+
+        col[2], row[0], // top
+        col[2], row[1],
+        col[3], row[0],
+        col[3], row[1],
+    };
+
+    const unsigned i_nbVertices = ARRAY_SIZE(coord) / 3;
+
+    for (unsigned v = 0; v < i_nbVertices; ++v)
+    {
+        dst_data[v].position.x = coord[3 * v];
+        dst_data[v].position.y = coord[3 * v + 1];
+        dst_data[v].position.z = coord[3 * v + 2];
+
+        dst_data[v].texture.x = tex[2 * v];
+        dst_data[v].texture.y = tex[2 * v + 1];
+    }
+
+    const WORD ind[] = {
+        2, 1, 0,       3, 1, 2, // front
+        4, 7, 6,       5, 7, 4, // back
+        8, 11, 10,     9, 11, 8, // left
+        14, 13, 12,    15, 13, 14, // right
+        16, 19, 18,    17, 19, 16, // bottom
+        22, 21, 20,    23, 21, 22, // top
+    };
+
+    memcpy(triangle_pos, ind, sizeof(ind));
+}
+
+
 static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad,
                               video_projection_mode_t projection)
 {
     HRESULT hr;
     vout_display_sys_t *sys = vd->sys;
 
-    if (projection == PROJECTION_MODE_RECTANGULAR)
+    switch (projection)
     {
+    case PROJECTION_MODE_RECTANGULAR:
         quad->vertexCount = 4;
         quad->indexCount = 2 * 3;
-    }
-    else if (projection == PROJECTION_MODE_EQUIRECTANGULAR)
-    {
-        quad->vertexCount = (SPHERE_SLICES+1) * (SPHERE_SLICES+1);
+        break;
+    case PROJECTION_MODE_EQUIRECTANGULAR:
+        quad->vertexCount = (SPHERE_SLICES + 1) * (SPHERE_SLICES + 1);
         quad->indexCount = nbLatBands * nbLonBands * 2 * 3;
-    }
-    else
-    {
+        break;
+    case PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD:
+        quad->vertexCount = 4 * 6;
+        quad->indexCount = 6 * 2 * 3;
+        break;
+    default:
         msg_Warn(vd, "Projection mode %d not handled", projection);
         return false;
     }
@@ -2610,10 +2712,21 @@ static bool UpdateQuadPosition( vout_display_t *vd, d3d_quad_t *quad,
     }
     WORD *triangle_pos = mappedResource.pData;
 
-    if ( projection == PROJECTION_MODE_RECTANGULAR )
+    switch (projection)
+    {
+    case PROJECTION_MODE_RECTANGULAR:
         SetupQuadFlat(dst_data, output, quad, triangle_pos, orientation);
-    else
+        break;
+    case PROJECTION_MODE_EQUIRECTANGULAR:
         SetupQuadSphere(dst_data, output, quad, triangle_pos);
+        break;
+    case PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD:
+        SetupQuadCube(dst_data, output, quad, triangle_pos);
+        break;
+    default:
+        msg_Warn(vd, "Projection mode %d not handled", projection);
+        return false;
+    }
 
     ID3D11DeviceContext_Unmap(sys->d3d_dev.d3dcontext, (ID3D11Resource *)quad->pIndexBuffer, 0);
     ID3D11DeviceContext_Unmap(sys->d3d_dev.d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0);
@@ -2762,7 +2875,8 @@ static int SetupQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
     quad->PSConstantsCount = 2;
 
     /* vertex shader constant buffer */
-    if ( projection == PROJECTION_MODE_EQUIRECTANGULAR )
+    if (projection == PROJECTION_MODE_EQUIRECTANGULAR
+        || projection == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD)
     {
         constantDesc.ByteWidth = sizeof(VS_PROJECTION_CONST);
         static_assert((sizeof(VS_PROJECTION_CONST)%16)==0,"Constant buffers require 16-byte alignment");



More information about the vlc-commits mailing list