MythTV  master
mythvisualmonoscopeopengl.cpp
Go to the documentation of this file.
1 // MythTV
4 
6  : VideoVisualMonoScope(Audio, Render, Fade)
7 {
8 }
9 
11 {
13 }
14 
16 {
17  auto * render = dynamic_cast<MythRenderOpenGL*>(m_render);
18  if (!render)
19  return;
20 
21  OpenGLLocker locker(render);
22  render->DeleteShaderProgram(m_openglShader);
23  for (auto & vbo : m_vbos)
24  delete vbo.first;
25  m_openglShader = nullptr;
26  m_vbos.clear();
27  m_vertices.clear();
28 }
29 
30 void MythVisualMonoScopeOpenGL::Draw(const QRect Area, MythPainter* /*Painter*/, QPaintDevice* /*Device*/)
31 {
32  MythRenderOpenGL* render = Initialise(Area);
33  if (!render)
34  return;
35 
36  UpdateTime();
37 
38  render->makeCurrent();
39 
40  // Rotate the vertex buffers and state
41  if (m_fade)
42  {
43  // fade away...
44  float fade = 1.0F - (m_rate / 150.0F);
45  float zoom = 1.0F - (m_rate / 4000.0F);
46  for (auto & state : m_vbos)
47  {
48  state.second[1] *= fade;
49  state.second[2] *= zoom;
50  }
51 
52  // drop oldest
53  auto vertex = m_vbos.front();
54  m_vbos.pop_front();
55  m_vbos.append(vertex);
56  }
57 
58  // Update the newest vertex buffer
59  auto & vbo = m_vbos.back();
60  vbo.second[0] = m_hue;
61  vbo.second[1] = 1.0;
62  vbo.second[2] = 1.0;
63 
64  bool updated = false;
65  vbo.first->bind();
66  if (m_bufferMaps)
67  {
68  void* buffer = vbo.first->map(QOpenGLBuffer::WriteOnly);
69  updated = UpdateVertices(static_cast<float*>(buffer));
70  vbo.first->unmap();
71  }
72  else
73  {
74  updated = UpdateVertices(m_vertices.data());
75  vbo.first->write(0, m_vertices.data(), static_cast<int>(m_vertices.size() * sizeof(GLfloat)));
76  }
77 
78  if (!updated)
79  {
80  // this is generally when the visualiser is embedding and hidden. We must
81  // still drain the buffers but don't actually draw
82  render->doneCurrent();
83  return;
84  }
85 
86  // Common calls
87  render->glEnableVertexAttribArray(0);
88  QPointF center { m_area.left() + static_cast<qreal>(m_area.width()) / 2,
89  m_area.top() + static_cast<qreal>(m_area.height()) / 2 };
90 
91  // Draw lines
92  for (auto & vertex : m_vbos)
93  {
94  vertex.first->bind();
95  render->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
96 
97  if (m_fade)
98  {
99  UIEffects fx;
100  fx.m_vzoom = vertex.second[2];
101  fx.m_hzoom = vertex.second[2];
102  render->PushTransformation(fx, center);
103  }
104 
106  auto color = QColor::fromHsvF(static_cast<qreal>(vertex.second[0]), 1.0, 1.0);
107  render->glVertexAttrib4f(1, static_cast<GLfloat>(color.redF()),
108  static_cast<GLfloat>(color.greenF()),
109  static_cast<GLfloat>(color.blueF()),
110  vertex.second[1]);
111  render->glLineWidth(std::clamp(m_lineWidth * vertex.second[2], 1.0F, m_maxLineWidth));
112  render->glDrawArrays(GL_LINE_STRIP, 0, NUM_SAMPLES);
113 
114  if (m_fade)
115  render->PopTransformation();
116  }
117 
118  // Cleanup
119  render->glLineWidth(1);
120  QOpenGLBuffer::release(QOpenGLBuffer::VertexBuffer);
121  render->glDisableVertexAttribArray(0);
122  render->doneCurrent();
123 }
124 
126 {
127  auto * render = dynamic_cast<MythRenderOpenGL*>(m_render);
128  if (!render)
129  return nullptr;
130 
131  if ((Area == m_area) && m_openglShader && !m_vbos.empty())
132  return render;
133 
134  TearDown();
135  InitCommon(Area);
136 
137  OpenGLLocker locker(render);
138 
139  // Check line width constraints
140  std::array<GLfloat,2> ranges { 1.0 };
141  render->glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, ranges.data());
142  m_maxLineWidth = ranges[1];
143 
144  // Use direct updates if available, otherwise create an intermediate buffer
145  m_bufferMaps = (render->GetExtraFeatures() & kGLBufferMap) == kGLBufferMap;
146  if (m_bufferMaps)
147  m_vertices.clear();
148  else
149  m_vertices.resize(NUM_SAMPLES * 2);
150 
151  if (!m_openglShader)
152  m_openglShader = render->CreateShaderProgram(kSimpleVertexShader, kSimpleFragmentShader);
153 
154  int size = m_fade ? 8 : 1;
155  while (m_vbos.size() < size)
156  m_vbos.push_back({render->CreateVBO(NUM_SAMPLES * 2 * sizeof(GLfloat), false), {}});
157 
158  if (m_openglShader && m_vbos.size() == size)
159  return render;
160  return nullptr;
161 }
162 
VideoVisualMonoScope::UpdateVertices
bool UpdateVertices(float *Buffer)
Definition: videovisualmonoscope.cpp:34
mythrenderopenglshaders.h
NUM_SAMPLES
static constexpr size_t NUM_SAMPLES
Definition: videovisualmonoscope.h:7
MythVisualMonoScopeOpenGL::m_vertices
Vertices m_vertices
Definition: mythvisualmonoscopeopengl.h:28
AudioPlayer
Definition: audioplayer.h:22
MythVisualMonoScopeOpenGL::m_openglShader
QOpenGLShaderProgram * m_openglShader
Definition: mythvisualmonoscopeopengl.h:26
VideoVisualMonoScope::m_maxLineWidth
float m_maxLineWidth
Definition: videovisualmonoscope.h:27
kSimpleFragmentShader
static const QString kSimpleFragmentShader
Definition: mythrenderopenglshaders.h:49
MythRenderOpenGL::PushTransformation
void PushTransformation(const UIEffects &Fx, QPointF &Center)
Definition: mythrenderopengl.cpp:1383
MythVisualMonoScopeOpenGL::MythVisualMonoScopeOpenGL
MythVisualMonoScopeOpenGL(AudioPlayer *Audio, MythRender *Render, bool Fade)
Definition: mythvisualmonoscopeopengl.cpp:5
MythVisualMonoScopeOpenGL::~MythVisualMonoScopeOpenGL
~MythVisualMonoScopeOpenGL() override
Definition: mythvisualmonoscopeopengl.cpp:10
MythVisualMonoScopeOpenGL::Draw
void Draw(QRect Area, MythPainter *, QPaintDevice *) override
Definition: mythvisualmonoscopeopengl.cpp:30
mythvisualmonoscopeopengl.h
MythRenderOpenGL::PopTransformation
void PopTransformation(void)
Definition: mythrenderopengl.cpp:1396
MythRenderOpenGL::makeCurrent
void makeCurrent()
Definition: mythrenderopengl.cpp:566
VideoVisualMonoScope::m_lineWidth
float m_lineWidth
Definition: videovisualmonoscope.h:26
kGLBufferMap
@ kGLBufferMap
Definition: mythrenderopengl.h:43
kSimpleVertexShader
static const QString kSimpleVertexShader
Definition: mythrenderopenglshaders.h:38
MythRenderOpenGL::doneCurrent
void doneCurrent()
Definition: mythrenderopengl.cpp:574
MythRenderOpenGL
Definition: mythrenderopengl.h:96
UIEffects::m_vzoom
float m_vzoom
Definition: mythuianimation.h:41
VideoVisualMonoScope
Definition: videovisualmonoscope.h:11
MythVisualMonoScopeOpenGL::m_vbos
VertexStatesGL m_vbos
Definition: mythvisualmonoscopeopengl.h:27
MythRender
Definition: mythrender_base.h:23
MythVisualMonoScopeOpenGL::m_bufferMaps
bool m_bufferMaps
Definition: mythvisualmonoscopeopengl.h:25
MythPainter
Definition: mythpainter.h:34
VideoVisual::m_render
MythRender * m_render
Definition: videovisual.h:73
UIEffects
Definition: mythuianimation.h:13
UIEffects::m_hzoom
float m_hzoom
Definition: mythuianimation.h:40
VideoVisualMonoScope::m_hue
float m_hue
Definition: videovisualmonoscope.h:24
MythVisualMonoScopeOpenGL::Initialise
MythRenderOpenGL * Initialise(QRect Area)
Definition: mythvisualmonoscopeopengl.cpp:125
VideoVisual::m_area
QRect m_area
Definition: videovisual.h:72
VideoVisualMonoScope::m_rate
float m_rate
Definition: videovisualmonoscope.h:25
VideoVisualMonoScope::m_fade
bool m_fade
Definition: videovisualmonoscope.h:28
MythRenderOpenGL::SetShaderProjection
void SetShaderProjection(QOpenGLShaderProgram *Program)
Definition: mythrenderopengl.cpp:1490
VideoVisualMonoScope::InitCommon
void InitCommon(QRect Area)
Definition: videovisualmonoscope.cpp:25
VideoVisualMonoScope::UpdateTime
void UpdateTime()
Definition: videovisualmonoscope.cpp:74
MythVisualMonoScopeOpenGL::TearDown
void TearDown()
Definition: mythvisualmonoscopeopengl.cpp:15
OpenGLLocker
Definition: mythrenderopengl.h:255