From c15e8c3a5ba9629aaaf54cf19afeb26cd2a3e286 Mon Sep 17 00:00:00 2001 From: ArgonarioD Date: Sat, 18 Mar 2023 03:51:47 +0800 Subject: [PATCH 1/2] =?UTF-8?q?[style]=20=E9=87=8D=E6=96=B0=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E4=BA=86LayerStyle=E5=9C=A8Layer=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=BD=A2=E5=BC=8F=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BA=86LayerStyleContainer=E7=B1=BB=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BA=86=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BA=86=E9=83=A8=E5=88=86bad=20smells?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LayerStyleDialog.cpp | 48 ++-- .../EditorWidgetComponent/LayerStyleDialog.h | 10 +- .../StrokeStyleWidget.cpp | 30 +- .../src/Editor/GraphicElement.cpp | 13 +- .../src/Editor/GraphicElement.h | 13 +- .../src/Editor/LayerStyle.cpp | 264 ++++++++++++------ .../src/Editor/LayerStyle.h | 72 +++-- .../src/Editor/LayerWrapper.cpp | 12 +- .../src/Editor/LayerWrapper.h | 3 +- .../src/Editor/RightBar/InfoDisplayWidget.cpp | 75 ++--- 10 files changed, 330 insertions(+), 210 deletions(-) diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp index 478301a..33a3568 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.cpp @@ -3,20 +3,18 @@ #include #include #include -#include -#include LayerStyleDialog::LayerStyleDialog( - QWidget* parent, - std::shared_ptr existedStyle, - std::vector>* excludeStyles -) : QDialog(parent) + LayerStyleContainer& styles, + std::shared_ptr existedStyle, + QWidget* parent +) : QDialog(parent), styles(&styles) { - QVBoxLayout* dialogLayout = new QVBoxLayout(this); + auto* dialogLayout = new QVBoxLayout(this); dialogLayout->setAlignment(Qt::AlignmentFlag::AlignHCenter); this->setLayout(dialogLayout); - if (existedStyle) + if (existedStyle) { this->modifyingStyle = existedStyle->clone(); @@ -28,28 +26,14 @@ LayerStyleDialog::LayerStyleDialog( } else { - std::unordered_set excludeStyleNames; - for(auto &style : *excludeStyles) - { - excludeStyleNames.insert(style->getStyleName()); - } + QStringList unusedStyleNames = styles.unusedStyleNames(); + auto* typeSelector = new QComboBox(this); - QComboBox* typeSelector = new QComboBox(this); - - for (auto& pair : LayerStyle::types) + if (!unusedStyleNames.empty()) { - if (!excludeStyleNames.contains(pair.first)) - { - typeSelector->addItem(pair.first); - if (!this->modifyingStyle) - { - this->modifyingStyle = std::move(pair.second()); - } - } - } + typeSelector->addItems(unusedStyleNames); + this->modifyingStyle = std::move(styles.makeUnusedStyle(unusedStyleNames[0])); - if (typeSelector->count() > 0) - { dialogLayout->addWidget(typeSelector); this->styleContainer = new QGridLayout(this); dialogLayout->addLayout(styleContainer); @@ -57,11 +41,11 @@ LayerStyleDialog::LayerStyleDialog( this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget->setParent(this); this->styleContainer->addWidget(styleWidget); - connect(typeSelector, QOverload::of(&QComboBox::currentIndexChanged), + connect(typeSelector, &QComboBox::currentTextChanged, this, &LayerStyleDialog::onStyleTypeSelectorChanged); } } - QDialogButtonBox* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); + auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); connect(buttonBox, &QDialogButtonBox::accepted, this, &LayerStyleDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &LayerStyleDialog::reject); dialogLayout->addWidget(buttonBox); @@ -73,7 +57,7 @@ void LayerStyleDialog::accept() QDialog::accept(); } -void LayerStyleDialog::onStyleTypeSelectorChanged(int index) +void LayerStyleDialog::onStyleTypeSelectorChanged(const QString& current) { if (this->styleWidget) { @@ -81,8 +65,10 @@ void LayerStyleDialog::onStyleTypeSelectorChanged(int index) this->styleWidget->setParent(nullptr); delete styleWidget; } - this->modifyingStyle = std::move(LayerStyle::types[index].second()); + this->modifyingStyle = std::move(styles->makeUnusedStyle(current)); this->styleWidget = this->modifyingStyle->getInputWidget(); this->styleWidget->setParent(this); this->styleContainer->addWidget(styleWidget, 0, 0, 1, 1); + this->styleWidget->adjustSize(); + this->adjustSize(); } diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h index 8246cca..b703e80 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerStyleDialog.h @@ -9,15 +9,17 @@ class LayerStyleDialog : public QDialog private: QWidget* styleWidget; QGridLayout* styleContainer; + LayerStyleContainer* styles; std::unique_ptr modifyingStyle; public: LayerStyleDialog( - QWidget* parent = nullptr, - std::shared_ptr existedStyle = nullptr, - std::vector>* excludeStyles = nullptr); + LayerStyleContainer& styles, + std::shared_ptr existedStyle = nullptr, + QWidget* parent = nullptr + ); std::shared_ptr layerStyle; private slots: - void onStyleTypeSelectorChanged(int index); + void onStyleTypeSelectorChanged(const QString& current); void accept() override; }; diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp index 7e014db..670e185 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/StrokeStyleWidget.cpp @@ -2,8 +2,8 @@ #include "ColorPicker.h" #include #include +#include -#define radialStroke(stroke) std::dynamic_pointer_cast(stroke->materialStroke) constexpr int COLUMN_WIDTH = 0; constexpr int COLUMN_COLOR = 1; constexpr int COLUMN_METALLIC = 2; @@ -15,12 +15,12 @@ StrokeStyleWidget::StrokeStyleWidget( QWidget* parent ) : QWidget(parent), stroke(stroke) { - QVBoxLayout* viewLayout = new QVBoxLayout(this); + auto* viewLayout = new QVBoxLayout(this); this->setLayout(viewLayout); initStrokeSettings(); - QWidget* strokeProperties = new QWidget(this); - QHBoxLayout* strokePropertiesLayout = new QHBoxLayout(strokeProperties); + auto* strokeProperties = new QWidget(this); + auto* strokePropertiesLayout = new QHBoxLayout(strokeProperties); strokePropertiesLayout->setMargin(0); strokeProperties->setLayout(strokePropertiesLayout); @@ -38,7 +38,7 @@ StrokeStyleWidget::StrokeStyleWidget( void StrokeStyleWidget::initStrokeSettings() { this->enableGradual = new QtMaterialCheckBox(this); - enableGradual->setText(QStringLiteral("启用渐变")); + enableGradual->setText(QStringLiteral("渐变")); enableGradual->setChecked(radialStroke(stroke)->gradual); connect(enableGradual, &QtMaterialCheckBox::toggled, [this](bool checked) { radialStroke(this->stroke)->gradual = checked; @@ -72,7 +72,7 @@ void StrokeStyleWidget::initStrokeSettings() this->widthField = new QtMaterialTextField(this); widthField->setLabel(QStringLiteral("本侧描边宽度")); widthField->setText(QString::number(stroke->halfWidth)); - QDoubleValidator* widthValidator = new QDoubleValidator(0.1, std::numeric_limits::max(), 3, widthField); + auto* widthValidator = new QDoubleValidator(0.1, std::numeric_limits::max(), 3, widthField); widthValidator->setNotation(QDoubleValidator::StandardNotation); widthField->setValidator(widthValidator); connect(widthField, &QtMaterialTextField::textChanged, [this](const QString& changed) { @@ -106,8 +106,12 @@ void StrokeStyleWidget::initTable(std::shared_ptrsetBackgroundColor(QtMaterialStyle::instance().themeColor("primary1")); strokeTable->setSpan(row, 0, 1, 5); strokeTable->setCellWidget(row, 0, addButton); + strokeTable->setMinimumHeight(strokeTable->rowHeight(row) * 5); + strokeTable->setMinimumWidth(strokeTable->sizeHint().width()); + addButton->setFixedHeight(strokeTable->rowHeight(row)); connect(addButton, &QtMaterialRaisedButton::clicked, [this]() { handlingRowInsert = true; auto materialMap = &(radialStroke(this->stroke)->materialMap); @@ -129,37 +133,37 @@ void StrokeStyleWidget::initTable(std::shared_ptrstrokeTable->update(); handlingRowInsert = false; }); - connect(strokeTable, &QTableWidget::currentItemChanged, this, &StrokeStyleWidget::onCurrentItemChanged); connect(strokeTable, &QTableWidget::cellChanged, this, &StrokeStyleWidget::onCellChanged); } void StrokeStyleWidget::setTableRow(int row, float width, Renderer::Material& material) { - QTableWidgetItem* widthItem = new QTableWidgetItem; + auto* widthItem = new QTableWidgetItem; widthItem->setData(Qt::EditRole, width); strokeTable->setItem(row, COLUMN_WIDTH, widthItem); QColor* colorPtr = &(material.color); - QTableWidgetItem* colorItem = new QTableWidgetItem; + auto* colorItem = new QTableWidgetItem; colorItem->setData(Qt::DisplayRole, *colorPtr); strokeTable->setItem(row, COLUMN_COLOR, colorItem); - ColorPicker* colorPicker = new ColorPicker(*colorPtr, strokeTable); + auto* colorPicker = new ColorPicker(*colorPtr, strokeTable); strokeTable->setCellWidget(row, COLUMN_COLOR, colorPicker); connect(colorPicker, &ColorPicker::colorChanged, [this, colorPtr](QColor color) { *colorPtr = color; this->strokeTable->update(); }); - QTableWidgetItem* metallicItem = new QTableWidgetItem; + auto* metallicItem = new QTableWidgetItem; metallicItem->setData(Qt::EditRole, material.metallicF()); strokeTable->setItem(row, COLUMN_METALLIC, metallicItem); - QTableWidgetItem* roughnessItem = new QTableWidgetItem; + auto* roughnessItem = new QTableWidgetItem; roughnessItem->setData(Qt::EditRole, material.roughnessF()); strokeTable->setItem(row, COLUMN_ROUGHNESS, roughnessItem); - QtMaterialRaisedButton* removeButton = new QtMaterialRaisedButton("-", strokeTable); + auto* removeButton = new QtMaterialRaisedButton("-", strokeTable); + removeButton->setBackgroundColor(QtMaterialStyle::instance().themeColor("primary1")); removeButton->setFixedSize(20, 20); strokeTable->setCellWidget(row, COLUMN_OPERATIONS, removeButton); connect(removeButton, &QtMaterialRaisedButton::clicked, [this, row]() { diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index f515210..8896f9e 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -48,11 +48,11 @@ PixelPath GroupElement::getPaintObject() const } //TODO: apply styles and send back -PixelPath SimpleElement::getPaintObject(std::vector>* styles) const { +PixelPath SimpleElement::getPaintObject(const LayerStyleContainer& styles) const { return this->getPaintObject(); } -PixelPath GroupElement::getPaintObject(std::vector>* styles) const { +PixelPath GroupElement::getPaintObject(const LayerStyleContainer& styles) const { return getPaintObject(); } @@ -92,7 +92,7 @@ QJsonObject GroupElement::toJson() const return result; } -void SimpleElement::paint(QPainter* painter, QTransform transform, const vector>& styles) +void SimpleElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) { painter->save(); painter->setTransform(transform); @@ -102,9 +102,6 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< } else { - std::shared_ptr style; - style = styles[0]; - double angle = atan(transform.m12() / transform.m11()); double maxScale; if (fabs(cos(angle))>1e-5) @@ -112,7 +109,7 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< else maxScale = std::max(fabs(transform.m12() / sin(angle)), fabs(transform.m21() / sin(angle))); double pixelRatio = maxScale * QGuiApplication::primaryScreen()->devicePixelRatio(); - auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, *style, pixelRatio); + auto [img, mov] = Renderer::ElementRenderer::instance()->drawElement(painterPath, styles, pixelRatio); transform.translate(mov.x(), mov.y()); painter->setTransform(transform.scale(1 / pixelRatio, 1 / pixelRatio)); painter->drawImage(0, 0, img); @@ -120,7 +117,7 @@ void SimpleElement::paint(QPainter* painter, QTransform transform, const vector< painter->restore(); } -void GroupElement::paint(QPainter* painter, QTransform transform, const vector>& styles) +void GroupElement::paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) { sourceLayer->paint(painter, transform); } diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index d417e7e..12e2cfa 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -2,7 +2,6 @@ #include "LayerWrapper.h" #include "LayerStyle.h" -#include #include #include #include @@ -27,8 +26,8 @@ public: // TODO: 改为BitmapPath virtual QJsonObject toJson() const = 0; virtual PixelPath getPaintObject() const = 0; - virtual PixelPath getPaintObject(std::vector>*) const = 0; - virtual void paint(QPainter* painter, QTransform transform, const std::vector> &styles) = 0; + virtual PixelPath getPaintObject(const LayerStyleContainer& styles) const = 0; + virtual void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) = 0; virtual QPixmap getPreview(QSize size) = 0; }; @@ -47,8 +46,8 @@ public: SimpleElement(QString filePath); ~SimpleElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector>*) const override; - void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; + PixelPath getPaintObject(const LayerStyleContainer& styles) const override; + void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override; QPixmap getPreview(QSize size) override; }; @@ -63,9 +62,9 @@ public: GroupElement(FolderLayerWrapper* mSourceLayer); ~GroupElement() = default; PixelPath getPaintObject() const override; - PixelPath getPaintObject(std::vector>*) const override; + PixelPath getPaintObject(const LayerStyleContainer& styles) const override; void setSourceLayer(FolderLayerWrapper* sourceLayer); - void paint(QPainter* painter, QTransform transform, const std::vector> &styles) override; + void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override; QPixmap getPreview(QSize size) override; }; diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp index 215ec15..5be1b72 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.cpp @@ -9,31 +9,29 @@ #include #include #include - -const std::vector()>>> LayerStyle::types = { - { - QStringLiteral("描边"), - []() { return std::make_unique(); } - }, - { - QStringLiteral("填充"), - []() { return std::make_unique(); } - } -}; +#define _USE_JOIN_VIEW_INPUT_RANGE +#include +#include std::vector StrokeElementLayerStyle::toBaseStyles() const { std::vector baseStyles; if (enableEachSideIndependent) { - baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), - strokePair.first)); - baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), - strokePair.second)); + if (!radialStroke(strokePair.first)->materialMap.empty()) + { + baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), + strokePair.first)); + } + if (!radialStroke(strokePair.second)->materialMap.empty()) + { + baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), + strokePair.second)); + } } - else + else if (!radialStroke(strokePair.first)->materialMap.empty()) { - auto material = std::shared_ptr(std::move(strokePair.first->clone())); + const auto material = std::shared_ptr(std::move(strokePair.first->clone())); std::dynamic_pointer_cast(material)->strokeType = Renderer::StrokeType::kBothSides; baseStyles.push_back(Renderer::BaseStyle(std::make_shared(), material)); @@ -41,50 +39,23 @@ std::vector StrokeElementLayerStyle::toBaseStyles() const return baseStyles; } -QString StrokeElementLayerStyle::getStyleName() const -{ - return QStringLiteral("描边"); -} - QWidget* StrokeElementLayerStyle::getInputWidget() { - if (this->strokePair.first == nullptr) - { - auto materialMap = std::map(); - this->strokePair.first = std::shared_ptr(new Renderer::MaterialStyleStroke( - 15, - Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, - std::shared_ptr(new Renderer::StrokeRadialGradient( - materialMap, false - )) - )); - } - if (this->strokePair.second == nullptr) - { - auto materialMap = std::map(); - this->strokePair.second = std::shared_ptr(new Renderer::MaterialStyleStroke( - 15, - Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, - std::shared_ptr(new Renderer::StrokeRadialGradient( - materialMap, false - )) - )); - } - QWidget* w = new QWidget; - QListView* materialList = new QListView; + auto* w = new QWidget; + auto* materialList = new QListView; - QVBoxLayout* layout = new QVBoxLayout(w); + auto* layout = new QVBoxLayout(w); layout->setMargin(0); - StrokeStyleWidget* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w); + auto* leftStrokeView = new StrokeStyleWidget(this->strokePair.first, w); layout->addWidget(leftStrokeView); - - QtMaterialCheckBox* checkEachSideIndependent = new QtMaterialCheckBox(w); - checkEachSideIndependent->setText(QStringLiteral("启用两侧独立描边")); + + auto* checkEachSideIndependent = new QtMaterialCheckBox(w); + checkEachSideIndependent->setText(QStringLiteral("右侧独立描边")); checkEachSideIndependent->setChecked(enableEachSideIndependent); layout->addWidget(checkEachSideIndependent); - StrokeStyleWidget* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w); + auto* rightStrokeView = new StrokeStyleWidget(this->strokePair.second, w); layout->addWidget(rightStrokeView); rightStrokeView->setDisabled(!this->enableEachSideIndependent); @@ -97,39 +68,180 @@ QWidget* StrokeElementLayerStyle::getInputWidget() QWidget* StrokeElementLayerStyle::getListDisplayWidget() const { - QWidget* w = new QWidget; - QLabel* name = new QLabel(w); + auto* w = new QWidget; + auto* name = new QLabel(w); name->setText(QStringLiteral("描边")); - QHBoxLayout* layout = new QHBoxLayout(w); + auto* layout = new QHBoxLayout(w); layout->setMargin(0); layout->addWidget(name); return w; } +void LayerStyleContainer::computeNewHash() +{ + hash = 0; + for (auto& f : styles + | std::views::values + | std::views::transform(&LayerStyle::toBaseStyles) + | std::views::join + | std::views::transform(&Renderer::BaseStyle::material) + | std::views::transform(&MaterialStyle::encoded) + | std::views::join) + { + const unsigned int u = *reinterpret_cast(&f); + hash ^= u + 0x9e3779b9 + (hash << 6) + (hash >> 2); + } +} + +LayerStyleContainer LayerStyleContainer::fromJson(const QJsonArray& jsonArray) +{ + LayerStyleContainer container; + for (const auto& style : jsonArray) + { + container.useStyle(LayerStyle::fromJson(style.toObject())); + } + return container; +} + +LayerStyleContainer::LayerStyleContainer() : hash(0) +{ + unusedStyles = { { + StrokeElementLayerStyle::displayName(), + [] { return std::make_unique(); } + }, + { + FillElementLayerStyle::displayName(), + [] { return std::make_unique(); } + } }; +} + +std::vector LayerStyleContainer::toBaseStyles() const +{ + std::vector result; + for (const auto& style : styles | std::views::values) + { + auto baseStyles = style->toBaseStyles(); + result.insert(result.end(), + std::make_move_iterator(baseStyles.begin()), + std::make_move_iterator(baseStyles.end())); + } + return result; +} + +QJsonArray LayerStyleContainer::toJson() const +{ + QJsonArray json; + for (const auto& style : styles | std::views::values) + { + json.append(style->toJson()); + } + return json; +} + +QStringList LayerStyleContainer::unusedStyleNames() const +{ + QStringList result; + for(const auto& name : unusedStyles | std::views::keys) + { + result << name; + } + return result; +} + +std::unique_ptr LayerStyleContainer::makeUnusedStyle(const QString& styleName) const +{ + return unusedStyles.at(styleName)(); +} + +bool LayerStyleContainer::empty() const +{ + return styles.empty(); +} + +bool LayerStyleContainer::full() const +{ + return unusedStyles.empty(); +} + +std::map>::iterator LayerStyleContainer::begin() +{ + return styles.begin(); +} + +std::map>::iterator LayerStyleContainer::end() +{ + return styles.end(); +} + +bool LayerStyleContainer::useStyle(const std::shared_ptr& style) +{ + auto styleNode = unusedStyles.extract(style->getDisplayName()); + if (styleNode.empty()) + { + return false; + } + styles[styleNode.key()] = style; + usedStyles.insert(std::move(styleNode)); + return true; +} + +bool LayerStyleContainer::dropStyle(const QString& styleName) +{ + auto styleNode = usedStyles.extract(styleName); + if (styleNode.empty()) + { + return false; + } + styles.erase(styleName); + unusedStyles.insert(std::move(styleNode)); + return true; +} + +inline size_t LayerStyleContainer::getHash() const +{ + return hash; +} + +StrokeElementLayerStyle::StrokeElementLayerStyle() +{ + const auto materialMap = std::map(); + this->strokePair.first = std::make_shared( + 7, + Renderer::StrokeType::kLeftSide, Renderer::StrokeEndType::kFlat, + std::make_shared(materialMap, false) + ); + + this->strokePair.second = std::make_shared( + 7, + Renderer::StrokeType::kRightSide, Renderer::StrokeEndType::kFlat, + std::make_shared(materialMap, false) + ); + +} + StrokeElementLayerStyle::StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right) { this->strokePair.first = left; - this->strokePair.second = right ? right : std::dynamic_pointer_cast( - std::shared_ptr(std::move(left->clone())) + this->strokePair.second = right ? right : std::static_pointer_cast( + std::shared_ptr(std::move(left->clone())) ); } StrokeElementLayerStyle::StrokeElementLayerStyle(const StrokeElementLayerStyle& other) { - strokePair.first = std::dynamic_pointer_cast( - std::shared_ptr(std::move(other.strokePair.first->clone())) + strokePair.first = std::static_pointer_cast( + std::shared_ptr(std::move(other.strokePair.first->clone())) ); - strokePair.second = std::dynamic_pointer_cast( - std::shared_ptr(std::move(other.strokePair.second->clone())) + strokePair.second = std::static_pointer_cast( + std::shared_ptr(std::move(other.strokePair.second->clone())) ); enableEachSideIndependent = other.enableEachSideIndependent; } QJsonObject StrokeElementLayerStyle::toJson() const { - // todo: 修改打开逻辑 QJsonObject json; - json["type"] = getTypeName(); + json["type"] = typeName(); json["enableEachSideIndependent"] = enableEachSideIndependent; json["left"] = EncodeUtil::toBase64(strokePair.first->encoded()); json["right"] = EncodeUtil::toBase64(strokePair.second->encoded()); @@ -143,28 +255,24 @@ std::unique_ptr StrokeElementLayerStyle::clone() const std::vector FillElementLayerStyle::toBaseStyles() const { + // TODO: implement return std::vector(); } -QString FillElementLayerStyle::getStyleName() const -{ - return QStringLiteral("填充"); -} - QWidget* FillElementLayerStyle::getInputWidget() { // TODO - QLineEdit* name = new QLineEdit; + auto* name = new QLineEdit; name->setText(QStringLiteral("填充")); return name; } QWidget* FillElementLayerStyle::getListDisplayWidget() const { - QWidget* w = new QWidget; - QLabel* name = new QLabel(w); + auto* w = new QWidget; + auto* name = new QLabel(w); name->setText(QStringLiteral("填充")); - QHBoxLayout* layout = new QHBoxLayout(w); + auto* layout = new QHBoxLayout(w); layout->setMargin(0); layout->addWidget(name); return w; @@ -192,20 +300,20 @@ std::unique_ptr FillElementLayerStyle::clone() const std::unique_ptr LayerStyle::fromJson(const QJsonObject& json) { QString type = json["type"].toString(); - if (type == StrokeElementLayerStyle::getTypeName()) + if (type == StrokeElementLayerStyle::typeName()) { auto ptr = std::make_unique( - std::dynamic_pointer_cast( - std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString())))) + std::static_pointer_cast( + std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["left"].toString())))) ), - std::dynamic_pointer_cast( - std::shared_ptr(std::move(Renderer::MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString())))) + std::static_pointer_cast( + std::shared_ptr(std::move(MaterialStyle::decoded(EncodeUtil::fromBase64(json["right"].toString())))) ) ); ptr->enableEachSideIndependent = json["enableEachSideIndependent"].toBool(); return ptr; } - else if (type == FillElementLayerStyle::getTypeName()) + else if (type == FillElementLayerStyle::typeName()) { return std::make_unique(); } diff --git a/ArchitectureColoredPainting/src/Editor/LayerStyle.h b/ArchitectureColoredPainting/src/Editor/LayerStyle.h index 636201d..a310b6e 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerStyle.h +++ b/ArchitectureColoredPainting/src/Editor/LayerStyle.h @@ -1,11 +1,11 @@ #pragma once -#include #include #include -#include -#include +#include +#include #include #include +#include #include "../Renderer/Painting/ElementStyle.h" #include "../Renderer/Painting/MaterialStyleStroke.h" #include "../Renderer/Painting/MaterialStyleFill.h" @@ -13,64 +13,90 @@ using Renderer::MaterialStyle; using Renderer::MaterialStyleStroke; -#define STYLE_TYPENAME(name) static QString getTypeName() { return name; } +#define STYLE_NAME(display_name, type_name) \ + static QString displayName() { return QStringLiteral(display_name); } \ + QString getDisplayName() const override { return QStringLiteral(display_name); } \ + static QString typeName() { return type_name; } +#define radialStroke(stroke) std::static_pointer_cast(stroke->materialStroke) -/** - * 在进行Style的添加时,首先创建空对象,然后直接调用getInputWidget()方法 - * 在进行Style的修改时,直接调用getInputWidget()方法 - * - * 对于LayerStyle的实现类,应该同时实现ElementStyle,并将相同种类的(如描边或填充)的style整合成一个类, - * 对于相同的类,一个图层应该只拥有一个 - */ class LayerStyle : public Renderer::ElementStyle { public: - const static std::vector()>>> types; static std::unique_ptr fromJson(const QJsonObject& json); - virtual QString getStyleName() const = 0; + virtual QString getDisplayName() const = 0; virtual QWidget* getInputWidget() = 0; virtual QWidget* getListDisplayWidget() const = 0; - virtual ~LayerStyle() {}; + virtual ~LayerStyle() = default; virtual QJsonObject toJson() const = 0; virtual std::unique_ptr clone() const = 0; }; +class LayerStyleContainer : public Renderer::ElementStyle +{ + using DisplayNameWithSupplier = std::map()>>; +private: + DisplayNameWithSupplier unusedStyles; + DisplayNameWithSupplier usedStyles; + std::map> styles; + size_t hash; +public: + static LayerStyleContainer fromJson(const QJsonArray& jsonArray); + + LayerStyleContainer(); + std::vector toBaseStyles() const override; + QJsonArray toJson() const; + + bool empty() const; + bool full() const; + std::map>::iterator begin(); + std::map>::iterator end(); + + QStringList unusedStyleNames() const; + std::unique_ptr makeUnusedStyle(const QString& styleName) const; + bool useStyle(const std::shared_ptr& style); + bool dropStyle(const QString& styleName); + size_t getHash() const; + + /** + * 需要在每次更改后手动调用 + */ + void computeNewHash(); +}; + class StrokeElementLayerStyle : public LayerStyle { using PMaterialStyleStroke = std::shared_ptr; -private: - std::pair strokePair; public: - STYLE_TYPENAME("stroke") + STYLE_NAME("描边","stroke") - StrokeElementLayerStyle() = default; + StrokeElementLayerStyle(); StrokeElementLayerStyle(PMaterialStyleStroke left, PMaterialStyleStroke right = nullptr); StrokeElementLayerStyle(const StrokeElementLayerStyle& other); - ~StrokeElementLayerStyle() = default; + ~StrokeElementLayerStyle() override = default; std::vector toBaseStyles() const override; - QString getStyleName() const override; QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; QJsonObject toJson() const override; std::unique_ptr clone() const override; + std::pair strokePair; bool enableEachSideIndependent = false; }; class FillElementLayerStyle : public LayerStyle { public: - STYLE_TYPENAME("fill") + STYLE_NAME("填充","fill") + std::vector toBaseStyles() const override; - QString getStyleName() const override; QWidget* getInputWidget() override; QWidget* getListDisplayWidget() const override; FillElementLayerStyle() = default; FillElementLayerStyle(const FillElementLayerStyle& other); - ~FillElementLayerStyle() = default; + ~FillElementLayerStyle() override = default; std::vector> materialStyles; QJsonObject toJson() const override; std::unique_ptr clone() const override; diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index febc24a..9281248 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -80,10 +80,7 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana int elementIndex = json.value("element").toInt(); wrappedElement = elementManager->getElementById(elementIndex); QJsonArray stylesArray = json.value("styles").toArray(); - for (const auto& style : stylesArray) - { - styles.push_back(LayerStyle::fromJson(style.toObject())); - } + styles = LayerStyleContainer::fromJson(stylesArray); } void LayerWrapper::SimpleProperty::apply(PixelPath&cache) @@ -135,7 +132,7 @@ void LeafLayerWrapper::refresh(LayerWrapper* layer) cache.clear(); if (wrappedElement != nullptr) { - cache.addPath(wrappedElement->getPaintObject(&(this->styles))); + cache.addPath(wrappedElement->getPaintObject(this->styles)); } LayerWrapper::refresh(); } @@ -245,10 +242,7 @@ QJsonObject LeafLayerWrapper::toJson() const QJsonObject json = LayerWrapper::toJson(); json.insert("element", wrappedElement->index); json.insert("is-folder", false); - QJsonArray stylesJson; - for (auto& style : styles) - stylesJson.push_back(style->toJson()); - json.insert("styles", stylesJson); + json.insert("styles", styles.toJson()); return json; } diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index 9a76c3b..dd87c4f 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -98,8 +98,7 @@ class LeafLayerWrapper : public LayerWrapper { public: GraphicElement *wrappedElement; - //const vector styles; - vector> styles; + LayerStyleContainer styles; public: ~LeafLayerWrapper() = default; diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp index d41d374..6e84bd7 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -81,39 +80,40 @@ void InfoDisplayWidget::generateLayerForm() layout->addRow("scale-X:", scaleX); layout->addRow("scale-Y:", scaleY); layout->setRowWrapPolicy(QFormLayout::DontWrapRows); - - LeafLayerWrapper* leafP = dynamic_cast(this->displayLayer); - if (leafP) { - QListWidget* styleList = new QListWidget(this); - QListWidgetItem* header = new QListWidgetItem; - QWidget* headerWidget = new QWidget(styleList); - QHBoxLayout* headerLayout = new QHBoxLayout; + if (auto* leafP = dynamic_cast(this->displayLayer); leafP) { + auto* styleList = new QListWidget(this); - QLabel* headerLabel = new QLabel(headerWidget); + auto* header = new QListWidgetItem; + auto* headerWidget = new QWidget(styleList); + auto* headerLayout = new QHBoxLayout; + + auto* headerLabel = new QLabel(headerWidget); headerLabel->setText("鏍峰紡鍒楄〃"); headerLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); //QtMaterialRaisedButton* addStyleButton = new QtMaterialRaisedButton("+", headerWidget); - QPushButton* addStyleButton = new QPushButton("+", headerWidget); + auto* addStyleButton = new QPushButton("+", headerWidget); addStyleButton->setFixedSize(QSize(20, 20)); - if (leafP->styles.size() >= LayerStyle::types.size()) + if (leafP->styles.full()) { addStyleButton->setDisabled(true); } else { - connect(addStyleButton, &QPushButton::clicked, [&, leafP]() { - LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, nullptr, &(leafP->styles)); - dialog->exec(); - if (dialog->layerStyle) - { - leafP->styles.push_back(dialog->layerStyle); - emit requireRefreshPreview(); - emit requireSelfRefresh(); - emit requireRefreshElementWidget(); - } - dialog->deleteLater(); + connect(addStyleButton, &QPushButton::clicked, [&, leafP] { + auto* dialog = new LayerStyleDialog(leafP->styles); + dialog->exec(); + if (dialog->layerStyle) + { + leafP->styles.useStyle(dialog->layerStyle); + leafP->styles.computeNewHash(); + + emit requireRefreshPreview(); + emit requireSelfRefresh(); + emit requireRefreshElementWidget(); + } + dialog->deleteLater(); }); } @@ -179,32 +179,35 @@ void InfoDisplayWidget::generateLayerForm() { leafP->styles.push_back(std::shared_ptr(new StrokeElementLayerStyle())); }*/ - std::vector>* styles = &(leafP->styles); - for (auto styleIterator = styles->begin(); styleIterator != styles->end(); styleIterator++) + auto* styles = &leafP->styles; + for (auto styleIterator = styles->begin(); styleIterator != styles->end(); ++styleIterator) { - QListWidgetItem* item = new QListWidgetItem; - QWidget* w = new QWidget; + auto* item = new QListWidgetItem; + auto* w = new QWidget(this); item->setSizeHint(QSize(50, 40)); - QHBoxLayout* layout = new QHBoxLayout; + auto* layout = new QHBoxLayout(w); layout->setAlignment(Qt::AlignmentFlag::AlignRight); //QtMaterialFlatButton* detailButton = new QtMaterialFlatButton(w); //QtMaterialFlatButton* removeButton = new QtMaterialFlatButton(w); - QPushButton* detailButton = new QPushButton(w); - QPushButton* removeButton = new QPushButton(w); + auto* detailButton = new QPushButton(w); + auto* removeButton = new QPushButton(w); detailButton->setText("..."); detailButton->setFixedSize(QSize(20, 20)); removeButton->setText("脳"); removeButton->setFixedSize(QSize(20, 20)); connect(detailButton, &QPushButton::clicked, this, - [this, styleIterator]() + [this, styles, styleIterator] { - LayerStyleDialog* dialog = new LayerStyleDialog(nullptr, *styleIterator); + auto* dialog = + new LayerStyleDialog(*styles, styleIterator->second); dialog->exec(); if (dialog->layerStyle) { - (*styleIterator) = dialog->layerStyle; + styleIterator->second = dialog->layerStyle; + styles->computeNewHash(); + emit requireRefreshPreview(); emit requireSelfRefresh(); emit requireRefreshElementWidget(); @@ -213,15 +216,17 @@ void InfoDisplayWidget::generateLayerForm() }); connect(removeButton, &QPushButton::clicked, this, - [this, styleIterator, styles]() + [this, styleIterator, styles] { - styles->erase(styleIterator); + styles->dropStyle(styleIterator->first); + styles->computeNewHash(); + emit requireRefreshPreview(); emit requireSelfRefresh(); emit requireRefreshElementWidget(); }); - QWidget* styleDisplayWidget = (*styleIterator)->getListDisplayWidget(); + QWidget* styleDisplayWidget = styleIterator->second->getListDisplayWidget(); styleDisplayWidget->setParent(w); styleDisplayWidget->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); From 31f2c1be8f11e728050cef1b3fe7011787f48320 Mon Sep 17 00:00:00 2001 From: wuyize Date: Sat, 18 Mar 2023 12:17:04 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=89=93=E5=BC=80=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E6=97=B6=E5=8D=B8=E8=BD=BD=E7=8E=B0=E6=9C=89=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ArchitectureColoredPainting/RendererWidget.ui | 18 +++++++- .../src/Renderer/Mesh.h | 2 +- .../src/Renderer/Model.cpp | 43 ++++++++++++------- .../src/Renderer/Model.h | 5 ++- .../src/Renderer/RendererWidget.h | 1 + .../src/Renderer/VirtualTextureManager.cpp | 24 +++++++++-- .../src/Renderer/VirtualTextureManager.h | 5 ++- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/ArchitectureColoredPainting/RendererWidget.ui b/ArchitectureColoredPainting/RendererWidget.ui index e116c32..e0d5a12 100644 --- a/ArchitectureColoredPainting/RendererWidget.ui +++ b/ArchitectureColoredPainting/RendererWidget.ui @@ -84,10 +84,26 @@ - + QLayout::SetDefaultConstraint + + + + + 0 + 0 + + + + + 0 + 16777215 + + + + diff --git a/ArchitectureColoredPainting/src/Renderer/Mesh.h b/ArchitectureColoredPainting/src/Renderer/Mesh.h index ec452fd..35348bc 100644 --- a/ArchitectureColoredPainting/src/Renderer/Mesh.h +++ b/ArchitectureColoredPainting/src/Renderer/Mesh.h @@ -18,7 +18,7 @@ namespace Renderer glm::vec3 Position; glm::vec3 Normal; glm::vec2 TexCoords; - Vertex(const aiVector3D& position, const aiVector3D& Normal, const aiVector3D& TexCoords); + Vertex(const aiVector3D& position, const aiVector3D& normal, const aiVector3D& texCoords); }; struct Texture diff --git a/ArchitectureColoredPainting/src/Renderer/Model.cpp b/ArchitectureColoredPainting/src/Renderer/Model.cpp index e96d36a..bcbfbb5 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -32,14 +32,12 @@ Model::Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, } void Model::draw() { - //shaderProgram->bind(); for (auto& mesh : meshes) { mesh->draw(); } } void Model::drawShadow() { - //shaderProgram->bind(); for (auto& mesh : meshes) { mesh->drawShadow(); } @@ -55,7 +53,7 @@ void Renderer::Model::loadModel(QString path) const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { - qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl; + qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString(); return; } qDebug() << modelFile.absoluteFilePath() << "Loaded Successfully"; @@ -63,9 +61,11 @@ void Renderer::Model::loadModel(QString path) qDebug() << "NumMaterials: " << scene->mNumMaterials; qDebug() << "NumTextures: " << scene->mNumTextures; + unloadModel(); + + if (QFile paintingConfigFile(directory.filePath(name + ".txt")); paintingConfigFile.open(QFile::ReadOnly | QIODevice::Text)) { - paintingMap.clear(); QTextStream stream(&paintingConfigFile); while (!stream.atEnd()) { @@ -81,6 +81,30 @@ void Renderer::Model::loadModel(QString path) { qWarning() << "Painting Config Not Found!"; } + + + aiMatrix4x4 transform; + aiMatrix4x4::Scaling(aiVector3D(1 / 0.008), transform); + processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation); + AABB.clear(); + AABB.emplace_back(minX, minY, minZ); + AABB.emplace_back(minX, minY, maxZ); + AABB.emplace_back(minX, maxY, minZ); + AABB.emplace_back(minX, maxY, maxZ); + AABB.emplace_back(maxX, minY, minZ); + AABB.emplace_back(maxX, minY, maxZ); + AABB.emplace_back(maxX, maxY, minZ); + AABB.emplace_back(maxX, maxY, maxZ); +} + +void Renderer::Model::unloadModel() +{ + paintingMap.clear(); + for(auto& i: paintingLoaded) + vtManager->deleteVirtualTexture(i.second); + paintingLoaded.clear(); + texturesLoaded.clear(); + meshes.clear(); minX = std::numeric_limits::max(); maxX = std::numeric_limits::min(); @@ -88,17 +112,6 @@ void Renderer::Model::loadModel(QString path) maxY = std::numeric_limits::min(); minZ = std::numeric_limits::max(); maxZ = std::numeric_limits::min(); - aiMatrix4x4 transform; - aiMatrix4x4::Scaling(aiVector3D(1 / 0.008), transform); - processNode(scene->mRootNode, scene, transform * scene->mRootNode->mTransformation); - AABB.push_back(QVector3D(minX, minY, minZ)); - AABB.push_back(QVector3D(minX, minY, maxZ)); - AABB.push_back(QVector3D(minX, maxY, minZ)); - AABB.push_back(QVector3D(minX, maxY, maxZ)); - AABB.push_back(QVector3D(maxX, minY, minZ)); - AABB.push_back(QVector3D(maxX, minY, maxZ)); - AABB.push_back(QVector3D(maxX, maxY, minZ)); - AABB.push_back(QVector3D(maxX, maxY, maxZ)); } void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4) diff --git a/ArchitectureColoredPainting/src/Renderer/Model.h b/ArchitectureColoredPainting/src/Renderer/Model.h index d9a6bea..d8112f9 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.h +++ b/ArchitectureColoredPainting/src/Renderer/Model.h @@ -15,6 +15,7 @@ namespace Renderer void draw(); void drawShadow(); void loadModel(QString path); + void unloadModel(); Model(QOpenGLContext* context, QOpenGLShaderProgram* shaderProgram, QOpenGLShaderProgram* paintingProgram, QOpenGLShaderProgram* shadowProgram, VirtualTextureManager* vtManager); private: QOpenGLContext* context = nullptr; @@ -25,8 +26,8 @@ namespace Renderer VirtualTextureManager* vtManager = nullptr; /** - * @param key BaseColor路径 - * @param value json路径, 纹理坐标 + * @brief key BaseColor路径 \n + * value json路径, 纹理坐标 */ std::unordered_map> paintingMap; std::unordered_map paintingLoaded; diff --git a/ArchitectureColoredPainting/src/Renderer/RendererWidget.h b/ArchitectureColoredPainting/src/Renderer/RendererWidget.h index 258a173..d5a3725 100644 --- a/ArchitectureColoredPainting/src/Renderer/RendererWidget.h +++ b/ArchitectureColoredPainting/src/Renderer/RendererWidget.h @@ -13,6 +13,7 @@ namespace Renderer ~RendererWidget(); public slots: void currentTabChanged(int index); + private: Ui::RendererWidgetClass ui; }; diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp index b926ad4..87888db 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.cpp @@ -76,7 +76,7 @@ Renderer::VirtualTextureManager::VirtualTextureManager(GladGLContext* glMain) pageIdBufferMutex.lock(); currentBuffer = 1 - currentBuffer; pageIdBufferMutex.unlock(); - + gl->BeginQuery(GL_TIME_ELAPSED, pageLoadTimeQuery); updatePages(pageIds); gl->EndQuery(GL_TIME_ELAPSED); @@ -152,8 +152,26 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai } } - paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); - return paintings.size(); + if (const auto it = std::find_if(paintings.begin(), paintings.end(), [](const PaintingHandle& i) { return i.baseColor == 0; }); + it != paintings.end()) + { + *it = { baseColor, metallicRoughness, painting.buffers }; + return it - paintings.begin() + 1; + } + else + { + paintings.emplace_back(baseColor, metallicRoughness, painting.buffers); + return paintings.size(); + } + +} + +void Renderer::VirtualTextureManager::deleteVirtualTexture(std::uint16_t id) +{ + auto& painting = getPaintingHandle(id); + glMain->DeleteTextures(2, (GLuint*)&painting); + painting.baseColor = 0; + painting.metallicRoughness = 0; } Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std::uint16_t id) diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 520800b..bd31cbe 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -24,11 +24,12 @@ namespace Renderer VirtualTextureManager(GladGLContext* glMain); /** - * @brief - * @param painting + * @brief 创建彩绘虚拟纹理 + * @param painting 彩绘 * @return 虚拟纹理id */ std::uint16_t createVirtualTexture(Painting painting); + void deleteVirtualTexture(std::uint16_t id); PaintingHandle& getPaintingHandle(std::uint16_t id); void tryUpdatePages(const std::vector& pageIds);