Alessandro Bonazzi 8c43d5cf2f Patch level : 12.00
Files correlati     : cg0.exe cg0700a.msk cg0700b.msk cg3.exe cg4.exe

Bug                 :

Commento:
Merge 1.0 libraries
2025-04-06 00:42:21 +02:00

357 lines
11 KiB
C++

/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include <QtOpenGL>
#include <QtSvg>
#define NUM_SWIRLY_ITEMS 10
class GLPainter : public QObject
{
Q_OBJECT
public:
GLPainter(QGLWidget *widget);
void stop();
void resizeViewport(const QSize &size);
public slots:
void start();
protected:
void timerEvent(QTimerEvent *event);
void paint();
void initSwirlyItems();
void updateSwirlyItems();
void drawSuggestiveMessages(QPainter *p);
private:
QMutex mutex;
QGLWidget *glWidget;
int viewportWidth;
int viewportHeight;
bool doRendering;
qreal rotationAngle;
bool swirlClockwise;
QSvgRenderer svgRenderer;
QPixmap logo;
QPainter::PixmapFragment swirlyItems[NUM_SWIRLY_ITEMS];
int swirlyCounter;
int textCounter;
int messageYPos;
qreal scaleFactor;
};
GLPainter::GLPainter(QGLWidget *widget)
: glWidget(widget)
, doRendering(true)
, rotationAngle(rand() % 360)
, swirlClockwise((rand() % 2) == 1)
, svgRenderer(QLatin1String(":/spiral.svg"), this)
, logo(QLatin1String(":/qt-logo.png"))
{
}
void GLPainter::start()
{
glWidget->makeCurrent();
startTimer(20);
}
void GLPainter::stop()
{
QMutexLocker locker(&mutex);
doRendering = false;
}
void GLPainter::resizeViewport(const QSize &size)
{
QMutexLocker locker(&mutex);
viewportWidth = size.width();
viewportHeight = size.height();
initSwirlyItems();
textCounter = 0;
messageYPos = -1;
}
void GLPainter::timerEvent(QTimerEvent *event)
{
QMutexLocker locker(&mutex);
if (!doRendering) {
killTimer(event->timerId());
QThread::currentThread()->quit();
return;
}
updateSwirlyItems();
paint();
}
void GLPainter::paint()
{
QPainter p(glWidget);
p.fillRect(QRect(0, 0, viewportWidth, viewportHeight), Qt::white);
p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
p.translate(viewportWidth / 2, viewportHeight / 2);
p.rotate(rotationAngle * (swirlClockwise ? 1 : -1));
p.scale(svgRenderer.viewBox().width() / 200.0 * 0.65,
svgRenderer.viewBox().height() / 200.0 * 0.65);
p.translate(-viewportWidth / 2, -viewportHeight / 2);
svgRenderer.render(&p);
p.resetTransform();
p.drawPixmapFragments(swirlyItems, NUM_SWIRLY_ITEMS, logo);
drawSuggestiveMessages(&p);
p.end();
rotationAngle += 1.2;
}
void GLPainter::drawSuggestiveMessages(QPainter *p)
{
const int numSuggestiveMessages = 7;
const char *texts[numSuggestiveMessages] = {" You feel relaxed.. ",
" Let your mind wander.. ",
" Look deep into the swirls.. ",
" Even deeper.. ",
" Qt is good! ",
" Qt is good for you! ",
" You MUST use Qt! "};
QFont font(p->font());
font.setPointSizeF(font.pointSizeF() * viewportWidth/200.0);
p->setFont(font);
QFontMetrics fm(font);
int messageNo = textCounter/314;
if (messageNo > 6 || messageNo < 0) {
qFatal("This should not happen: %d - %d", messageNo, textCounter);
}
QLatin1String text(texts[textCounter / 314]);
qreal textWidth = fm.width(text);
int alpha = 255 * qAbs(qSin(textCounter * 0.01));
if (messageYPos < 0 || (textCounter % 314 == 0)) {
messageYPos = qBound(fm.height(), rand() % viewportHeight,
viewportHeight - fm.height());
}
p->setPen(QColor(255, 255, 255, alpha));
p->setBackground(QColor(50, 50, 50, qBound(0, alpha, 50)));
p->setBackgroundMode(Qt::OpaqueMode);
p->drawText((viewportWidth / 2) - (textWidth/ 2), messageYPos, text);
++textCounter;
if (textCounter >= (314 * numSuggestiveMessages))
textCounter = 0;
}
void GLPainter::initSwirlyItems()
{
swirlyCounter = swirlClockwise ? 0 : 360;
scaleFactor = viewportWidth / 200.0;
QRectF logoRect(0, 0, logo.width(), logo.height());
for (int i=0; i<NUM_SWIRLY_ITEMS; ++i) {
if (swirlClockwise) {
swirlyItems[i] = QPainter::PixmapFragment::create(QPointF(0, 0), logoRect,
scaleFactor,
scaleFactor);
} else {
swirlyItems[i] = QPainter::PixmapFragment::create(QPointF(0, 0), logoRect,
scaleFactor * 1 / 360.0,
scaleFactor * 1 / 360.0);
}
}
}
void GLPainter::updateSwirlyItems()
{
swirlyCounter += swirlClockwise ? 1 : -1;
for (int i=0; i<NUM_SWIRLY_ITEMS; ++i) {
int factor;
factor = swirlClockwise ? (swirlyCounter - i * 20) : (swirlyCounter + i * 20);
if (factor > 0 && factor <= 360) {
swirlyItems[i].x = viewportWidth / 2.0 + qSin(factor * 0.05) * (viewportWidth / 2.0) * (100.0 / factor);
swirlyItems[i].y = viewportHeight / 2.0 + qCos(factor * 0.05) * (viewportHeight / 2.0) * (100.0 / factor);
swirlyItems[i].rotation += -swirlyCounter * 0.01;
swirlyItems[i].scaleX += swirlClockwise ? -scaleFactor * 1 / 360.0 : scaleFactor * 1 / 360.0;
if (swirlClockwise) {
if (swirlyItems[i].scaleX < 0)
swirlyItems[i].scaleX = scaleFactor;
} else {
if (swirlyItems[i].scaleX > scaleFactor)
swirlyItems[i].scaleX = scaleFactor * 1 / 360.0;
}
swirlyItems[i].scaleY = swirlyItems[i].scaleX;
} else {
swirlyItems[i].scaleX = swirlyItems[i].scaleY = 0;
}
}
if (swirlClockwise) {
if (swirlyCounter > (360 + NUM_SWIRLY_ITEMS * 20))
swirlyCounter = 0;
} else {
if (swirlyCounter < -NUM_SWIRLY_ITEMS * 20)
swirlyCounter = 360;
}
}
class GLWidget : public QGLWidget
{
public:
GLWidget(QWidget *parent, QGLWidget *shareWidget = 0);
~GLWidget();
void startRendering();
void stopRendering();
protected:
void resizeEvent(QResizeEvent *event);
void paintEvent(QPaintEvent *event);
QSize sizeHint() const { return QSize(200, 200); }
private:
GLPainter glPainter;
QThread glThread;
};
GLWidget::GLWidget(QWidget *parent, QGLWidget *share)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent, share)
, glPainter(this)
, glThread(this)
{
setAttribute(Qt::WA_PaintOutsidePaintEvent);
setAttribute(Qt::WA_DeleteOnClose);
}
GLWidget::~GLWidget()
{
stopRendering();
}
void GLWidget::startRendering()
{
glPainter.moveToThread(&glThread);
connect(&glThread, SIGNAL(started()), &glPainter, SLOT(start()));
glThread.start();
}
void GLWidget::stopRendering()
{
glPainter.stop();
glThread.wait();
}
void GLWidget::resizeEvent(QResizeEvent *event)
{
glPainter.resizeViewport(event->size());
}
void GLWidget::paintEvent(QPaintEvent *)
{
// Handled by GLPainter.
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
private slots:
void newThread();
void killThread();
private:
QMdiArea mdiArea;
QGLWidget shareWidget;
};
MainWindow::MainWindow()
: QMainWindow(0)
, mdiArea(this)
, shareWidget(this)
{
setWindowTitle("Qt GL Hypnotizer");
QMenu *menu = menuBar()->addMenu("&Hypnotizers");
menu->addAction("&New hypnotizer thread", this, SLOT(newThread()), QKeySequence("Ctrl+N"));
menu->addAction("&End current hypnotizer thread", this, SLOT(killThread()), QKeySequence("Ctrl+K"));
menu->addSeparator();
menu->addAction("E&xit", qApp, SLOT(quit()), QKeySequence("Ctrl+Q"));
setCentralWidget(&mdiArea);
shareWidget.resize(1, 1);
newThread();
}
void MainWindow::newThread()
{
static int windowCount = 1;
if (mdiArea.subWindowList().count() > 9)
return;
GLWidget *widget = new GLWidget(&mdiArea, &shareWidget);
mdiArea.addSubWindow(widget);
widget->setWindowTitle("Thread #" + QString::number(windowCount++));
widget->show();
widget->startRendering();
}
void MainWindow::killThread()
{
delete mdiArea.activeSubWindow();
}
int main(int argc, char *argv[])
{
// Make Xlib and GLX thread safe under X11
QApplication::setAttribute(Qt::AA_X11InitThreads);
QApplication application(argc, argv);
// Using QPainter to draw into QGLWidgets is only supported with GL 2.0
if (!((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0) ||
(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_ES_Version_2_0))) {
QMessageBox::information(0, "Qt GL Hypnotizer",
"This system does not support OpenGL 2.0 or OpenGL ES 2.0, "
"which is required for this example to work.");
return 0;
}
MainWindow mainWindow;
mainWindow.show();
return application.exec();
}
#include "main.moc"