From 8cf1f7108d503531cc74725cd9b2cb8dc781796e Mon Sep 17 00:00:00 2001 From: kaetemi Date: Fri, 19 Sep 2014 14:30:46 +0200 Subject: [PATCH] Implement panoply_preview tool --HG-- branch : qt5 --- .../3d/panoply_preview/panoply_preview.cpp | 150 +++++++++++++++--- .../3d/panoply_preview/panoply_preview.h | 23 ++- 2 files changed, 148 insertions(+), 25 deletions(-) diff --git a/code/nel/tools/3d/panoply_preview/panoply_preview.cpp b/code/nel/tools/3d/panoply_preview/panoply_preview.cpp index 0e3306470..811055348 100644 --- a/code/nel/tools/3d/panoply_preview/panoply_preview.cpp +++ b/code/nel/tools/3d/panoply_preview/panoply_preview.cpp @@ -29,6 +29,7 @@ #include #include #include +#include // NeL includes #include @@ -37,6 +38,7 @@ #include #include #include +#include // Project includes #include "main_window.h" @@ -72,7 +74,8 @@ public: m_ColorModifier.Lightness = Lightness; m_ColorModifier.Saturation = Saturation; m_ColorModifier.Luminosity = Luminosity; - m_ColorModifier.Saturation = Saturation; + m_ColorModifier.Contrast = Contrast; + Process = false; SettingsMutex.leave(); BitmapMutex.enter(); @@ -81,7 +84,7 @@ public: BitmapMutex.leave(); return; } - if (!m_BitmapsOk) + if (!BitmapsOk) { nldebug("Bitmaps not ready"); BitmapMutex.leave(); @@ -98,13 +101,12 @@ public: } } - CColorThread() : m_BitmapsOk(false), Hue(0), Lightness(0), Saturation(0), Luminosity(0), Contrast(0), Process(false), Running(true) { } + CColorThread() : PanoplyPreview(NULL), BitmapsOk(false), Hue(0), Lightness(0), Saturation(0), Luminosity(0), Contrast(0), Process(false), Running(true) { } virtual ~CColorThread() { } virtual void getName (std::string &result) const { result = "CColorThread"; } private: CColorModifier m_ColorModifier; - bool m_BitmapsOk; public: CPanoplyPreview *PanoplyPreview; @@ -112,6 +114,7 @@ public: NLMISC::CMutex BitmapMutex; NLMISC::CBitmap ColorBitmap; NLMISC::CBitmap MaskBitmap; + bool BitmapsOk; NLMISC::CBitmap DestBitmap; NLMISC::CMutex SettingsMutex; @@ -129,19 +132,15 @@ public: CPanoplyPreview::CPanoplyPreview(CMainWindow *parent) : QWidget(parent) { - m_DisplayerOutput = new QTextEdit(); - m_DisplayerOutput->setReadOnly(true); - m_DisplayerOutput->setFocusPolicy(Qt::NoFocus); - m_CommandInput = new QLineEdit(); + connect(this, SIGNAL(tSigBitmap()), this, SLOT(tSlotBitmap())); - QVBoxLayout *layout = new QVBoxLayout(); - layout->addWidget(m_DisplayerOutput); - layout->addWidget(m_CommandInput); - setLayout(layout); + createDockWindows(parent); - // connect(m_CommandInput, SIGNAL(returnPressed()), this, SLOT(returnPressed())); + m_Image = new QImage(512, 512, QImage::Format_RGB32); + m_Pixmap = new QPixmap(512, 512); - createDockWindows(parent); + setMinimumWidth(512); + setMinimumHeight(512); m_ColorThread = new CColorThread(); m_ColorThread->PanoplyPreview = this; @@ -151,34 +150,135 @@ CPanoplyPreview::CPanoplyPreview(CMainWindow *parent) : QWidget(parent) CPanoplyPreview::~CPanoplyPreview() { - m_ColorThread->BitmapMutex.enter(); m_ColorThread->SettingsMutex.enter(); + m_ColorThread->BitmapMutex.enter(); m_ColorThread->Running = false; - m_ColorThread->SettingsMutex.leave(); m_ColorThread->BitmapMutex.leave(); + m_ColorThread->SettingsMutex.leave(); m_Thread->wait(); delete m_Thread; delete m_ColorThread; } +void CPanoplyPreview::paintEvent(QPaintEvent* e) +{ + QPainter painter(this); + painter.drawPixmap(0, 0, *m_Pixmap); +} + void CPanoplyPreview::displayBitmap(const CBitmap &bitmap) // Called from thread! { - nldebug("display bitmap!"); + nldebug("received bitmap"); + + m_ColorThread->BitmapMutex.enter(); + m_ImageMutex.enter(); + + const char *buffer = (const char *)&bitmap.getPixels()[0]; + + if (bitmap.getWidth() != m_Image->width() || bitmap.getHeight() != m_Image->height()) + { + QImage *image = m_Image; + m_Image = new QImage(bitmap.getWidth(), bitmap.getHeight(), QImage::Format_RGB32); + delete image; + } + + for (uint32 y = 0; y < bitmap.getHeight(); ++y) + { + uint8 *dst = (uint8 *)m_Image->scanLine(y); + const uint8 *src = (const uint8 *)&buffer[y * bitmap.getWidth() * sizeof(uint32)]; + for (uint32 x = 0; x < bitmap.getWidth(); ++x) + { + uint32 xb = x * 4; + dst[xb + 0] = src[xb + 2]; + dst[xb + 1] = src[xb + 1]; + dst[xb + 2] = src[xb + 0]; + dst[xb + 3] = src[xb + 3]; + } + + //memcpy(m_Image->scanLine(y), &buffer[y * bitmap.getWidth() * sizeof(uint32)], sizeof(uint32) * bitmap.getWidth()); + } + + m_ImageMutex.leave(); + m_ColorThread->BitmapMutex.leave(); + + tSigBitmap(); } -void CPanoplyPreview::colorEdited(const QString &text) +void CPanoplyPreview::tSlotBitmap() { + nldebug("display bitmap"); + + m_ImageMutex.enter(); + + if (m_Image->width() != m_Pixmap->width() + || m_Image->height() != m_Pixmap->height()) + { + QPixmap *pixmap = m_Pixmap; + m_Pixmap = new QPixmap(m_Image->width(), m_Image->height()); + setMinimumWidth(m_Pixmap->width()); + setMinimumHeight(m_Pixmap->height()); + delete pixmap; + } + m_Pixmap->convertFromImage(*m_Image); + repaint(); + + m_ImageMutex.leave(); } +void CPanoplyPreview::colorEdited(const QString &text) +{ + m_ColorFile = text; +} + void CPanoplyPreview::maskEdited(const QString &text) { - + m_MaskFile = text; } -void CPanoplyPreview::goPushed() +void CPanoplyPreview::goPushed(bool) { - + nldebug("push bitmaps"); + m_ColorThread->SettingsMutex.enter(); + m_ColorThread->BitmapMutex.enter(); + m_ColorThread->BitmapsOk = false; + + try + { + { + NLMISC::CIFile is; + if (!is.open(m_ColorFile.toLocal8Bit().data())) + throw NLMISC::Exception("Cannot open file '%s'", m_ColorFile.toLocal8Bit().data()); + uint32 depth = m_ColorThread->ColorBitmap.load(is); + if (depth == 0 || m_ColorThread->ColorBitmap.getPixels().empty()) + throw NLMISC::Exception("Failed to load bitmap '%s'", m_ColorFile.toLocal8Bit().data()); + if (m_ColorThread->ColorBitmap.PixelFormat != NLMISC::CBitmap::RGBA) + m_ColorThread->ColorBitmap.convertToType(NLMISC::CBitmap::RGBA); + } + { + NLMISC::CIFile is; + if (!is.open(m_MaskFile.toLocal8Bit().data())) + throw NLMISC::Exception("Cannot open file '%s'", m_MaskFile.toLocal8Bit().data()); + uint32 depth = m_ColorThread->MaskBitmap.load(is); + if (depth == 0 || m_ColorThread->MaskBitmap.getPixels().empty()) + throw NLMISC::Exception("Failed to load bitmap '%s'", m_MaskFile.toLocal8Bit().data()); + if (m_ColorThread->MaskBitmap.PixelFormat != NLMISC::CBitmap::RGBA) + m_ColorThread->MaskBitmap.convertToType(NLMISC::CBitmap::RGBA); + } + { + m_ColorThread->DestBitmap = m_ColorThread->ColorBitmap; + m_ColorThread->BitmapsOk = true; + m_ColorThread->Process = true; + } + } + catch (const NLMISC::Exception &e) + { + nlwarning("Exception: '%s'", e.what()); + } + + m_ColorThread->BitmapMutex.leave(); + m_ColorThread->SettingsMutex.leave(); + nldebug("done pushing butmaps"); } void CPanoplyPreview::hueChanged(int value) @@ -288,19 +388,27 @@ void CPanoplyPreview::createDockWindows(CMainWindow *mainWindow) groupLayout->addWidget(colorLabel, 0, 0); QLineEdit *colorFile = new QLineEdit(groupBox); + colorFile->setText("W:\\database\\stuff\\fyros\\agents\\_textures\\actors\\fy_hof_armor00_arm01_c1.png"); groupLayout->addWidget(colorFile, 0, 1); + connect(colorFile, SIGNAL(textEdited(const QString &)), this, SLOT(colorEdited(const QString &))); + QLabel *maskLabel = new QLabel(groupBox); maskLabel->setText(tr("Mask: ")); groupLayout->addWidget(maskLabel, 1, 0); QLineEdit *maskFile = new QLineEdit(groupBox); + maskFile->setText("W:\\database\\stuff\\fyros\\agents\\_textures\\actors\\mask\\fy_hof_armor00_arm01_c1_skin.png"); groupLayout->addWidget(maskFile, 1, 1); + connect(maskFile, SIGNAL(textEdited(const QString &)), this, SLOT(maskEdited(const QString &))); + QPushButton *go = new QPushButton(groupBox); go->setText(tr("Go")); groupLayout->addWidget(go, 2, 0, 1, 2); + connect(go, SIGNAL(clicked(bool)), this, SLOT(goPushed(bool))); + groupBox->setLayout(groupLayout); vboxLayout->addWidget(groupBox); } diff --git a/code/nel/tools/3d/panoply_preview/panoply_preview.h b/code/nel/tools/3d/panoply_preview/panoply_preview.h index bddacf77c..9fbe2bad3 100644 --- a/code/nel/tools/3d/panoply_preview/panoply_preview.h +++ b/code/nel/tools/3d/panoply_preview/panoply_preview.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include // NeL includes #include @@ -57,10 +59,18 @@ public: void displayBitmap(const NLMISC::CBitmap &bitmap); // Called from thread! +protected: + virtual void paintEvent(QPaintEvent *e); + +signals: + void tSigBitmap(); + private slots: + void tSlotBitmap(); + void colorEdited(const QString &text); void maskEdited(const QString &text); - void goPushed(); + void goPushed(bool); void hueChanged(int value); void lightnessChanged(int value); @@ -72,12 +82,17 @@ private: void createDockWindows(CMainWindow *mainWindow); private: - QTextEdit *m_DisplayerOutput; - QLineEdit *m_CommandInput; - NLMISC::IThread *m_Thread; CColorThread *m_ColorThread; + QString m_ColorFile; + QString m_MaskFile; + + QImage *m_Image; + QPixmap *m_Pixmap; + + NLMISC::CMutex m_ImageMutex; + private: CPanoplyPreview(const CPanoplyPreview &); CPanoplyPreview &operator=(const CPanoplyPreview &);