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
30void 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
void PushTransformation(const UIEffects &Fx, QPointF &Center)
void PopTransformation(void)
void SetShaderProjection(QOpenGLShaderProgram *Program)
MythRenderOpenGL * Initialise(QRect Area)
void Draw(QRect Area, MythPainter *, QPaintDevice *) override
QOpenGLShaderProgram * m_openglShader
MythVisualMonoScopeOpenGL(AudioPlayer *Audio, MythRender *Render, bool Fade)
bool UpdateVertices(float *Buffer)
MythRender * m_render
Definition: videovisual.h:72
QRect m_area
Definition: videovisual.h:71
@ kGLBufferMap
static const QString kSimpleVertexShader
static const QString kSimpleFragmentShader
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:206
static constexpr size_t NUM_SAMPLES