Gui: remove support of using deprecated Qt OpenGL API

This commit is contained in:
wmayer
2022-01-26 14:46:41 +01:00
parent 233182dcd6
commit a87e33258d
20 changed files with 22 additions and 1261 deletions

View File

@@ -71,10 +71,6 @@ macro(InitializeFreeCADBuildOptions)
)
if (BUILD_QT5)
option(FREECAD_USE_QTOPENGL_WIDGET "Replace QGLWidget with QOpenGLWidget." ON)
if (FREECAD_USE_QTOPENGL_WIDGET)
set(HAVE_QT5_OPENGL 1 )
endif()
set(FREECAD_USE_QTWEBMODULE "Automatic" CACHE STRING "Qt Webkit or Qt WebEngine")
set_property(CACHE FREECAD_USE_QTWEBMODULE PROPERTY STRINGS
"Automatic"

View File

@@ -47,9 +47,7 @@
#include <boost/interprocess/sync/file_lock.hpp>
#include <boost/filesystem.hpp>
#include <QtOpenGL.h>
#if defined(HAVE_QT5_OPENGL)
#include <QWindow>
#endif
// FreeCAD Base header
#include <Base/Console.h>
@@ -2017,40 +2015,6 @@ void Application::runApplication(void)
// register action style event type
ActionStyleEvent::EventType = QEvent::registerEventType(QEvent::User + 1);
// check for OpenGL
#if !defined(HAVE_QT5_OPENGL)
if (!QGLFormat::hasOpenGL()) {
QMessageBox::critical(0, QObject::tr("No OpenGL"), QObject::tr("This system does not support OpenGL"));
throw Base::RuntimeError("This system does not support OpenGL");
}
if (!QGLFramebufferObject::hasOpenGLFramebufferObjects()) {
Base::Console().Log("This system does not support framebuffer objects\n");
}
if (!QGLPixelBuffer::hasOpenGLPbuffers()) {
Base::Console().Log("This system does not support pbuffers\n");
}
QGLFormat::OpenGLVersionFlags version = QGLFormat::openGLVersionFlags ();
if (version & QGLFormat::OpenGL_Version_3_0)
Base::Console().Log("OpenGL version 3.0 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_2_1)
Base::Console().Log("OpenGL version 2.1 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_2_0)
Base::Console().Log("OpenGL version 2.0 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_1_5)
Base::Console().Log("OpenGL version 1.5 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_1_4)
Base::Console().Log("OpenGL version 1.4 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_1_3)
Base::Console().Log("OpenGL version 1.3 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_1_2)
Base::Console().Log("OpenGL version 1.2 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_1_1)
Base::Console().Log("OpenGL version 1.1 or higher is present\n");
else if (version & QGLFormat::OpenGL_Version_None)
Base::Console().Log("No OpenGL is present or no OpenGL context is current\n");
#endif
ParameterGrp::handle hTheme = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Bitmaps/Theme");
#if !defined(Q_OS_LINUX)
QIcon::setThemeSearchPaths(QIcon::themeSearchPaths() << QString::fromLatin1(":/icons/FreeCAD-default"));
@@ -2135,7 +2099,6 @@ void Application::runApplication(void)
mainApp.installEventFilter(filter);
}
#if defined(HAVE_QT5_OPENGL)
{
QWindow window;
window.setSurfaceType(QWindow::OpenGLSurface);
@@ -2157,7 +2120,6 @@ void Application::runApplication(void)
Base::Console().Log("OpenGL version is: %d.%d (%s)\n", major, minor, glVersion);
}
}
#endif
// init the Inventor subsystem
initOpenInventor();

View File

@@ -1705,7 +1705,6 @@ void StdViewDockUndockFullscreen::activated(int iMsg)
MDIView* view = getMainWindow()->activeWindow();
if (!view) return; // no active view
#if defined(HAVE_QT5_OPENGL)
// nothing to do when the view is docked and 'Docked' is pressed
if (iMsg == 0 && view->currentViewMode() == MDIView::Child)
return;
@@ -1747,23 +1746,6 @@ void StdViewDockUndockFullscreen::activated(int iMsg)
// destroy the old view
view->deleteSelf();
}
#else
if (iMsg==0) {
view->setCurrentViewMode(MDIView::Child);
}
else if (iMsg==1) {
if (view->currentViewMode() == MDIView::TopLevel)
view->setCurrentViewMode(MDIView::Child);
else
view->setCurrentViewMode(MDIView::TopLevel);
}
else if (iMsg==2) {
if (view->currentViewMode() == MDIView::FullScreen)
view->setCurrentViewMode(MDIView::Child);
else
view->setCurrentViewMode(MDIView::FullScreen);
}
#endif
}
bool StdViewDockUndockFullscreen::isActive(void)

View File

@@ -45,9 +45,7 @@ Flag::Flag(QWidget* parent)
: QtGLWidget(parent), coord(0.0f, 0.0f, 0.0f)
{
this->setFixedHeight(20);
#if defined(HAVE_QT5_OPENGL)
setAutoFillBackground(true);
#endif
}
Flag::~Flag()
@@ -57,31 +55,17 @@ Flag::~Flag()
void Flag::initializeGL()
{
const QPalette& p = this->palette();
#if !defined(HAVE_QT5_OPENGL)
qglClearColor(p.color(QPalette::Window));
#else
QColor c(p.color(QPalette::Window));
glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF());
#endif
}
void Flag::paintGL()
{
#if !defined(HAVE_QT5_OPENGL)
const QPalette& p = this->palette();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
qglColor(p.color(QPalette::Text));
renderText(10,15,this->text);
#else
QOpenGLWidget::paintGL();
#endif
}
void Flag::paintEvent(QPaintEvent* e)
{
#if !defined(HAVE_QT5_OPENGL)
QtGLWidget::paintEvent(e);
#else
const QPalette& p = this->palette();
QColor c(p.color(QPalette::Text));
@@ -92,7 +76,6 @@ void Flag::paintEvent(QPaintEvent* e)
painter.setPen(c);
painter.drawText(10, 15, this->text);
painter.end();
#endif
}
void Flag::resizeGL(int width, int height)
@@ -125,9 +108,6 @@ void Flag::drawLine (View3DInventorViewer* v, int tox, int toy)
GLPainter p;
p.begin(v->getGLWidget());
#if !defined(HAVE_QT5_OPENGL)
p.setDrawBuffer(GL_BACK);
#endif
// the line
p.setLineWidth(1.0f);
@@ -153,11 +133,9 @@ void Flag::mouseMoveEvent(QMouseEvent *e)
if (e->buttons() & Qt::LeftButton) {
move(e->globalPos() - dragPosition);
e->accept();
#if defined(HAVE_QT5_OPENGL)
View3DInventorViewer* viewer = dynamic_cast<View3DInventorViewer*>(parentWidget());
if (viewer)
viewer->getSoRenderManager()->scheduleRedraw();
#endif
}
}
@@ -371,10 +349,8 @@ void GLFlagWindow::deleteFlags()
flag->deleteLater();
}
}
#if defined(HAVE_QT5_OPENGL)
if (ct > 0)
_viewer->getSoRenderManager()->scheduleRedraw();
#endif
}
}
@@ -395,9 +371,7 @@ void GLFlagWindow::removeFlag(Flag* item)
{
if (_flagLayout) {
_flagLayout->removeWidget(item);
#if defined(HAVE_QT5_OPENGL)
_viewer->getSoRenderManager()->scheduleRedraw();
#endif
}
}

View File

@@ -91,10 +91,6 @@ bool GLPainter::begin(QPaintDevice * device)
glColor4f(1.0, 1.0, 1.0, 0.0);
glViewport(0, 0, this->width, this->height);
#if !defined(HAVE_QT5_OPENGL)
glDrawBuffer(GL_FRONT);
#endif
return true;
}

View File

@@ -380,9 +380,6 @@ public:
if (samples > 1) {
glformat = true;
#if !defined(HAVE_QT5_OPENGL)
f.setSampleBuffers(true);
#endif
f.setSamples(samples);
}
else if (samples > 0) {

View File

@@ -109,10 +109,7 @@
#include <QImage>
#include <QPainterPath>
#include <QApplication>
#if defined(HAVE_QT5_OPENGL)
# include <QOpenGLTexture>
#endif
#include <QOpenGLTexture>
//#include <OpenGL/glu.h>
#include <Eigen/Dense>
@@ -285,9 +282,7 @@ public:
map<int,GLuint> m_Textures;
vector<Face*> m_Faces;
vector<int> m_Buttons;
#if defined(HAVE_QT5_OPENGL)
vector<QOpenGLTexture *> m_glTextures;
#endif
static vector<string> m_commands;
static vector<string> m_labels;
QMenu* m_Menu;
@@ -350,10 +345,8 @@ NaviCubeImplementation::~NaviCubeImplementation() {
delete m_PickingFramebuffer;
for (vector<Face*>::iterator f = m_Faces.begin(); f != m_Faces.end(); f++)
delete *f;
#if defined(HAVE_QT5_OPENGL)
for (vector<QOpenGLTexture *>::iterator t = m_glTextures.begin(); t != m_glTextures.end(); t++)
delete *t;
#endif
}
void NaviCubeImplementation::OnChange(ParameterGrp::SubjectType &rCaller, ParameterGrp::MessageType reason)
@@ -473,16 +466,12 @@ GLuint NaviCubeImplementation::createCubeFaceTex(QtGLWidget* gl, float gap, cons
}
paint.end();
#if !defined(HAVE_QT5_OPENGL)
return gl->bindTexture(image);
#else
Q_UNUSED(gl);
QOpenGLTexture *texture = new QOpenGLTexture(image.mirrored());
m_glTextures.push_back(texture);
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
return texture->textureId();
#endif
}
@@ -581,16 +570,12 @@ GLuint NaviCubeImplementation::createButtonTex(QtGLWidget* gl, int button) {
painter.end();
//image.save(str(enum2str(button))+str(".png"));
#if !defined(HAVE_QT5_OPENGL)
return gl->bindTexture(image);
#else
Q_UNUSED(gl);
QOpenGLTexture *texture = new QOpenGLTexture(image.mirrored());
m_glTextures.push_back(texture);
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
return texture->textureId();
#endif
}
GLuint NaviCubeImplementation::createMenuTex(QtGLWidget* gl, bool forPicking) {
@@ -656,16 +641,12 @@ GLuint NaviCubeImplementation::createMenuTex(QtGLWidget* gl, bool forPicking) {
painter.fillPath(path5, QColor(64,64,64));
}
painter.end();
#if !defined(HAVE_QT5_OPENGL)
return gl->bindTexture(image);
#else
Q_UNUSED(gl);
QOpenGLTexture *texture = new QOpenGLTexture(image.mirrored());
m_glTextures.push_back(texture);
texture->setMinificationFilter(QOpenGLTexture::Nearest);
texture->setMagnificationFilter(QOpenGLTexture::Linear);
return texture->textureId();
#endif
}
void NaviCubeImplementation::addFace(const Vector3f& x, const Vector3f& z, int frontTex, int pickTex, int pickId, bool text) {

View File

@@ -66,10 +66,8 @@
#include <QPaintEvent>
#include <QResizeEvent>
#if defined(HAVE_QT5_OPENGL)
#include <QOpenGLDebugMessage>
#include <QOpenGLDebugLogger>
#endif
#if COIN_MAJOR_VERSION >= 4
#include <Inventor/SbByteBuffer.h>
@@ -147,7 +145,6 @@ using namespace SIM::Coin3D::Quarter;
#endif
//We need to avoid buffer swapping when initializing a QPainter on this widget
#if defined(HAVE_QT5_OPENGL)
class CustomGLWidget : public QOpenGLWidget {
public:
QSurfaceFormat myFormat;
@@ -247,16 +244,6 @@ public:
update(); // fixes flickering on some systems
}
};
#else
class CustomGLWidget : public QGLWidget {
public:
CustomGLWidget(const QGLFormat& fo, QWidget* parent = 0, const QGLWidget* shareWidget = 0, Qt::WindowFlags f = 0)
: QGLWidget(fo, parent, shareWidget, f)
{
setAutoBufferSwap(false);
}
};
#endif
/*! constructor */
QuarterWidget::QuarterWidget(const QtGLFormat & format, QWidget * parent, const QtGLWidget * sharewidget, Qt::WindowFlags f)
@@ -340,7 +327,6 @@ QuarterWidget::constructor(const QtGLFormat & format, const QtGLWidget * sharewi
void
QuarterWidget::replaceViewport()
{
#if defined(HAVE_QT5_OPENGL)
CustomGLWidget* oldvp = static_cast<CustomGLWidget*>(viewport());
CustomGLWidget* newvp = new CustomGLWidget(oldvp->myFormat, this);
PRIVATE(this)->replaceGLWidget(newvp);
@@ -348,7 +334,6 @@ QuarterWidget::replaceViewport()
setAutoFillBackground(false);
viewport()->setAutoFillBackground(false);
#endif
}
void
@@ -884,18 +869,12 @@ void QuarterWidget::paintEvent(QPaintEvent* event)
}
if(!initialized) {
#if !defined(HAVE_QT5_OPENGL)
glEnable(GL_DEPTH_TEST);
#endif
this->getSoRenderManager()->reinitialize();
initialized = true;
}
getSoRenderManager()->activate();
#if !defined(HAVE_QT5_OPENGL)
glEnable(GL_DEPTH_TEST);
#endif
glMatrixMode(GL_PROJECTION);
QtGLWidget* w = static_cast<QtGLWidget*>(this->viewport());
@@ -928,12 +907,8 @@ void QuarterWidget::paintEvent(QPaintEvent* event)
assert(w->isValid() && "No valid GL context found!");
#if defined(HAVE_QT5_OPENGL)
// Causes an OpenGL error on resize
//glDrawBuffer(w->format().swapBehavior() == QSurfaceFormat::DoubleBuffer ? GL_BACK : GL_FRONT);
#else
glDrawBuffer(w->doubleBuffer() ? GL_BACK : GL_FRONT);
#endif
w->makeCurrent();
this->actualRedraw();
@@ -945,13 +920,9 @@ void QuarterWidget::paintEvent(QPaintEvent* event)
inherited::paintEvent(event);
glPopAttrib();
#if defined(HAVE_QT5_OPENGL)
// Causes an OpenGL error on resize
//if (w->format().swapBehavior() == QSurfaceFormat::DoubleBuffer)
// w->context()->swapBuffers(w->context()->surface());
#else
if (w->doubleBuffer()) { w->swapBuffers(); }
#endif
PRIVATE(this)->autoredrawenabled = true;

View File

@@ -53,10 +53,8 @@
#include "SoFCOffscreenRenderer.h"
#include "BitmapFactory.h"
#if defined(HAVE_QT5_OPENGL)
# include <QOffscreenSurface>
# include <QOpenGLContext>
#endif
#include <QOffscreenSurface>
#include <QOpenGLContext>
using namespace Gui;
using namespace std;
@@ -412,18 +410,10 @@ void SoQtOffscreenRenderer::init(const SbViewportRegion & vpr,
this->didallocation = glrenderaction ? false : true;
this->viewport = vpr;
#if !defined(HAVE_QT5_OPENGL)
this->pixelbuffer = NULL; // constructed later
#endif
this->framebuffer = NULL;
this->numSamples = -1;
#if defined(HAVE_QT5_OPENGL)
//this->texFormat = GL_RGBA32F_ARB;
this->texFormat = GL_RGB32F_ARB;
#else
//this->texFormat = GL_RGBA;
this->texFormat = GL_RGB;
#endif
this->cache_context = 0;
this->pbuffer = false;
}
@@ -452,9 +442,6 @@ SoQtOffscreenRenderer::SoQtOffscreenRenderer(SoGLRenderAction * action)
*/
SoQtOffscreenRenderer::~SoQtOffscreenRenderer()
{
#if !defined(HAVE_QT5_OPENGL)
delete pixelbuffer;
#endif
delete framebuffer;
if (this->didallocation) {
@@ -573,37 +560,6 @@ SoQtOffscreenRenderer::pre_render_cb(void * /*userdata*/, SoGLRenderAction * act
action->setRenderingIsRemote(false);
}
#if !defined(HAVE_QT5_OPENGL)
void
SoQtOffscreenRenderer::makePixelBuffer(int width, int height, int samples)
{
if (pixelbuffer) {
delete pixelbuffer;
pixelbuffer = NULL;
}
viewport.setWindowSize(width, height);
QGLFormat fmt;
// With enabled alpha a transparent background is supported but
// at the same time breaks semi-transparent models. A workaround
// is to use a certain background color using GL_RGB as texture
// format and in the output image search for the above color and
// replaces it with the color requested by the user.
//fmt.setAlpha(true);
if (samples > 0) {
fmt.setSampleBuffers(true);
fmt.setSamples(samples);
}
else {
fmt.setSampleBuffers(false);
}
pixelbuffer = new QGLPixelBuffer(width, height, fmt);
cache_context = SoGLCacheContextElement::getUniqueCacheContext(); // unique per pixel buffer object, just to be sure
}
#endif
void
SoQtOffscreenRenderer::makeFrameBuffer(int width, int height, int samples)
{
@@ -633,7 +589,6 @@ SoQtOffscreenRenderer::renderFromBase(SoBase * base)
{
const SbVec2s fullsize = this->viewport.getViewportSizePixels();
#if defined(HAVE_QT5_OPENGL)
QSurfaceFormat format;
format.setSamples(PRIVATE(this)->numSamples);
QOpenGLContext context;
@@ -644,34 +599,17 @@ SoQtOffscreenRenderer::renderFromBase(SoBase * base)
offscreen.setFormat(format);
offscreen.create();
context.makeCurrent(&offscreen);
#endif
#if !defined(HAVE_QT5_OPENGL)
if (PRIVATE(this)->pbuffer) {
if (!pixelbuffer) {
makePixelBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
else if (pixelbuffer->width() != fullsize[0] || pixelbuffer->height() != fullsize[1]) {
// get the size right!
makePixelBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
pixelbuffer->makeCurrent(); // activate us!
if (!framebuffer) {
makeFrameBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
else
#endif
{
if (!framebuffer) {
makeFrameBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
else if (framebuffer->width() != fullsize[0] || framebuffer->height() != fullsize[1]) {
// get the size right!
makeFrameBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
framebuffer->bind(); // activate us!
else if (framebuffer->width() != fullsize[0] || framebuffer->height() != fullsize[1]) {
// get the size right!
makeFrameBuffer(fullsize[0], fullsize[1], PRIVATE(this)->numSamples);
}
framebuffer->bind(); // activate us!
// oldcontext is used to restore the previous context id, in case
// the render action is not allocated by us.
const uint32_t oldcontext = this->renderaction->getCacheContext();
@@ -697,23 +635,12 @@ SoQtOffscreenRenderer::renderFromBase(SoBase * base)
}
this->renderaction->removePreRenderCallback(pre_render_cb, NULL);
#if !defined(HAVE_QT5_OPENGL)
if (pixelbuffer) {
pixelbuffer->doneCurrent();
}
else
#endif
{
framebuffer->release();
}
framebuffer->release();
this->renderaction->setCacheContext(oldcontext); // restore old
#if defined(HAVE_QT5_OPENGL)
glImage = framebuffer->toImage();
context.doneCurrent();
#endif
return true;
}
@@ -780,14 +707,7 @@ SoQtOffscreenRenderer::render(SoPath * scene)
void
SoQtOffscreenRenderer::writeToImage (QImage& img) const
{
#if !defined(HAVE_QT5_OPENGL)
if (pixelbuffer)
img = pixelbuffer->toImage();
else if (framebuffer)
img = framebuffer->toImage();
#else
img = this->glImage;
#endif
if (PRIVATE(this)->backgroundcolor[3] < 1.0) {
QColor c1, c2;
c1.setRedF(PRIVATE(this)->backgroundcolor[0]);

View File

@@ -133,14 +133,8 @@ private:
void init(const SbViewportRegion & vpr, SoGLRenderAction * glrenderaction = NULL);
static void pre_render_cb(void * userdata, SoGLRenderAction * action);
SbBool renderFromBase(SoBase * base);
#if !defined(HAVE_QT5_OPENGL)
void makePixelBuffer(int width, int height, int samples);
#endif
void makeFrameBuffer(int width, int height, int samples);
#if !defined(HAVE_QT5_OPENGL)
QGLPixelBuffer* pixelbuffer; // the offscreen rendering supported by Qt
#endif
QtGLFramebufferObject* framebuffer;
uint32_t cache_context; // our unique context id
@@ -152,9 +146,7 @@ private:
SbBool pbuffer;
int numSamples;
GLenum texFormat;
#if defined(HAVE_QT5_OPENGL)
QImage glImage;
#endif
};
} // namespace Gui

View File

@@ -377,10 +377,10 @@ void SoStringLabel::GLRender(SoGLRenderAction *action)
QStringList list;
for (int i=0; i<this->string.getNum(); i++)
list << QLatin1String(this->string[i].getString());
#if !defined(HAVE_QT5_OPENGL)
#if 0 // Old OpenGL API
window->renderText(nil[0],nil[1],nil[2],list.join(QLatin1String("\n")),font);
#else
//FIXME: HAVE_QT5_OPENGL
//FIXME: renderText
#endif
// Leave 2D screen mode

View File

@@ -767,9 +767,6 @@ SplitView3DInventor::SplitView3DInventor(int views, Gui::Document* pcDocument, Q
if (samples > 1) {
glformat = true;
#if !defined(HAVE_QT5_OPENGL)
f.setSampleBuffers(true);
#endif
f.setSamples(samples);
}
else if (samples > 0) {

View File

@@ -56,12 +56,10 @@
# include <Inventor/fields/SoSFString.h>
# include <Inventor/fields/SoSFColor.h>
#endif
# include <QStackedWidget>
#include <QStackedWidget>
#include <QtOpenGL.h>
#if defined(HAVE_QT5_OPENGL)
# include <QWindow>
#endif
#include <QWindow>
#include <Base/Exception.h>
#include <Base/Console.h>
@@ -131,9 +129,6 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent,
if (samples > 1) {
glformat = true;
#if !defined(HAVE_QT5_OPENGL)
f.setSampleBuffers(true);
#endif
f.setSamples(samples);
}
else if (samples > 0) {
@@ -948,7 +943,6 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
if (oldmode == newmode)
return;
#if defined(HAVE_QT5_OPENGL)
if (newmode == Child) {
// Fix in two steps:
// The mdi view got a QWindow when it became a top-level widget and when resetting it to a child widget
@@ -960,11 +954,9 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
if (winHandle)
winHandle->destroy();
}
#endif
MDIView::setCurrentViewMode(newmode);
#if defined(HAVE_QT5_OPENGL)
// Internally the QOpenGLWidget switches of the multi-sampling and there is no
// way to switch it on again. So as a workaround we just re-create a new viewport
// The method is private but defined as slot to avoid to call it by accident.
@@ -972,7 +964,6 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
//if (index >= 0) {
// _viewer->qt_metacall(QMetaObject::InvokeMetaMethod, index, 0);
//}
#endif
// This widget becomes the focus proxy of the embedded GL widget if we leave
// the 'Child' mode. If we reenter 'Child' mode the focus proxy is reset to 0.
@@ -1000,12 +991,10 @@ void View3DInventor::setCurrentViewMode(ViewMode newmode)
for (QList<QAction*>::Iterator it = acts.begin(); it != acts.end(); ++it)
this->removeAction(*it);
#if defined(HAVE_QT5_OPENGL)
// Step two
QMdiSubWindow* mdi = qobject_cast<QMdiSubWindow*>(parentWidget());
if (mdi && mdi->layout())
mdi->layout()->invalidate();
#endif
}
}

View File

@@ -1634,12 +1634,6 @@ void View3DInventorViewer::savePicture(int w, int h, int s, const QColor& bg, QI
gl->setCallback(setGLWidgetCB, this->getGLWidget());
root->addChild(gl);
root->addChild(pcViewProviderRoot);
#if !defined(HAVE_QT5_OPENGL)
if (useBackground)
root->addChild(cb);
#endif
root->addChild(foregroundroot);
try {
@@ -1981,7 +1975,6 @@ int View3DInventorViewer::getNumSamples()
GLenum View3DInventorViewer::getInternalTextureFormat() const
{
#if defined(HAVE_QT5_OPENGL)
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath
("User parameter:BaseApp/Preferences/View");
std::string format = hGrp->GetASCII("InternalTextureFormat", "Default");
@@ -2020,10 +2013,6 @@ GLenum View3DInventorViewer::getInternalTextureFormat() const
QOpenGLFramebufferObjectFormat fboFormat;
return fboFormat.internalTextureFormat();
}
#else
//return GL_RGBA;
return GL_RGB;
#endif
}
void View3DInventorViewer::setRenderType(const RenderType type)
@@ -2048,10 +2037,6 @@ void View3DInventorViewer::setRenderType(const RenderType type)
QtGLWidget* gl = static_cast<QtGLWidget*>(this->viewport());
gl->makeCurrent();
#if !defined(HAVE_QT5_OPENGL)
framebuffer = new QtGLFramebufferObject(width, height, QtGLFramebufferObject::Depth);
renderToFramebuffer(framebuffer);
#else
QOpenGLFramebufferObjectFormat fboFormat;
fboFormat.setSamples(getNumSamples());
fboFormat.setAttachment(QtGLFramebufferObject::Depth);
@@ -2067,7 +2052,6 @@ void View3DInventorViewer::setRenderType(const RenderType type)
renderToFramebuffer(fbo);
framebuffer = fbo;
}
#endif
}
break;
case Image:
@@ -2089,13 +2073,6 @@ QImage View3DInventorViewer::grabFramebuffer()
gl->makeCurrent();
QImage res;
#if !defined(HAVE_QT5_OPENGL)
int w = gl->width();
int h = gl->height();
QImage img(QSize(w,h), QImage::Format_RGB32);
glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, img.bits());
res = img;
#else
const SbViewportRegion vp = this->getSoRenderManager()->getViewportRegion();
SbVec2s size = vp.getViewportSizePixels();
int width = size[0];
@@ -2127,7 +2104,6 @@ QImage View3DInventorViewer::grabFramebuffer()
painter.end();
res = image;
}
#endif
return res;
}
@@ -2320,11 +2296,7 @@ void View3DInventorViewer::renderGLImage()
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2f(0,0);
#if !defined(HAVE_QT5_OPENGL)
glDrawPixels(glImage.width(),glImage.height(),GL_RGBA,GL_UNSIGNED_BYTE,glImage.bits());
#else
glDrawPixels(glImage.width(),glImage.height(),GL_BGRA,GL_UNSIGNED_BYTE,glImage.bits());
#endif
printDimension();
navigation->redraw();

View File

@@ -56,6 +56,8 @@ SET(ImageGui_SRCS
Resources/Image.qrc
ImageView.cpp
ImageView.h
OpenGLImageBox.cpp
OpenGLImageBox.h
PreCompiled.cpp
PreCompiled.h
Workbench.cpp
@@ -63,18 +65,6 @@ SET(ImageGui_SRCS
XpmImages.h
)
if(FREECAD_USE_QTOPENGL_WIDGET)
list(APPEND ImageGui_SRCS
OpenGLImageBox.cpp
OpenGLImageBox.h
)
else()
list(APPEND ImageGui_SRCS
GLImageBox.cpp
GLImageBox.h
)
endif()
SET(ImageGuiIcon_SVG
Resources/icons/ImageWorkbench.svg
)

View File

@@ -1,812 +0,0 @@
/***************************************************************************
* *
* This is a QGLWidget displaying an image or portion of an image in a *
* box. *
* *
* Author: Graeme van der Vlugt *
* Copyright: Imetric 3D GmbH *
* Year: 2004 *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <cmath>
# include <QMessageBox>
#endif
#if defined(__MINGW32__)
# include <GL/gl.h>
# include <GL/glext.h>
#elif defined (FC_OS_MACOSX)
# include <OpenGL/gl.h>
# include <OpenGL/glu.h>
# include <GLKit/GLKMatrix4.h>
#elif defined (FC_OS_WIN32)
# include <Windows.h>
# include <GL/gl.h>
# include <GL/glu.h>
#else
# include <GL/gl.h>
# include <GL/glu.h>
#endif
#include "GLImageBox.h"
using namespace ImageGui;
#if defined(Q_CC_MSVC)
#pragma warning(disable:4305) // init: truncation from const double to float
#endif
bool GLImageBox::haveMesa = false;
/* TRANSLATOR ImageGui::GLImageBox */
// Constructor
GLImageBox::GLImageBox(QWidget * parent, const QGLWidget * shareWidget, Qt::WindowFlags f)
: QGLWidget(parent, shareWidget, f)
{
// uses default display format for the OpenGL rendering context
// (double buffering is enabled)
// enable mouse tracking when moving even if no buttons are pressed
setMouseTracking(true);
// initialise variables
_x0 = 0;
_y0 = 0;
_zoomFactor = 1.0;
_base_x0 = 0;
_base_y0 = 0;
_pColorMap = 0;
_numMapEntries = 0;
}
// Destructor
GLImageBox::~GLImageBox()
{
try
{
delete [] _pColorMap;
}
catch(...) {}
}
// Set up the OpenGL rendering state
void GLImageBox::initializeGL()
{
QPalette p = this->palette();
qglClearColor(p.color(this->backgroundRole())); // Let OpenGL clear to background color
//qglClearColor(Qt::black); // Let OpenGL clear to black
static bool init = false;
if (!init) {
init = true;
std::string ver = (const char*)(glGetString(GL_VERSION));
haveMesa = (ver.find("Mesa") != std::string::npos);
}
}
// Update the viewport
void GLImageBox::resizeGL( int w, int h )
{
glViewport( 0, 0, (GLint)w, (GLint)h );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
#if defined (FC_OS_MACOSX)
GLKMatrix4 orthoMat = GLKMatrix4MakeOrtho(0, width() - 1, height() - 1, 0, -1, 1);
glLoadMatrixf(orthoMat.m);
#else
gluOrtho2D(0, width() - 1, height() - 1, 0);
#endif
glMatrixMode(GL_MODELVIEW);
}
// Redraw (current image)
void GLImageBox::redraw()
{
glDraw();
}
// Paint the box
void GLImageBox::paintGL()
{
// clear background (in back buffer)
glDrawBuffer(GL_BACK);
glClear(GL_COLOR_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);
// Draw the image
drawImage();
// Emit a signal for owners to draw any graphics that is needed.
if (_image.hasValidData() == true)
drawGraphics();
// flush the OpenGL graphical pipeline
glFinish();
// Double buffering is used so we need to swap the buffers
// There is no need to explicitly call this function because it is
// done automatically after each widget repaint, i.e. each time after paintGL() has been executed
// swapBuffers();
}
// Draw the image
void GLImageBox::drawImage()
{
if (_image.hasValidData() == false)
return;
// Gets the size of the displayed image area using the current display settings
// (in units of image pixels)
int dx, dy;
getDisplayedImageAreaSize(dx, dy);
// Draw the visible image region with the correct position and zoom
if ((dx > 0) && (dy > 0))
{
// Get top left image pixel to display
int tlx = std::max<int>(0, _x0);
int tly = std::max<int>(0, _y0);
// Get pointer to first pixel in source image rectangle
unsigned char* pPix = (unsigned char *)(_image.getPixelDataPtr());
pPix += (unsigned long)(_image.getNumBytesPerPixel()) * (tly * _image.getWidth() + tlx);
// Draw in the back buffer, using the following parameters
glDrawBuffer(GL_BACK);
glPixelStorei(GL_UNPACK_ROW_LENGTH, _image.getWidth()); // defines number of pixels in a row
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // defines byte alignment of rows
glPixelZoom(_zoomFactor, -_zoomFactor); // defines the zoom factors to draw at
// set current raster position to coincide with top left image pixel to display
// the first pixel is always displayed in full when zoomed in
// round to nearest widget pixel that coincides with top left corner of top left image pixel to display
int xx = (int)floor(ICToWC_X(tlx - 0.5) + 0.5);
int yy = (int)floor(ICToWC_Y(tly - 0.5) + 0.5);
glRasterPos2f(xx, yy);
// Compute scale to stretch number of significant bits to full range
// e.g. stretch 12 significant bits to 16-bit range: 0-4095 -> 0-65535, therefore scale = 65535/4095
double scale = (pow(2.0, _image.getNumBitsPerSample()) - 1.0) / (pow(2.0, _image.getNumSigBitsPerSample()) - 1.0);
glPixelTransferf(GL_RED_SCALE, (float)scale);
glPixelTransferf(GL_GREEN_SCALE, (float)scale);
glPixelTransferf(GL_BLUE_SCALE, (float)scale);
// Load the color map if present
if (_pColorMap != 0)
{
if (!haveMesa) glPixelTransferf(GL_MAP_COLOR, 1.0);
glPixelMapfv(GL_PIXEL_MAP_R_TO_R, _numMapEntries, _pColorMap);
glPixelMapfv(GL_PIXEL_MAP_G_TO_G, _numMapEntries, _pColorMap + _numMapEntries);
glPixelMapfv(GL_PIXEL_MAP_B_TO_B, _numMapEntries, _pColorMap + _numMapEntries * 2);
glPixelMapfv(GL_PIXEL_MAP_A_TO_A, _numMapEntries, _pColorMap + _numMapEntries * 3);
}
else
{
glPixelTransferf(GL_MAP_COLOR, 0.0);
glPixelMapfv(GL_PIXEL_MAP_R_TO_R, 0, NULL);
glPixelMapfv(GL_PIXEL_MAP_G_TO_G, 0, NULL);
glPixelMapfv(GL_PIXEL_MAP_B_TO_B, 0, NULL);
glPixelMapfv(GL_PIXEL_MAP_A_TO_A, 0, NULL);
}
// Get the pixel format
GLenum pixFormat;
GLenum pixType;
getPixFormat(pixFormat, pixType);
// Draw the defined source rectangle
glDrawPixels(dx, dy, pixFormat, pixType, (GLvoid *)pPix);
glFlush();
}
}
// Gets the size of the displayed image area using the current display settings
// (in units of image pixels)
void GLImageBox::getDisplayedImageAreaSize(int &dx, int &dy)
{
if (_image.hasValidData() == false)
{
dx = 0;
dy = 0;
}
else
{
// Make sure drawing position and zoom factor are valid
limitCurrPos();
limitZoomFactor();
// Image coordinates of top left widget pixel = (_x0, _y0)
// Get image coordinates of bottom right widget pixel
int brx = (int)ceil(WCToIC_X(width() - 1));
int bry = (int)ceil(WCToIC_Y(height() - 1));
// Find the outer coordinates of the displayed image area
int itlx = std::max<int>(_x0, 0);
int itly = std::max<int>(_y0, 0);
int ibrx = std::min<int>(brx, (int)(_image.getWidth()) - 1);
int ibry = std::min<int>(bry, (int)(_image.getHeight()) - 1);
if ((itlx >= (int)(_image.getWidth())) ||
(itly >= (int)(_image.getHeight())) ||
(ibrx < 0) ||
(ibry < 0))
{
dx = 0;
dy = 0;
}
else {
dx = ibrx - itlx + 1;
dy = ibry - itly + 1;
}
}
}
// Gets the value of an image sample at the given image pixel position
// Returns 0 for valid value or -1 if coordinates or sample index are out of range or
// if there is no image data
int GLImageBox::getImageSample(int x, int y, unsigned short sampleIndex, double &value)
{
return (_image.getSample(x, y, sampleIndex, value));
}
// Gets the number of samples per pixel for the image
unsigned short GLImageBox::getImageNumSamplesPerPix()
{
return (_image.getNumSamples());
}
// Gets the format (color space format) of the image
int GLImageBox::getImageFormat()
{
return (_image.getFormat());
}
// Get the OpenGL pixel format and pixel type from the image properties
void GLImageBox::getPixFormat(GLenum &pixFormat, GLenum &pixType)
{
switch(_image.getFormat())
{
case IB_CF_GREY8:
pixFormat = GL_LUMINANCE;
pixType = GL_UNSIGNED_BYTE;
break;
case IB_CF_GREY16:
pixFormat = GL_LUMINANCE;
pixType = GL_UNSIGNED_SHORT;
break;
case IB_CF_GREY32:
pixFormat = GL_LUMINANCE;
pixType = GL_UNSIGNED_INT;
break;
case IB_CF_RGB24:
pixFormat = GL_RGB;
pixType = GL_UNSIGNED_BYTE;
break;
#ifndef FC_OS_CYGWIN
case IB_CF_BGR24:
pixFormat = GL_BGR_EXT;
pixType = GL_UNSIGNED_BYTE;
break;
case IB_CF_RGB48:
pixFormat = GL_RGB;
pixType = GL_UNSIGNED_SHORT;
break;
case IB_CF_BGR48:
pixFormat = GL_BGR_EXT;
pixType = GL_UNSIGNED_SHORT;
break;
#endif
case IB_CF_RGBA32:
pixFormat = GL_RGBA;
pixType = GL_UNSIGNED_BYTE;
break;
case IB_CF_RGBA64:
pixFormat = GL_RGBA;
pixType = GL_UNSIGNED_SHORT;
break;
#ifndef FC_OS_CYGWIN
case IB_CF_BGRA32:
pixFormat = GL_BGRA_EXT;
pixType = GL_UNSIGNED_BYTE;
break;
case IB_CF_BGRA64:
pixFormat = GL_BGRA_EXT;
pixType = GL_UNSIGNED_SHORT;
break;
#endif
default:
// Should never happen
pixFormat = GL_LUMINANCE;
pixType = GL_UNSIGNED_BYTE;
QMessageBox::warning((QWidget *)this, tr("Image pixel format"),
tr("Undefined type of colour space for image viewing"));
return;
}
}
// Limits the current position (centre of top left image pixel)
// Currently we don't limit it!
void GLImageBox::limitCurrPos()
{
if (_image.hasValidData() == false)
return;
/*
if (_x0 < 0)
_x0 = 0;
else if (_x0 >= (int)(_image.getWidth()))
_x0 = _image.getWidth() - 1;
if (_y0 < 0)
_y0 = 0;
else if (_y0 >= (int)(_image.getHeight()))
_y0 = _image.getHeight() - 1;
*/
}
// Limits the current zoom factor from 1:64 to 64:1
void GLImageBox::limitZoomFactor()
{
if (_zoomFactor > 64.0)
_zoomFactor = 64.0;
else if (_zoomFactor < (1.0 / 64.0))
_zoomFactor = 1.0 / 64.0;
}
// Set the current position (centre of top left image pixel coordinates)
// This function does not redraw (call redraw afterwards)
void GLImageBox::setCurrPos(int x0, int y0)
{
_x0 = x0;
_y0 = y0;
limitCurrPos();
}
// Fixes a base position at the current position
void GLImageBox::fixBasePosCurr()
{
if (_image.hasValidData() == false)
{
_base_x0 = 0;
_base_y0 = 0;
}
else
{
_base_x0 = _x0;
_base_y0 = _y0;
}
}
// Set the current zoom factor
// Option to centre the zoom at a given image point or not
// This function does not redraw (call redraw afterwards)
void GLImageBox::setZoomFactor(double zoomFactor, bool useCentrePt, int ICx, int ICy)
{
if ((useCentrePt == false) || (_image.hasValidData() == false))
{
_zoomFactor = zoomFactor;
limitZoomFactor();
}
else
{
// Set new zoom factor
_zoomFactor = zoomFactor;
limitZoomFactor();
// get centre position of widget in image coordinates
int ix, iy;
getCentrePoint(ix, iy);
// try to shift the current position so that defined centre point is in the middle of the widget
// (this can be modified by the limitCurrPos function)
setCurrPos(_x0 - ix + ICx, _y0 - iy + ICy);
}
}
// Stretch or shrink the image to fit the view (although the zoom factor is limited so a
// very small or very big image may not fit completely (depending on the size of the view)
// This function redraws
void GLImageBox::stretchToFit()
{
if (_image.hasValidData() == false)
return;
setToFit();
glDraw();
}
// Sets the settings needed to fit the image into the view (although the zoom factor is limited so a
// very small or very big image may not fit completely (depending on the size of the view)
// This function does not redraw (call redraw afterwards)
void GLImageBox::setToFit()
{
if (_image.hasValidData() == false)
return;
// Compute ideal zoom factor to fit the image
double zoomX = (double)width() / (double)(_image.getWidth());
double zoomY = (double)height() / (double)(_image.getHeight());
if (zoomX > zoomY)
_zoomFactor = zoomY;
else
_zoomFactor = zoomX;
limitZoomFactor();
// set current position to top left image pixel
setCurrPos(0, 0);
}
// Sets the normal viewing position and zoom = 1
// If the image is smaller than the widget then the image is centred
// otherwise we view the top left part of the image
// This function does not redraw (call redraw afterwards)
void GLImageBox::setNormal()
{
if (_image.hasValidData() == false)
return;
if (((int)(_image.getWidth()) < width()) && ((int)(_image.getHeight()) < height()))
{
setZoomFactor(1.0, true, _image.getWidth() / 2, _image.getHeight() / 2);
}
else
{
_zoomFactor = 1;
setCurrPos(0, 0);
}
}
// Gets the image coordinates of the centre point of the widget
void GLImageBox::getCentrePoint(int &ICx, int &ICy)
{
ICx = (int)floor(WCToIC_X((double)(width() - 1) / 2.0) + 0.5);
ICy = (int)floor(WCToIC_Y((double)(height() - 1) / 2.0) + 0.5);
}
// Moves the image by a relative amount (in widget pixel units) from the base position
// First use fixBasePosCurr() to fix the base position at a position
void GLImageBox::relMoveWC(int WCdx, int WCdy)
{
double ICdx = WCdx / _zoomFactor;
double ICdy = WCdy / _zoomFactor;
setCurrPos(_base_x0 - (int)floor(ICdx + 0.5), _base_y0 - (int)floor(ICdy + 0.5));
glDraw();
}
// Computes an image x-coordinate from the widget x-coordinate
// Note: (_x0,_y0) is the centre of the image pixel displayed at the top left of the widget
// therefore (_x0 - 0.5, _y0 - 0.5) is the top left coordinate of this pixel which will
// theoretically coincide with widget coordinate (-0.5,-0.5)
// Zoom = 4: Widget(0,0) = Image(_x0 - 0.375,_y0 - 0.375)
// Zoom = 2: Widget(0,0) = Image(_x0 - 0.250,_y0 - 0.250)
// Zoom = 1: Widget(0,0) = Image(_x0,_y0)
// Zoom = 0.5: Widget(0,0) = Image(_x0 + 0.500,_y0 + 0.500)
// Zoom = 0.25: Widget(0,0) = Image(_x0 + 1.500,_y0 + 1.500)
double GLImageBox::WCToIC_X(double WidgetX)
{
return ((double)_x0 - 0.5 + (WidgetX + 0.5) / _zoomFactor);
}
// Computes an image y-coordinate from the widget y-coordinate
// Note: (_x0,_y0) is the centre of the image pixel displayed at the top left of the widget
// therefore (_x0 - 0.5, _y0 - 0.5) is the top left coordinate of this pixel which will
// theoretically coincide with widget coordinate (-0.5,-0.5)
// Zoom = 4: Widget(0,0) = Image(_x0 - 0.375,_y0 - 0.375)
// Zoom = 2: Widget(0,0) = Image(_x0 - 0.250,_y0 - 0.250)
// Zoom = 1: Widget(0,0) = Image(_x0,_y0)
// Zoom = 0.5: Widget(0,0) = Image(_x0 + 0.500,_y0 + 0.500)
// Zoom = 0.25: Widget(0,0) = Image(_x0 + 1.500,_y0 + 1.500)
double GLImageBox::WCToIC_Y(double WidgetY)
{
return ((double)_y0 - 0.5 + (WidgetY + 0.5) / _zoomFactor);
}
// Computes a widget x-coordinate from an image x-coordinate
// Note: (_x0,_y0) is the centre of the image pixel displayed at the top left of the widget
// therefore (_x0 - 0.5, _y0 - 0.5) is the top left coordinate of this pixel which will
// theoretically coincide with widget coordinate (-0.5,-0.5)
// Zoom = 4: Widget(0,0) = Image(_x0 - 0.375,_y0 - 0.375)
// Zoom = 2: Widget(0,0) = Image(_x0 - 0.250,_y0 - 0.250)
// Zoom = 1: Widget(0,0) = Image(_x0,_y0)
// Zoom = 0.5: Widget(0,0) = Image(_x0 + 0.500,_y0 + 0.500)
// Zoom = 0.25: Widget(0,0) = Image(_x0 + 1.500,_y0 + 1.500)
double GLImageBox::ICToWC_X(double ImageX)
{
return ((ImageX - (double)_x0 + 0.5) * _zoomFactor - 0.5);
}
// Computes a widget y-coordinate from an image y-coordinate
// Note: (_x0,_y0) is the centre of the image pixel displayed at the top left of the widget
// therefore (_x0 - 0.5, _y0 - 0.5) is the top left coordinate of this pixel which will
// theoretically coincide with widget coordinate (-0.5,-0.5)
// Zoom = 4: Widget(0,0) = Image(_x0 - 0.375,_y0 - 0.375)
// Zoom = 2: Widget(0,0) = Image(_x0 - 0.250,_y0 - 0.250)
// Zoom = 1: Widget(0,0) = Image(_x0,_y0)
// Zoom = 0.5: Widget(0,0) = Image(_x0 + 0.500,_y0 + 0.500)
// Zoom = 0.25: Widget(0,0) = Image(_x0 + 1.500,_y0 + 1.500)
double GLImageBox::ICToWC_Y(double ImageY)
{
return ((ImageY - (double)_y0 + 0.5) * _zoomFactor - 0.5);
}
// Clears the image data
void GLImageBox::clearImage()
{
_image.clear();
resetDisplay();
}
// Load image by copying the pixel data
// The image object will take ownership of the copied pixel data
// (the source image is still controlled by the caller)
// If numSigBitsPerSample = 0 then the full range is assumed to be significant
// displayMode ... controls the initial display of the image, one of:
// IV_DISPLAY_NOCHANGE ... no change to view settings when displaying a new image
// IV_DISPLAY_FITIMAGE ... fit-image when displaying a new image (other settings remain the same)
// IV_DISPLAY_RESET ... reset settings when displaying a new image (image will be displayed at 1:1 scale with no color map)
// This function does not redraw (call redraw afterwards)
// Returns:
// 0 for OK
// -1 for invalid color format
// -2 for memory allocation error
int GLImageBox::createImageCopy(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, int displayMode)
{
// Copy image
int ret = _image.createCopy(pSrcPixelData, width, height, format, numSigBitsPerSample);
// Set display settings depending on mode
if (displayMode == IV_DISPLAY_RESET)
{
// reset drawing settings (position, scale, colour mapping) if requested
resetDisplay();
}
else if (displayMode == IV_DISPLAY_FITIMAGE)
{
// compute stretch to fit settings
setToFit();
}
else // if (displayMode == IV_DISPLAY_NOCHANGE)
{
// use same settings
limitCurrPos();
limitZoomFactor();
}
return ret;
}
// Make the image object point to another image source
// If takeOwnership is false then:
// This object will not own (control) or copy the pixel data
// (the source image is still controlled by the caller)
// Else if takeOwnership is true then:
// This object will take ownership (control) of the pixel data
// (the source image is not (should not be) controlled by the caller anymore)
// In this case the memory must have been allocated with the new operator (because this class will use the delete operator)
// If numSigBitsPerSample = 0 then the full range is assumed to be significant
// displayMode ... controls the initial display of the image, one of:
// IV_DISPLAY_NOCHANGE ... no change to view settings when displaying a new image
// IV_DISPLAY_FITIMAGE ... fit-image when displaying a new image (other settings remain the same)
// IV_DISPLAY_RESET ... reset settings when displaying a new image (image will be displayed at 1:1 scale with no color map)
// This function does not redraw (call redraw afterwards)
// Returns:
// 0 for OK
// -1 for invalid color format
int GLImageBox::pointImageTo(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, bool takeOwnership, int displayMode)
{
// Point to image
int ret = _image.pointTo(pSrcPixelData, width, height, format, numSigBitsPerSample, takeOwnership);
// Set display settings depending on mode
if (displayMode == IV_DISPLAY_RESET)
{
// reset drawing settings (position, scale, colour mapping) if requested
resetDisplay();
}
else if (displayMode == IV_DISPLAY_FITIMAGE)
{
// compute stretch to fit settings
setToFit();
}
else // if (displayMode == IV_DISPLAY_NOCHANGE)
{
// use same settings
limitCurrPos();
limitZoomFactor();
}
return ret;
}
// Reset display settings
void GLImageBox::resetDisplay()
{
clearColorMap();
setNormal(); // re-draws as well
}
// Clears the color map
void GLImageBox::clearColorMap()
{
delete [] _pColorMap;
_pColorMap = 0;
_numMapEntries = 0;
}
// Calculate the number of color map entries to use
int GLImageBox::calcNumColorMapEntries()
{
// Get the maximum number of map entries that the system supports
// Get the number of bits per sample for the image if it exists and compute the number of pixel values
// Return the fewer amount of entries
GLint maxMapEntries;
glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &maxMapEntries);
int NumEntries = maxMapEntries;
if (_image.hasValidData() == true)
NumEntries = (int)std::min<double>(pow(2.0, (double)(_image.getNumSigBitsPerSample())), (double)maxMapEntries);
return NumEntries;
}
// Creates a color map (All red entries come first, then green, then blue, then alpha)
// returns 0 for OK, -1 for memory allocation error
// numRequestedEntries ... requested number of map entries (used if not greater than maximum possible or number of intensity values)
// Initialise ... flag to initialise the map to a linear scale or not
int GLImageBox::createColorMap(int numEntriesReq, bool Initialise)
{
// Get the number of map entries to use
int maxNumEntries = calcNumColorMapEntries();
int numEntries;
if (numEntriesReq <= 0)
numEntries = maxNumEntries;
else
numEntries = std::min<int>(numEntriesReq, maxNumEntries);
// Clear and re-create the color map if it's not the desired size
if (numEntries != _numMapEntries)
{
clearColorMap();
_numMapEntries = numEntries;
// Create the color map (RGBA)
try
{
_pColorMap = new float[4 * _numMapEntries];
}
catch(...)
{
clearColorMap();
return -1;
}
}
// Initialise the color map if requested
// (All red entries come first, then green, then blue, then alpha)
if (Initialise == true)
{
// For each RGB channel
int arrayIndex = 0;
for (int chan = 0; chan < 3; chan++)
{
for (int in = 0; in < _numMapEntries; in++)
{
_pColorMap[arrayIndex] = (float)in / (float)(_numMapEntries - 1);
arrayIndex++;
}
}
// For alpha channel
for (int in = 0; in < _numMapEntries; in++)
{
_pColorMap[arrayIndex] = 1.0;
arrayIndex++;
}
}
return 0;
}
// Sets a color map RGBA value
// (All red entries come first, then green, then blue, then alpha)
// index ... index of color map RGBA entry
// red ... intensity value for this red entry (range 0 to 1)
// green ... intensity value for this green entry (range 0 to 1)
// blue ... intensity value for this blue entry (range 0 to 1)
// alpha ... value for this alpha entry (range 0 to 1)
int GLImageBox::setColorMapRGBAValue(int index, float red, float green, float blue, float alpha)
{
if ((index < 0) || (index >= _numMapEntries) ||
(red < 0.0) || (red > 1.0) ||
(green < 0.0) || (green > 1.0) ||
(blue < 0.0) || (blue > 1.0) ||
(alpha < 0.0) || (alpha > 1.0))
return -1;
_pColorMap[index] = red;
_pColorMap[_numMapEntries + index] = green;
_pColorMap[_numMapEntries * 2 + index] = blue;
_pColorMap[_numMapEntries * 3 + index] = alpha;
return 0;
}
// Sets a color map red value
// (All red entries come first, then green, then blue, then alpha)
// index ... index of color map red entry
// value ... intensity value for this red entry (range 0 to 1)
int GLImageBox::setColorMapRedValue(int index, float value)
{
if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
return -1;
_pColorMap[index] = value;
return 0;
}
// Sets a color map green value
// (All red entries come first, then green, then blue, then alpha)
// index ... index of color map green entry
// value ... intensity value for this green entry (range 0 to 1)
int GLImageBox::setColorMapGreenValue(int index, float value)
{
if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
return -1;
_pColorMap[_numMapEntries + index] = value;
return 0;
}
// Sets a color map blue value
// (All red entries come first, then green, then blue, then alpha)
// index ... index of color map blue entry
// value ... intensity value for this blue entry (range 0 to 1)
int GLImageBox::setColorMapBlueValue(int index, float value)
{
if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
return -1;
_pColorMap[_numMapEntries * 2 + index] = value;
return 0;
}
// Sets a color map alpha value
// (All red entries come first, then green, then blue, then alpha)
// index ... index of color map alpha entry
// value ... value for this alpha entry (range 0 to 1)
int GLImageBox::setColorMapAlphaValue(int index, float value)
{
if ((index < 0) || (index >= _numMapEntries) || (value < 0.0) || (value > 1.0))
return -1;
_pColorMap[_numMapEntries * 3 + index] = value;
return 0;
}
// Helper function to convert a pixel's value (of a sample) to the color map index (i.e. the map index that will be used for that pixel value)
unsigned int GLImageBox::pixValToMapIndex(double PixVal)
{
if (_pColorMap != NULL)
{
double MaxVal = pow(2.0, _image.getNumBitsPerSample()) - 1.0;
double Scale = (pow(2.0, _image.getNumBitsPerSample()) - 1.0) / (pow(2.0, _image.getNumSigBitsPerSample()) - 1.0);
double PixVal01 = Scale * PixVal / MaxVal;
int numMapEntries = getNumColorMapEntries();
unsigned int MapIndex = (unsigned int)floor(0.5 + PixVal01 * (double)(numMapEntries - 1));
return MapIndex;
}
else
{
return 0;
}
}
#include "moc_GLImageBox.cpp"

View File

@@ -1,115 +0,0 @@
/***************************************************************************
* *
* This is a QGLWidget displaying an image or portion of an image in a *
* box. *
* *
* Author: Graeme van der Vlugt *
* Copyright: Imetric 3D GmbH *
* Year: 2004 *
* *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Library General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* for detail see the LICENCE text file. *
* *
***************************************************************************/
#ifndef GLIMAGEBOX_H
#define GLIMAGEBOX_H
#include <Mod/Image/App/ImageBase.h>
#include <QGLWidget>
namespace ImageGui
{
#define IV_DISPLAY_NOCHANGE 0 // no change to view settings when displaying a new image
#define IV_DISPLAY_FITIMAGE 1 // fit-image when displaying a new image (other settings remain the same)
#define IV_DISPLAY_RESET 2 // reset settings when displaying a new image (image will be displayed at 1:1 scale with no color map)
class ImageGuiExport GLImageBox : public QGLWidget
{
Q_OBJECT
public:
GLImageBox(QWidget * parent = 0, const QGLWidget * shareWidget = 0, Qt::WindowFlags f = 0);
~GLImageBox();
Image::ImageBase *getImageBasePtr() { return &_image; }
void redraw();
int getImageSample(int x, int y, unsigned short sampleIndex, double &value);
unsigned short getImageNumSamplesPerPix();
int getImageFormat();
void fixBasePosCurr();
double getZoomFactor() { return _zoomFactor; }
void setZoomFactor(double zoomFactor, bool useCentrePt = false, int ICx = 0, int ICy = 0);
void zoom(int power, bool useCentrePt = false, int ICx = 0, int ICy = 0);
void stretchToFit();
void setNormal();
void getCentrePoint(int &ICx, int &ICy);
void relMoveWC(int WCdx, int WCdy);
double WCToIC_X(double WidgetX);
double WCToIC_Y(double WidgetY);
double ICToWC_X(double ImageX);
double ICToWC_Y(double ImageY);
void clearImage();
int createImageCopy(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, int displayMode = IV_DISPLAY_RESET);
int pointImageTo(void* pSrcPixelData, unsigned long width, unsigned long height, int format, unsigned short numSigBitsPerSample, bool takeOwnership, int displayMode = IV_DISPLAY_RESET);
void clearColorMap();
int createColorMap(int numEntriesReq = 0, bool Initialise = true);
int getNumColorMapEntries() const { return _numMapEntries; }
int setColorMapRGBAValue(int index, float red, float green, float blue, float alpha = 1.0);
int setColorMapRedValue(int index, float value);
int setColorMapGreenValue(int index, float value);
int setColorMapBlueValue(int index, float value);
int setColorMapAlphaValue(int index, float value);
unsigned int pixValToMapIndex(double PixVal);
Q_SIGNALS:
void drawGraphics();
private:
void initializeGL();
void paintGL();
void resizeGL( int w, int h );
void drawImage();
void getDisplayedImageAreaSize(int &dx, int &dy);
void getPixFormat(GLenum &pixFormat, GLenum &pixType);
void limitCurrPos();
void limitZoomFactor();
void setCurrPos(int x0, int y0);
void setToFit();
void resetDisplay();
int calcNumColorMapEntries();
Image::ImageBase _image; // the image data
int _x0; // image x-coordinate of top-left widget pixel
int _y0; // image y-coordinate of top-left widget pixel
double _zoomFactor; // zoom factor = (num_widget_pixels / num_image_pixels)
int _base_x0; // defines a fixed position of x0
int _base_y0; // defines a fixed position of y0
float* _pColorMap; // a RGBA color map (to alter the intensity or colors)
int _numMapEntries; // number of entries in color map
static bool haveMesa;
};
} // namespace ImageGui
#endif // GLIMAGEBOX_H

View File

@@ -41,8 +41,7 @@ TYPESYSTEM_SOURCE_ABSTRACT(ImageGui::ImageView, Gui::MDIView)
ImageView::ImageView(QWidget* parent)
: MDIView(0, parent), _ignoreCloseEvent(false)
{
// Create an OpenGL widget for displaying images
#if QT_VERSION >=0x050000
// Create an OpenGL widget for displaying images
// Since Qt5 there is a weird behaviour when creating a GLImageBox.
// It works correctly for the first time when creating an image view
// but only when no 3d view is created. For the second time or if a
@@ -66,14 +65,7 @@ ImageView::ImageView(QWidget* parent)
// Since Qt5 the class QGLWidget is marked as deprecated and should be
// replaced by QOpenGLWidget.
#if defined(HAVE_QT5_OPENGL)
_pGLImageBox = new GLImageBox(this);
#else
_pGLImageBox = new GLImageBox(parent);
#endif // HAVE_QT5_OPENGL
#else
_pGLImageBox = new GLImageBox(this);
#endif
setCentralWidget(_pGLImageBox);
// enable mouse tracking when moving even if no buttons are pressed

View File

@@ -18,13 +18,9 @@
#ifndef ImageView_H
#define ImageView_H
#include <QMouseEvent>
#include <Gui/MDIView.h>
#include <QtOpenGL.h>
#if defined(HAVE_QT5_OPENGL)
#include "OpenGLImageBox.h"
#else
#include "GLImageBox.h"
#endif
#include <Mod/Image/Gui/OpenGLImageBox.h>
#include <Mod/Image/ImageGlobal.h>
class QSlider;
@@ -36,6 +32,8 @@ class QToolBar;
namespace ImageGui
{
class GLImageBox;
class ImageGuiExport ImageView : public Gui::MDIView
{
Q_OBJECT

View File

@@ -26,10 +26,6 @@
/* QtOpenGL.h. Generated from QtOpenGL.h.cmake by cmake. */
#cmakedefine HAVE_QT5_OPENGL
#if defined(HAVE_QT5_OPENGL)
#include <QOpenGLContext>
#include <QSurfaceFormat>
#include <QOpenGLWidget>
@@ -43,21 +39,4 @@ typedef QOpenGLWidget QtGLWidget;
typedef QOpenGLFramebufferObject QtGLFramebufferObject;
typedef QOpenGLFramebufferObjectFormat QtGLFramebufferObjectFormat;
#else // HAVE_QT5_OPENGL
#include <QGLContext>
#include <QGLFormat>
#include <QGLWidget>
#include <QGLPixelBuffer>
#include <QGLFramebufferObject>
typedef QGLContext QtGLContext;
typedef QGLFormat QtGLFormat;
typedef QGLWidget QtGLWidget;
typedef QGLPixelBuffer QtGLPixelBuffer;
typedef QGLFramebufferObject QtGLFramebufferObject;
typedef QGLFramebufferObjectFormat QtGLFramebufferObjectFormat;
#endif // HAVE_QT5_OPENGL
#endif //QUARTER_QTOPENGL_H