Overte C++ Documentation
HmdDisplayPlugin.h
1 //
2 // Created by Bradley Austin Davis on 2016/02/15
3 // Copyright 2016 High Fidelity, Inc.
4 //
5 // Distributed under the Apache License, Version 2.0.
6 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
7 //
8 #pragma once
9 
10 #include <ThreadSafeValueCache.h>
11 
12 #include <array>
13 
14 #include <QtGlobal>
15 #include <Transform.h>
16 
17 #include <gpu/Format.h>
18 #include <gpu/Stream.h>
19 
20 #include "../CompositorHelper.h"
21 #include "../OpenGLDisplayPlugin.h"
22 
23 class HmdDisplayPlugin : public OpenGLDisplayPlugin {
24  Q_OBJECT
25  using Parent = OpenGLDisplayPlugin;
26 public:
27  ~HmdDisplayPlugin();
28  bool isHmd() const override final { return true; }
29  float getIPD() const override final { return _ipd; }
30  glm::mat4 getEyeToHeadTransform(Eye eye) const override final;
31  glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override;
32  glm::mat4 getCullingProjection(const glm::mat4& baseProjection) const override;
33  glm::uvec2 getRecommendedUiSize() const override final;
34  glm::uvec2 getRecommendedRenderSize() const override final { return _renderTargetSize; }
35  bool isDisplayVisible() const override { return isHmdMounted(); }
36 
37  ivec4 eyeViewport(Eye eye) const;
38 
39  QRect getRecommendedHUDRect() const override final;
40 
41  virtual glm::mat4 getHeadPose() const override;
42 
43  bool wantVsync() const override {
44  return false;
45  }
46 
47  float stutterRate() const override;
48 
49  virtual bool onDisplayTextureReset() override { _clearPreviewFlag = true; return true; };
50 
51  void pluginUpdate() override {};
52 
53  std::function<void(gpu::Batch&, const gpu::TexturePointer&)> getHUDOperator() override;
54  virtual StencilMaskMode getStencilMaskMode() const override { return StencilMaskMode::PAINT; }
55  void updateVisionSqueezeParameters(float visionSqueezeX, float visionSqueezeY, float visionSqueezeTransition,
56  int visionSqueezePerEye, float visionSqueezeGroundPlaneY,
57  float visionSqueezeSpotlightSize);
58  // Attempt to reserve two threads.
59  int getRequiredThreadCount() const override { return 2; }
60 
61 signals:
62  void hmdMountedChanged();
63  void hmdVisibleChanged(bool visible);
64 
65 protected:
66  virtual void hmdPresent() = 0;
67  virtual bool isHmdMounted() const = 0;
68  virtual void postPreview() {};
69  virtual void updatePresentPose();
70 
71  bool internalActivate() override;
72  void internalDeactivate() override;
73  void compositePointer() override;
74  void internalPresent() override;
75  void customizeContext() override;
76  void uncustomizeContext() override;
77  void updateFrameData() override;
78  glm::mat4 getViewCorrection() override;
79 
80  std::array<mat4, 2> _eyeOffsets;
81  std::array<mat4, 2> _eyeProjections;
82  std::array<mat4, 2> _eyeInverseProjections;
83 
84  mat4 _cullingProjection;
85  uvec2 _renderTargetSize;
86  float _ipd { 0.064f };
87 
88  struct FrameInfo {
89  mat4 renderPose;
90  mat4 presentPose;
91  double sensorSampleTime { 0 };
92  double predictedDisplayTime { 0 };
93  };
94 
95  QMap<uint32_t, FrameInfo> _frameInfos;
96  FrameInfo _currentPresentFrameInfo;
97  FrameInfo _currentRenderFrameInfo;
98  RateCounter<> _stutterRate;
99 
100  bool _disablePreview { true };
101 
102  class VisionSqueezeParameters {
103  public:
104  float _visionSqueezeX { 0.0f };
105  float _visionSqueezeY { 0.0f };
106  float _spareA { 0.0f };
107  float _spareB { 0.0f };
108  glm::mat4 _leftProjection;
109  glm::mat4 _rightProjection;
110  glm::mat4 _hmdSensorMatrix;
111  float _visionSqueezeTransition { 0.15f };
112  int _visionSqueezePerEye { 0 };
113  float _visionSqueezeGroundPlaneY { 0.0f };
114  float _visionSqueezeSpotlightSize { 0.0f };
115 
116  VisionSqueezeParameters() {}
117  };
118  typedef gpu::BufferView UniformBufferView;
119  gpu::BufferView _visionSqueezeParametersBuffer;
120 
121  virtual void setupCompositeScenePipeline(gpu::Batch& batch) override;
122 
123  float _visionSqueezeDeviceLowX { 0.0f };
124  float _visionSqueezeDeviceHighX { 1.0f };
125  float _visionSqueezeDeviceLowY { 0.0f };
126  float _visionSqueezeDeviceHighY { 1.0f };
127 
128 private:
129  ivec4 getViewportForSourceSize(const uvec2& size) const;
130  float getLeftCenterPixel() const;
131 
132  bool _monoPreview { true };
133  bool _clearPreviewFlag { false };
134  gpu::TexturePointer _previewTexture;
135  glm::vec2 _lastWindowSize;
136 
137  struct HUDRenderer {
138  gpu::Stream::FormatPointer format;
139  gpu::BufferPointer vertices;
140  gpu::BufferPointer indices;
141  uint32_t indexCount { 0 };
142  gpu::PipelinePointer pipeline { nullptr };
143 
144  gpu::BufferPointer uniformsBuffer;
145 
146  struct Uniforms {
147  float alpha { 1.0f };
148  } uniforms;
149 
150  struct Vertex {
151  vec3 pos;
152  vec2 uv;
153  } vertex;
154 
155  static const size_t VERTEX_OFFSET { offsetof(Vertex, pos) };
156  static const size_t TEXTURE_OFFSET { offsetof(Vertex, uv) };
157  static const int VERTEX_STRIDE { sizeof(Vertex) };
158 
159  void build();
160  std::function<void(gpu::Batch&, const gpu::TexturePointer&)> render();
161  } _hudRenderer;
162 };
163 
164 const int drawTextureWithVisionSqueezeParamsSlot = 1; // must match binding in DrawTextureWithVisionSqueeze.slf