[vlc-commits] direct3d11: move the viewpoint update in d3d11_quad
Steve Lhomme
git at videolan.org
Tue Sep 1 12:06:17 CEST 2020
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Mon Aug 31 14:01:58 2020 +0200| [4c47775ffae62276afea1df45bbec4ffdab7c19a] | committer: Steve Lhomme
direct3d11: move the viewpoint update in d3d11_quad
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4c47775ffae62276afea1df45bbec4ffdab7c19a
---
modules/video_output/win32/d3d11_quad.c | 91 +++++++++++++++++++++++++++
modules/video_output/win32/d3d11_quad.h | 3 +
modules/video_output/win32/direct3d11.c | 106 +++-----------------------------
3 files changed, 102 insertions(+), 98 deletions(-)
diff --git a/modules/video_output/win32/d3d11_quad.c b/modules/video_output/win32/d3d11_quad.c
index f5d2bc285b..36abdfec86 100644
--- a/modules/video_output/win32/d3d11_quad.c
+++ b/modules/video_output/win32/d3d11_quad.c
@@ -640,6 +640,97 @@ void D3D11_UpdateQuadLuminanceScale(vlc_object_t *o, d3d11_device_t *d3d_dev, d3
quad->shaderConstants.LuminanceScale = old;
}
+
+static void getZoomMatrix(float zoom, FLOAT matrix[static 16]) {
+
+ const FLOAT m[] = {
+ /* x y z w */
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, zoom, 1.0f
+ };
+
+ memcpy(matrix, m, sizeof(m));
+}
+
+/* perspective matrix see https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml */
+static void getProjectionMatrix(float sar, float fovy, FLOAT matrix[static 16]) {
+
+ float zFar = 1000;
+ float zNear = 0.01;
+
+ float f = 1.f / tanf(fovy / 2.f);
+
+ const FLOAT m[] = {
+ f / sar, 0.f, 0.f, 0.f,
+ 0.f, f, 0.f, 0.f,
+ 0.f, 0.f, (zNear + zFar) / (zNear - zFar), -1.f,
+ 0.f, 0.f, (2 * zNear * zFar) / (zNear - zFar), 0.f};
+
+ memcpy(matrix, m, sizeof(m));
+}
+
+static float UpdateFOVy(float f_fovx, float f_sar)
+{
+ return 2 * atanf(tanf(f_fovx / 2) / f_sar);
+}
+
+static float UpdateZ(float f_fovx, float f_fovy)
+{
+ /* Do trigonometry to calculate the minimal z value
+ * that will allow us to zoom out without seeing the outside of the
+ * sphere (black borders). */
+ float tan_fovx_2 = tanf(f_fovx / 2);
+ float tan_fovy_2 = tanf(f_fovy / 2);
+ float z_min = - SPHERE_RADIUS / sinf(atanf(sqrtf(
+ tan_fovx_2 * tan_fovx_2 + tan_fovy_2 * tan_fovy_2)));
+
+ /* The FOV value above which z is dynamically calculated. */
+ const float z_thresh = 90.f;
+
+ float f_z;
+ if (f_fovx <= z_thresh * M_PI / 180)
+ f_z = 0;
+ else
+ {
+ float f = z_min / ((FIELD_OF_VIEW_DEGREES_MAX - z_thresh) * M_PI / 180);
+ f_z = f * f_fovx - f * z_thresh * M_PI / 180;
+ if (f_z < z_min)
+ f_z = z_min;
+ }
+ return f_z;
+}
+
+void (D3D11_UpdateViewpoint)(vlc_object_t *o, d3d11_device_t *d3d_dev, d3d_quad_t *quad,
+ const vlc_viewpoint_t *viewpoint, float f_sar)
+{
+ if (!quad->pVertexShaderConstants)
+ return;
+
+ // Convert degree into radian
+ float f_fovx = viewpoint->fov * (float)M_PI / 180.f;
+ if ( f_fovx > FIELD_OF_VIEW_DEGREES_MAX * M_PI / 180 + 0.001f ||
+ f_fovx < -0.001f )
+ return;
+
+ float f_fovy = UpdateFOVy(f_fovx, f_sar);
+ float f_z = UpdateZ(f_fovx, f_fovy);
+ vlc_viewpoint_t vp;
+ vlc_viewpoint_reverse(&vp, viewpoint);
+
+ HRESULT hr;
+ D3D11_MAPPED_SUBRESOURCE mapped;
+ hr = ID3D11DeviceContext_Map(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pVertexShaderConstants, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
+ if (SUCCEEDED(hr)) {
+ VS_PROJECTION_CONST *dst_data = mapped.pData;
+ getZoomMatrix(SPHERE_RADIUS * f_z, dst_data->Zoom);
+ getProjectionMatrix(f_sar, f_fovy, dst_data->Projection);
+ vlc_viewpoint_to_4x4(&vp, dst_data->View);
+ }
+ ID3D11DeviceContext_Unmap(d3d_dev->d3dcontext, (ID3D11Resource *)quad->pVertexShaderConstants, 0);
+}
+
#undef D3D11_AllocateQuad
int D3D11_AllocateQuad(vlc_object_t *o, d3d11_device_t *d3d_dev,
video_projection_mode_t projection, d3d_quad_t *quad)
diff --git a/modules/video_output/win32/d3d11_quad.h b/modules/video_output/win32/d3d11_quad.h
index db3926befe..57ab0ac7fe 100644
--- a/modules/video_output/win32/d3d11_quad.h
+++ b/modules/video_output/win32/d3d11_quad.h
@@ -72,4 +72,7 @@ void D3D11_UpdateQuadOpacity(vlc_object_t *, d3d11_device_t *, d3d_quad_t *, flo
void D3D11_UpdateQuadLuminanceScale(vlc_object_t *, d3d11_device_t *, d3d_quad_t *, float luminanceScale);
#define D3D11_UpdateQuadLuminanceScale(a,b,c,d) D3D11_UpdateQuadLuminanceScale(VLC_OBJECT(a),b,c,d)
+void D3D11_UpdateViewpoint(vlc_object_t *, d3d11_device_t *, d3d_quad_t *, const vlc_viewpoint_t*, float sar);
+#define D3D11_UpdateViewpoint(a,b,c,d,e) D3D11_UpdateViewpoint(VLC_OBJECT(a),b,c,d,e)
+
#endif /* VLC_D3D11_QUAD_H */
diff --git a/modules/video_output/win32/direct3d11.c b/modules/video_output/win32/direct3d11.c
index 9d1c43a3e2..1e9ae1e733 100644
--- a/modules/video_output/win32/direct3d11.c
+++ b/modules/video_output/win32/direct3d11.c
@@ -141,8 +141,6 @@ static void Direct3D11DestroyResources(vout_display_t *);
static void Direct3D11DeleteRegions(int, picture_t **);
static int Direct3D11MapSubpicture(vout_display_t *, int *, picture_t ***, subpicture_t *);
-static void SetQuadVSProjection(vout_display_sys_t *);
-
static int Control(vout_display_t *, int, va_list);
@@ -281,7 +279,8 @@ static void UpdateSize(vout_display_t *vd)
D3D11_UpdateQuadPosition(vd, sys->d3d_dev, &sys->picQuad, &source_rect,
vd->source.orientation);
- SetQuadVSProjection(sys);
+ D3D11_UpdateViewpoint( vd, sys->d3d_dev, &sys->picQuad, &sys->area.vdcfg.viewpoint,
+ (float) sys->area.vdcfg.display.width / sys->area.vdcfg.display.height );
d3d11_device_unlock( sys->d3d_dev );
@@ -401,98 +400,6 @@ static void Close(vout_display_t *vd)
CommonWindowClean(&vd->sys->sys);
#endif
}
-
-static void getZoomMatrix(float zoom, FLOAT matrix[static 16]) {
-
- const FLOAT m[] = {
- /* x y z w */
- 1.0f, 0.0f, 0.0f, 0.0f,
- 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, zoom, 1.0f
- };
-
- memcpy(matrix, m, sizeof(m));
-}
-
-/* perspective matrix see https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml */
-static void getProjectionMatrix(float sar, float fovy, FLOAT matrix[static 16]) {
-
- float zFar = 1000;
- float zNear = 0.01;
-
- float f = 1.f / tanf(fovy / 2.f);
-
- const FLOAT m[] = {
- f / sar, 0.f, 0.f, 0.f,
- 0.f, f, 0.f, 0.f,
- 0.f, 0.f, (zNear + zFar) / (zNear - zFar), -1.f,
- 0.f, 0.f, (2 * zNear * zFar) / (zNear - zFar), 0.f};
-
- memcpy(matrix, m, sizeof(m));
-}
-
-static float UpdateFOVy(float f_fovx, float f_sar)
-{
- return 2 * atanf(tanf(f_fovx / 2) / f_sar);
-}
-
-static float UpdateZ(float f_fovx, float f_fovy)
-{
- /* Do trigonometry to calculate the minimal z value
- * that will allow us to zoom out without seeing the outside of the
- * sphere (black borders). */
- float tan_fovx_2 = tanf(f_fovx / 2);
- float tan_fovy_2 = tanf(f_fovy / 2);
- float z_min = - SPHERE_RADIUS / sinf(atanf(sqrtf(
- tan_fovx_2 * tan_fovx_2 + tan_fovy_2 * tan_fovy_2)));
-
- /* The FOV value above which z is dynamically calculated. */
- const float z_thresh = 90.f;
-
- float f_z;
- if (f_fovx <= z_thresh * M_PI / 180)
- f_z = 0;
- else
- {
- float f = z_min / ((FIELD_OF_VIEW_DEGREES_MAX - z_thresh) * M_PI / 180);
- f_z = f * f_fovx - f * z_thresh * M_PI / 180;
- if (f_z < z_min)
- f_z = z_min;
- }
- return f_z;
-}
-
-static void SetQuadVSProjection(vout_display_sys_t *sys)
-{
- if (!sys->picQuad.pVertexShaderConstants)
- return;
-
- // Convert degree into radian
- float f_fovx = sys->area.vdcfg.viewpoint.fov * (float)M_PI / 180.f;
- if ( f_fovx > FIELD_OF_VIEW_DEGREES_MAX * M_PI / 180 + 0.001f ||
- f_fovx < -0.001f )
- return;
-
- float f_sar = (float) sys->area.vdcfg.display.width / sys->area.vdcfg.display.height;
- float f_fovy = UpdateFOVy(f_fovx, f_sar);
- float f_z = UpdateZ(f_fovx, f_fovy);
-
- HRESULT hr;
- D3D11_MAPPED_SUBRESOURCE mapped;
- hr = ID3D11DeviceContext_Map(sys->d3d_dev->d3dcontext, (ID3D11Resource *)sys->picQuad.pVertexShaderConstants, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);
- if (SUCCEEDED(hr)) {
- VS_PROJECTION_CONST *dst_data = mapped.pData;
- getZoomMatrix(SPHERE_RADIUS * f_z, dst_data->Zoom);
- getProjectionMatrix(f_sar, f_fovy, dst_data->Projection);
-
- vlc_viewpoint_t vp;
- vlc_viewpoint_reverse(&vp, &sys->area.vdcfg.viewpoint);
- vlc_viewpoint_to_4x4(&vp, dst_data->View);
- }
- ID3D11DeviceContext_Unmap(sys->d3d_dev->d3dcontext, (ID3D11Resource *)sys->picQuad.pVertexShaderConstants, 0);
-}
-
static int Control(vout_display_t *vd, int query, va_list args)
{
vout_display_sys_t *sys = vd->sys;
@@ -505,7 +412,8 @@ static int Control(vout_display_t *vd, int query, va_list args)
const vlc_viewpoint_t *viewpoint = va_arg(args, const vlc_viewpoint_t*);
sys->area.vdcfg.viewpoint = *viewpoint;
d3d11_device_lock( sys->d3d_dev );
- SetQuadVSProjection( sys );
+ D3D11_UpdateViewpoint( vd, sys->d3d_dev, &sys->picQuad, viewpoint,
+ (float) sys->area.vdcfg.display.width / sys->area.vdcfg.display.height );
d3d11_device_unlock( sys->d3d_dev );
res = VLC_SUCCESS;
}
@@ -1082,7 +990,8 @@ static int Direct3D11CreateFormatResources(vout_display_t *vd, const video_forma
if ( vd->source.projection_mode == PROJECTION_MODE_EQUIRECTANGULAR ||
vd->source.projection_mode == PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD )
- SetQuadVSProjection( sys );
+ D3D11_UpdateViewpoint( vd, sys->d3d_dev, &sys->picQuad, &sys->area.vdcfg.viewpoint,
+ (float) sys->area.vdcfg.display.width / sys->area.vdcfg.display.height );
if (is_d3d11_opaque(fmt->i_chroma)) {
ID3D10Multithread *pMultithread;
@@ -1209,7 +1118,8 @@ static int Direct3D11CreateGenericResources(vout_display_t *vd)
sys->picQuad.cropViewport[0].Width, sys->picQuad.cropViewport[0].Height );
#endif
- SetQuadVSProjection(sys);
+ D3D11_UpdateViewpoint( vd, sys->d3d_dev, &sys->picQuad, &sys->area.vdcfg.viewpoint,
+ (float) sys->area.vdcfg.display.width / sys->area.vdcfg.display.height );
msg_Dbg(vd, "Direct3D11 resources created");
return VLC_SUCCESS;
More information about the vlc-commits
mailing list