From c3a71ed4e68394c9ec4fcdbb7bc32adfacf24431 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Sun, 10 May 2020 21:03:10 +0200 Subject: [PATCH] Working scroll --- image.frag | 9 ++-- image.vert | 8 ++- imagescrollareagl.cpp | 115 ++++++++++++++++++++++++++++++++++++++---- imagescrollareagl.h | 32 ++++++++++-- mainwindow.cpp | 4 +- 5 files changed, 148 insertions(+), 20 deletions(-) diff --git a/image.frag b/image.frag index 2f6dc88..911853d 100644 --- a/image.frag +++ b/image.frag @@ -4,10 +4,11 @@ uniform sampler2D qt_Texture0; varying vec2 qt_TexCoord0; uniform vec2 scale; + void main(void) { - float c = texture2D(qt_Texture0, qt_TexCoord0).r; - c = c*scale.x + scale.y; - float color = pow(c, 0.4545); - gl_FragColor = vec4(color, color, color, 1.0); + vec4 color = texture2D(qt_Texture0, qt_TexCoord0); + color = color*scale.x + scale.y; + //float color = pow(c, 0.4545); + gl_FragColor = color; } diff --git a/image.vert b/image.vert index 10da880..002c7e7 100644 --- a/image.vert +++ b/image.vert @@ -1,11 +1,17 @@ #version 130 +uniform sampler2D qt_Texture0; attribute vec2 qt_Vertex; attribute vec2 qt_MultiTexCoord0; varying vec2 qt_TexCoord0; +uniform vec2 viewport; +uniform vec2 offset; void main(void) { + vec2 texSize = vec2(textureSize(qt_Texture0, 0)); + vec2 scale = viewport / texSize; + vec2 offsetRel = offset / texSize; gl_Position = vec4(qt_Vertex, 0.0, 1.0); - qt_TexCoord0 = qt_MultiTexCoord0; + qt_TexCoord0 = qt_MultiTexCoord0 * scale + offsetRel; } diff --git a/imagescrollareagl.cpp b/imagescrollareagl.cpp index 0a9d5ce..a5ed712 100644 --- a/imagescrollareagl.cpp +++ b/imagescrollareagl.cpp @@ -4,29 +4,33 @@ #include #include #include +#include -ImageScrollAreaGL::ImageScrollAreaGL(QWidget *parent) : QOpenGLWidget(parent) +ImageWidget::ImageWidget(QWidget *parent) : QOpenGLWidget(parent) { setFocusPolicy(Qt::ClickFocus); m_range = UINT16_MAX; m_low = 0; m_high = 1; + m_dx = m_dy = 0; } -ImageScrollAreaGL::~ImageScrollAreaGL() +ImageWidget::~ImageWidget() { makeCurrent(); } -void ImageScrollAreaGL::setImage(RawImage *image) +void ImageWidget::setImage(RawImage *image) { if(image == nullptr)return; m_image->destroy(); m_image->setFormat(QOpenGLTexture::R16_UNorm); m_image->setSize(image->width(), image->height()); - m_image->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear); m_image->allocateStorage(); + m_image->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear); + m_image->setWrapMode(QOpenGLTexture::ClampToBorder); + m_image->setBorderColor(0, 0, 0, 0); switch(image->type()) { case RawImage::UINT8: @@ -44,45 +48,57 @@ void ImageScrollAreaGL::setImage(RawImage *image) repaint(); } -void ImageScrollAreaGL::setImage(const QPixmap &pixmap) +void ImageWidget::setImage(const QPixmap &pixmap) { QImage img = pixmap.toImage(); m_image->destroy(); m_image->setData(img); + m_image->setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear); + m_image->setWrapMode(QOpenGLTexture::ClampToBorder); + m_image->setBorderColor(0, 0, 0, 0); repaint(); } -void ImageScrollAreaGL::setLow(int low) +void ImageWidget::setLow(int low) { m_low = low/m_range; repaint(); } -void ImageScrollAreaGL::setHigh(int high) +void ImageWidget::setHigh(int high) { m_high = high/m_range; repaint(); } -void ImageScrollAreaGL::paintGL() +void ImageWidget::setOffset(int dx, int dy) +{ + m_dx = dx; + m_dy = dy; + repaint(); +} + +void ImageWidget::paintGL() { float s = 1.0f/(m_high-m_low); m_program->bind(); m_program->setUniformValue("scale", s, -m_low*s); + m_program->setUniformValue("viewport", (float)width(), (float)height()); + m_program->setUniformValue("offset", m_dx, m_dy); m_image->bind(0); f->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } -void ImageScrollAreaGL::resizeGL(int w, int h) +void ImageWidget::resizeGL(int w, int h) { m_width = w; m_height = h; f->glViewport(0, 0, w, h); } -void ImageScrollAreaGL::initializeGL() +void ImageWidget::initializeGL() { f = context()->functions(); f->glClearColor(0.5f, 0.5f, 0.5f, 1.0f); @@ -141,3 +157,82 @@ void ImageScrollAreaGL::initializeGL() m_transferOptions = std::unique_ptr(new QOpenGLPixelTransferOptions); m_transferOptions->setAlignment(1); } + +ImageScrollAreaGL::ImageScrollAreaGL(QWidget *parent) +{ + QGridLayout *layout = new QGridLayout(this); + setLayout(layout); + + m_imageWidget = new ImageWidget(this); + + m_verticalScrollBar = new QScrollBar(Qt::Vertical, this); + m_horizontalScrollBar = new QScrollBar(Qt::Horizontal, this); + + layout->setSpacing(0); + layout->addWidget(m_imageWidget, 0, 0); + layout->addWidget(m_verticalScrollBar, 0, 1); + layout->addWidget(m_horizontalScrollBar, 1, 0); + + connect(m_verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollEvent())); + connect(m_horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(scrollEvent())); +} + +ImageScrollAreaGL::~ImageScrollAreaGL() +{ + +} + +void ImageScrollAreaGL::setImage(RawImage *image) +{ + m_imageWidget->setImage(image); + m_imgWidth = image->width(); + m_imgHeight = image->height(); + updateScrollbars(); +} + +void ImageScrollAreaGL::setImage(const QPixmap &pixmap) +{ + m_imageWidget->setImage(pixmap); + m_imgWidth = pixmap.width(); + m_imgHeight = pixmap.height(); + updateScrollbars(); +} + +ImageWidget *ImageScrollAreaGL::imageWidget() +{ + return m_imageWidget; +} + +void ImageScrollAreaGL::updateScrollbars() +{ + m_verticalScrollBar->setRange(0, m_imgHeight-m_verticalScrollBar->pageStep()); + m_horizontalScrollBar->setRange(0, m_imgWidth-m_horizontalScrollBar->pageStep()); +} + +void ImageScrollAreaGL::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + qDebug() << "resize" << m_imageWidget->size(); + m_verticalScrollBar->setPageStep(m_imageWidget->height()); + m_horizontalScrollBar->setPageStep(m_imageWidget->width()); + updateScrollbars(); +} + +void ImageScrollAreaGL::mouseMoveEvent(QMouseEvent *event) +{ + QPoint delta = m_lastPos - event->pos(); + m_horizontalScrollBar->setValue(m_horizontalScrollBar->value() + delta.x()); + m_verticalScrollBar->setValue(m_verticalScrollBar->value() + delta.y()); + m_lastPos = event->pos(); +} + +void ImageScrollAreaGL::mousePressEvent(QMouseEvent *event) +{ + m_lastPos = event->pos(); +} + +void ImageScrollAreaGL::scrollEvent() +{ + qDebug() << m_horizontalScrollBar->value() << m_verticalScrollBar->value(); + m_imageWidget->setOffset(m_horizontalScrollBar->value(), m_verticalScrollBar->value()); +} diff --git a/imagescrollareagl.h b/imagescrollareagl.h index 1c97838..b2eedbb 100644 --- a/imagescrollareagl.h +++ b/imagescrollareagl.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "rawimage.h" typedef enum @@ -20,7 +21,7 @@ typedef enum Asinh, }StretchFunc; -class ImageScrollAreaGL : public QOpenGLWidget +class ImageWidget : public QOpenGLWidget { Q_OBJECT QOpenGLFunctions *f; @@ -33,18 +34,43 @@ class ImageScrollAreaGL : public QOpenGLWidget float m_low; float m_high; float m_range; + float m_dx, m_dy; public: - explicit ImageScrollAreaGL(QWidget *parent = nullptr); - ~ImageScrollAreaGL(); + explicit ImageWidget(QWidget *parent = nullptr); + ~ImageWidget(); void setImage(RawImage *image); void setImage(const QPixmap &pixmap); public slots: void setLow(int low); void setHigh(int high); + void setOffset(int dx, int dy); protected: void paintGL(); void resizeGL(int w, int h); void initializeGL(); }; +class ImageScrollAreaGL : public QWidget +{ + Q_OBJECT + QScrollBar *m_verticalScrollBar; + QScrollBar *m_horizontalScrollBar; + ImageWidget *m_imageWidget; + int m_imgWidth, m_imgHeight; + QPoint m_lastPos; +public: + explicit ImageScrollAreaGL(QWidget *parent = nullptr); + ~ImageScrollAreaGL(); + void setImage(RawImage *image); + void setImage(const QPixmap &pixmap); + ImageWidget* imageWidget(); +protected: + void updateScrollbars(); + void resizeEvent(QResizeEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); +protected slots: + void scrollEvent(); +}; + #endif // IMAGESCROLLAREAGL_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 66f02cf..521367d 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -49,8 +49,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) addDockWidget(Qt::BottomDockWidgetArea, captureDock); StretchPanel *stretchPanel = new StretchPanel(this); - connect(stretchPanel, SIGNAL(lowChanged(int)), m_imageGL, SLOT(setLow(int))); - connect(stretchPanel, SIGNAL(highChanged(int)), m_imageGL, SLOT(setHigh(int))); + connect(stretchPanel, SIGNAL(lowChanged(int)), m_imageGL->imageWidget(), SLOT(setLow(int))); + connect(stretchPanel, SIGNAL(highChanged(int)), m_imageGL->imageWidget(), SLOT(setHigh(int))); QDockWidget *stretchDock = new QDockWidget(tr("Stretch"), this); stretchDock->setWidget(stretchPanel);