color calibration with 3d lut (#1793)

This commit is contained in:
shun-iwasawa 2018-02-19 12:06:07 +09:00 committed by masafumi-inoue
parent 24e7f37ed3
commit ad7711e42d
21 changed files with 899 additions and 221 deletions

View file

@ -59,9 +59,6 @@ class ToolOptionsBox;
class QMenu; class QMenu;
// iwsw commented out
// class Ghibli3DLutUtil;
//=================================================================== //===================================================================
//***************************************************************************************** //*****************************************************************************************
@ -655,8 +652,8 @@ public:
/*-- Toolで画面の内外を判断するため --*/ /*-- Toolで画面の内外を判断するため --*/
virtual TRectD getGeometry() const = 0; virtual TRectD getGeometry() const = 0;
// iwsw commented out virtual void bindFBO() {}
// virtual Ghibli3DLutUtil* get3DLutUtil(){ return 0; } virtual void releaseFBO() {}
}; };
#endif #endif

View file

@ -235,6 +235,15 @@ public:
void setInterfaceFontWeight(int weight); void setInterfaceFontWeight(int weight);
int getInterfaceFontWeight() { return m_interfaceFontWeight; } int getInterfaceFontWeight() { return m_interfaceFontWeight; }
// color calibration using 3DLUT
void enableColorCalibration(bool on);
bool isColorCalibrationEnabled() const { return m_colorCalibrationEnabled; }
void setColorCalibrationLutPath(QString monitorName, QString path);
QMap<QString, QString> &getColorCalibrationLutPathMap() {
return m_colorCalibrationLutPaths;
}
QString getColorCalibrationLutPath(QString &monitorName) const;
// Visualization tab // Visualization tab
void setShow0ThickLines(bool on); void setShow0ThickLines(bool on);
@ -652,6 +661,12 @@ private:
bool m_currentTimelineEnabled; bool m_currentTimelineEnabled;
// color calibration using 3DLUT
bool m_colorCalibrationEnabled = true; //とりあえず
// map of [monitor name]-[path to the lut file].
// for now non-Windows accepts only one lut path for all kinds of monitors
QMap<QString, QString> m_colorCalibrationLutPaths;
private: private:
Preferences(); Preferences();
~Preferences(); ~Preferences();

View file

@ -0,0 +1,78 @@
#pragma once
#ifndef LUT_CALIBRATOR_H
#define LUT_CALIBRATOR_H
#include "tcommon.h"
#include "tpixelutils.h"
#include <QOpenGLBuffer>
#include <QMatrix4x4>
#include <QOpenGLFunctions>
#undef DVAPI
#undef DVVAR
#ifdef TOONZQT_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
class QOpenGLShader;
class QOpenGLShaderProgram;
class QOpenGLFramebufferObject;
class QOpenGLTexture;
class QColor;
class DVAPI LutCalibrator : public QOpenGLFunctions // sigleton
{
bool m_isValid = false;
struct LutTextureShader {
QOpenGLShader* vert = nullptr;
QOpenGLShader* frag = nullptr;
QOpenGLShaderProgram* program = nullptr;
int texUniform = -1;
int lutUniform = -1;
int lutSizeUniform = -1;
int vertexAttrib = -1;
int texCoordAttrib = -1;
} m_shader;
struct Lut {
int meshSize;
float* data = NULL;
QOpenGLTexture* tex = NULL;
} m_lut;
QOpenGLBuffer m_viewerVBO;
LutCalibrator() {}
bool initializeLutTextureShader();
void createViewerVBO();
bool loadLutFile(const QString& path);
void assignLutTexture();
public:
static LutCalibrator* instance();
// to be computed once through the software
void initialize();
void finalize();
bool isValid() { return m_isValid; }
~LutCalibrator() { finalize(); }
void onEndDraw(QOpenGLFramebufferObject*);
QString& getMonitorName() const;
void convert(float&, float&, float&);
void convert(QColor&);
void convert(TPixel32&);
};
#endif

View file

@ -14,7 +14,6 @@
#include "toonz/tpalettehandle.h" #include "toonz/tpalettehandle.h"
#include "toonz/txshlevelhandle.h" #include "toonz/txshlevelhandle.h"
#include "toonz/txshlevel.h" #include "toonz/txshlevel.h"
//#include "toonz/preferences.h" //iwsw commented out temporarily
// TnzQt includes // TnzQt includes
#include "toonzqt/checkbox.h" #include "toonzqt/checkbox.h"
@ -24,9 +23,6 @@
#include "toonzqt/tabbar.h" #include "toonzqt/tabbar.h"
#include "toonzqt/glwidget_for_highdpi.h" #include "toonzqt/glwidget_for_highdpi.h"
// Toonz includes
//#include "../toonz/tapp.h" //iwsw commented out temporarily
// Qt includes // Qt includes
#include <QWidget> #include <QWidget>
#include <QFrame> #include <QFrame>
@ -39,9 +35,6 @@
#include <QSettings> #include <QSettings>
#include <QSplitter> #include <QSplitter>
// iwsw commented out temporarily
//#include "ghibli_3dlut_util.h"
#undef DVAPI #undef DVAPI
#undef DVVAR #undef DVVAR
#ifdef TOONZQT_EXPORTS #ifdef TOONZQT_EXPORTS
@ -71,6 +64,7 @@ class QButtonGroup;
class QPushButton; class QPushButton;
class QTabWidget; class QTabWidget;
class QToolBar; class QToolBar;
class QOpenGLFramebufferObject;
class ColorSquaredWheel; class ColorSquaredWheel;
class TabBarContainter; class TabBarContainter;
@ -153,8 +147,8 @@ class DVAPI HexagonalColorWheel final : public GLWidgetForHighDpi {
CurrentWheel m_currentWheel; CurrentWheel m_currentWheel;
// iwsw commented out temporarily about 3DLUT // used for color calibration with 3DLUT
// Ghibli3DLutUtil * m_ghibli3DLutUtil; QOpenGLFramebufferObject *m_fbo = NULL;
private: private:
void drawCurrentColorMark(); void drawCurrentColorMark();

View file

@ -2087,8 +2087,8 @@ void BrushTool::checkGuideSnapping(bool beforeMousePress) {
snapPoint.x = hGuide; snapPoint.x = hGuide;
} }
beforeMousePress ? m_foundFirstSnap = true : m_foundLastSnap = true; beforeMousePress ? m_foundFirstSnap = true : m_foundLastSnap = true;
beforeMousePress ? m_firstSnapPoint = snapPoint : m_lastSnapPoint = beforeMousePress ? m_firstSnapPoint = snapPoint
snapPoint; : m_lastSnapPoint = snapPoint;
} }
} }
} }

View file

@ -22,15 +22,13 @@
#include "toonzqt/icongenerator.h" #include "toonzqt/icongenerator.h"
#include "toonzqt/dvdialog.h" #include "toonzqt/dvdialog.h"
#include "toonzqt/lutcalibrator.h"
#include "tools/toolhandle.h" #include "tools/toolhandle.h"
#include "tools/stylepicker.h" #include "tools/stylepicker.h"
#include "tools/toolutils.h" #include "tools/toolutils.h"
#include "tools/RGBpicker.h" #include "tools/RGBpicker.h"
// iwsw commented out temporarily
//#include "toonzqt/ghibli_3dlut_util.h"
#define NORMAL_PICK L"Normal" #define NORMAL_PICK L"Normal"
#define RECT_PICK L"Rectangular" #define RECT_PICK L"Rectangular"
#define FREEHAND_PICK L"Freehand" #define FREEHAND_PICK L"Freehand"
@ -420,8 +418,12 @@ void RGBPickerTool::passivePick() {
StylePicker picker(image); StylePicker picker(image);
if (LutCalibrator::instance()->isValid()) m_viewer->bindFBO();
TPixel32 pix = picker.pickColor(area); TPixel32 pix = picker.pickColor(area);
if (LutCalibrator::instance()->isValid()) m_viewer->releaseFBO();
QColor col((int)pix.r, (int)pix.g, (int)pix.b); QColor col((int)pix.r, (int)pix.g, (int)pix.b);
PaletteController *controller = PaletteController *controller =
@ -444,8 +446,12 @@ void RGBPickerTool::pick() {
m_mousePixelPosition.x + 1, m_mousePixelPosition.y + 1); m_mousePixelPosition.x + 1, m_mousePixelPosition.y + 1);
StylePicker picker(image, palette); StylePicker picker(image, palette);
if (LutCalibrator::instance()->isValid()) m_viewer->bindFBO();
m_currentValue = picker.pickColor(area); m_currentValue = picker.pickColor(area);
if (LutCalibrator::instance()->isValid()) m_viewer->releaseFBO();
TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel();
UndoPickRGBM *cmd = new UndoPickRGBM(palette, styleId, m_currentValue, level); UndoPickRGBM *cmd = new UndoPickRGBM(palette, styleId, m_currentValue, level);
TUndoManager::manager()->add(cmd); TUndoManager::manager()->add(cmd);
@ -485,7 +491,11 @@ void RGBPickerTool::pickRect() {
if (area.getLx() <= 1 || area.getLy() <= 1) return; if (area.getLx() <= 1 || area.getLy() <= 1) return;
StylePicker picker(image, palette); StylePicker picker(image, palette);
if (LutCalibrator::instance()->isValid()) m_viewer->bindFBO();
m_currentValue = picker.pickColor(area); m_currentValue = picker.pickColor(area);
if (LutCalibrator::instance()->isValid()) m_viewer->releaseFBO();
} }
//--------------------------------------------------------- //---------------------------------------------------------
@ -502,8 +512,12 @@ void RGBPickerTool::pickStroke() {
StylePicker picker(image, palette); StylePicker picker(image, palette);
TStroke *stroke = new TStroke(*m_stroke); TStroke *stroke = new TStroke(*m_stroke);
if (LutCalibrator::instance()->isValid()) m_viewer->bindFBO();
m_currentValue = picker.pickColor(stroke); m_currentValue = picker.pickColor(stroke);
if (LutCalibrator::instance()->isValid()) m_viewer->releaseFBO();
if (!(m_pickType.getValue() == POLYLINE_PICK)) { if (!(m_pickType.getValue() == POLYLINE_PICK)) {
TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel(); TXshSimpleLevel *level = app->getCurrentLevel()->getSimpleLevel();
TUndoManager::manager()->add( TUndoManager::manager()->add(

View file

@ -22,8 +22,7 @@
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
#include "toonzqt/gutil.h" #include "toonzqt/gutil.h"
#include "toonzqt/dvscrollwidget.h" #include "toonzqt/dvscrollwidget.h"
// iwsw commented out temporarily #include "toonzqt/lutcalibrator.h"
//#include "toonzqt/ghibli_3dlut_converter.h"
// TnzLib includes // TnzLib includes
#include "toonz/tobjecthandle.h" #include "toonz/tobjecthandle.h"
@ -2279,18 +2278,12 @@ protected:
QPainter p(this); QPainter p(this);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) {
/* QColor convertedColor(m_color);
if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) LutCalibrator::instance()->convert(convertedColor);
{ p.setBrush(convertedColor);
QColor convertedColor(m_color); } else
Ghibli3DLutConverter::instance()->convert(convertedColor); p.setBrush(m_color);
p.setBrush(convertedColor);
}
else
*/
p.setBrush(m_color);
p.setBrush(m_color);
p.drawRect(rect()); p.drawRect(rect());

View file

@ -20,6 +20,7 @@
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
#include "toonzqt/viewcommandids.h" #include "toonzqt/viewcommandids.h"
#include "toonzqt/imageutils.h" #include "toonzqt/imageutils.h"
#include "toonzqt/lutcalibrator.h"
// TnzLib includes // TnzLib includes
#include "toonz/tscenehandle.h" #include "toonz/tscenehandle.h"
@ -36,6 +37,7 @@
#include <QAction> #include <QAction>
#include <QMouseEvent> #include <QMouseEvent>
#include <QWheelEvent> #include <QWheelEvent>
#include <QOpenGLFramebufferObject>
//=================================================================================== //===================================================================================
@ -226,11 +228,6 @@ ImageViewer::ImageViewer(QWidget *parent, FlipBook *flipbook,
if (m_isHistogramEnable) if (m_isHistogramEnable)
m_histogramPopup = new HistogramPopup(tr("Flipbook Histogram")); m_histogramPopup = new HistogramPopup(tr("Flipbook Histogram"));
// iwsw commented out 2 lines temporarily
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// Ghibli3DLutUtil::m_isValid)
// m_ghibli3DLutUtil = new Ghibli3DLutUtil();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -365,6 +362,7 @@ ImageViewer::~ImageViewer() {
delete m_ghibli3DLutUtil; delete m_ghibli3DLutUtil;
} }
*/ */
if (m_fbo) delete m_fbo;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -413,13 +411,12 @@ void ImageViewer::hideHistogram() {
void ImageViewer::initializeGL() { void ImageViewer::initializeGL() {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
// to be computed once through the software
LutCalibrator::instance()->initialize();
// glClearColor(1.0,1.0,1.0,1); // glClearColor(1.0,1.0,1.0,1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// iwsw commented out temporarily
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->onInit();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -439,19 +436,17 @@ void ImageViewer::resizeGL(int w, int h) {
glTranslatef(0.375, 0.375, 0.0); glTranslatef(0.375, 0.375, 0.0);
glTranslated(w * 0.5, h * 0.5, 0); glTranslated(w * 0.5, h * 0.5, 0);
// iwsw commented out temporarily // remake fbo with new size
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() && if (LutCalibrator::instance()->isValid()) {
// m_ghibli3DLutUtil) if (m_fbo) delete m_fbo;
// m_ghibli3DLutUtil->onResize(w, h); m_fbo = new QOpenGLFramebufferObject(w, h);
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ImageViewer::paintGL() { void ImageViewer::paintGL() {
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) m_fbo->bind();
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->startDraw();
TDimension viewerSize(width(), height()); TDimension viewerSize(width(), height());
TAffine aff = m_viewAff; TAffine aff = m_viewAff;
@ -508,11 +503,8 @@ void ImageViewer::paintGL() {
} }
if (!m_image) { if (!m_image) {
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid())
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() && LutCalibrator::instance()->onEndDraw(m_fbo);
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->endDraw();
return; return;
} }
@ -590,10 +582,8 @@ void ImageViewer::paintGL() {
} }
} }
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid())
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() && LutCalibrator::instance()->onEndDraw(m_fbo);
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->endDraw();
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -851,17 +841,11 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) {
TPoint mousePos = TPoint(curPos.x(), height() - 1 - curPos.y()); TPoint mousePos = TPoint(curPos.x(), height() - 1 - curPos.y());
TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y); TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y);
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) m_fbo->bind();
// if (get3DLutUtil() &&
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
// get3DLutUtil()->bindFBO();
const TPixel32 pix = picker.pickColor(area); const TPixel32 pix = picker.pickColor(area);
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) m_fbo->release();
// if (get3DLutUtil() &&
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
// get3DLutUtil()->releaseFBO();
QPoint viewP = mapFrom(this, curPos); QPoint viewP = mapFrom(this, curPos);
TPointD pos = getViewAff().inv() * TPointD pos = getViewAff().inv() *
@ -899,17 +883,11 @@ void ImageViewer::rectPickColor(bool putValueToStyleEditor) {
return; return;
} }
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid() && m_fbo) m_fbo->bind();
// if (get3DLutUtil() &&
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
// get3DLutUtil()->bindFBO();
const TPixel32 pix = picker.pickColor(area.enlarge(-1, -1)); const TPixel32 pix = picker.pickColor(area.enlarge(-1, -1));
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid() && m_fbo) m_fbo->release();
// if (get3DLutUtil() &&
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
// get3DLutUtil()->releaseFBO();
// throw the picked color to the histogram // throw the picked color to the histogram
m_histogramPopup->updateAverageColor(pix); m_histogramPopup->updateAverageColor(pix);

View file

@ -3,9 +3,6 @@
#ifndef IMAGEVIEWER_INCLUDE #ifndef IMAGEVIEWER_INCLUDE
#define IMAGEVIEWER_INCLUDE #define IMAGEVIEWER_INCLUDE
// iwsw commented out temporarily
//#include "toonzqt/ghibli_3dlut_util.h"
#include "toonz/imagepainter.h" #include "toonz/imagepainter.h"
#include "toonzqt/glwidget_for_highdpi.h" #include "toonzqt/glwidget_for_highdpi.h"
@ -14,6 +11,7 @@
// Forward declarations // Forward declarations
class FlipBook; class FlipBook;
class HistogramPopup; class HistogramPopup;
class QOpenGLFramebufferObject;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -57,8 +55,8 @@ class ImageViewer final : public GLWidgetForHighDpi {
// a flipbook shows a red border line before the rendered result is shown. // a flipbook shows a red border line before the rendered result is shown.
bool m_isRemakingPreviewFx; bool m_isRemakingPreviewFx;
// iwsw commented out temporarily // used for color calibration with 3DLUT
// Ghibli3DLutUtil * m_ghibli3DLutUtil; QOpenGLFramebufferObject *m_fbo = NULL;
int getDragType(const TPoint &pos, const TRect &loadBox); int getDragType(const TPoint &pos, const TRect &loadBox);
void updateLoadbox(const TPoint &curPos); void updateLoadbox(const TPoint &curPos);
@ -109,9 +107,6 @@ public:
void doSwapBuffers(); void doSwapBuffers();
void changeSwapBehavior(bool enable); void changeSwapBehavior(bool enable);
// iwsw commented out temporarily
// Ghibli3DLutUtil* get3DLutUtil(){ return m_ghibli3DLutUtil; }
protected: protected:
void contextMenuEvent(QContextMenuEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override;
void initializeGL() override; void initializeGL() override;

View file

@ -25,8 +25,6 @@
#include "toonzqt/icongenerator.h" #include "toonzqt/icongenerator.h"
#include "toonzqt/gutil.h" #include "toonzqt/gutil.h"
#include "toonzqt/pluginloader.h" #include "toonzqt/pluginloader.h"
// iwsw commented out temporarily
//#include "toonzqt/ghibli_3dlut_util.h"
// TnzStdfx includes // TnzStdfx includes
#include "stdfx/shaderfx.h" #include "stdfx/shaderfx.h"
@ -532,32 +530,6 @@ int main(int argc, char *argv[]) {
TTool::setApplication(TApp::instance()); TTool::setApplication(TApp::instance());
TApp::instance()->init(); TApp::instance()->init();
// iwsw commented out temporarily
#if 0
QStringList monitorNames;
/*-- 接続モニタがPVM-2541の場合のみLUTを読み込む --*/
if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
{
/*-- 接続モニタがPVM-2541の場合のみLUTを読み込む --*/
monitorNames = Ghibli3DLutUtil::getMonitorName();
if (monitorNames.contains(QString::fromStdWString(L"PVM-2541")))
/*-- 3DLUTファイルを読み込む --*/
Ghibli3DLutUtil::loadLutFile(Preferences::instance()->get3DLutPath());
}
/*-- 接続モニタをスプラッシュ画面にも表示 --*/
if (!monitorNames.isEmpty())
{
lastUpdateStr += QString("Monitor Name : ");
for (int mn = 0; mn < monitorNames.size(); mn++)
{
if (mn != 0)
lastUpdateStr += QString(", ");
lastUpdateStr += monitorNames.at(mn);
}
lastUpdateStr += QString("\n");
}
#endif
splash.showMessage(offsetStr + "Loading Plugins...", Qt::AlignCenter, splash.showMessage(offsetStr + "Loading Plugins...", Qt::AlignCenter,
Qt::white); Qt::white);
a.processEvents(); a.processEvents();

View file

@ -17,6 +17,7 @@
#include "toonzqt/doublefield.h" #include "toonzqt/doublefield.h"
#include "toonzqt/dvdialog.h" #include "toonzqt/dvdialog.h"
#include "toonzqt/filefield.h" #include "toonzqt/filefield.h"
#include "toonzqt/lutcalibrator.h"
// TnzLib includes // TnzLib includes
#include "toonz/txsheethandle.h" #include "toonz/txsheethandle.h"
@ -1145,6 +1146,20 @@ void PreferencesPopup::onShowCurrentTimelineChanged(int index) {
m_pref->enableCurrentTimelineIndicator(index == Qt::Checked); m_pref->enableCurrentTimelineIndicator(index == Qt::Checked);
} }
//-----------------------------------------------------------------------------
void PreferencesPopup::onColorCalibrationChanged(bool on) {
m_pref->enableColorCalibration(on);
}
//-----------------------------------------------------------------------------
void PreferencesPopup::onLutPathChanged() {
m_pref->setColorCalibrationLutPath(
LutCalibrator::instance()->getMonitorName(),
m_lutPathFileField->getPath());
}
//********************************************************************************** //**********************************************************************************
// PrefencesPopup's constructor // PrefencesPopup's constructor
//********************************************************************************** //**********************************************************************************
@ -1259,6 +1274,11 @@ PreferencesPopup::PreferencesPopup()
m_interfaceFont = new QComboBox(this); m_interfaceFont = new QComboBox(this);
m_interfaceFontWeight = new QComboBox(this); m_interfaceFontWeight = new QComboBox(this);
m_colorCalibration =
new QGroupBox(tr("Color Calibration using 3D Look-up Table *"));
m_lutPathFileField = new DVGui::FileField(
this, QString("- Please specify 3DLUT file (.3dl) -"), false, true);
//--- Visualization ------------------------------ //--- Visualization ------------------------------
categoryList->addItem(tr("Visualization")); categoryList->addItem(tr("Visualization"));
CheckBox *show0ThickLinesCB = CheckBox *show0ThickLinesCB =
@ -1583,6 +1603,16 @@ PreferencesPopup::PreferencesPopup()
m_interfaceFontWeight->addItems(fontStyles); m_interfaceFontWeight->addItems(fontStyles);
m_interfaceFontWeight->setCurrentIndex(m_pref->getInterfaceFontWeight()); m_interfaceFontWeight->setCurrentIndex(m_pref->getInterfaceFontWeight());
m_colorCalibration->setCheckable(true);
m_colorCalibration->setChecked(m_pref->isColorCalibrationEnabled());
QString lutPath = m_pref->getColorCalibrationLutPath(
LutCalibrator::instance()->getMonitorName());
if (!lutPath.isEmpty()) m_lutPathFileField->setPath(lutPath);
m_lutPathFileField->setFileMode(QFileDialog::ExistingFile);
QStringList lutFileTypes;
lutFileTypes << "3dl";
m_lutPathFileField->setFilters(lutFileTypes);
//--- Visualization ------------------------------ //--- Visualization ------------------------------
show0ThickLinesCB->setChecked(m_pref->getShow0ThickLines()); show0ThickLinesCB->setChecked(m_pref->getShow0ThickLines());
regionAntialiasCB->setChecked(m_pref->getRegionAntialias()); regionAntialiasCB->setChecked(m_pref->getRegionAntialias());
@ -1985,6 +2015,20 @@ PreferencesPopup::PreferencesPopup()
interfaceBottomLay->setColumnStretch(5, 1); interfaceBottomLay->setColumnStretch(5, 1);
userInterfaceFrameLay->addLayout(interfaceBottomLay, 0); userInterfaceFrameLay->addLayout(interfaceBottomLay, 0);
QHBoxLayout *lutLayout = new QHBoxLayout();
lutLayout->setMargin(10);
lutLayout->setSpacing(5);
{
lutLayout->addWidget(
new QLabel(tr("3DLUT File for [%1] *:")
.arg(LutCalibrator::instance()->getMonitorName()),
this),
0);
lutLayout->addWidget(m_lutPathFileField, 1);
}
m_colorCalibration->setLayout(lutLayout);
userInterfaceFrameLay->addWidget(m_colorCalibration);
userInterfaceFrameLay->addStretch(1); userInterfaceFrameLay->addStretch(1);
userInterfaceFrameLay->addWidget(note_interface, 0); userInterfaceFrameLay->addWidget(note_interface, 0);
@ -2562,6 +2606,11 @@ PreferencesPopup::PreferencesPopup()
ret = ret && connect(levelNameOnEachMarkerCB, SIGNAL(stateChanged(int)), ret = ret && connect(levelNameOnEachMarkerCB, SIGNAL(stateChanged(int)),
SLOT(onLevelNameOnEachMarkerChanged(int))); SLOT(onLevelNameOnEachMarkerChanged(int)));
ret = ret && connect(m_colorCalibration, SIGNAL(clicked(bool)), this,
SLOT(onColorCalibrationChanged(bool)));
ret = ret && connect(m_lutPathFileField, SIGNAL(pathChanged()), this,
SLOT(onLutPathChanged()));
//--- Visualization --------------------- //--- Visualization ---------------------
ret = ret && connect(show0ThickLinesCB, SIGNAL(stateChanged(int)), this, ret = ret && connect(show0ThickLinesCB, SIGNAL(stateChanged(int)), this,
SLOT(onShow0ThickLinesChanged(int))); SLOT(onShow0ThickLinesChanged(int)));

View file

@ -81,9 +81,10 @@ private:
DVGui::FileField *m_customProjectRootFileField; DVGui::FileField *m_customProjectRootFileField;
DVGui::FileField *m_ffmpegPathFileFld, *m_fastRenderPathFileField; DVGui::FileField *m_ffmpegPathFileFld, *m_fastRenderPathFileField,
*m_lutPathFileField;
QGroupBox *m_autoSaveGroup, *m_showXSheetToolbar; QGroupBox *m_autoSaveGroup, *m_showXSheetToolbar, *m_colorCalibration;
private: private:
// QWidget* create(const QString& lbl, bool def, const char* slot); // QWidget* create(const QString& lbl, bool def, const char* slot);
@ -200,6 +201,8 @@ private slots:
void onXsheetLayoutChanged(const QString &text); void onXsheetLayoutChanged(const QString &text);
void onPathAliasPriorityChanged(int index); void onPathAliasPriorityChanged(int index);
void onShowCurrentTimelineChanged(int); void onShowCurrentTimelineChanged(int);
void onColorCalibrationChanged(bool);
void onLutPathChanged();
}; };
//********************************************************************************** //**********************************************************************************

View file

@ -23,6 +23,7 @@
#include "toonzqt/icongenerator.h" #include "toonzqt/icongenerator.h"
#include "toonzqt/gutil.h" #include "toonzqt/gutil.h"
#include "toonzqt/imageutils.h" #include "toonzqt/imageutils.h"
#include "toonzqt/lutcalibrator.h"
// TnzLib includes // TnzLib includes
#include "toonz/tscenehandle.h" #include "toonz/tscenehandle.h"
@ -81,6 +82,7 @@
#include <QInputContext> #include <QInputContext>
#endif #endif
#include <QGLContext> #include <QGLContext>
#include <QOpenGLFramebufferObject>
#include "sceneviewer.h" #include "sceneviewer.h"
@ -500,10 +502,6 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent)
m_3DSideL = rasterFromQPixmap(svgToPixmap(":Resources/3Dside_l.svg")); m_3DSideL = rasterFromQPixmap(svgToPixmap(":Resources/3Dside_l.svg"));
m_3DTop = rasterFromQPixmap(svgToPixmap(":Resources/3Dtop.svg")); m_3DTop = rasterFromQPixmap(svgToPixmap(":Resources/3Dtop.svg"));
// iwsw commented out temporarily
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// Ghibli3DLutUtil::m_isValid)
// m_ghibli3DLutUtil = new Ghibli3DLutUtil();
setAttribute(Qt::WA_AcceptTouchEvents); setAttribute(Qt::WA_AcceptTouchEvents);
grabGesture(Qt::SwipeGesture); grabGesture(Qt::SwipeGesture);
grabGesture(Qt::PanGesture); grabGesture(Qt::PanGesture);
@ -525,14 +523,7 @@ void SceneViewer::setVisual(const ImagePainter::VisualSettings &settings) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
SceneViewer::~SceneViewer() { SceneViewer::~SceneViewer() {
// iwsw commented out temporarily if (m_fbo) delete m_fbo;
/*
if (m_ghibli3DLutUtil)
{
m_ghibli3DLutUtil->onEnd();
delete m_ghibli3DLutUtil;
}
*/
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
@ -825,13 +816,12 @@ double SceneViewer::getHGuide(int index) { return m_hRuler->getGuide(index); }
void SceneViewer::initializeGL() { void SceneViewer::initializeGL() {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
// to be computed once through the software
LutCalibrator::instance()->initialize();
// glClearColor(1.0,1.0,1.0,1); // glClearColor(1.0,1.0,1.0,1);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// iwsw commented out temporarily
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->onInit();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -856,12 +846,14 @@ void SceneViewer::resizeGL(int w, int h) {
if (m_previewMode != NO_PREVIEW) requestTimedRefresh(); if (m_previewMode != NO_PREVIEW) requestTimedRefresh();
// remake fbo with new size
if (LutCalibrator::instance()->isValid()) {
if (m_fbo) delete m_fbo;
m_fbo = new QOpenGLFramebufferObject(w, h);
}
// for updating the navigator in levelstrip // for updating the navigator in levelstrip
emit refreshNavi(); emit refreshNavi();
// iwsw commented out temporarily
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->onResize(w, h);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1381,11 +1373,7 @@ void SceneViewer::paintGL() {
time.start(); time.start();
#endif #endif
// iwsw commented out temporarily if (!m_isPicking && LutCalibrator::instance()->isValid()) m_fbo->bind();
// if (!m_isPicking &&
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->startDraw();
if (m_hRuler && m_vRuler) { if (m_hRuler && m_vRuler) {
if (!viewRulerToggle.getStatus() && if (!viewRulerToggle.getStatus() &&
@ -1415,11 +1403,8 @@ void SceneViewer::paintGL() {
glPopMatrix(); glPopMatrix();
m_viewGrabImage->unlock(); m_viewGrabImage->unlock();
// iwsw commented out temporarily if (!m_isPicking && LutCalibrator::instance()->isValid())
// if (!m_isPicking && LutCalibrator::instance()->onEndDraw(m_fbo);
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->endDraw();
return; return;
} }
@ -1427,11 +1412,8 @@ void SceneViewer::paintGL() {
drawBuildVars(); drawBuildVars();
check_framebuffer_status(); check_framebuffer_status();
// iwsw commented out temporarily
// if (!m_isPicking &&
// !Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() ||
//! m_ghibli3DLutUtil)
copyFrontBufferToBackBuffer(); copyFrontBufferToBackBuffer();
check_framebuffer_status(); check_framebuffer_status();
drawEnableScissor(); drawEnableScissor();
check_framebuffer_status(); check_framebuffer_status();
@ -1465,11 +1447,8 @@ void SceneViewer::paintGL() {
#endif #endif
// TOfflineGL::setContextManager(0); // TOfflineGL::setContextManager(0);
// iwsw commented out temporarily if (!m_isPicking && LutCalibrator::instance()->isValid())
// if (!m_isPicking && LutCalibrator::instance()->onEndDraw(m_fbo);
// Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
// m_ghibli3DLutUtil)
// m_ghibli3DLutUtil->endDraw();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2556,3 +2535,15 @@ TRectD SceneViewer::getGeometry() const {
void SceneViewer::doDeleteSubCamera() { void SceneViewer::doDeleteSubCamera() {
PreviewSubCameraManager::instance()->deleteSubCamera(this); PreviewSubCameraManager::instance()->deleteSubCamera(this);
} }
//-----------------------------------------------------------------------------
void SceneViewer::bindFBO() {
if (m_fbo) m_fbo->bind();
}
//-----------------------------------------------------------------------------
void SceneViewer::releaseFBO() {
if (m_fbo) m_fbo->release();
}

View file

@ -14,8 +14,6 @@
#include "toonzqt/menubarcommand.h" #include "toonzqt/menubarcommand.h"
#include "toonzqt/flipconsole.h" #include "toonzqt/flipconsole.h"
#include "toonzqt/glwidget_for_highdpi.h" #include "toonzqt/glwidget_for_highdpi.h"
// iwsw commented out temporarily
//#include "toonzqt/ghibli_3dlut_util.h"
// TnzTools includes // TnzTools includes
#include "tools/tool.h" #include "tools/tool.h"
@ -36,6 +34,7 @@ class SceneViewer;
class LocatorPopup; class LocatorPopup;
class QGestureEvent; class QGestureEvent;
class QTouchEvent; class QTouchEvent;
class QOpenGLFramebufferObject;
namespace ImageUtils { namespace ImageUtils {
class FullScreenWidget; class FullScreenWidget;
@ -145,6 +144,9 @@ class SceneViewer final : public GLWidgetForHighDpi,
bool m_editPreviewSubCamera; bool m_editPreviewSubCamera;
// used for color calibration with 3DLUT
QOpenGLFramebufferObject *m_fbo = NULL;
enum Device3D { enum Device3D {
NONE, NONE,
SIDE_LEFT_3D, SIDE_LEFT_3D,
@ -160,8 +162,6 @@ class SceneViewer final : public GLWidgetForHighDpi,
QMatrix4x4 m_projectionMatrix; QMatrix4x4 m_projectionMatrix;
// iwsw commented out temporarily
// Ghibli3DLutUtil * m_ghibli3DLutUtil;
public: public:
// iwsw commented out temporarily // iwsw commented out temporarily
// Ghibli3DLutUtil* get3DLutUtil(){ return m_ghibli3DLutUtil; } // Ghibli3DLutUtil* get3DLutUtil(){ return m_ghibli3DLutUtil; }
@ -262,6 +262,9 @@ public:
double getVGuide(int index); double getVGuide(int index);
double getHGuide(int index); double getHGuide(int index);
void bindFBO() override;
void releaseFBO() override;
public: public:
// SceneViewer's gadget public functions // SceneViewer's gadget public functions
TPointD winToWorld(const QPointF &pos) const; TPointD winToWorld(const QPointF &pos) const;

View file

@ -666,6 +666,18 @@ Preferences::Preferences()
m_loadedXsheetLayout = m_xsheetLayoutPreference; m_loadedXsheetLayout = m_xsheetLayoutPreference;
getValue(*m_settings, "currentTimelineEnabled", m_currentTimelineEnabled); getValue(*m_settings, "currentTimelineEnabled", m_currentTimelineEnabled);
getValue(*m_settings, "colorCalibrationEnabled", m_colorCalibrationEnabled);
QVariant val = m_settings->value("colorCalibrationLutPaths");
if (val.canConvert<QVariantMap>()) {
QAssociativeIterable iterable = val.value<QAssociativeIterable>();
QAssociativeIterable::const_iterator it = iterable.begin();
const QAssociativeIterable::const_iterator end = iterable.end();
for (; it != end; ++it) {
m_colorCalibrationLutPaths.insert(it.key().toString(),
it.value().toString());
}
}
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
@ -1617,3 +1629,30 @@ void Preferences::enableCurrentTimelineIndicator(bool on) {
m_currentTimelineEnabled = on; m_currentTimelineEnabled = on;
m_settings->setValue("currentTimelineEnabled", on ? "1" : "0"); m_settings->setValue("currentTimelineEnabled", on ? "1" : "0");
} }
//-----------------------------------------------------------------
// color calibration using 3DLUT
void Preferences::enableColorCalibration(bool on) {
m_colorCalibrationEnabled = on;
m_settings->setValue("colorCalibrationEnabled", on ? "1" : "0");
}
void Preferences::setColorCalibrationLutPath(QString monitorName,
QString path) {
m_colorCalibrationLutPaths.insert(monitorName, path);
QMap<QString, QVariant> map;
QMap<QString, QString>::const_iterator i =
m_colorCalibrationLutPaths.constBegin();
while (i != m_colorCalibrationLutPaths.constEnd()) {
map.insert(i.key(), i.value());
i++;
}
m_settings->setValue("colorCalibrationLutPaths", map);
}
QString Preferences::getColorCalibrationLutPath(QString &monitorName) const {
return m_colorCalibrationLutPaths.value(monitorName);
}
//-----------------------------------------------------------------

View file

@ -87,6 +87,7 @@ set(MOC_HEADERS
../include/toonzqt/combohistogram.h ../include/toonzqt/combohistogram.h
../include/toonzqt/fxiconmanager.h ../include/toonzqt/fxiconmanager.h
../include/toonzqt/glwidget_for_highdpi.h ../include/toonzqt/glwidget_for_highdpi.h
../include/toonzqt/lutcalibrator.h
pluginhost.h pluginhost.h
) )
@ -193,6 +194,7 @@ set(SOURCES
plugin_param_view_interface.cpp plugin_param_view_interface.cpp
plugin_ui_page_interface.cpp plugin_ui_page_interface.cpp
toonz_params.cpp toonz_params.cpp
lutcalibrator.cpp
) )
set(RESOURCES toonzqt.qrc) set(RESOURCES toonzqt.qrc)

View file

@ -9,6 +9,7 @@
#include "tconvert.h" #include "tconvert.h"
#include "tcolorstyles.h" #include "tcolorstyles.h"
#include "trop.h" #include "trop.h"
#include "toonzqt/lutcalibrator.h"
#include <QLayout> #include <QLayout>
#include <QPainter> #include <QPainter>
@ -95,9 +96,9 @@ void StyleSample::setStyle(TColorStyle &style) {
*/ */
void StyleSample::setColor(const TPixel32 &pixel) { void StyleSample::setColor(const TPixel32 &pixel) {
QColor color(pixel.r, pixel.g, pixel.b, pixel.m); QColor color(pixel.r, pixel.g, pixel.b, pixel.m);
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid())
// if (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) LutCalibrator::instance()->convert(color);
// Ghibli3DLutConverter::instance()->convert(color);
m_samplePixmap.fill(color.rgba()); m_samplePixmap.fill(color.rgba());
update(); update();
} }

View file

@ -10,8 +10,7 @@
#include <QString> #include <QString>
#include "toonz/preferences.h" #include "toonz/preferences.h"
// iwsw commented out temporarily #include "toonzqt/lutcalibrator.h"
//#include "toonzqt/ghibli_3dlut_converter.h"
#include <QPushButton> #include <QPushButton>
#include <QDialog> #include <QDialog>
@ -323,17 +322,12 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) {
return; return;
} }
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) {
/* QColor convertedColor(m_color);
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled()) LutCalibrator::instance()->convert(convertedColor);
{ p.setBrush(convertedColor);
QColor convertedColor(m_color); } else
Ghibli3DLutConverter::instance()->convert(convertedColor); p.setBrush(m_color);
p.setBrush(convertedColor);
}
else
*/
p.setBrush(m_color);
p.drawRect(bgRect); p.drawRect(bgRect);

View file

@ -0,0 +1,589 @@
#include "toonzqt/lutcalibrator.h"
// Tnzlib includes
#include "toonz/preferences.h"
// TnzCore includes
#include "tmsgcore.h"
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QOpenGLFramebufferObject>
#include <QOpenGLTexture>
#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QFile>
#include <QColor>
namespace {
inline bool execWarning(const QString& s) {
DVGui::MsgBox(DVGui::WARNING, s);
return false;
}
};
#ifdef WIN32
#include <QStringList>
#include <QSettings>
#include <QByteArray>
namespace {
// obtain monitor information from registry
QStringList getMonitorNames() {
QStringList subPathSet;
// QSettings regSys("SYSTEM\\CurrentControlSet\\Enum\\DISPLAY",
// QSettings::NativeFormat);
QSettings regSys(
"HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Enum\\DISPLAY",
QSettings::NativeFormat);
QStringList children = regSys.childGroups();
// return value
QStringList nameList;
if (children.isEmpty()) {
std::cout << "getMonitorNames : Failed to Open Registry" << std::endl;
return nameList;
}
for (int c = 0; c < children.size(); c++) {
// Parent Key : DISPLAY
// Child Keys : AVO0000, ENC2174, etc.
// Grandchild Key : 5&388..
// Find grandchild key which contains a great-grandchild key named "Control"
regSys.beginGroup(children.at(c)); // Child keys : AVO0000, ENC2174, etc.
QStringList grandChildren = regSys.childGroups();
for (int gc = 0; gc < grandChildren.size(); gc++) {
regSys.beginGroup(grandChildren.at(gc)); // Grandchild key : 5&388..
QStringList greatGrandChildren = regSys.childGroups();
if (greatGrandChildren.contains(
"Control")) // If the key "Control" is found
{
// Obtain variable "EDID" from the key "Device Parameters"
regSys.beginGroup("Device Parameters");
// the key may be not "EDID", but "BAD_EDID"
if (regSys.contains("EDID")) {
QString subPath = regSys.group().replace("/", "\\").prepend(
"SYSTEM\\CurrentControlSet\\Enum\\DISPLAY\\");
subPathSet.push_back(subPath);
}
regSys.endGroup();
}
regSys.endGroup();
}
// subPath may not be one...?
// if(!subPath.isEmpty())
// break;
regSys.endGroup();
}
if (subPathSet.isEmpty()) {
std::cout << "getMonitorNames : Failed to Find Current EDID" << std::endl;
return nameList;
}
// for each subPath ( it may become more than one when using submonitor )
for (int sp = 0; sp < subPathSet.size(); sp++) {
QString subPath = subPathSet.at(sp);
HKEY handle = 0;
LONG res = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
reinterpret_cast<const wchar_t*>(subPath.utf16()),
0, KEY_READ, &handle);
if (res == ERROR_SUCCESS && handle) {
QString keyStr("EDID");
// get the size and type of the value
DWORD dataType;
DWORD dataSize;
LONG res = RegQueryValueExW(
handle, reinterpret_cast<const wchar_t*>(keyStr.utf16()), 0,
&dataType, 0, &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
continue;
}
// get the value
QByteArray ba(dataSize, 0);
res = RegQueryValueExW(
handle, reinterpret_cast<const wchar_t*>(keyStr.utf16()), 0, 0,
reinterpret_cast<unsigned char*>(ba.data()), &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
continue;
}
QString s;
if (dataSize) {
s = QString::fromUtf16((const ushort*)ba.constData(), ba.size() / 2);
}
QString valStr;
QList<int> valArray;
for (int b = 0; b < s.length(); b++) {
QChar c1((int)s[b].unicode() % 256);
QChar c2((int)s[b].unicode() / 256);
valStr.append(c1.toLatin1());
valStr.append(c2.toLatin1());
valArray.append((int)s[b].unicode() % 256);
valArray.append((int)s[b].unicode() / 256);
}
// machine name starts from "FC 00", end with "0A"
int index1 = valArray.indexOf(252); // FC
int index2 = valArray.indexOf(10, index1); // 0A
if (index1 > 0 && index2 > 0) {
QString machineName = valStr.mid(index1 + 2, index2 - index1 - 2);
nameList.push_back(machineName);
// std::wcout << "machine name = " << machineName.toStdWString() <<
// std::endl;
}
RegCloseKey(handle);
} else {
std::cout << "getMonitorNames : failed to get handle" << std::endl;
continue;
}
}
if (nameList.isEmpty())
std::cout << "getMonitorNames : No Monitor Name Found" << std::endl;
return nameList;
}
};
#endif
//-----------------------------------------------------------------------------
LutCalibrator* LutCalibrator::instance() {
static LutCalibrator _instance;
return &_instance;
}
//-----------------------------------------------------------------------------
void LutCalibrator::initialize() {
static bool hasInitialized = false;
if (hasInitialized) return;
hasInitialized = true;
initializeOpenGLFunctions();
// check whether preference enables color calibration
if (!Preferences::instance()->isColorCalibrationEnabled()) return;
// obtain current monitor name
QString monitorName = getMonitorName();
// obtain 3dlut path associated to the monitor name
QString lutPath =
Preferences::instance()->getColorCalibrationLutPath(monitorName);
if (lutPath.isEmpty()) return;
// check existence of the 3dlut file
// load 3dlut data
if (!loadLutFile(lutPath)) return;
// create shader
if (!initializeLutTextureShader()) {
if (m_shader.program) delete m_shader.program;
if (m_shader.vert) delete m_shader.vert;
if (m_shader.frag) delete m_shader.frag;
return;
}
createViewerVBO();
// input 3dlut data to the shader
assignLutTexture();
m_isValid = true;
return;
}
//-----------------------------------------------------------------------------
void LutCalibrator::finalize() {
if (!m_isValid) return;
// release shader
if (m_shader.program) delete m_shader.program;
if (m_shader.vert) delete m_shader.vert;
if (m_shader.frag) delete m_shader.frag;
// release VBO
if (m_viewerVBO.isCreated()) m_viewerVBO.destroy();
// release LUT texture
if (m_lut.tex && m_lut.tex->isCreated()) {
m_lut.tex->destroy();
delete m_lut.tex;
}
if (m_lut.data) delete[] m_lut.data;
}
//-----------------------------------------------------------------------------
bool LutCalibrator::initializeLutTextureShader() {
m_shader.vert = new QOpenGLShader(QOpenGLShader::Vertex);
const char* simple_vsrc =
"#version 330 core\n"
"// Input vertex data, different for all executions of this shader.\n"
"layout(location = 0) in vec3 vertexPosition;\n"
"layout(location = 1) in vec2 texCoord;\n"
"// Output data ; will be interpolated for each fragment.\n"
"out vec2 UV;\n"
"// Values that stay constant for the whole mesh.\n"
"void main() {\n"
" // Output position of the vertex, in clip space : MVP * position\n"
" gl_Position = vec4(vertexPosition, 1);\n"
" // UV of the vertex. No special space for this one.\n"
" UV = texCoord;\n"
"}\n";
bool ret = m_shader.vert->compileSourceCode(simple_vsrc);
if (!ret)
return execWarning(
QObject::tr("Failed to compile m_textureShader.vert.", "gl"));
m_shader.frag = new QOpenGLShader(QOpenGLShader::Fragment);
const char* simple_fsrc =
"#version 330 core \n"
"// Interpolated values from the vertex shaders \n"
"in vec2 UV; \n"
"// Ouput data \n"
"out vec4 color; \n"
"// Values that stay constant for the whole mesh. \n"
"uniform sampler2D tex; \n"
"uniform sampler3D lut; \n"
"uniform vec3 lutSize; \n"
"void main() { \n"
" vec3 rawColor = texture(tex,UV).rgb; \n"
" vec3 scale = (lutSize - 1.0) / lutSize; \n"
" vec3 offset = 1.0 / (2.0 * lutSize); \n"
" color = vec4(texture(lut, scale * rawColor + offset).rgb, 1.0); \n"
"} \n";
ret = m_shader.frag->compileSourceCode(simple_fsrc);
if (!ret)
return execWarning(QObject::tr("Failed to compile m_shader.frag.", "gl"));
m_shader.program = new QOpenGLShaderProgram();
// add shaders
ret = m_shader.program->addShader(m_shader.vert);
if (!ret)
return execWarning(QObject::tr("Failed to add m_shader.vert.", "gl"));
ret = m_shader.program->addShader(m_shader.frag);
if (!ret)
return execWarning(QObject::tr("Failed to add m_shader.frag.", "gl"));
// link shaders
ret = m_shader.program->link();
if (!ret)
return execWarning(QObject::tr("Failed to link simple shader: %1", "gl")
.arg(m_shader.program->log()));
// obtain parameter locations
m_shader.vertexAttrib = m_shader.program->attributeLocation("vertexPosition");
if (m_shader.vertexAttrib == -1)
return execWarning(
QObject::tr("Failed to get attribute location of %1", "gl")
.arg("vertexPosition"));
m_shader.texCoordAttrib = m_shader.program->attributeLocation("texCoord");
if (m_shader.texCoordAttrib == -1)
return execWarning(
QObject::tr("Failed to get attribute location of %1", "gl")
.arg("texCoord"));
m_shader.texUniform = m_shader.program->uniformLocation("tex");
if (m_shader.texUniform == -1)
return execWarning(
QObject::tr("Failed to get uniform location of %1", "gl").arg("tex"));
m_shader.lutUniform = m_shader.program->uniformLocation("lut");
if (m_shader.lutUniform == -1)
return execWarning(
QObject::tr("Failed to get uniform location of %1", "gl").arg("lut"));
m_shader.lutSizeUniform = m_shader.program->uniformLocation("lutSize");
if (m_shader.lutSizeUniform == -1)
return execWarning(QObject::tr("Failed to get uniform location of %1", "gl")
.arg("lutSize"));
return true;
}
//-----------------------------------------------------------------------------
void LutCalibrator::createViewerVBO() {
GLfloat vertex[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
GLfloat texCoord[] = {0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f};
m_viewerVBO.create();
m_viewerVBO.bind();
m_viewerVBO.allocate(4 * 4 * sizeof(GLfloat));
m_viewerVBO.write(0, vertex, sizeof(vertex));
m_viewerVBO.write(sizeof(vertex), texCoord, sizeof(texCoord));
m_viewerVBO.release();
}
//-----------------------------------------------------------------------------
void LutCalibrator::onEndDraw(QOpenGLFramebufferObject* fbo) {
assert((glGetError()) == GL_NO_ERROR);
fbo->release();
GLuint textureId = fbo->texture();
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE4);
glBindTexture(GL_TEXTURE_2D, textureId);
glActiveTexture(GL_TEXTURE5);
m_lut.tex->bind();
glPushMatrix();
glLoadIdentity();
m_shader.program->bind();
m_shader.program->setUniformValue(m_shader.texUniform,
4); // use texture unit 4
m_shader.program->setUniformValue(m_shader.lutUniform,
5); // use texture unit 5
GLfloat size = (GLfloat)m_lut.meshSize;
m_shader.program->setUniformValue(m_shader.lutSizeUniform, size, size, size);
m_shader.program->enableAttributeArray(m_shader.vertexAttrib);
m_shader.program->enableAttributeArray(m_shader.texCoordAttrib);
m_viewerVBO.bind();
m_shader.program->setAttributeBuffer(m_shader.vertexAttrib, GL_FLOAT, 0, 2);
m_shader.program->setAttributeBuffer(m_shader.texCoordAttrib, GL_FLOAT,
4 * 2 * sizeof(GLfloat), 2);
m_viewerVBO.release();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
m_shader.program->disableAttributeArray(m_shader.vertexAttrib);
m_shader.program->disableAttributeArray(m_shader.texCoordAttrib);
m_shader.program->release();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
assert((glGetError()) == GL_NO_ERROR);
}
//-----------------------------------------------------------------------------
QString& LutCalibrator::getMonitorName() const {
static QString monitorName;
if (!monitorName.isEmpty()) return monitorName;
#ifdef WIN32
QStringList list = getMonitorNames();
if (list.isEmpty())
monitorName = "Any Monitor"; // this should not be translated
else
monitorName = list.at(0); // for now only the first monitor is handled
#else
monitorName = "Any Monitor"; // this should not be translated
#endif
return monitorName;
}
//-----------------------------------------------------------------------------
bool LutCalibrator::loadLutFile(const QString& fp) {
struct locals {
// skip empty or comment lines
static inline QString readDataLine(QTextStream& stream) {
while (1) {
if (stream.atEnd()) return QString();
QString ret = stream.readLine();
if (!ret.isEmpty() && ret[0] != QChar('#')) return ret;
}
}
static inline int lutCoords(int r, int g, int b, int meshSize) {
return b * meshSize * meshSize * 3 + g * meshSize * 3 + r * 3;
}
};
QFile file(fp);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
return execWarning(QObject::tr("Failed to Open 3DLUT File."));
QTextStream stream(&file);
QString line;
//---- read the 3DLUT files
// The first line shoud start from "3DMESH" keyword (case sensitive)
line = locals::readDataLine(stream);
if (line != "3DMESH") {
file.close();
return execWarning(
QObject::tr("Failed to Load 3DLUT File.\nIt should start with "
"\"3DMESH\" keyword."));
}
// The second line is "Mesh [Input bit depth] [Output bit depth]"
// "Mesh" is a keyword (case sensitive)
line = locals::readDataLine(stream);
QStringList list = line.split(" ");
if (list.size() != 3 || list.at(0) != "Mesh") {
file.close();
return execWarning(
QObject::tr("Failed to Load 3DLUT File.\nThe second line should be "
"\"Mesh [Input bit depth] [Output bit depth]\""));
}
int inputBitDepth = list.at(1).toInt();
int outputBitDepth = list.at(2).toInt();
m_lut.meshSize = (int)pow(2.0, inputBitDepth) + 1;
float maxValue = pow(2.0, outputBitDepth) - 1.0f;
// The third line is corrections of values at each LUT grid
line = locals::readDataLine(stream);
list = line.split(" ", QString::SkipEmptyParts);
if (list.size() != m_lut.meshSize) {
file.close();
return execWarning(QObject::tr("Failed to Load 3DLUT File."));
}
m_lut.data = new float[m_lut.meshSize * m_lut.meshSize * m_lut.meshSize * 3];
for (int k = 0; k < m_lut.meshSize; ++k) // r
{
for (int j = 0; j < m_lut.meshSize; ++j) // g
{
for (int i = 0; i < m_lut.meshSize; ++i) // b
{
line = locals::readDataLine(stream);
list = line.split(" ", QString::SkipEmptyParts);
if (list.size() != 3) {
file.close();
delete[] m_lut.data;
return execWarning(QObject::tr("Failed to Load 3DLUT File."));
}
float* lut = m_lut.data + locals::lutCoords(k, j, i, m_lut.meshSize);
*lut = (float)(list.at(0).toInt()) / maxValue;
lut++;
*lut = (float)(list.at(1).toInt()) / maxValue;
lut++;
*lut = (float)(list.at(2).toInt()) / maxValue;
}
}
}
file.close();
return true;
}
//-----------------------------------------------------------------------------
void LutCalibrator::assignLutTexture() {
assert(glGetError() == GL_NO_ERROR);
m_lut.tex = new QOpenGLTexture(QOpenGLTexture::Target3D);
m_lut.tex->setSize(m_lut.meshSize, m_lut.meshSize, m_lut.meshSize);
m_lut.tex->setFormat(QOpenGLTexture::RGB32F);
m_lut.tex->setLayers(1);
m_lut.tex->setMipLevels(1);
m_lut.tex->allocateStorage();
m_lut.tex->setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
m_lut.tex->setWrapMode(QOpenGLTexture::ClampToEdge);
m_lut.tex->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, m_lut.data);
assert(glGetError() == GL_NO_ERROR);
}
//-----------------------------------------------------------------------------
// input : 0-1
void LutCalibrator::convert(float& r, float& g, float& b) {
struct locals {
static inline float lerp(float val1, float val2, float ratio) {
return val1 * (1.0f - ratio) + val2 * ratio;
}
static inline int getCoord(int r, int g, int b, int meshSize) {
return b * meshSize * meshSize * 3 + g * meshSize * 3 + r * 3;
}
};
if (!m_isValid) return;
float ratio[3]; // RGB軸
int index[3][2]; // rgb インデックス
float rawVal[3] = {r, g, b};
float vertex_color[2][2][2][3]; //補間用の1ボクセルの頂点色
for (int c = 0; c < 3; c++) {
float val = rawVal[c] * (float)(m_lut.meshSize - 1);
index[c][0] = (int)val;
// boundary condition: if rawVal == 1 the value will not be interporated
index[c][1] = (rawVal[c] >= 1.0f) ? index[c][0] : index[c][0] + 1;
ratio[c] = val - (float)index[c][0];
}
for (int rr = 0; rr < 2; rr++)
for (int gg = 0; gg < 2; gg++)
for (int bb = 0; bb < 2; bb++) {
float* val = &m_lut.data[locals::getCoord(
index[0][rr], index[1][gg], index[2][bb], m_lut.meshSize)];
for (int chan = 0; chan < 3; chan++, val++)
vertex_color[rr][gg][bb][chan] = *val;
}
float result[3];
for (int chan = 0; chan < 3; chan++) {
result[chan] = locals::lerp(
locals::lerp(locals::lerp(vertex_color[0][0][0][chan],
vertex_color[0][0][1][chan], ratio[2]),
locals::lerp(vertex_color[0][1][0][chan],
vertex_color[0][1][1][chan], ratio[2]),
ratio[1]),
locals::lerp(locals::lerp(vertex_color[1][0][0][chan],
vertex_color[1][0][1][chan], ratio[2]),
locals::lerp(vertex_color[1][1][0][chan],
vertex_color[1][1][1][chan], ratio[2]),
ratio[1]),
ratio[0]);
}
r = result[0];
g = result[1];
b = result[2];
}
//-----------------------------------------------------------------------------
void LutCalibrator::convert(QColor& col) {
if (!m_isValid) return;
float r = col.redF();
float g = col.greenF();
float b = col.blueF();
convert(r, g, b);
// 0.5 offset is necessary for converting to 255 grading
col = QColor((int)(r * 255.0 + 0.5), (int)(g * 255.0 + 0.5),
(int)(b * 255.0 + 0.5), col.alpha());
}
//-----------------------------------------------------------------------------
void LutCalibrator::convert(TPixel32& col) {
if (!m_isValid) return;
float r = (float)col.r / 255.0;
float g = (float)col.g / 255.0;
float b = (float)col.b / 255.0;
convert(r, g, b);
col = TPixel32((int)(r * 255.0 + 0.5), (int)(g * 255.0 + 0.5),
(int)(b * 255.0 + 0.5), col.m);
}

View file

@ -11,6 +11,7 @@
#include "toonzqt/stylenameeditor.h" #include "toonzqt/stylenameeditor.h"
#include "toonzqt/viewcommandids.h" #include "toonzqt/viewcommandids.h"
#include "palettedata.h" #include "palettedata.h"
#include "toonzqt/lutcalibrator.h"
// TnzLib includes // TnzLib includes
#include "toonz/palettecmd.h" #include "toonz/palettecmd.h"
@ -681,10 +682,8 @@ void PageViewer::paintEvent(QPaintEvent *e) {
// and TBlackCleanupStyle(2002) // and TBlackCleanupStyle(2002)
if (style->getTagId() == 3 || style->getTagId() == 2001 || if (style->getTagId() == 3 || style->getTagId() == 2001 ||
style->getTagId() == 2002) { style->getTagId() == 2002) {
// iwsw commented out temporaly if (LutCalibrator::instance()->isValid())
// if LutCalibrator::instance()->convert(styleColor);
// (Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled())
// Ghibli3DLutConverter::instance()->convert(styleColor);
p.fillRect(chipRect, QBrush(styleColor)); p.fillRect(chipRect, QBrush(styleColor));

View file

@ -6,6 +6,7 @@
#include "toonzqt/gutil.h" #include "toonzqt/gutil.h"
#include "toonzqt/filefield.h" #include "toonzqt/filefield.h"
#include "historytypes.h" #include "historytypes.h"
#include "toonzqt/lutcalibrator.h"
// TnzLib includes // TnzLib includes
#include "toonz/txshlevel.h" #include "toonz/txshlevel.h"
@ -53,6 +54,7 @@
#include <QStyleOptionSlider> #include <QStyleOptionSlider>
#include <QToolTip> #include <QToolTip>
#include <QSplitter> #include <QSplitter>
#include <QOpenGLFramebufferObject>
using namespace StyleEditorGUI; using namespace StyleEditorGUI;
@ -557,44 +559,24 @@ HexagonalColorWheel::HexagonalColorWheel(QWidget *parent)
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setFocusPolicy(Qt::NoFocus); setFocusPolicy(Qt::NoFocus);
m_currentWheel = none; m_currentWheel = none;
// iwsw commented out temporarily
/*
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
Ghibli3DLutUtil::m_isValid)
{
m_ghibli3DLutUtil = new Ghibli3DLutUtil();
m_ghibli3DLutUtil->setInvert();
}
*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
HexagonalColorWheel::~HexagonalColorWheel() { HexagonalColorWheel::~HexagonalColorWheel() {
// iwsw commented out temporarily if (m_fbo) delete m_fbo;
/*
if(m_ghibli3DLutUtil)
{
m_ghibli3DLutUtil->onEnd();
delete m_ghibli3DLutUtil;
}
*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void HexagonalColorWheel::initializeGL() { void HexagonalColorWheel::initializeGL() {
initializeOpenGLFunctions(); initializeOpenGLFunctions();
// to be computed once through the software
LutCalibrator::instance()->initialize();
QColor const color = getBGColor(); QColor const color = getBGColor();
glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF()); glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
// iwsw commented out temporarily
/*
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
m_ghibli3DLutUtil)
m_ghibli3DLutUtil->onInit();
*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -646,12 +628,11 @@ void HexagonalColorWheel::resizeGL(int w, int h) {
glLoadIdentity(); glLoadIdentity();
glOrtho(0.0, (GLdouble)w, (GLdouble)h, 0.0, 1.0, -1.0); glOrtho(0.0, (GLdouble)w, (GLdouble)h, 0.0, 1.0, -1.0);
// iwsw commented out temporarily // remake fbo with new size
/* if (LutCalibrator::instance()->isValid()) {
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() && if (m_fbo) delete m_fbo;
m_ghibli3DLutUtil) m_fbo = new QOpenGLFramebufferObject(w, h);
m_ghibli3DLutUtil->onResize(w,h); }
*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -664,12 +645,7 @@ void HexagonalColorWheel::paintGL() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid()) m_fbo->bind();
/*
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
m_ghibli3DLutUtil)
m_ghibli3DLutUtil->startDraw();
*/
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
@ -716,12 +692,8 @@ void HexagonalColorWheel::paintGL() {
glPopMatrix(); glPopMatrix();
// iwsw commented out temporarily if (LutCalibrator::instance()->isValid())
/* LutCalibrator::instance()->onEndDraw(m_fbo);
if(Preferences::instance()->isDoColorCorrectionByUsing3DLutEnabled() &&
m_ghibli3DLutUtil)
m_ghibli3DLutUtil->endDraw();
*/
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------