-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathscreensaver.cpp
124 lines (90 loc) · 2.91 KB
/
screensaver.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "screensaver.h"
QQuickFramebufferObject::Renderer *Screensaver::createRenderer() const
{
return new StickRenderer();
}
StickRenderer::StickRenderer()
{
_barSticks = QVector<Stick*>();
for (int i = 0; i < 100; i++) {
Stick *stick = new Stick;
stick->setSize(0.00585366, 0.117073);
stick->setColor("#FFFFFF");
_barSticks.push_back(stick);
}
_timer.start();
randomRadius = std::uniform_real_distribution<qreal>(-1, 1);
randomFrequency = std::uniform_real_distribution<qreal>(0.01, 0.1);
randomRatioRotation = std::uniform_real_distribution<qreal>(-0.1, 0.1);
initializeGLCanvas();
}
void StickRenderer::initializeGLCanvas()
{
initializeOpenGLFunctions();
QSurfaceFormat format;
format.setSamples(16);
QOpenGLContext::currentContext()->setFormat(format);
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClearColor(0, 0, 0, 0);
}
void StickRenderer::resizeGLCanvas(int width, int height)
{
glViewport(0, 0,width, height);
qreal right = qreal(width) / qreal(height);
qreal left = -right;
qreal top = 1;
qreal bottom = -top;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW );
glLoadIdentity();
glOrtho(left, right, bottom, top, -1, 1);
randomX = std::uniform_real_distribution<qreal>(left, right);
randomY = std::uniform_real_distribution<qreal>(bottom, top);
}
void StickRenderer::paintGLCanvas()
{
glClearColor(0, 0, 0, 0);
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(0);
QRandomGenerator generator;
for (auto stick : _barSticks) {
qreal centerX = randomX(generator);
qreal centerY = randomY(generator);
qreal radius = randomRadius(generator);
qreal frequency = randomFrequency(generator);
qreal ratioRotation = randomRatioRotation(generator);
qreal timeNow = elapsed() / 1000.0;
qreal posX = centerX + cos(timeNow * frequency) * radius;
qreal posY = centerY + sin(timeNow * frequency) * radius;
qreal rotation = (elapsed() + 10000) * frequency * ratioRotation;
stick->setX(posX);
stick->setY(posY);
stick->setRotation(fmod(rotation, 360));
stick->draw();
}
update();
}
void StickRenderer::render()
{
paintGLCanvas();
}
QOpenGLFramebufferObject *StickRenderer::createFramebufferObject(const QSize &size)
{
initializeGLCanvas();
resizeGLCanvas(size.width(), size.height());
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(16);
return new QOpenGLFramebufferObject(size, format);
}
void StickRenderer::synchronize(QQuickFramebufferObject *item)
{
Screensaver *screensaver = qobject_cast<Screensaver *>(item);
screensaver->window()->resetOpenGLState();
screensaver->window()->setClearBeforeRendering(true);
}