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/res/Shaders/painting.comp b/ArchitectureColoredPainting/res/Shaders/painting.comp index 7324942..6e166cf 100644 --- a/ArchitectureColoredPainting/res/Shaders/painting.comp +++ b/ArchitectureColoredPainting/res/Shaders/painting.comp @@ -20,22 +20,25 @@ layout(std430, binding = 1) buffer bvhBoundBuffer { vec4 bvhBound[]; }; -layout(std430, binding = 2) buffer elementOffsetBuffer +layout(std430, binding = 2) buffer elementTranformBuffer +{ + mat3x2 elementTranform[]; +}; +layout(std430, binding = 3) buffer elementOffsetBuffer { /** * @[0] elementBvhRoot * @[1] styleOffset * @[2] pointsOffset * @[3] linesOffset - */ - uint elementOffset[][5]; + uint elementOffset[][4]; }; -layout(std430, binding = 3) buffer elementIndexBuffer +layout(std430, binding = 4) buffer elementIndexBuffer { uint elementIndexs[]; // 线和面 }; -layout(std430, binding = 4) buffer elementDataBuffer +layout(std430, binding = 5) buffer elementDataBuffer { float elementData[]; // 点和Style }; @@ -1115,15 +1118,11 @@ bool fillElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsO } bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint pointsOffset, uint styleIndex, - float widthHeightRatio, inout vec4 elementColor, inout vec2 metallicRoughness) + inout vec4 elementColor, inout vec2 metallicRoughness) { bool hitElement = false; float strokeWidth = elementData[styleIndex]; - vec2 size = normalize(vec2(widthHeightRatio, 1)) + vec2(2 * strokeWidth); - vec2 ratio = widthHeightRatio < 1 ? vec2(widthHeightRatio, 1) : vec2(1, 1 / widthHeightRatio); - localUV *= ratio; - float minDistance = 1e38; uint lineCount = elementIndexs[contourIndex]; vec4 styleHead = unpackUnorm4x8(floatBitsToUint(elementData[styleIndex + 1])); @@ -1149,17 +1148,13 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point mat4x2 p = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); - p[0] *= ratio; - p[1] *= ratio; - p[2] *= ratio; - p[3] *= ratio; vec2 tangentBeginNext = vec2(0); if (contourIterator + 1 < contourIndex + 1 + lineCount) { uint lineIndex = elementIndexs[contourIterator + 1]; uint pLocation = linesOffset + 3 * lineIndex; - //vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]); + // vec2 percent = unpackUnorm2x16(elementIndexs[pLocation + 2]); uvec4 pxIndex = uvec4(pointsOffset) + 2 * uvec4(elementIndexs[pLocation] >> 16, elementIndexs[pLocation] & 0xFFFF, elementIndexs[pLocation + 1] >> 16, elementIndexs[pLocation + 1] & 0xFFFF); @@ -1168,10 +1163,6 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point mat4x2 pNext = mat4x2(elementData[pxIndex[0]], elementData[pyIndex[0]], elementData[pxIndex[1]], elementData[pyIndex[1]], elementData[pxIndex[2]], elementData[pyIndex[2]], elementData[pxIndex[3]], elementData[pyIndex[3]]); - pNext[0] *= ratio; - pNext[1] *= ratio; - pNext[2] *= ratio; - pNext[3] *= ratio; if (pNext[0] == pNext[1] && pNext[2] == pNext[3]) { @@ -1179,8 +1170,8 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point pNext[2] = pNext[1]; } - //if(pNext[0]!=p[3]) - // break; + // if(pNext[0]!=p[3]) + // break; if (pNext[0] != pNext[1]) tangentBeginNext = normalize(pNext[0] - pNext[1]); else @@ -1221,11 +1212,11 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point bool hit = d < minDistance; if (onBegin) - hit = - hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0], tangentBegin, p3Last - p2Last); + hit = hit && shouldFillBeginCap(localUV, contourIterator == contourIndex + 1, endType, p[0], + tangentBegin, p3Last - p2Last); if (onEnd) - hit = hit && - shouldFillEndCap(localUV, tangentBeginNext==vec2(0), endType, p[3], tangentEnd, tangentBeginNext); + hit = hit && shouldFillEndCap(localUV, tangentBeginNext == vec2(0), endType, p[3], tangentEnd, + tangentBeginNext); if (hit) { @@ -1272,7 +1263,7 @@ bool strokeElement(vec2 localUV, uint contourIndex, uint linesOffset, uint point return hitElement; } -bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, out vec2 metallicRoughness, +bool drawElement(uint elementIndex, vec2 localUV, out vec3 color, out vec2 metallicRoughness, inout vec3 debugBVH = vec3(0)) { bool hitElement = false; @@ -1284,7 +1275,7 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou uint styleIndex = currentOffset[1]; uint pointsOffset = currentOffset[2]; uint linesOffset = currentOffset[3]; - float widthHeightRatio = uintBitsToFloat(currentOffset[4]); + // float widthHeightRatio = uintBitsToFloat(currentOffset[4]); elementStack.top = 0; uint elementBvhIndex = 0; @@ -1317,7 +1308,7 @@ bool drawElement(uint elementIndex, vec2 localUV, vec2 scale, out vec3 color, ou else // 线 { hitElement = strokeElement(localUV, contourIndex, linesOffset, pointsOffset, styleIndex, - widthHeightRatio, elementColor, metallicRoughness); + elementColor, metallicRoughness); } elementBvhIndex = elementBvhLength; @@ -1357,7 +1348,7 @@ void main() vec3 debugBVH = vec3(0); // bool debugHit = false; - //vec4 color = vec4(0.76, 0.33, 0.15, -1); + // vec4 color = vec4(0.76, 0.33, 0.15, -1); vec4 color = vec4(backgroundColor, -1); vec2 metallicRoughness = vec2(0, 0.8); stack.top = 0; @@ -1371,49 +1362,39 @@ void main() visitTime++; vec4 bound = bvhBound[index]; uint leftChild = bvhChildren[index].x; - if (leftChild >= bvhLength) - { - uint zIndex = bvhChildren[index].y >> 18; - bvec2 flip = bvec2(bvhChildren[index].y & (1 << 16), bvhChildren[index].y & (1 << 17)); - float angle = (float(bvhChildren[index].y & ((1 << 16) - 1)) / 65535.0) * 2 * PI; - mat2 rotation = {{cos(angle), -sin(angle)}, {sin(angle), cos(angle)}}; - vec2 localUV = uv - (bound.xy + bound.zw) / 2; - localUV = rotation * localUV; - vec2 scale = (bound.zw - bound.xy) / 2; - localUV /= scale; - if (all(lessThan(vec2(-1), localUV)) && all(lessThan(localUV, vec2(1))) && zIndex > color.w) - { - // if (any(greaterThan(bound.xy+vec2(0.005), uv)) || any(greaterThan(uv, bound.zw-vec2(0.005)))) - if (any(greaterThan(vec2(-1) + vec2(0.005), localUV)) || - any(greaterThan(localUV, vec2(1) - vec2(0.005)))) - debugBVH.g += 0.3; - // uint elementIndex = leftChild - bvhLength; - // debugBVH.bg += 0.5 * (localUV + vec2(1)); - // debugBVH = vec3(0); - if (flip.x) - localUV.x = -localUV.x; - if (flip.y) - localUV.y = -localUV.y; + if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw))) + { + if (any(greaterThan(bound.xy + vec2(0.005), uv)) || any(greaterThan(uv, bound.zw - vec2(0.005)))) + debugBVH.g += 0.3; + + if (leftChild >= bvhLength) + { + uint transformIndex = leftChild - 0x80000000; + uint zIndex = bvhChildren[index].y >> 18; + uint elementIndex = bvhChildren[index].y - zIndex; + mat3x2 transform = elementTranform[transformIndex]; + vec2 localUV = + (mat3(vec3(transform[0], 0), vec3(transform[1], 0), vec3(transform[2], 1)) * vec3(uv, 1)).xy; + vec3 elementColor; vec2 elementMetallicRoughness; - if (drawElement(leftChild - 0x80000000, localUV, scale, elementColor, elementMetallicRoughness, + if (drawElement(elementIndex, localUV, elementColor, elementMetallicRoughness, debugBVH)) { color = vec4(elementColor, zIndex); metallicRoughness = elementMetallicRoughness; } - } + //if(elementIndex == 1 && transformIndex==1) + // color = vec4(1,1,0,1); - index = bvhLength; - } - else if (all(lessThan(bound.xy, uv)) && all(lessThan(uv, bound.zw))) - { - if (any(greaterThan(bound.xy + vec2(0.005), uv)) || any(greaterThan(uv, bound.zw - vec2(0.005)))) - debugBVH.g += 0.3; - // debugBVH.r += 0.02; - stack.push(index); - index = leftChild; + index = bvhLength; + } + else + { + stack.push(index); + index = leftChild; + } } else index = bvhLength; @@ -1428,7 +1409,7 @@ void main() imageStore(gBaseColor, pixelLocation, vec4(color.rgb, 1)); imageStore(gMetallicRoughness, pixelLocation, vec4(metallicRoughness, 0, 1)); - return; + //return; if (/*color.a!=-1&&*/ debugBVH == vec3(0)) { // imageStore(gBaseColor, pixelLocation, vec4(vec3(1, 1, 0),1)); diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.cpp b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.cpp index ed6743a..45d8dfe 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.cpp @@ -1,15 +1,46 @@ #include "LayerCreateWidget.h" #include -LayerCreateWidget::LayerCreateWidget(ElementManager* elementManager, QWidget* parent) : +LayerCreateWidget::LayerCreateWidget(ElementManager* elementManager, FolderLayerWrapper* folderLayer, QWidget* parent) : QDialog(parent) { + this->elementManager = elementManager; ui.setupUi(this); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(accept())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(ui.comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int))); elementPool = new ElementPoolWidget(ui.elementPool); - elementPool->setElementList(elementManager->elements); + elements = elementManager->elements; + elementsCheck(folderLayer); + elementPool->setElementList(elements); +} + +void LayerCreateWidget::elementsCheck(FolderLayerWrapper* parent) +{ + std::set upSet, downSet; + parent->collectUpReachable(upSet); + for (auto it = elements.begin(); it != elements.end();) + { + bool valid = true; + auto ele = dynamic_cast(*it); + if (ele != nullptr) + { + downSet.clear(); + ele->collectReachable(downSet); + for (auto& layer : downSet) + { + if (upSet.find(layer) != upSet.end()) + { + valid = false; + break; + } + } + } + if (valid) + ++it; + else + it = elements.erase(it); + } } LayerCreateWidget::~LayerCreateWidget() @@ -21,8 +52,20 @@ void LayerCreateWidget::accept() QJsonObject jsonObj; jsonObj.insert("name", ui.name->text()); if (ui.comboBox->currentIndex() == 0) { + auto currentEle = elements[elementPool->currentIndex]; + int index = -1; + for (int i = 0; i < elementManager->elements.size(); i++) + { + if (elementManager->elements[i] == currentEle) + { + index = i; + break; + } + } + if (index == -1) + return; jsonObj.insert("is-folder", false); - jsonObj.insert("element", elementPool->currentIndex); + jsonObj.insert("element", index); } else { jsonObj.insert("is-folder", true); diff --git a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.h b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.h index c9b7c89..38456b2 100644 --- a/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.h +++ b/ArchitectureColoredPainting/src/Editor/EditorWidgetComponent/LayerCreateWidget.h @@ -11,12 +11,15 @@ class LayerCreateWidget : Q_OBJECT private: + ElementManager* elementManager; + std::vector elements; Ui::LayerCreateWidget ui; ElementPoolWidget* elementPool; + void elementsCheck(FolderLayerWrapper*); public: - LayerCreateWidget(ElementManager* elementManager,QWidget* parent = nullptr); + LayerCreateWidget(ElementManager* elementManager, FolderLayerWrapper* folderLayer, QWidget* parent = nullptr); ~LayerCreateWidget(); void accept() override; diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp index 8896f9e..5c0acb0 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.cpp @@ -148,4 +148,12 @@ QPixmap GroupElement::getPreview(QSize size) rect.setBottomRight(rect.bottomRight() + QPoint(5, 5)); result = result.copy(rect); return result.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); +} + +void GroupElement::collectReachable(std::set& set) const +{ + if (sourceLayer != nullptr) + { + sourceLayer->collectDownReachable(set); + } } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/GraphicElement.h b/ArchitectureColoredPainting/src/Editor/GraphicElement.h index 12e2cfa..d0500b2 100644 --- a/ArchitectureColoredPainting/src/Editor/GraphicElement.h +++ b/ArchitectureColoredPainting/src/Editor/GraphicElement.h @@ -66,6 +66,7 @@ public: void setSourceLayer(FolderLayerWrapper* sourceLayer); void paint(QPainter* painter, QTransform transform, const LayerStyleContainer& styles) override; QPixmap getPreview(QSize size) override; + void collectReachable(std::set& set) const; }; //******************************** BitmapPath ********************************// diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp index 9281248..e30b068 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.cpp @@ -285,4 +285,36 @@ void LeafLayerWrapper::paint(QPainter* painter, QTransform transform, bool ignor { wrappedElement->paint(painter, transform, styles); } +} + +void LayerWrapper::collectUpReachable(std::set& reachable) +{ + auto cPos = this; + while (cPos != nullptr) + { + reachable.insert(cPos); + cPos = cPos->parent; + } +} + +void LayerWrapper::collectDownReachable(std::set& reachable) +{ + reachable.insert(this); +} + +void LeafLayerWrapper::collectDownReachable(std::set& reachable) +{ + LayerWrapper::collectDownReachable(reachable); + auto ele = dynamic_cast(wrappedElement); + if (ele != nullptr) + { + ele->collectReachable(reachable); + } +} + +void FolderLayerWrapper::collectDownReachable(std::set& reachable) +{ + LayerWrapper::collectDownReachable(reachable); + for (auto& child : children) + child->collectDownReachable(reachable); } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h index dd87c4f..92d82d1 100644 --- a/ArchitectureColoredPainting/src/Editor/LayerWrapper.h +++ b/ArchitectureColoredPainting/src/Editor/LayerWrapper.h @@ -68,7 +68,8 @@ class LayerWrapper virtual void delSelf(); virtual QJsonObject toJson() const; ~LayerWrapper() = default; - + virtual void collectUpReachable(std::set& reachable); + virtual void collectDownReachable(std::set& reachable); }; class FolderLayerWrapper : public LayerWrapper @@ -92,6 +93,7 @@ class FolderLayerWrapper : public LayerWrapper QJsonObject toJson() const override; int getReferencedBy()const; void paint(QPainter* painter, QTransform transform = QTransform(), bool ignoreSelected = false) override; + void collectDownReachable(std::set& reachable) override; }; class LeafLayerWrapper : public LayerWrapper @@ -107,6 +109,7 @@ class LeafLayerWrapper : public LayerWrapper LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent); QJsonObject toJson() const override; void paint(QPainter* painter, QTransform transform = QTransform(), bool ignoreSelected = false) override; + void collectDownReachable(std::set& reachable) override; }; Q_DECLARE_METATYPE(LayerWrapper *) diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp index 6e84bd7..ca1e2ca 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/InfoDisplayWidget.cpp @@ -60,13 +60,13 @@ void InfoDisplayWidget::generateLayerForm() emit requireRefreshElementWidget(); emit requireRefreshPreview(); }); - scaleX->setValidator(new QDoubleValidator(0.001, 1000, 4, this)); + scaleX->setValidator(new QDoubleValidator(-1000, 1000, 4, this)); connect(scaleX, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.scale = {content.toDouble(), this->displayLayer->property.scale.y()}; emit requireRefreshElementWidget(); emit requireRefreshPreview(); }); - scaleY->setValidator(new QDoubleValidator(0.001, 1000, 4, this)); + scaleY->setValidator(new QDoubleValidator(-1000, 1000, 4, this)); connect(scaleY, &QLineEdit::textChanged, [=](QString content) { this->displayLayer->property.scale = {this->displayLayer->property.scale.x(), content.toDouble()}; emit requireRefreshElementWidget(); diff --git a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp index a27da25..8b85c1a 100644 --- a/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp +++ b/ArchitectureColoredPainting/src/Editor/RightBar/LayerTreeWidget.cpp @@ -50,7 +50,7 @@ void LayerTreeWidget::popMenu(const QPoint &pos) if (layer != nullptr) { if (typeid(*layer) == typeid(FolderLayerWrapper)) { menu.addAction(QString::fromLocal8Bit("创建子节点"), this, [this, layer]() { - auto dialog = new LayerCreateWidget(elementManager, this); + auto dialog = new LayerCreateWidget(elementManager, dynamic_cast(layer), this); connect(dialog, &LayerCreateWidget::LayerInfoReturned, this, [this, layer](QJsonObject jsonObj) { auto folderLayer = dynamic_cast(layer); LayerWrapper* newLayer; @@ -76,15 +76,18 @@ void LayerTreeWidget::popMenu(const QPoint &pos) layer->getParent()->removeChild(layer); this->refresh(); emit requireRefreshPreview(); + emit requireRefreshElementWidget(); }); menu.addAction(QString::fromLocal8Bit("重命名"), this, &LayerTreeWidget::onRenameEvent); - menu.addAction(QString::fromLocal8Bit("删除(保留子节点)"), this, [this]() { - auto layer = this->selectedItem->data(0, Qt::UserRole).value(); - layer->delSelf(); - layer->getParent()->removeChild(layer); - this->refresh(); - emit requireRefreshPreview(); - }); + if(typeid(*layer) == typeid(FolderLayerWrapper)) + menu.addAction(QString::fromLocal8Bit("删除(保留子节点)"), this, [this]() { + auto layer = this->selectedItem->data(0, Qt::UserRole).value(); + layer->delSelf(); + layer->getParent()->removeChild(layer); + this->refresh(); + emit requireRefreshPreview(); + emit requireRefreshElementWidget(); + }); } if (typeid(*layer) == typeid(FolderLayerWrapper) && ((FolderLayerWrapper*)layer)->getReferencedBy() == -1) { menu.addAction(QString::fromLocal8Bit("创建组合元素"), this, [this]() { diff --git a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp index 8c4ec74..aea42d4 100644 --- a/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp +++ b/ArchitectureColoredPainting/src/Editor/util/PaintingUtil.cpp @@ -99,7 +99,10 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr qDebug() << painterPath; bound = painterPath.boundingRect(); qDebug() << bound; - elementTrans.center = glm::vec2( + + // TODO 改用矩阵 + + /* elementTrans.center = glm::vec2( (2 * bound.center().x() - screenSize.width()) / screenSize.width(), (2 * bound.center().y() - screenSize.height()) / screenSize.height() ); @@ -114,7 +117,7 @@ FolderLayerWrapper* PaintingUtil::handleLayerWrapper(LayerWrapper* nowLayer, QTr nowLayer->property.flipVertically ); qDebug() << elementTrans.scale.x << elementTrans.scale.y; - painting.addElement(element, elementTrans); + painting.addElement(element, elementTrans);*/ return nullptr; } 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..3510ed7 100644 --- a/ArchitectureColoredPainting/src/Renderer/Model.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Model.cpp @@ -16,6 +16,7 @@ #include #include #include "Painting/MaterialStyleStroke.h" +#include using namespace Renderer; using std::vector; @@ -32,14 +33,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 +54,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 +62,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()) { @@ -82,23 +83,36 @@ 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(); minY = std::numeric_limits::max(); 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) @@ -267,13 +281,13 @@ GLuint Renderer::Model::loadPainting(std::string path) if (path == "0.json") { - painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); - painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); - painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,-0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.45, 0.45), glm::vec2(0.5,0.5) / 2.f, 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[2], ElementTransform{ glm::vec2(0.50,-0.45), glm::vec2(0.6,0.7) / 2.f, 0, glm::bvec2(false), 0 }); } else if (path == "1.json") { - painting.backgroundColor = QColor(196, 81, 35); + //painting.backgroundColor = QColor(196, 81, 35); float widths[] = { 0.22, 0.22 * 0.25 / 0.15, 0.22 * 0.25 / 0.15 }; QPainterPath painterPaths[6]; for (int i = 0; i < 6; i++) @@ -309,14 +323,39 @@ GLuint Renderer::Model::loadPainting(std::string path) std::make_shared(widths[1], StrokeType::kRightSide), std::make_shared(widths[2], StrokeType::kLeftSide), }; - vector> element = { - std::make_shared(Element{ contours[0].first, style[0], contours[0].second}), - std::make_shared(Element{ contours[1].first, style[1], contours[1].second}), - std::make_shared(Element{ contours[2].first, style[2], contours[2].second}), + std::map materialMap = { + {0.09, Material{QColor(255,255,255),0,0.8}}, + {0.63, Material{QColor(165,176,207),0,0.8}}, + {1.00, Material{QColor(58,64,151),0,0.8}} }; - painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 }); - painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); - painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); + vector> element = { + std::make_shared(contours[0].first, std::make_shared( + widths[0], StrokeType::kLeftSide, StrokeEndType::kFlat, std::make_shared(materialMap, false))), + std::make_shared(contours[1].first, std::make_shared( + widths[1], StrokeType::kRightSide, StrokeEndType::kFlat, std::make_shared(materialMap, false))), + std::make_shared(contours[2].first, std::make_shared( + widths[2], StrokeType::kLeftSide, StrokeEndType::kFlat, std::make_shared(materialMap, false))), + }; + + QTransform trans = QTransform::fromScale(0.3, 0.3).inverted(); + glm::mat3x2 mat(trans.m11(), trans.m12(), trans.m21(), trans.m22(), trans.m31(), trans.m32()); + + trans = QTransform::fromTranslate(0.5, 0).scale(0.3, 0.3).inverted(); + glm::mat3x2 mat2(trans.m11(), trans.m12(), trans.m21(), trans.m22(), trans.m31(), trans.m32()); + //mat = glm::mat3x2(11, 22, 33, 44, 55, 66); + //mat2 = glm::mat3x2(1, 2, 3, 4, 5, 6); + + qDebug() << std::format("\n{} {} {}\n {} {} {}\n{} {} {}", + trans.m11(), trans.m21(), trans.m31(), + trans.m12(), trans.m22(), trans.m32(), + trans.m13(), trans.m23(), trans.m33()).c_str(); + + //painting.addElement(*element[0], ElementTransform{ glm::vec4(-1,-1,1,1), mat, 0}); + painting.addElement(*element[1], ElementTransform{ glm::vec4(-1,-1,0,1), mat, 0 }); + painting.addElement(*element[2], ElementTransform{ glm::vec4(0,-1,1,1), mat2, 0 }); + //painting.addElement(*element[0], ElementTransform{ glm::vec2(-0.45,0.45), glm::vec2(0.25), 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[1], ElementTransform{ glm::vec2(-0.535,0.33), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); + //painting.addElement(*element[2], ElementTransform{ glm::vec2(-0.535,0.23), glm::vec2(0.15), 0, glm::bvec2(false), 0 }); } else { @@ -324,7 +363,7 @@ GLuint Renderer::Model::loadPainting(std::string path) { float x = (float)rand() / RAND_MAX * 2 - 1; float y = (float)rand() / RAND_MAX * 2 - 1; - painting.addElement(*element[i % 3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.025), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); + //painting.addElement(*element[i % 3], ElementTransform{ glm::vec2(x,y), glm::vec2(0.025), (float)rand() / RAND_MAX * 360, glm::bvec2(false), 0 }); } } } 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/Painting/Element.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Element.cpp index 4f2dab0..ce01a11 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Element.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Element.cpp @@ -1,16 +1,16 @@ #include "Element.h" -void Renderer::ElementTransform::applyTransformStyle(const TransformStyle& t) -{ - center += t.translation; - scale *= t.scale; - rotation += t.rotation; - flip ^= t.flip; -} - -Renderer::ElementTransform Renderer::ElementTransform::appliedTransformStyle(const TransformStyle& t) const -{ - ElementTransform result = *this; - result.applyTransformStyle(t); - return result; -} +//void Renderer::ElementTransform::applyTransformStyle(const TransformStyle& t) +//{ +// /*center += t.translation; +// scale *= t.scale; +// rotation += t.rotation; +// flip ^= t.flip;*/ +//} +// +//Renderer::ElementTransform Renderer::ElementTransform::appliedTransformStyle(const TransformStyle& t) const +//{ +// ElementTransform result = *this; +// result.applyTransformStyle(t); +// return result; +//} diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h index 2e5c892..c7655ed 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Element.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Element.h @@ -5,7 +5,7 @@ #include "Line.h" #include "ElementStyle.h" -namespace Renderer +namespace Renderer { using Contour = std::vector>; @@ -18,14 +18,15 @@ namespace Renderer struct ElementTransform { - glm::vec2 center; - //glm::vec2 size; - glm::vec2 scale; /// 相对于画布 - float rotation; /// 角度制 - glm::bvec2 flip; + //glm::vec2 center; + //glm::vec2 scale; /// 相对于画布 + //float rotation; /// 角度制 + //glm::bvec2 flip; + glm::vec4 bound; /// 包围盒,不影响变换 + glm::mat3x2 transform; /// 逆变换 GLuint zIndex; - - void applyTransformStyle(const TransformStyle& t); - ElementTransform appliedTransformStyle(const TransformStyle& t) const; + + //void applyTransformStyle(const TransformStyle& t); + //ElementTransform appliedTransformStyle(const TransformStyle& t) const; }; } \ No newline at end of file diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp index afd7e04..2fd6d73 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.cpp @@ -53,87 +53,40 @@ void Renderer::Painting::addElement(ElementWithTransform elementWithTransform) elementPool.insert({ element, 0 }); } elements.push_back(elementWithTransform); + elementTransformPool.emplace(elementWithTransform.transform.transform, 0); } -void Renderer::Painting::addElement(const Element& element, const ElementTransform& transform) +void Renderer::Painting::addElement(const BaseElement& element, const ElementTransform& transform) { - auto contour = element.contour; - auto it = elementStyleMap.find(element.style); - if (it == elementStyleMap.end()) - { - std::vector baseStyles; - for (auto& style : element.style->toBaseStyles()) - { - auto [iter, _] = styleSet.insert(style.material); - baseStyles.push_back(BaseStyle{ style.transform, *iter }); - } - it = elementStyleMap.insert({ element.style, baseStyles }).first; - } - for (int i = 0; i < it->second.size(); i++) - { - auto& style = it->second[i]; - ElementTransform trans = transform; - trans.applyTransformStyle(*style.transform); - trans.zIndex = trans.zIndex * 10 + i; - - addElement(ElementWithTransform{ BaseElement{element.contour, style.material, element.ratio}, trans }); - } + addElement({ element , transform }); } -Renderer::BaseTransform::BaseTransform(ElementTransform t) - : bound(glm::vec4(t.center - t.scale, t.center + t.scale)) - , rotation(t.rotation) - , flip(t.flip) - , zIndex(t.zIndex) +BvhTreeData Painting::encodeElementLeaf(const ElementWithTransform& e) { -} - -void Renderer::Painting::addElement(std::shared_ptr element, QVector4D bound, float rotation, int zIndex) -{ - -} - -BvhTreeData Painting::encodeElementLeaf(ElementWithTransform e) -{ - glm::vec4 bound; - switch (e.element.style->type()) - { - case MaterialStyleType::kStroke: - { - auto w = std::static_pointer_cast(e.element.style)->getHalfWidth(); - glm::vec2 size = e.element.ratio < 1 ? glm::vec2(e.element.ratio, 1) : glm::vec2(1, 1 / e.element.ratio); - glm::vec2 scale = size * e.transform.scale; - bound = glm::vec4(e.transform.center - scale, e.transform.center + scale); - break; - } - case MaterialStyleType::kFill: - { - bound = glm::vec4(e.transform.center - e.transform.scale, e.transform.center + e.transform.scale); - break; - } - } - //bound = glm::vec4(e.transform.center - e.transform.scale, e.transform.center + e.transform.scale); - GLuint rightSon = (GLuint)(glm::mod(e.transform.rotation, 360.f) / 360.f * (1 << 16)) - + (e.transform.flip.x << 16) + (e.transform.flip.y << 17) + (e.transform.zIndex << 18); - return BvhTreeData(QVector4D(bound.x, bound.y, bound.z, bound.w), elementPool[e.element], rightSon); + QVector4D bound(e.transform.bound.x, e.transform.bound.y, e.transform.bound.z, e.transform.bound.w); + GLuint rightSon = elementPool[e.element] + (e.transform.zIndex << 18); + return { bound, elementTransformPool[e.transform.transform], rightSon }; } void Painting::generateBuffers(QOpenGLFunctions_4_5_Core* glFunc) { qDebug() << "Element Count: " << elementPool.size(); - qDebug() << "Coutour Count: " << contourPool.size(); + qDebug() << "Contour Count: " << contourPool.size(); qDebug() << " Style Count: " << stylePool.size(); bvhChildren.clear(); bvhBounds.clear(); + elementTransform.clear(); elementOffsets.clear(); elementIndex.clear(); elementData.clear(); for (int index = 0; auto & i : elementPool) - { i.second = index++; - } + for (int index = 0; auto & i : elementTransformPool) + i.second = index++; + + std::vector rootBvhTreeData; for (auto& i : elements) @@ -162,30 +115,35 @@ void Painting::generateBuffers(QOpenGLFunctions_4_5_Core* glFunc) elementData.insert(elementData.end(), encodedStyle.begin(), encodedStyle.end()); } + for (auto & i : elementTransformPool) + elementTransform.emplace_back(i.first); + for (auto& i : elementPool) { //qDebug() <<"element:" << i.second; //std::shared_ptr contourBuffer = i.first.style->type() == MaterialStyleType::kStroke ? contourPool[i.first.contour].second : contourPool[i.first.contour].first; auto& contourBuffer = contourPool[{i.first.contour, i.first.style->type()}]; - elementOffsets.push_back({ contourBuffer.bvhOffset, stylePool[i.first.style], contourBuffer.pointsOffset, contourBuffer.linesOffset, glm::floatBitsToUint(i.first.ratio) }); + elementOffsets.push_back({ contourBuffer.bvhOffset, stylePool[i.first.style], contourBuffer.pointsOffset, contourBuffer.linesOffset }); //std::cout << std::format("{} {} {} {}\n", contourBuffer->bvhOffset, stylePool[i.first->style], contourBuffer->pointsOffset, contourBuffer->linesOffset); } - glFunc->glCreateBuffers(6, buffers.data()); + glFunc->glCreateBuffers(7, buffers.data()); GLuint& bvhSSBO = buffers[0]; GLuint& bvhBoundSSBO = buffers[1]; - GLuint& elementOffsetSSBO = buffers[2]; - GLuint& elementIndexSSBO = buffers[3]; - GLuint& elementDataSSBO = buffers[4]; - GLuint& backgroundColorUBO = buffers[5]; + GLuint& elementTransformSSBO = buffers[2]; + GLuint& elementOffsetSSBO = buffers[3]; + GLuint& elementIndexSSBO = buffers[4]; + GLuint& elementDataSSBO = buffers[5]; + GLuint& backgroundColorUBO = buffers[6]; glFunc->glNamedBufferData(buffers[0], bvhChildren.size() * sizeof(bvhChildren[0]), bvhChildren.data(), GL_STATIC_READ); glFunc->glNamedBufferData(buffers[1], bvhBounds.size() * sizeof(bvhBounds[0]), bvhBounds.data(), GL_STATIC_READ); - glFunc->glNamedBufferData(buffers[2], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ); - glFunc->glNamedBufferData(buffers[3], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ); - glFunc->glNamedBufferData(buffers[4], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(buffers[2], elementTransform.size() * sizeof(elementTransform[0]), elementTransform.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(buffers[3], elementOffsets.size() * sizeof(elementOffsets[0]), elementOffsets.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(buffers[4], elementIndex.size() * sizeof(elementIndex[0]), elementIndex.data(), GL_STATIC_READ); + glFunc->glNamedBufferData(buffers[5], elementData.size() * sizeof(elementData[0]), elementData.data(), GL_STATIC_READ); glm::vec3 color(backgroundColor.redF(), backgroundColor.greenF(), backgroundColor.blueF()); - glFunc->glNamedBufferData(buffers[5], sizeof(glm::vec3), &color, GL_STATIC_READ); + glFunc->glNamedBufferData(buffers[6], sizeof(glm::vec3), &color, GL_STATIC_READ); } GLuint Renderer::Painting::getElementCount() @@ -223,3 +181,17 @@ bool Renderer::Painting::CompareMaterialStyle::operator()(const std::shared_ptr< else return left < right; } + +std::size_t Renderer::Painting::HashMat3x2::operator()(const glm::mat3x2& mat) const +{ + std::size_t result = 0; + constexpr long long P = 998244353; + long long base = 1; + for (int i = 0; i < 3; i++) + for (int j = 0; j < 2; j++) + { + result += base * mat[i][j]; + base *= P; + } + return result; +} diff --git a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h index 9194040..cf18500 100644 --- a/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h +++ b/ArchitectureColoredPainting/src/Renderer/Painting/Painting.h @@ -15,24 +15,13 @@ namespace Renderer { std::shared_ptr contour; std::shared_ptr style; - float ratio; /// 宽高比 bool operator<(const BaseElement& e) const; }; - struct BaseTransform - { - glm::vec4 bound; - float rotation; - glm::bvec2 flip; - GLuint zIndex; - BaseTransform(ElementTransform t); - }; - struct ElementWithTransform { BaseElement element; ElementTransform transform; - //BaseTransform transform; }; struct ContourBuffer @@ -52,7 +41,6 @@ namespace Renderer GLuint styleOffset; GLuint pointsOffset; GLuint linesOffset; - GLuint ratio; }; class Painting @@ -60,16 +48,16 @@ namespace Renderer public: std::vector bvhChildren; std::vector bvhBounds; + std::vector elementTransform; std::vector elementOffsets; std::vector elementIndex; std::vector elementData; int paintingId = 0; - std::array buffers; + std::array buffers; QColor backgroundColor; Painting(QColor backgroundColor = Qt::white); - void addElement(const Element& element, const ElementTransform& transform); - void addElement(std::shared_ptr element, QVector4D bound, float rotation, int zIndex); + void addElement(const BaseElement& element, const ElementTransform& transform); void generateBuffers(QOpenGLFunctions_4_5_Core* glFunc); GLuint getElementCount(); private: @@ -77,14 +65,15 @@ namespace Renderer std::unordered_map, MaterialStyleType>, ContourBuffer, ContourHash> contourPool; struct CompareMaterialStyle { bool operator()(const std::shared_ptr&, const std::shared_ptr&) const; }; std::set, CompareMaterialStyle> styleSet; - std::unordered_map, std::vector> elementStyleMap; std::unordered_map, GLuint> stylePool; + struct HashMat3x2 { std::size_t operator()(const glm::mat3x2&) const; }; + std::unordered_map elementTransformPool; std::map elementPool; std::vector elements; void addElement(ElementWithTransform element); void insertContourBuffer(ContourBuffer& buffer); - BvhTreeData encodeElementLeaf(ElementWithTransform e); + BvhTreeData encodeElementLeaf(const ElementWithTransform& e); }; } diff --git a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp index 3be860f..259cc20 100644 --- a/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp +++ b/ArchitectureColoredPainting/src/Renderer/Preview/ElementRenderer.cpp @@ -76,7 +76,7 @@ std::vector generateStyleBuffer(const std::vector& styles) styleBuffer.push_back(style.transform->scale.y); styleBuffer.push_back(style.transform->rotation); styleBuffer.push_back(glm::uintBitsToFloat(glm::packUnorm2x16(style.transform->flip))); - + auto encoded = style.material->encoded(); styleBuffer.insert(styleBuffer.end(), encoded.begin(), encoded.end()); //qDebug() << "style size" << styleBuffer.size(); @@ -88,13 +88,23 @@ QRectF calcBoundingRect(const QPainterPath& path, const std::vector& { QRectF bound = path.boundingRect(); - ElementTransform originTransform{ glm::vec2(bound.center().x(), bound.center().y()), glm::vec2(bound.width(), bound.height()), 0, glm::bvec2(false), 0 }; + //ElementTransform originTransform{ glm::vec2(bound.center().x(), bound.center().y()), glm::vec2(bound.width(), bound.height()), 0, glm::bvec2(false), 0 }; glm::vec2 leftTop(std::numeric_limits::max()), rightBottom(std::numeric_limits::min()); for (auto& baseStyle : styles) { - BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform)); + struct BaseTransform + { + glm::vec4 bound; + float rotation = 0; + glm::bvec2 flip = glm::bvec2(false); + GLuint zIndex = 0; + }; + //BaseTransform transform(originTransform.appliedTransformStyle(*baseStyle.transform)); + glm::vec2 center(bound.center().x(), bound.center().y()); + glm::vec2 scale(bound.width(), bound.height()); + BaseTransform transform{ glm::vec4(center - scale, center + scale) }; if (baseStyle.material->type() == MaterialStyleType::kStroke) { float halfWidth = std::static_pointer_cast(baseStyle.material)->getHalfWidth(); 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..55a2c01 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); @@ -124,9 +124,9 @@ std::uint16_t Renderer::VirtualTextureManager::createVirtualTexture(Painting pai glMain->TextureParameteri(metallicRoughness, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glMain->TextureStorage2D(metallicRoughness, levels, GL_RG8, GLsizei(textureSize), GLsizei(textureSize)); - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) glMain->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); - glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]); + glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[6]); for (auto level = levels - 1; level < levels; ++level) { @@ -152,8 +152,28 @@ 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); + glMain->DeleteBuffers(7, painting.buffers.data()); + painting.baseColor = 0; + painting.metallicRoughness = 0; + painting.buffers.fill(0); } Renderer::PaintingHandle& Renderer::VirtualTextureManager::getPaintingHandle(std::uint16_t id) @@ -189,9 +209,9 @@ void Renderer::VirtualTextureManager::pageCommitmentById(const glm::u16vec2& pag if (commit) { program.bind(); - for (int i = 0; i < 5; i++) + for (int i = 0; i < 6; i++) gl->BindBufferBase(GL_SHADER_STORAGE_BUFFER, i, painting.buffers[i]); - glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[5]); + glMain->BindBufferBase(GL_UNIFORM_BUFFER, 1, painting.buffers[6]); gl->Uniform2i(gl->GetUniformLocation(program.programId(), "pixelOffset"), static_cast(pageSize) * page.x, static_cast(pageSize) * page.y); gl->BindImageTexture(0, painting.baseColor, level, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8); gl->BindImageTexture(1, painting.metallicRoughness, level, GL_FALSE, 0, GL_READ_WRITE, GL_RG8); diff --git a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h index 520800b..e5bbd24 100644 --- a/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h +++ b/ArchitectureColoredPainting/src/Renderer/VirtualTextureManager.h @@ -15,7 +15,7 @@ namespace Renderer { GLuint baseColor; GLuint metallicRoughness; - std::array buffers; + std::array buffers; }; class VirtualTextureManager @@ -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);