[vlc-commits] direct3d11: display equirectangle sources in a sphere
Steve Lhomme
git at videolan.org
Tue Nov 22 21:40:27 CET 2016
vlc | branch: master | Steve Lhomme <robUx4 at videolabs.io> | Tue Nov 22 11:59:40 2016 +0100| [a12906dc5d8632d2e78dcf1b5a31dc47bdc6b9d1] | committer: Jean-Baptiste Kempf
direct3d11: display equirectangle sources in a sphere
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a12906dc5d8632d2e78dcf1b5a31dc47bdc6b9d1
---
modules/video_output/win32/direct3d11.c | 88 +++++++++++++++++++++++++++++----
1 file changed, 78 insertions(+), 10 deletions(-)
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 1d912c5..e6ec5ad 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -152,7 +152,8 @@ static void Direct3D11DeleteRegions(int, picture_t **);
static int Direct3D11MapSubpicture(vout_display_t *, int *, picture_t ***, subpicture_t *);
static int AllocQuad(vout_display_t *, const video_format_t *, d3d_quad_t *,
- d3d_quad_cfg_t *, ID3D11PixelShader *, bool b_visible);
+ d3d_quad_cfg_t *, ID3D11PixelShader *, bool b_visible,
+ video_projection_mode_t);
static void ReleaseQuad(d3d_quad_t *);
static void UpdatePicQuadPosition(vout_display_t *);
static void UpdateQuadOpacity(vout_display_t *, const d3d_quad_t *, float);
@@ -1364,7 +1365,8 @@ static int Direct3D11Open(vout_display_t *vd, video_format_t *fmt)
if ( fmt->i_height != fmt->i_visible_height || fmt->i_width != fmt->i_visible_width )
{
msg_Dbg( vd, "use a staging texture to crop to visible size" );
- AllocQuad( vd, fmt, &sys->stagingQuad, &sys->picQuadConfig, NULL, false );
+ AllocQuad( vd, fmt, &sys->stagingQuad, &sys->picQuadConfig, NULL, false,
+ PROJECTION_MODE_RECTANGULAR );
}
video_format_t core_source;
@@ -1602,7 +1604,8 @@ static int Direct3D11CreateResources(vout_display_t *vd, video_format_t *fmt)
}
}
- if (AllocQuad( vd, fmt, &sys->picQuad, &sys->picQuadConfig, pPicQuadShader, true) != VLC_SUCCESS) {
+ if (AllocQuad( vd, fmt, &sys->picQuad, &sys->picQuadConfig, pPicQuadShader,
+ true, vd->fmt.projection_mode) != VLC_SUCCESS) {
ID3D11PixelShader_Release(pPicQuadShader);
msg_Err(vd, "Could not Create the main quad picture. (hr=0x%lX)", hr);
return VLC_EGENERIC;
@@ -1744,14 +1747,74 @@ static void SetupQuadFlat(d3d_vertex_t *dst_data, WORD *triangle_pos)
triangle_pos[5] = 3;
}
-static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad)
+#define SPHERE_SLICES 128
+#define nbLatBands SPHERE_SLICES
+#define nbLonBands SPHERE_SLICES
+
+static void SetupQuadSphere(d3d_vertex_t *dst_data, WORD *triangle_pos)
+{
+ for (unsigned lat = 0; lat <= nbLatBands; lat++) {
+ float theta = lat * (float) M_PI / nbLatBands;
+ float sinTheta, cosTheta;
+
+ sincosf(theta, &sinTheta, &cosTheta);
+
+ for (unsigned lon = 0; lon <= nbLonBands; lon++) {
+ float phi = lon * 2 * (float) M_PI / nbLonBands;
+ float sinPhi, cosPhi;
+
+ sincosf(phi, &sinPhi, &cosPhi);
+
+ float x = cosPhi * sinTheta;
+ float y = cosTheta;
+ float z = sinPhi * sinTheta;
+
+ unsigned off1 = lat * (nbLonBands + 1) + lon;
+ dst_data[off1].position.x = SPHERE_RADIUS * x;
+ dst_data[off1].position.y = SPHERE_RADIUS * y;
+ dst_data[off1].position.z = SPHERE_RADIUS * z;
+
+ dst_data[off1].texture.x = lon / (float) nbLonBands; // 0(left) to 1(right)
+ dst_data[off1].texture.y = lat / (float) nbLatBands; // 0(top) to 1 (bottom)
+ }
+ }
+
+ for (unsigned lat = 0; lat < nbLatBands; lat++) {
+ for (unsigned lon = 0; lon < nbLonBands; lon++) {
+ unsigned first = (lat * (nbLonBands + 1)) + lon;
+ unsigned second = first + nbLonBands + 1;
+
+ unsigned off = (lat * nbLatBands + lon) * 3 * 2;
+
+ triangle_pos[off] = first;
+ triangle_pos[off + 1] = second;
+ triangle_pos[off + 2] = first + 1;
+
+ triangle_pos[off + 3] = second;
+ triangle_pos[off + 4] = second + 1;
+ triangle_pos[off + 5] = first + 1;
+ }
+ }
+}
+
+static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad, video_projection_mode_t projection)
{
HRESULT hr;
D3D11_MAPPED_SUBRESOURCE mappedResource;
vout_display_sys_t *sys = vd->sys;
- quad->vertexCount = 4;
- quad->indexCount = 2 * 3;
+ if (projection == PROJECTION_MODE_RECTANGULAR)
+ {
+ quad->vertexCount = 4;
+ quad->indexCount = 2 * 3;
+ }
+ else if (projection == PROJECTION_MODE_EQUIRECTANGULAR)
+ {
+ quad->vertexCount = (SPHERE_SLICES+1) * (SPHERE_SLICES+1);
+ quad->indexCount = nbLatBands * nbLonBands * 2 * 3;
+ }
+ else
+ return false;
D3D11_BUFFER_DESC bd;
memset(&bd, 0, sizeof(bd));
@@ -1797,7 +1860,10 @@ static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad)
}
WORD *triangle_pos = mappedResource.pData;
- SetupQuadFlat(dst_data, triangle_pos);
+ if ( projection == PROJECTION_MODE_RECTANGULAR )
+ SetupQuadFlat(dst_data, triangle_pos);
+ else
+ SetupQuadSphere(dst_data, triangle_pos);
ID3D11DeviceContext_Unmap(sys->d3dcontext, (ID3D11Resource *)quad->pIndexBuffer, 0);
ID3D11DeviceContext_Unmap(sys->d3dcontext, (ID3D11Resource *)quad->pVertexBuffer, 0);
@@ -1806,7 +1872,8 @@ static bool AllocQuadVertices(vout_display_t *vd, d3d_quad_t *quad)
}
static int AllocQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *quad,
- d3d_quad_cfg_t *cfg, ID3D11PixelShader *d3dpixelShader, bool b_visible)
+ d3d_quad_cfg_t *cfg, ID3D11PixelShader *d3dpixelShader, bool b_visible,
+ video_projection_mode_t projection)
{
vout_display_sys_t *sys = vd->sys;
D3D11_MAPPED_SUBRESOURCE mappedResource;
@@ -1903,7 +1970,7 @@ static int AllocQuad(vout_display_t *vd, const video_format_t *fmt, d3d_quad_t *
if ( d3dpixelShader != NULL )
{
- if ( !AllocQuadVertices( vd, quad ) )
+ if (!AllocQuadVertices(vd, quad, projection))
goto error;
quad->d3dvertexShader = sys->flatVSShader;
@@ -2103,7 +2170,8 @@ static int Direct3D11MapSubpicture(vout_display_t *vd, int *subpicture_region_co
.textureFormat = sys->d3dregion_format,
.resourceFormatYRGB = sys->d3dregion_format,
};
- err = AllocQuad(vd, &r->fmt, d3dquad, &rgbaCfg, sys->pSPUPixelShader, false);
+ err = AllocQuad( vd, &r->fmt, d3dquad, &rgbaCfg, sys->pSPUPixelShader,
+ false, PROJECTION_MODE_RECTANGULAR );
if (err != VLC_SUCCESS) {
msg_Err(vd, "Failed to create %dx%d texture for OSD",
r->fmt.i_visible_width, r->fmt.i_visible_height);
More information about the vlc-commits
mailing list