mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-30 08:24:11 +01:00
Merge remote-tracking branch 'origin/GCS_CachedSvgItem_Dmytro' into next
This commit is contained in:
commit
9c38bd0cf6
159
ground/openpilotgcs/src/libs/utils/cachedsvgitem.cpp
Normal file
159
ground/openpilotgcs/src/libs/utils/cachedsvgitem.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file cachedsvgitem.h
|
||||
* @author Dmytro Poplavskiy Copyright (C) 2011.
|
||||
* @{
|
||||
* @brief OpenGL texture cached SVG item
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "cachedsvgitem.h"
|
||||
#include <QGLContext>
|
||||
#include <QDebug>
|
||||
|
||||
#ifndef GL_CLAMP_TO_EDGE
|
||||
#define GL_CLAMP_TO_EDGE 0x812F
|
||||
#endif
|
||||
|
||||
CachedSvgItem::CachedSvgItem(QGraphicsItem * parent) :
|
||||
QGraphicsSvgItem(parent),
|
||||
m_context(0),
|
||||
m_texture(0),
|
||||
m_scale(1.0)
|
||||
{
|
||||
setCacheMode(NoCache);
|
||||
}
|
||||
|
||||
CachedSvgItem::CachedSvgItem(const QString & fileName, QGraphicsItem * parent):
|
||||
QGraphicsSvgItem(fileName, parent),
|
||||
m_context(0),
|
||||
m_texture(0),
|
||||
m_scale(1.0)
|
||||
{
|
||||
setCacheMode(NoCache);
|
||||
}
|
||||
|
||||
CachedSvgItem::~CachedSvgItem()
|
||||
{
|
||||
if (m_context && m_texture) {
|
||||
m_context->makeCurrent();
|
||||
glDeleteTextures(1, &m_texture);
|
||||
}
|
||||
}
|
||||
|
||||
void CachedSvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
|
||||
if (painter->paintEngine()->type() != QPaintEngine::OpenGL &&
|
||||
painter->paintEngine()->type() != QPaintEngine::OpenGL2) {
|
||||
//Fallback to direct painting
|
||||
QGraphicsSvgItem::paint(painter, option, widget);
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF br = boundingRect();
|
||||
QTransform transform = painter->worldTransform();
|
||||
qreal sceneScale = transform.map(QLineF(0,0,1,0)).length();
|
||||
|
||||
bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
|
||||
bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);
|
||||
|
||||
painter->beginNativePainting();
|
||||
|
||||
if (stencilTestEnabled)
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
if (scissorTestEnabled)
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
bool dirty = false;
|
||||
if (!m_texture) {
|
||||
glGenTextures(1, &m_texture);
|
||||
m_context = const_cast<QGLContext*>(QGLContext::currentContext());
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (!qFuzzyCompare(sceneScale, m_scale)) {
|
||||
m_scale = sceneScale;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
int textureWidth = (int(br.width()*m_scale) + 3) & ~3;
|
||||
int textureHeight = (int(br.height()*m_scale) + 3) & ~3;
|
||||
|
||||
if (dirty) {
|
||||
//qDebug() << "re-render image";
|
||||
|
||||
QImage img(textureWidth, textureHeight, QImage::Format_ARGB32);
|
||||
{
|
||||
img.fill(Qt::transparent);
|
||||
QPainter p;
|
||||
p.begin(&img);
|
||||
p.setRenderHints(painter->renderHints());
|
||||
p.translate(br.topLeft());
|
||||
p.scale(m_scale, m_scale);
|
||||
QGraphicsSvgItem::paint(&p, option, 0);
|
||||
p.end();
|
||||
|
||||
img = img.rgbSwapped();
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
textureWidth,
|
||||
textureHeight,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
img.bits());
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_texture);
|
||||
|
||||
//texture may be slightly large than svn image, ensure only used area is rendered
|
||||
qreal tw = br.width()*m_scale/textureWidth;
|
||||
qreal th = br.height()*m_scale/textureHeight;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2d(0, 0 ); glVertex3d(br.left(), br.top(), -1);
|
||||
glTexCoord2d(tw, 0 ); glVertex3d(br.right(), br.top(), -1);
|
||||
glTexCoord2d(tw, th); glVertex3d(br.right(), br.bottom(), -1);
|
||||
glTexCoord2d(0, th); glVertex3d(br.left(), br.bottom(), -1);
|
||||
glEnd();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
painter->endNativePainting();
|
||||
}
|
54
ground/openpilotgcs/src/libs/utils/cachedsvgitem.h
Normal file
54
ground/openpilotgcs/src/libs/utils/cachedsvgitem.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
*
|
||||
* @file cachedsvgitem.h
|
||||
* @author Dmytro Poplavskiy Copyright (C) 2011.
|
||||
* @{
|
||||
* @brief OpenGL texture cached SVG item
|
||||
*****************************************************************************/
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef CACHEDSVGITEM_H
|
||||
#define CACHEDSVGITEM_H
|
||||
|
||||
#include <QGraphicsSvgItem>
|
||||
#include <QGLContext>
|
||||
|
||||
#include "utils_global.h"
|
||||
|
||||
class QGLContext;
|
||||
|
||||
//Cache Svg item as GL Texture.
|
||||
//Texture is regenerated each time item is scaled
|
||||
//but it's reused during rotation, unlike DeviceCoordinateCache mode
|
||||
class QTCREATOR_UTILS_EXPORT CachedSvgItem: public QGraphicsSvgItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CachedSvgItem(QGraphicsItem * parent = 0);
|
||||
CachedSvgItem(const QString & fileName, QGraphicsItem * parent = 0);
|
||||
~CachedSvgItem();
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
|
||||
private:
|
||||
QGLContext *m_context;
|
||||
GLuint m_texture;
|
||||
qreal m_scale;
|
||||
};
|
||||
|
||||
#endif
|
@ -3,7 +3,9 @@ TARGET = Utils
|
||||
|
||||
QT += gui \
|
||||
network \
|
||||
xml
|
||||
xml \
|
||||
svg \
|
||||
opengl
|
||||
|
||||
DEFINES += QTCREATOR_UTILS_LIB
|
||||
|
||||
@ -48,7 +50,8 @@ SOURCES += reloadpromptutils.cpp \
|
||||
homelocationutil.cpp \
|
||||
mytabbedstackwidget.cpp \
|
||||
mytabwidget.cpp \
|
||||
mylistwidget.cpp
|
||||
mylistwidget.cpp \
|
||||
cachedsvgitem.cpp
|
||||
SOURCES += xmlconfig.cpp
|
||||
|
||||
win32 {
|
||||
@ -102,7 +105,8 @@ HEADERS += utils_global.h \
|
||||
homelocationutil.h \
|
||||
mytabbedstackwidget.h \
|
||||
mytabwidget.h \
|
||||
mylistwidget.h
|
||||
mylistwidget.h \
|
||||
cachedsvgitem.h
|
||||
HEADERS += xmlconfig.h
|
||||
|
||||
FORMS += filewizardpage.ui \
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
#include "pfdgadgetwidget.h"
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/cachedsvgitem.h>
|
||||
#include <iostream>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
@ -383,7 +384,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
- Battery stats: battery-txt
|
||||
*/
|
||||
l_scene->clear(); // Deletes all items contained in the scene as well.
|
||||
m_background = new QGraphicsSvgItem();
|
||||
m_background = new CachedSvgItem();
|
||||
// All other items will be clipped to the shape of the background
|
||||
m_background->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
QGraphicsItem::ItemClipsToShape);
|
||||
@ -391,28 +392,28 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
m_background->setElementId("background");
|
||||
l_scene->addItem(m_background);
|
||||
|
||||
m_world = new QGraphicsSvgItem();
|
||||
m_world = new CachedSvgItem();
|
||||
m_world->setParentItem(m_background);
|
||||
m_world->setSharedRenderer(m_renderer);
|
||||
m_world->setElementId("world");
|
||||
l_scene->addItem(m_world);
|
||||
|
||||
// red Roll scale: rollscale
|
||||
m_rollscale = new QGraphicsSvgItem();
|
||||
m_rollscale = new CachedSvgItem();
|
||||
m_rollscale->setSharedRenderer(m_renderer);
|
||||
m_rollscale->setElementId("rollscale");
|
||||
l_scene->addItem(m_rollscale);
|
||||
|
||||
// Home point:
|
||||
m_homewaypoint = new QGraphicsSvgItem();
|
||||
m_homewaypoint = new CachedSvgItem();
|
||||
// Next point:
|
||||
m_nextwaypoint = new QGraphicsSvgItem();
|
||||
m_nextwaypoint = new CachedSvgItem();
|
||||
// Home point bearing:
|
||||
m_homepointbearing = new QGraphicsSvgItem();
|
||||
m_homepointbearing = new CachedSvgItem();
|
||||
// Next point bearing:
|
||||
m_nextpointbearing = new QGraphicsSvgItem();
|
||||
m_nextpointbearing = new CachedSvgItem();
|
||||
|
||||
QGraphicsSvgItem *m_foreground = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *m_foreground = new CachedSvgItem();
|
||||
m_foreground->setParentItem(m_background);
|
||||
m_foreground->setSharedRenderer(m_renderer);
|
||||
m_foreground->setElementId("foreground");
|
||||
@ -429,7 +430,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
// into a QGraphicsSvgItem which we will display at the same
|
||||
// place: we do this so that the heading scale can be clipped to
|
||||
// the compass dial region.
|
||||
m_compass = new QGraphicsSvgItem();
|
||||
m_compass = new CachedSvgItem();
|
||||
m_compass->setSharedRenderer(m_renderer);
|
||||
m_compass->setElementId("compass");
|
||||
m_compass->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
@ -440,7 +441,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
m_compass->setTransform(matrix,false);
|
||||
|
||||
// Now place the compass scale inside:
|
||||
m_compassband = new QGraphicsSvgItem();
|
||||
m_compassband = new CachedSvgItem();
|
||||
m_compassband->setSharedRenderer(m_renderer);
|
||||
m_compassband->setElementId("compass-band");
|
||||
m_compassband->setParentItem(m_compass);
|
||||
@ -462,7 +463,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
compassMatrix = m_renderer->matrixForElement("speed-bg");
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-bg")).y();
|
||||
QGraphicsSvgItem *verticalbg = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *verticalbg = new CachedSvgItem();
|
||||
verticalbg->setSharedRenderer(m_renderer);
|
||||
verticalbg->setElementId("speed-bg");
|
||||
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
@ -477,7 +478,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
m_speedscale = new QGraphicsItemGroup();
|
||||
m_speedscale->setParentItem(verticalbg);
|
||||
|
||||
QGraphicsSvgItem *speedscalelines = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *speedscalelines = new CachedSvgItem();
|
||||
speedscalelines->setSharedRenderer(m_renderer);
|
||||
speedscalelines->setElementId("speed-scale");
|
||||
speedScaleHeight = m_renderer->matrixForElement("speed-scale").mapRect(
|
||||
@ -523,7 +524,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).y();
|
||||
qreal speedWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("speed-window")).height();
|
||||
QGraphicsSvgItem *speedwindow = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *speedwindow = new CachedSvgItem();
|
||||
speedwindow->setSharedRenderer(m_renderer);
|
||||
speedwindow->setElementId("speed-window");
|
||||
speedwindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
@ -548,7 +549,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
compassMatrix = m_renderer->matrixForElement("altitude-bg");
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-bg")).y();
|
||||
verticalbg = new QGraphicsSvgItem();
|
||||
verticalbg = new CachedSvgItem();
|
||||
verticalbg->setSharedRenderer(m_renderer);
|
||||
verticalbg->setElementId("altitude-bg");
|
||||
verticalbg->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
@ -563,7 +564,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
m_altitudescale = new QGraphicsItemGroup();
|
||||
m_altitudescale->setParentItem(verticalbg);
|
||||
|
||||
QGraphicsSvgItem *altitudescalelines = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *altitudescalelines = new CachedSvgItem();
|
||||
altitudescalelines->setSharedRenderer(m_renderer);
|
||||
altitudescalelines->setElementId("altitude-scale");
|
||||
altitudeScaleHeight = m_renderer->matrixForElement("altitude-scale").mapRect(
|
||||
@ -604,7 +605,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).y();
|
||||
qreal altitudeWindowHeight = compassMatrix.mapRect(m_renderer->boundsOnElement("altitude-window")).height();
|
||||
QGraphicsSvgItem *altitudewindow = new QGraphicsSvgItem();
|
||||
QGraphicsSvgItem *altitudewindow = new CachedSvgItem();
|
||||
altitudewindow->setSharedRenderer(m_renderer);
|
||||
altitudewindow->setElementId("altitude-window");
|
||||
altitudewindow->setFlags(QGraphicsItem::ItemClipsChildrenToShape|
|
||||
@ -633,7 +634,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
|
||||
gcsTelemetryArrow = new QGraphicsSvgItem();
|
||||
gcsTelemetryArrow = new CachedSvgItem();
|
||||
gcsTelemetryArrow->setSharedRenderer(m_renderer);
|
||||
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
|
||||
l_scene->addItem(gcsTelemetryArrow);
|
||||
@ -669,7 +670,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
|
||||
gcsTelemetryArrow = new QGraphicsSvgItem();
|
||||
gcsTelemetryArrow = new CachedSvgItem();
|
||||
gcsTelemetryArrow->setSharedRenderer(m_renderer);
|
||||
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
|
||||
l_scene->addItem(gcsTelemetryArrow);
|
||||
@ -702,7 +703,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
compassMatrix = m_renderer->matrixForElement("gcstelemetry-Disconnected");
|
||||
startX = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).x();
|
||||
startY = compassMatrix.mapRect(m_renderer->boundsOnElement("gcstelemetry-Disconnected")).y();
|
||||
gcsTelemetryArrow = new QGraphicsSvgItem();
|
||||
gcsTelemetryArrow = new CachedSvgItem();
|
||||
gcsTelemetryArrow->setSharedRenderer(m_renderer);
|
||||
gcsTelemetryArrow->setElementId("gcstelemetry-Disconnected");
|
||||
l_scene->addItem(gcsTelemetryArrow);
|
||||
@ -771,7 +772,7 @@ void PFDGadgetWidget::setDialFile(QString dfn)
|
||||
{ qDebug()<<"Error on PFD artwork file.";
|
||||
m_renderer->load(QString(":/pfd/images/pfd-default.svg"));
|
||||
l_scene->clear(); // This also deletes all items contained in the scene.
|
||||
m_background = new QGraphicsSvgItem();
|
||||
m_background = new CachedSvgItem();
|
||||
m_background->setSharedRenderer(m_renderer);
|
||||
l_scene->addItem(m_background);
|
||||
pfdError = true;
|
||||
|
Loading…
Reference in New Issue
Block a user