diff --git a/imagescrollareagl.cpp b/imagescrollareagl.cpp index 97a1496..e9d3f92 100644 --- a/imagescrollareagl.cpp +++ b/imagescrollareagl.cpp @@ -11,6 +11,7 @@ #include #include #include +#include struct RawImageType { @@ -36,6 +37,8 @@ const RawImageType rawImageTypes[] = { {QOpenGLTexture::RGB, QOpenGLTexture::RGB32F, QOpenGLTexture::Float32, false} }; +static bool MANUAL_MIPMAP_GEN = false; + void setScrollRange(QScrollBar *scrollBar, int newRange) { int page = scrollBar->pageStep(); @@ -105,8 +108,11 @@ void ImageWidget::setImage(std::shared_ptr image, int index) m_currentImg = index; const RawImageType &rawImageType = rawImageTypes[image->type()]; + m_srgb = rawImageType.textureFormat == QOpenGLTexture::SRGB8 || rawImageType.textureFormat == QOpenGLTexture::SRGB8_Alpha8; + m_bwImg = rawImageType.bw; m_image->destroy(); + m_image->setAutoMipMapGenerationEnabled(false); m_image->setFormat(rawImageType.textureFormat); m_image->setSize(image->width(), image->height()); m_image->setMipLevels([&](){ int c = 0; int s = std::min(m_imgWidth, m_imgHeight); while(s>>=1)c++; return c; }()); @@ -115,10 +121,42 @@ void ImageWidget::setImage(std::shared_ptr image, int index) m_image->setWrapMode(QOpenGLTexture::ClampToEdge); m_image->setBorderColor(0, 0, 0, 0); m_image->setData(0, rawImageType.pixelFormat, rawImageType.dataType, (const void*)image->data(), m_transferOptions.get()); + + auto sRGB_linear = [](cv::Point3f &pixel, const int *pos) + { + pixel.x = pixel.x <= 0.04045f ? pixel.x / 12.92f : std::pow((pixel.x + 0.055) / 1.055f, 2.4f); + pixel.y = pixel.y <= 0.04045f ? pixel.y / 12.92f : std::pow((pixel.y + 0.055) / 1.055f, 2.4f); + pixel.z = pixel.z <= 0.04045f ? pixel.z / 12.92f : std::pow((pixel.z + 0.055) / 1.055f, 2.4f); + }; + + auto linear_sRGB = [](cv::Point3f &pixel, const int *pos) + { + pixel.x = pixel.x <= 0.0031308f ? pixel.x * 12.92f : 1.055f * std::pow(pixel.x , 1/2.4f) - 0.055f; + pixel.y = pixel.y <= 0.0031308f ? pixel.y * 12.92f : 1.055f * std::pow(pixel.y , 1/2.4f) - 0.055f; + pixel.z = pixel.z <= 0.0031308f ? pixel.z * 12.92f : 1.055f * std::pow(pixel.z , 1/2.4f) - 0.055f; + }; + + //AMD OpenGL driver on Windows doesn't generate mipmaps for sRGB textures correctly + if(m_srgb && MANUAL_MIPMAP_GEN) + { + cv::Mat img = image->mat(); + img.convertTo(img, CV_32FC3, 1/255.0); + img.forEach(sRGB_linear); + cv::Size size(img.cols, img.rows); + for(int i=1; imipLevels(); i++) + { + cv::Mat mip; + size /= 2; + cv::resize(img, mip, size); + mip.copyTo(img); + mip.forEach(linear_sRGB); + mip.convertTo(mip, CV_8UC3, 255); + m_image->setData(i, rawImageType.pixelFormat, rawImageType.dataType, (const void*)mip.ptr(), m_transferOptions.get()); + } + } + else m_image->generateMipMaps(); + m_image->setLevelOfDetailRange(m_superpixel ? 1 : 0, m_image->mipMaxLevel()); - m_image->generateMipMaps(); - m_bwImg = rawImageType.bw; - m_srgb = rawImageType.textureFormat == QOpenGLTexture::SRGB8 || rawImageType.textureFormat == QOpenGLTexture::SRGB8_Alpha8; update(); } @@ -351,6 +389,8 @@ void ImageWidget::initializeGL() qDebug() << (char*)f->glGetString(GL_RENDERER); qDebug() << (char*)f->glGetString(GL_VERSION); + MANUAL_MIPMAP_GEN = QString((const char*)f->glGetString(GL_VENDOR)).startsWith("ATI Technologies Inc", Qt::CaseInsensitive); + qDebug() << context()->format(); // each vertex is x,y 2D position and s,t texture coordinates