Rabbit Remote Control 0.0.30
Loading...
Searching...
No Matches
FrmViewerOpenGL.cpp
1// Author: Kang Lin <kl222@126.com>
2
3#include "FrmViewer.h"
4#include <QDebug>
5#include <QPainter>
6#include <QResizeEvent>
7#include <QCursor>
8
10{
11public:
13 {
14 QSurfaceFormat fmt;
15 fmt.setDepthBufferSize(24);
16 fmt.setVersion(3, 3);
17 fmt.setProfile(QSurfaceFormat::CoreProfile);
18 QSurfaceFormat::setDefaultFormat(fmt);
19 }
20};
21
22COpenGLInit g_OpenGLInit;
23
24const char* g_VertexSource =
25 "#version 330\n"
26 "layout(location = 0) in vec2 position;\n"
27 "layout(location = 1) in vec2 texCoord;\n"
28 "out vec4 texc;\n"
29 "void main( void )\n"
30 "{\n"
31 " gl_Position = vec4(position, 0.0, 1.0);\n"
32 " texc = vec4(texCoord, 0.0, 1.0);\n"
33 "}\n";
34
35const char* g_FragmentSource =
36 "#version 330\n"
37 "uniform sampler2D texture;\n"
38 "in vec4 texc;\n"
39 "out vec4 fragColor;\n"
40 "void main( void )\n"
41 "{\n"
42 " fragColor = texture2D(texture, texc.st);\n"
43 "}\n";
44
45CFrmViewerOpenGL::CFrmViewerOpenGL(QWidget *parent)
46 : QOpenGLWidget(parent), m_pTexture(nullptr)
47{
48 setAttribute(Qt::WA_DeleteOnClose);
49
50 SetAdaptWindows(ZoomToWindow);
51 SetZoomFactor(1);
52
53 setMouseTracking(true);
54 setFocusPolicy(Qt::WheelFocus);
55 setFocus();
56
57 // store triangle vertex coordinate & texCoord
58 m_VertexData = { -1.0, 1.0, 0.0, 0.0,
59 1.0, 1.0, 1.0, 0.0,
60 1.0, -1.0, 1.0, 1.0,
61 -1.0, -1.0, 0.0, 1.0 };
62}
63
64CFrmViewerOpenGL::~CFrmViewerOpenGL()
65{
66 qDebug() << "CFrmViewerOpenGL::~CFrmViewerOpenGL()";
67 if(m_pTexture)
68 {
69 delete m_pTexture;
70 m_pTexture = nullptr;
71 }
72}
73
74void CFrmViewerOpenGL::InitVertor()
75{
76 m_ShaderProgram.bind();
77
78 // create the vertex array object
79 if(!m_VaoQuad.isCreated())
80 m_VaoQuad.create();
81 m_VaoQuad.bind();
82
83 // create the vertex buffer object
84 if(!m_VboQuad.isCreated())
85 {
86 m_VboQuad.create();
87 m_VboQuad.setUsagePattern(QOpenGLBuffer::StaticDraw);
88 }
89 m_VboQuad.bind();
90 m_VboQuad.allocate(m_VertexData.constData(),
91 m_VertexData.count() * sizeof(GLfloat));
92
93 // connect the inputs to the shader program
94 m_ShaderProgram.enableAttributeArray(0);
95 m_ShaderProgram.enableAttributeArray(1);
96 m_ShaderProgram.setAttributeBuffer(0, GL_FLOAT, 0, 2, 4 * sizeof(GLfloat));
97 m_ShaderProgram.setAttributeBuffer(
98 1, GL_FLOAT, 2 * sizeof(GLfloat), 2, 4 * sizeof(GLfloat));
99
100 QString errorLog = m_ShaderProgram.log();
101 //qDebug() << errorLog;
102
103 m_VboQuad.release();
104 m_VaoQuad.release();
105 m_ShaderProgram.release();
106
107 GLenum error = glGetError();
108 Q_UNUSED(error);
109}
110
111void CFrmViewerOpenGL::initializeGL()
112{
113 qDebug() << "CFrmViewerOpenGL::initializeGL()";
114 initializeOpenGLFunctions();
115 glClearColor(0.0, 0.0, 0.0, 1.0);
116
117 // create the shader program
118 bool success = m_ShaderProgram.addShaderFromSourceCode(QOpenGLShader::Vertex, g_VertexSource);
119 if(!success) {
120 qDebug() << "failed!";
121 }
122 success = m_ShaderProgram.addShaderFromSourceCode(QOpenGLShader::Fragment, g_FragmentSource);
123 if(!success) {
124 qDebug() << "failed!";
125 }
126
127 // bind location for the vertex shader
128 m_ShaderProgram.bindAttributeLocation("position", 0);
129 m_ShaderProgram.link();
130 InitVertor();
131}
132
133void CFrmViewerOpenGL::resizeGL(int width, int height)
134{
135 // only drawing the 2d surface so no need to modify any projections etc;
136 qDebug() << "CFrmViewerOpenGL::resizeGL:" << width << height;
137}
138
139void CFrmViewerOpenGL::paintGL()
140{
141 //qDebug() << "CFrmViewerOpenGL::paintGL()";
142 //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
143 if(m_Desktop.isNull() || !m_pTexture || !m_pTexture->isCreated()) return;
144
145 m_ShaderProgram.bind();
146 m_VaoQuad.bind();
147 m_pTexture->bind();
148 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
149 m_pTexture->release();
150 m_VaoQuad.release();
151 m_ShaderProgram.release();
152
153 QString errorLog = m_ShaderProgram.log();
154 Q_UNUSED(errorLog);
155 //qDebug() << errorLog;
156
157 GLenum error = glGetError();
158 Q_UNUSED(error);
159}
160
162{
163 return m_dbZoomFactor;
164}
165
166int CFrmViewerOpenGL::SetZoomFactor(double newZoomFactor)
167{
168 if(newZoomFactor < 0) return -1;
169 if (qFuzzyCompare(m_dbZoomFactor, newZoomFactor))
170 return 0;
171 m_dbZoomFactor = newZoomFactor;
172 return 0;
173}
174
175QSize CFrmViewerOpenGL::GetDesktopSize()
176{
177 return m_Desktop.size();
178}
179
180int CFrmViewerOpenGL::ReSize(int width, int height)
181{
182 int w = width * GetZoomFactor();
183 int h = height * GetZoomFactor();
184 resize(w, h);
185 return 0;
186}
187
188void CFrmViewerOpenGL::SetAdaptWindows(ADAPT_WINDOWS aw)
189{
190 m_AdaptWindows = aw;
191 if(!m_Desktop.isNull())
192 {
193 switch (m_AdaptWindows) {
194 case Original:
195 case OriginalCenter:
196 SetZoomFactor(1);
197 case Zoom:
198 ReSize(m_Desktop.width(), m_Desktop.height());
199 m_VertexData = { -1.0, 1.0, 0.0, 0.0,
200 1.0, 1.0, 1.0, 0.0,
201 1.0, -1.0, 1.0, 1.0,
202 -1.0, -1.0, 0.0, 1.0 };
203 InitVertor();
204 break;
205 case ZoomToWindow:
206 {
207 m_VertexData = { -1.0, 1.0, 0.0, 0.0,
208 1.0, 1.0, 1.0, 0.0,
209 1.0, -1.0, 1.0, 1.0,
210 -1.0, -1.0, 0.0, 1.0 };
211 InitVertor();
212 break;
213 }
215 {
216 QRectF r = GetAspectRationRect();
217 m_VertexData = { -((float)r.width()/(float)width()), (float)r.height()/(float)height(), 0.0, 0.0,
218 (float)r.width()/(float)width(), (float)r.height()/(float)height(), 1.0, 0.0,
219 (float)r.width()/(float)width(), -((float)r.height()/(float)height()), 1.0, 1.0,
220 -((float)r.width()/(float)width()), -((float)r.height()/(float)height()), 0.0, 1.0 };
221 InitVertor();
222 break;
223 }
224 default:
225 break;
226 }
227 }
228 update();
229 //setFocus();
230}
231
232CFrmViewerOpenGL::ADAPT_WINDOWS CFrmViewerOpenGL::GetAdaptWindows()
233{
234 return m_AdaptWindows;
235}
236
237int CFrmViewerOpenGL::Load(QSettings &set)
238{
239 SetZoomFactor(set.value("Viewer/ZoomFactor", GetZoomFactor()).toDouble());
240 SetAdaptWindows(static_cast<ADAPT_WINDOWS>(set.value("Viewer/AdaptType", GetAdaptWindows()).toInt()));
241 return 0;
242}
243
244int CFrmViewerOpenGL::Save(QSettings &set)
245{
246 set.setValue("Viewer/ZoomFactor", GetZoomFactor());
247 set.setValue("Viewer/AdaptType", GetAdaptWindows());
248 return 0;
249}
250
251QImage CFrmViewerOpenGL::GrabImage(int x, int y, int w, int h)
252{
253 int width = w, height = h;
254 if(-1 == w)
255 width = m_Desktop.width();
256 if(-1 == w)
257 height = m_Desktop.height();
258 return m_Desktop.copy(x, y, width, height);
259}
260
261void CFrmViewerOpenGL::slotSetDesktopSize(int width, int height)
262{
263 m_Desktop = QImage(width, height, QImage::Format_RGB32);
264
265 if(Original == m_AdaptWindows
266 || OriginalCenter == m_AdaptWindows
267 || Zoom == m_AdaptWindows)
268 ReSize(width, height);
269
270 return;
271}
272
273void CFrmViewerOpenGL::slotSetName(const QString& szName)
274{
275 this->setWindowTitle(szName);
276}
277
278void CFrmViewerOpenGL::slotUpdateRect(const QRect& r, const QImage& image)
279{
280 if(m_Desktop.isNull() || m_Desktop.rect() == r)
281 {
282 m_Desktop = image;
283 if(m_pTexture)
284 {
285 delete m_pTexture;
286 m_pTexture = nullptr;
287 }
288 m_pTexture = new QOpenGLTexture(m_Desktop);
289 update();
290 }
291}
292
293void CFrmViewerOpenGL::slotUpdateRect(QSharedPointer<CImage> image)
294{}
295
296void CFrmViewerOpenGL::slotUpdateCursor(const QCursor& cursor)
297{
298 setCursor(cursor);
299}
300
302{
303 cursor().setPos(pos);
304}
305
306void CFrmViewerOpenGL::slotSystemCombination()
307{
308 // Send ctl+alt+del
309 emit sigKeyPressEvent(Qt::Key_Control, Qt::NoModifier);
310 emit sigKeyPressEvent(Qt::Key_Alt, Qt::NoModifier);
311 emit sigKeyPressEvent(Qt::Key_Delete, Qt::NoModifier);
312 emit sigKeyPressEvent(Qt::Key_Control, Qt::NoModifier);
313 emit sigKeyPressEvent(Qt::Key_Alt, Qt::NoModifier);
314 emit sigKeyPressEvent(Qt::Key_Delete, Qt::NoModifier);
315}
316
317QRectF CFrmViewerOpenGL::GetAspectRationRect()
318{
319 QRectF dstRect = rect();
320 qreal newW = dstRect.width();
321 qreal newH = dstRect.height();
322 qreal newT = 0;
323 qreal newL = 0;
324
325 qreal rateW = static_cast<qreal>(rect().width())
326 / static_cast<qreal>(m_Desktop.width());
327 qreal rateH = static_cast<qreal>(rect().height())
328 / static_cast<qreal>(m_Desktop.height());
329 if(rateW < rateH)
330 {
331 newW = m_Desktop.width() * rateW;
332 newH = m_Desktop.height() * rateW;
333 newT = (static_cast<qreal>(rect().height()) - newH)
334 / static_cast<qreal>(2);
335 } else if(rateW > rateH) {
336 newW = m_Desktop.width() * rateH;
337 newH = m_Desktop.height() * rateH;
338 newL = (static_cast<qreal>(rect().width()) - newW)
339 / static_cast<qreal>(2);
340 }
341 dstRect = QRectF(newL, newT, newW, newH);
342 return dstRect;
343}
344
345int CFrmViewerOpenGL::TranslationMousePoint(QPointF inPos, QPointF &outPos)
346{
347 //qDebug() << "TranslationPoint x:" << inPos.x() << ";y:" << inPos.y();
348
349 switch (m_AdaptWindows) {
350 case Auto:
351 case Original:
352 case OriginalCenter:
353 outPos = inPos;
354 break;
355 case Zoom:
356 outPos.setX(inPos.x() / GetZoomFactor());
357 outPos.setY(inPos.y() / GetZoomFactor());
358 break;
359 case ZoomToWindow:
360 outPos.setX(m_Desktop.width() * inPos.x() / width());
361 outPos.setY(m_Desktop.height() * inPos.y() / height());
362 break;
364 {
365 QRectF r = GetAspectRationRect();
366 if(inPos.x() < r.left()
367 || inPos.x() > r.right()
368 || inPos.y() < r.top()
369 || inPos.y() > r.bottom())
370 return -1;
371 outPos.setX(m_Desktop.width() * (inPos.x() - r.left()) / r.width());
372 outPos.setY(m_Desktop.height() * (inPos.y() - r.top()) / r.height());
373 break;
374 }
375 default:
376 break;
377 }
378
379 return 0;
380}
381
382void CFrmViewerOpenGL::mousePressEvent(QMouseEvent *event)
383{
384 QPointF pos = event->pos();
385 if(TranslationMousePoint(event->pos(), pos)) return;
386 //qDebug() << "CFrmViewer::mousePressEvent" << event->button() << event->buttons();
387 emit sigMousePressEvent(event->buttons(), QPoint(pos.x(), pos.y()));
388 event->accept();
389}
390
391void CFrmViewerOpenGL::mouseReleaseEvent(QMouseEvent *event)
392{
393 QPointF pos = event->pos();
394 if(TranslationMousePoint(event->pos(), pos)) return;
395 //qDebug() << "CFrmViewer::mouseReleaseEvent" << event->button() << event->buttons();
396 emit sigMouseReleaseEvent(event->button(), QPoint(pos.x(), pos.y()));
397 event->accept();
398}
399
400void CFrmViewerOpenGL::mouseMoveEvent(QMouseEvent *event)
401{
402 QPointF pos = event->pos();
403 if(TranslationMousePoint(event->pos(), pos)) return;
404 emit sigMouseMoveEvent(event->buttons(), QPoint(pos.x(), pos.y()));
405 emit sigMouseMoveEvent(event);
406 event->accept();
407}
408
409void CFrmViewerOpenGL::wheelEvent(QWheelEvent *event)
410{
411#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
412 QPointF pos = event->position();
413 if(TranslationMousePoint(event->position(), pos)) return;
414#else
415 QPointF pos = event->pos();
416 if(TranslationMousePoint(event->pos(), pos)) return;
417#endif
418 emit sigWheelEvent(event->buttons(), QPoint(pos.x(), pos.y()), event->angleDelta());
419 event->accept();
420}
421
422void CFrmViewerOpenGL::keyPressEvent(QKeyEvent *event)
423{
424 //qDebug("keyPressEvent key:%d;modifiers:%d", event->key(), event->modifiers());
425 emit sigKeyPressEvent(event->key(), event->modifiers());
426 event->accept();
427}
428
429void CFrmViewerOpenGL::keyReleaseEvent(QKeyEvent *event)
430{
431 //qDebug("keyPressEvent key:%d;modifiers:%d", event->key(), event->modifiers());
432 emit sigKeyReleaseEvent(event->key(), event->modifiers());
433 event->accept();
434}
void slotUpdateCursor(const QCursor &cursor)
Update cursor.
ADAPT_WINDOWS
The ADAPT_WINDOWS enum.
@ Zoom
zoom windows = desktop size * factor
@ OriginalCenter
Original desktop size, the center of the desktop is aligned with the center of the window.
@ KeepAspectRationToWindow
Keep desktop aspectration adapt to windows.
@ Original
Original desktop size, the left-top of the desktop is aligned with the left-top of the window.
@ ZoomToWindow
Desktop adapt to windows.
double GetZoomFactor() const
Adjust the zoom factor.
void slotSetDesktopSize(int width, int height)
Update desktop size.
void slotSetName(const QString &szName)
Update desktop name.
void slotUpdateRect(const QRect &r, const QImage &image)
Update image.
void slotUpdateCursorPosition(const QPoint &pos)
Update cursor position.