7#define GL_SILENCE_DEPRECATION
9#undef GL_SILENCE_DEPRECATION
13#include <QQuickWindow>
14#include <QOpenGLShaderProgram>
15#include <QOpenGLFunctions>
16#include <QOpenGLVertexArrayObject>
17#include <QOpenGLTexture>
18#include <QOpenGLBuffer>
19#include <QQuickFramebufferObject>
20#include <QOpenGLFunctions_3_3_Core>
21#include <QOpenGLDebugLogger>
23#include <QSGSimpleTextureNode>
24#include <QSGRenderNode>
29const static void* ZERO_OFFSET =
nullptr;
30const static GLfloat VERTEX_POS[] = {
36const static GLuint VERTEX_INDEX[] = {
67class FireworksRenderer :
public QObject,
public QSGRenderNode,
protected QOpenGLFunctions_3_3_Core {
69 Q_PROPERTY(GLfloat
brightness READ getBrightness WRITE setBrightness)
70 Q_PROPERTY(GLfloat
contrast READ getContrast WRITE setContrast)
71 Q_PROPERTY(GLfloat
saturation READ getSaturation WRITE setSaturation)
72 Q_PROPERTY(
bool keepFrameRate READ isKeepFrameRate WRITE setKeepFrameRate)
75PONY_GUARD_BY(
MAIN) private:
78 [[nodiscard]]
bool isKeepFrameRate()
const {
return mainSettings.
keepFrameRate; }
80 void setKeepFrameRate(
bool keep) { mainSettings.keepFrameRate = keep; }
82 [[nodiscard]] GLfloat getBrightness()
const {
return mainSettings.brightness; }
86 [[nodiscard]] GLfloat getSaturation()
const {
return mainSettings.saturation; }
90 [[nodiscard]] GLfloat getContrast()
const {
return mainSettings.contrast; }
96 QOpenGLShaderProgram *program =
nullptr;
97 QMatrix4x4 viewMatrix;
102 void inline createTextureBuffer(GLuint *texture) {
103 QOpenGLFunctions_3_3_Core::glGenTextures(1, texture);
104 QOpenGLFunctions_3_3_Core::glBindTexture(GL_TEXTURE_2D, *texture);
105 QOpenGLFunctions_3_3_Core::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
106 QOpenGLFunctions_3_3_Core::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
107 QOpenGLFunctions_3_3_Core::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
108 QOpenGLFunctions_3_3_Core::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
113 GLuint vao = 0, vbo = 0, ebo = 0;
114 GLuint textureY = 0, textureU = 0, textureV = 0, textureLUT = 0;
115 GLint brightnessLoc = -1, contrastLoc = -1, saturationLoc = -1;
118 if (program) {
return; }
119 program =
new QOpenGLShaderProgram;
120 QOpenGLFunctions_3_3_Core::initializeOpenGLFunctions();
121 static bool info =
false;
123 qInfo() <<
"OpenGL version:"
124 << QLatin1String(
reinterpret_cast<const char*
>(glGetString(GL_VERSION)));
125 qInfo() <<
"GSLS version:"
126 << QLatin1String(
reinterpret_cast<const char*
>(glGetString(GL_SHADING_LANGUAGE_VERSION)));
127 qInfo() <<
"Vendor:" << QLatin1String(
reinterpret_cast<const char*
>(glGetString(GL_VENDOR)));
128 qInfo() <<
"Renderer:" << QLatin1String(
reinterpret_cast<const char*
>(glGetString(GL_RENDERER)));
131 program->addCacheableShaderFromSourceFile(QOpenGLShader::Vertex, u
":/player/shader/vertex.vsh"_qs);
132 program->addCacheableShaderFromSourceFile(QOpenGLShader::Fragment, u
":/player/shader/fragment.fsh"_qs);
135 brightnessLoc = program->uniformLocation(
"brightness");
136 contrastLoc = program->uniformLocation(
"contrast");
137 saturationLoc = program->uniformLocation(
"saturation");
140 glGenVertexArrays(1, &vao);
141 glGenBuffers(1, &vbo);
142 glGenBuffers(1, &ebo);
144 glBindBuffer(GL_ARRAY_BUFFER, vbo);
145 glBufferData(GL_ARRAY_BUFFER,
sizeof(VERTEX_POS), VERTEX_POS, GL_STATIC_DRAW);
147 glBindVertexArray(vao);
148 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat), ZERO_OFFSET);
149 glEnableVertexAttribArray(0);
150 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 *
sizeof(GLfloat),
151 reinterpret_cast<const void *
>(3 *
sizeof(GLfloat)));
152 glEnableVertexAttribArray(1);
154 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
155 glBufferData(GL_ELEMENT_ARRAY_BUFFER,
sizeof(VERTEX_INDEX), VERTEX_INDEX, GL_STATIC_DRAW);
157 program->setUniformValue(
"tex_y", 0);
158 program->setUniformValue(
"tex_u", 1);
159 program->setUniformValue(
"tex_v", 2);
160 program->setUniformValue(
"tex_lut", 3);
161 glEnable(GL_TEXTURE_2D);
162 glActiveTexture(GL_TEXTURE0);
163 createTextureBuffer(&textureY);
164 glActiveTexture(GL_TEXTURE1);
165 createTextureBuffer(&textureU);
166 glActiveTexture(GL_TEXTURE2);
167 createTextureBuffer(&textureV);
168 glActiveTexture(GL_TEXTURE3);
169 createTextureBuffer(&textureLUT);
170 glBindTexture(GL_TEXTURE_2D, textureLUT);
174 renderSettings.
updateBy(mainSettings);
178 qDebug() <<
"Create Hurricane Renderer:" <<
static_cast<void *
>(
this) <<
".";
197 [[nodiscard]] RenderingFlags
flags()
const override {
198 return BoundedRectRendering;
202 return BlendState | ScissorState | StencilState;
205 void render(
const RenderState *state)
override {
211 const QRect r = state->scissorRect();
214 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
215 if (state->scissorEnabled()) {
216 glEnable(GL_SCISSOR_TEST);
217 glScissor(r.x(), r.y(), r.width(), r.height());
219 ILLEGAL_STATE(
"Scissor Test must be enabled. For example: wrap Fireworks "
220 "in a Rectangle and set clip: true. ");
222 if (state->stencilEnabled()) {
223 glEnable(GL_STENCIL_TEST);
224 glStencilFunc(GL_EQUAL, state->stencilValue(), 0xFF);
225 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
231 program->setUniformValue(saturationLoc, renderSettings.
saturation.getUpdate());
232 program->setUniformValue(contrastLoc, renderSettings.
contrast.getUpdate());
233 program->setUniformValue(brightnessLoc, renderSettings.
brightness.getUpdate());
234 glBindVertexArray(vao);
235 glBindBuffer(GL_ARRAY_BUFFER, vbo);
236 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
238 if (!videoFrame.
isValid()) {
return; }
240 int imageHeight = videoFrame.
getHeight();
241 int imageWidth = videoFrame.
getWidth();
242 auto *imageY = videoFrame.
getY();
243 auto *imageU = videoFrame.
getU();
244 auto *imageV = videoFrame.
getV();
246 double rate =
static_cast<double>(imageHeight) /
static_cast<double>(imageWidth);
247 double h = r.width() * rate;
248 if (h >= r.height()) {
249 double wFit = r.height() / rate;
250 double wPad = r.width() - wFit;
251 glViewport(r.x() +
static_cast<GLsizei
>(wPad) / 2, r.y(),
static_cast<GLsizei
>(wFit), r.height());
253 double hFit = r.width() * rate;
254 double hPad = r.height() - hFit;
255 glViewport(r.x(), r.y() +
static_cast<GLsizei
>(hPad) / 2, r.width(),
static_cast<GLsizei
>(hFit));
258 glViewport(r.x(), r.y(), r.width(), r.height());
262 QImage lutTexture = renderSettings.
lutFilter;
266 viewMatrix.setToIdentity();
267 viewMatrix.ortho(0,
static_cast<float>(imageWidth) /
static_cast<float>(lineSize), 0, 1, -1, 1);
269 program->setUniformValue(
"view", viewMatrix);
270 glActiveTexture(GL_TEXTURE0);
271 glBindTexture(GL_TEXTURE_2D, textureY);
272 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, lineSize, imageHeight, 0, GL_RED, GL_UNSIGNED_BYTE, imageY);
273 glActiveTexture(GL_TEXTURE1);
274 glBindTexture(GL_TEXTURE_2D, textureU);
275 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, lineSize / 2, imageHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, imageU);
276 glActiveTexture(GL_TEXTURE2);
277 glBindTexture(GL_TEXTURE_2D, textureV);
278 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, lineSize / 2, imageHeight / 2, 0, GL_RED, GL_UNSIGNED_BYTE, imageV);
279 glActiveTexture(GL_TEXTURE3);
280 glBindTexture(GL_TEXTURE_2D, textureLUT);
281 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lutTexture.width(), lutTexture.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, lutTexture.constBits());
283 glActiveTexture(GL_TEXTURE0);
284 glBindTexture(GL_TEXTURE_2D, textureY);
285 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, lineSize, imageHeight, GL_RED, GL_UNSIGNED_BYTE, imageY);
286 glActiveTexture(GL_TEXTURE1);
287 glBindTexture(GL_TEXTURE_2D, textureU);
288 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, lineSize / 2, imageHeight / 2, GL_RED, GL_UNSIGNED_BYTE, imageU);
289 glActiveTexture(GL_TEXTURE2);
290 glBindTexture(GL_TEXTURE_2D, textureV);
291 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, lineSize / 2, imageHeight / 2, GL_RED, GL_UNSIGNED_BYTE, imageV);
292 glBindTexture(GL_TEXTURE_2D, textureLUT);
293 glActiveTexture(GL_TEXTURE3);
294 glBindTexture(GL_TEXTURE_2D, textureLUT);
295 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, lutTexture.width(), lutTexture.height(), GL_RED, GL_UNSIGNED_BYTE, lutTexture.constBits());
297 glDrawElements(GL_TRIANGLES,
sizeof(VERTEX_INDEX) /
sizeof(GLuint), GL_UNSIGNED_INT, ZERO_OFFSET);
302 glBindBuffer(GL_ARRAY_BUFFER, 0);
303 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
304 glBindVertexArray(0);
306 qDebug() <<
"Deconstruct Hurricane Renderer:" <<
static_cast<void *
>(
this) <<
".";
Definition: fireworks.hpp:10
QML_ELEMENTbool keepFrameRate
Definition: fireworks.hpp:13
Definition: renderer.hpp:67
void render(const RenderState *state) override
Definition: renderer.hpp:205
GLfloat brightness
Definition: renderer.hpp:69
PONY_GUARD_BY(MAIN) bool setVideoFrame(const VideoFrameRef &frame)
Definition: renderer.hpp:181
PONY_GUARD_BY(MAIN) void setLUTFilter(const QImage &image)
Definition: renderer.hpp:190
PONY_GUARD_BY(MAIN) FireworksRenderer()
Definition: renderer.hpp:177
void sync()
Definition: renderer.hpp:173
void init()
Definition: renderer.hpp:117
bool keepFrameRate
Definition: renderer.hpp:72
GLfloat saturation
Definition: renderer.hpp:71
RenderingFlags flags() const override
Definition: renderer.hpp:197
~FireworksRenderer() override
Definition: renderer.hpp:301
StateFlags changedStates() const override
Definition: renderer.hpp:201
GLfloat contrast
Definition: renderer.hpp:70
Definition: updatevalue.hpp:9
bool isUpdate() const
Definition: updatevalue.hpp:39
Definition: updatevalue.hpp:44
void updateBy(UpdateValueVideoFrameRef &updateValue)
Definition: updatevalue.hpp:68
bool isUpdateSize() const
Definition: updatevalue.hpp:74
std::byte * getV() const
Definition: frame.hpp:114
bool isValid() const
Definition: frame.hpp:97
int getWidth() const
Definition: frame.hpp:122
int getLineSize() const
Definition: frame.hpp:118
std::byte * getU() const
Definition: frame.hpp:110
std::byte * getY() const
Definition: frame.hpp:106
int getHeight() const
Definition: frame.hpp:126
constexpr PonyThread MAIN
Definition: ponyplayer.h:47
constexpr PonyThread RENDER
Definition: ponyplayer.h:48
#define ILLEGAL_STATE(msg)
Definition: ponyplayer.h:40
Definition: renderer.hpp:41
void updateBy(RenderSettings &settings)
Definition: renderer.hpp:52
UpdateValue< GLfloat > brightness
Definition: renderer.hpp:46
UpdateValue< GLfloat > contrast
Definition: renderer.hpp:47
UpdateValue< GLfloat > saturation
Definition: renderer.hpp:48
UpdateValueVideoFrameRef videoFrame
Definition: renderer.hpp:45
UpdateValue< bool > keepFrameRate
Definition: renderer.hpp:50
UpdateValue< QImage > lutFilter
Definition: renderer.hpp:49