Compare commits
13 Commits
7ff8fd90c0
...
e97e6d5281
Author | SHA1 | Date |
---|---|---|
ArgonarioD | e97e6d5281 | |
ArgonarioD | b429761d81 | |
karlis | 97097fcc3a | |
karlis | f2ceca724a | |
karlis | eab8d7aeec | |
karlis | dc7a793d3a | |
karlis | 684c28dafd | |
karlis | 72f0f78e64 | |
karlis | 3f1421a1bd | |
karlis | 4c9fe168a9 | |
karlis | de9d7143b6 | |
karlis | ed4c3c0064 | |
wuyize | 0d42af9200 |
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1124</width>
|
||||
<height>1010</height>
|
||||
<width>1473</width>
|
||||
<height>1103</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
|
@ -56,7 +56,20 @@
|
|||
<widget class="QWidget" name="LeftBar" native="true"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="PreviewWindow" name="Preview"/>
|
||||
<widget class="PreviewWindow" name="Preview">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>1080</width>
|
||||
<height>1080</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1080</width>
|
||||
<height>1080</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="RightBar" native="true">
|
||||
|
|
|
@ -1190,7 +1190,7 @@ void main()
|
|||
//imageStore(gBaseColor, pixelLocation, vec4(uv,1,1));
|
||||
//imageStore(gMetallicRoughness, pixelLocation, vec4(uv,1,1));
|
||||
//return;
|
||||
uv = vec2(1)-uv*2;
|
||||
uv = uv*2-vec2(1);
|
||||
//vec2 uv = imageLoad(gPaintingTexCoord, pixelLocation).rg;
|
||||
|
||||
vec3 debugBVH = vec3(0);
|
||||
|
|
|
@ -14,6 +14,8 @@ EditorWidgetItem::EditorWidgetItem(QString filePath,QWidget *parent) : QWidget(p
|
|||
elementInfoDisplayWidget = dynamic_cast<ElementPoolWidget *>(tabWidget->widget(1));
|
||||
qDebug() << layerInfoDisplayWidget;
|
||||
qDebug() << elementInfoDisplayWidget;
|
||||
connect(previewWindow, &PreviewWindow::layerInfoChanged, layerInfoDisplayWidget, &InfoDisplayWidget::triggerSelfRefresh);
|
||||
connect(treeWidget, &LayerTreeWidget::displayLayerChange, previewWindow, &PreviewWindow::currentLayerChanged);
|
||||
connect(treeWidget, &LayerTreeWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
||||
connect(layerInfoDisplayWidget, &InfoDisplayWidget::requireRefreshElementWidget, elementInfoDisplayWidget, &ElementPoolWidget::refresh);
|
||||
connect(treeWidget, &LayerTreeWidget::displayLayerChange, this, &EditorWidgetItem::onLayerChange);
|
||||
|
@ -57,7 +59,11 @@ EditorWidgetItem::~EditorWidgetItem()
|
|||
|
||||
void EditorWidgetItem::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
// 设置画刷的颜色为灰色,并填充整个窗口区域
|
||||
painter.setBrush(Qt::gray);
|
||||
painter.drawRect(this->rect());
|
||||
}
|
||||
|
||||
void EditorWidgetItem::onLayerChange(LayerWrapper *layer)
|
||||
|
|
|
@ -45,7 +45,6 @@ PixelPath GroupElement::getPaintObject() const
|
|||
//TODO: apply styles and send back
|
||||
PixelPath SimpleElement::getPaintObject(std::vector<std::shared_ptr<LayerStyle>>* styles) const {
|
||||
PixelPath result;
|
||||
//Renderer::ElementStyleStrokeDemo demo(2);
|
||||
std::shared_ptr<Renderer::ElementStyle> style;
|
||||
if ((*styles).empty())
|
||||
{
|
||||
|
@ -98,3 +97,41 @@ QJsonObject GraphicElement::toJson() const
|
|||
result.insert("name", name);
|
||||
return result;
|
||||
}
|
||||
|
||||
void SimpleElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles)
|
||||
{
|
||||
painter->save();
|
||||
painter->setTransform(transform);
|
||||
if (styles.empty())
|
||||
{
|
||||
painter->drawPath(painterPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
Renderer::ElementStyleStrokeDemo demo(2);
|
||||
std::shared_ptr<Renderer::ElementStyle> style;
|
||||
if (styles.empty())
|
||||
{
|
||||
style = std::make_shared<Renderer::ElementStyleStrokeDemo>(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
style = styles[0];
|
||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokePlain>(
|
||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
||||
)->material.color.name();*/
|
||||
/*qDebug() << std::dynamic_pointer_cast<Renderer::StrokeRadialGradient>(
|
||||
std::dynamic_pointer_cast<StrokeElementLayerStyle>(style)->materialStyles[0]->materialStroke
|
||||
)->materialMap[1.0].color;*/
|
||||
}
|
||||
auto [img, mov] = renderer->drawElement(painterPath, *style, 1.0);
|
||||
painter->drawImage(mov, img);
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void GroupElement::paint(QPainter* painter, QTransform transform, const vector<std::shared_ptr<LayerStyle>> &styles)
|
||||
{
|
||||
sourceLayer->paint(painter, transform);
|
||||
}
|
|
@ -28,6 +28,7 @@ public:
|
|||
virtual QJsonObject toJson() const;
|
||||
virtual PixelPath getPaintObject() const = 0;
|
||||
virtual PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const = 0;
|
||||
virtual void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) = 0;
|
||||
};
|
||||
|
||||
class SimpleElement : public GraphicElement
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
~SimpleElement() = default;
|
||||
PixelPath getPaintObject() const override;
|
||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
||||
};
|
||||
|
||||
class GroupElement : public GraphicElement
|
||||
|
@ -58,6 +60,7 @@ public:
|
|||
PixelPath getPaintObject() const override;
|
||||
PixelPath getPaintObject(std::vector<std::shared_ptr<LayerStyle>>*) const override;
|
||||
void setSourceLayer(FolderLayerWrapper* sourceLayer);
|
||||
void paint(QPainter* painter, QTransform transform, const std::vector<std::shared_ptr<LayerStyle>> &styles) override;
|
||||
};
|
||||
|
||||
//******************************** BitmapPath ********************************//
|
||||
|
|
|
@ -11,10 +11,10 @@ LayerWrapper *LayerManager::getRoot() const
|
|||
{
|
||||
return root;
|
||||
}
|
||||
void LayerManager::paint(QPainter *painter, QSize size) const
|
||||
void LayerManager::paint(QPainter *painter, QSize size,LayerWrapper* selecetedLayer) const
|
||||
{
|
||||
auto p = root->getCache().resizedPixel(size);
|
||||
painter->drawPixmap(0, 0, p);
|
||||
root->getCache();
|
||||
root->paint(painter);
|
||||
}
|
||||
bool LayerManager::singleSelectedCheck() const
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ class LayerManager
|
|||
LayerManager() = default;
|
||||
LayerManager(QJsonObject source, ElementManager* elementManager);
|
||||
QJsonObject toJson() const;
|
||||
void paint(QPainter *painter, QSize size) const;
|
||||
void paint(QPainter *painter, QSize size, LayerWrapper* selecetedLayer=nullptr) const;
|
||||
bool rename(QString newName) const;
|
||||
bool combine() const;
|
||||
// bool seperate() const;
|
||||
|
|
|
@ -23,9 +23,13 @@ FolderLayerWrapper*LayerWrapper::getParent() const
|
|||
return this == nullptr ? nullptr : this->parent;
|
||||
}
|
||||
|
||||
PixelPath LayerWrapper::getCache()
|
||||
PixelPath LayerWrapper::getCache(LayerWrapper* selectedLayer)
|
||||
{
|
||||
this->refresh();
|
||||
this->refresh(selectedLayer);
|
||||
if (selectedLayer == this)
|
||||
{
|
||||
this->cache.highLight();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
|
||||
|
@ -42,6 +46,7 @@ LayerWrapper::LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementM
|
|||
property.scale = {transformJson.value("scale").toObject().value("x").toDouble(),
|
||||
transformJson.value("scale").toObject().value("y").toDouble()};
|
||||
property.rotation = {transformJson.value("rotation").toDouble()};
|
||||
selected = false;
|
||||
}
|
||||
|
||||
FolderLayerWrapper::FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent)
|
||||
|
@ -75,35 +80,52 @@ LeafLayerWrapper::LeafLayerWrapper(QJsonObject json, ElementManager *elementMana
|
|||
int elementIndex = json.value("element").toInt();
|
||||
wrappedElement = elementManager->getElementById(elementIndex);
|
||||
}
|
||||
void LayerWrapper::SimpleProperty::apply(PixelPath&cache) const
|
||||
|
||||
void LayerWrapper::SimpleProperty::apply(PixelPath&cache)
|
||||
{
|
||||
transform.reset();
|
||||
double centerX = cache.getBoundingRect().center().x();
|
||||
double centerY = cache.getBoundingRect().center().y();
|
||||
//qDebug() << name << " " << cache.boundingRect().center();
|
||||
//qDebug() << name << " " << cache.boundingRect();
|
||||
transform.translate(centerX, centerY);
|
||||
transform.translate(offset.x(), offset.y());
|
||||
transform.rotate(rotation);
|
||||
transform.scale(scale.x(), scale.y());
|
||||
transform.translate(-centerX, -centerY);
|
||||
cache = cache.trans(transform);
|
||||
}
|
||||
|
||||
QTransform LayerWrapper::getTransform()
|
||||
{
|
||||
QTransform trans;
|
||||
double centerX = cache.getBoundingRect().center().x();
|
||||
double centerY = cache.getBoundingRect().center().y();
|
||||
//qDebug() << name << " " << cache.boundingRect().center();
|
||||
//qDebug() << name << " " << cache.boundingRect();
|
||||
trans.translate(offset.x(), offset.y());
|
||||
trans.translate(-centerX, -centerY);
|
||||
trans.rotate(rotation);
|
||||
trans.scale(scale.x(), scale.y());
|
||||
trans.translate(centerX, centerY);
|
||||
cache = cache.trans(trans);
|
||||
trans.translate(property.offset.x(), property.offset.y());
|
||||
trans.rotate(property.rotation);
|
||||
trans.scale(property.scale.x(), property.scale.y());
|
||||
trans.translate(-centerX, -centerY);
|
||||
return trans;
|
||||
}
|
||||
void LayerWrapper::refresh()
|
||||
|
||||
void LayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
property.apply(cache);
|
||||
}
|
||||
|
||||
void FolderLayerWrapper::refresh()
|
||||
void FolderLayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
cache.clear();
|
||||
for (auto& child : children) {
|
||||
cache.addPath(child.get()->getCache());
|
||||
cache.addPath(child.get()->getCache(layer));
|
||||
}
|
||||
LayerWrapper::refresh();
|
||||
}
|
||||
|
||||
void LeafLayerWrapper::refresh()
|
||||
void LeafLayerWrapper::refresh(LayerWrapper* layer)
|
||||
{
|
||||
cache.clear();
|
||||
if (wrappedElement != nullptr)
|
||||
|
@ -228,3 +250,36 @@ int FolderLayerWrapper::getReferencedBy()const
|
|||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void LayerWrapper::paint(QPainter* painter, QTransform transform)
|
||||
{
|
||||
if (this->selected)
|
||||
{
|
||||
painter->save();
|
||||
painter->setTransform(transform);
|
||||
painter->setPen(QPen(Qt::gray, 2));
|
||||
painter->setPen(Qt::DashLine);
|
||||
painter->drawRect(cache.getBoundingRect());
|
||||
painter->restore();
|
||||
}
|
||||
}
|
||||
|
||||
void FolderLayerWrapper::paint(QPainter* painter, QTransform transform)
|
||||
{
|
||||
LayerWrapper::paint(painter, transform);
|
||||
transform = property.transform * transform;
|
||||
qDebug() << transform;
|
||||
for (auto& child : children)
|
||||
child->paint(painter, transform);
|
||||
}
|
||||
|
||||
void LeafLayerWrapper::paint(QPainter* painter, QTransform transform)
|
||||
{
|
||||
LayerWrapper::paint(painter, transform);
|
||||
transform = property.transform * transform;
|
||||
qDebug() << transform;
|
||||
if (wrappedElement != nullptr)
|
||||
{
|
||||
wrappedElement->paint(painter, transform, styles);
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ class LayerWrapper
|
|||
|
||||
public:
|
||||
QTreeWidgetItem* qTreeWidgetItem;
|
||||
bool selected;
|
||||
struct SimpleProperty
|
||||
{
|
||||
QString name = "";
|
||||
|
@ -43,17 +44,20 @@ class LayerWrapper
|
|||
double rotation = 0;
|
||||
bool flipHorizontally = 0;
|
||||
bool flipVertically = 0;
|
||||
QTransform transform;
|
||||
// TODO: 将QPainterPath改为BitmapPath
|
||||
void apply(PixelPath&cache) const;
|
||||
void apply(PixelPath&cache);
|
||||
} property;
|
||||
virtual void setParent(FolderLayerWrapper*newParent);
|
||||
virtual void refresh();
|
||||
virtual void refresh(LayerWrapper* layer = nullptr);
|
||||
virtual QTreeWidgetItem* getQTreeItem();
|
||||
// TODO: 将QPainterPath改为BitmapPath/QImage,或者直接将其删除,绘制时直接使用BitmapPath的paint方法
|
||||
virtual PixelPath getCache();
|
||||
virtual PixelPath getCache(LayerWrapper* selectedLayer=nullptr);
|
||||
QTransform getTransform();
|
||||
FolderLayerWrapper*getParent() const; // invoke by manager, then invoke parent's applyStyles
|
||||
LayerWrapper(QJsonObject json, FolderLayerWrapper*parent, ElementManager* elementManager=nullptr);
|
||||
LayerWrapper() = default;
|
||||
virtual void paint(QPainter* painter, QTransform transform=QTransform());
|
||||
// TODO : export Function
|
||||
// virtual LayerWrapper *addChild() = 0; // Leaf Child Only
|
||||
// virtual LayerWrapper *addParent() = 0; // Folder Parent Only
|
||||
|
@ -75,7 +79,7 @@ class FolderLayerWrapper : public LayerWrapper
|
|||
public:
|
||||
|
||||
~FolderLayerWrapper() = default;
|
||||
void refresh() override;
|
||||
void refresh(LayerWrapper* layer=nullptr) override;
|
||||
FolderLayerWrapper() = default;
|
||||
FolderLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||
void addChild(shared_ptr<LayerWrapper> child);
|
||||
|
@ -86,6 +90,7 @@ class FolderLayerWrapper : public LayerWrapper
|
|||
QTreeWidgetItem* getQTreeItem() override;
|
||||
QJsonObject toJson() const override;
|
||||
int getReferencedBy()const;
|
||||
void paint(QPainter* painter, QTransform transform = QTransform()) override;
|
||||
};
|
||||
|
||||
class LeafLayerWrapper : public LayerWrapper
|
||||
|
@ -97,10 +102,11 @@ class LeafLayerWrapper : public LayerWrapper
|
|||
|
||||
public:
|
||||
~LeafLayerWrapper() = default;
|
||||
void refresh() override;
|
||||
void refresh(LayerWrapper* layer = nullptr) override;
|
||||
LeafLayerWrapper() = default;
|
||||
LeafLayerWrapper(QJsonObject json, ElementManager *elementManager, FolderLayerWrapper*parent);
|
||||
QJsonObject toJson() const override;
|
||||
void paint(QPainter* painter, QTransform transform = QTransform()) override;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(LayerWrapper *)
|
||||
|
|
|
@ -103,3 +103,18 @@ QPixmap PixelPath::getDetail()const
|
|||
result = pixmap.copy(rect);
|
||||
return result;
|
||||
}
|
||||
|
||||
void PixelPath::highLight()
|
||||
{
|
||||
// 创建一个QPainter对象,关联到QPixmap对象
|
||||
QPainter painter(&pixmap);
|
||||
|
||||
// 设置画笔的颜色、宽度和样式
|
||||
painter.setPen(QPen(Qt::black, 1, Qt::DashLine));
|
||||
|
||||
// 绘制一个矩形,指定左上角和右下角的坐标
|
||||
painter.drawRect(boundingRect);
|
||||
|
||||
// 结束绘制
|
||||
painter.end();
|
||||
}
|
|
@ -26,4 +26,5 @@ public:
|
|||
PixelPath trans(QTransform& mat)const;
|
||||
QPixmap resizedPixel(QSize size)const;
|
||||
QPixmap getDetail()const;
|
||||
void highLight();
|
||||
};
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
|
||||
{
|
||||
this->setFixedSize(QSize(1080, 1080));
|
||||
this->renderer = Renderer::ElementRenderer::instance();
|
||||
QSurfaceFormat surfaceFormat;
|
||||
surfaceFormat.setSamples(16);
|
||||
|
@ -10,6 +11,7 @@ PreviewWindow::PreviewWindow(QWidget *parent) : QOpenGLWidget(parent)
|
|||
painter->setRenderHint(QPainter::SmoothPixmapTransform);
|
||||
painter->setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
layerManager = nullptr;
|
||||
currentLayer = nullptr;
|
||||
}
|
||||
|
||||
void PreviewWindow::initialize(LayerManager *layerManager,QSize windowSize)
|
||||
|
@ -46,7 +48,7 @@ void PreviewWindow::paintGL()
|
|||
painter->begin(this);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setRenderHint(QPainter::HighQualityAntialiasing);
|
||||
layerManager->paint(painter,this->size());
|
||||
layerManager->paint(painter,this->size(),currentLayer);
|
||||
painter->end();
|
||||
}
|
||||
|
||||
|
@ -57,3 +59,47 @@ void PreviewWindow::resizeGL(int w, int h)
|
|||
Renderer::ElementRenderer* const PreviewWindow::getRenderer()const {
|
||||
return this->renderer;
|
||||
}
|
||||
|
||||
void PreviewWindow::currentLayerChanged(LayerWrapper* layer)
|
||||
{
|
||||
this->currentLayer = layer;
|
||||
}
|
||||
|
||||
void PreviewWindow::refresh()
|
||||
{
|
||||
this->repaint();
|
||||
}
|
||||
|
||||
void PreviewWindow::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
// 当鼠标按下时,记录当前的位置
|
||||
m_lastPos = event->pos();
|
||||
}
|
||||
|
||||
void PreviewWindow::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
// 当鼠标移动时,计算移动的距离,并根据需要更新图形的状态
|
||||
int dx = event->x() - m_lastPos.x();
|
||||
int dy = event->y() - m_lastPos.y();
|
||||
if (currentLayer != nullptr) {
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
// 如果按下的是左键,那么平移图形
|
||||
currentLayer->property.offset.setX(currentLayer->property.offset.x() + dx);
|
||||
currentLayer->property.offset.setY(currentLayer->property.offset.y() + dy);
|
||||
qDebug() << dx << "----" << dy;
|
||||
}
|
||||
else if (event->buttons() & Qt::RightButton) {
|
||||
// 如果按下的是右键,那么旋转图形
|
||||
qreal angle = dx;
|
||||
currentLayer->property.rotation += angle;
|
||||
}
|
||||
}
|
||||
// 更新上一次的位置
|
||||
m_lastPos = event->pos();
|
||||
this->repaint();
|
||||
}
|
||||
|
||||
void PreviewWindow::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
emit layerInfoChanged();
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QOpenGLFunctions>
|
||||
#include <QMouseEvent>
|
||||
#include <QOpenGLWidget>
|
||||
#include "../Renderer/Preview/ElementRenderer.h"
|
||||
|
||||
|
@ -19,6 +20,12 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
LayerManager *layerManager;
|
||||
Renderer::ElementRenderer* renderer;
|
||||
QSize logicalSize;
|
||||
QRectF viewportRect;
|
||||
LayerWrapper* currentLayer;
|
||||
QPointF m_lastPos;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
|
||||
public:
|
||||
PreviewWindow(QWidget *parent = nullptr);
|
||||
|
@ -28,4 +35,11 @@ class PreviewWindow : public QOpenGLWidget, protected QOpenGLFunctions
|
|||
void paintGL() override;
|
||||
void resizeGL(int w, int h) override;
|
||||
Renderer::ElementRenderer* const getRenderer()const;
|
||||
|
||||
public slots:
|
||||
void currentLayerChanged(LayerWrapper*);
|
||||
void refresh();
|
||||
|
||||
signals:
|
||||
void layerInfoChanged();
|
||||
};
|
||||
|
|
|
@ -12,11 +12,19 @@ LayerTreeWidget::LayerTreeWidget(QWidget *parent)
|
|||
this->setHeaderLabel("Layer Content");
|
||||
connect(this, &QTreeWidget::customContextMenuRequested, this, &LayerTreeWidget::popMenu);
|
||||
connect(this, &QTreeWidget::currentItemChanged, [=](QTreeWidgetItem *currentItem) {
|
||||
if (this->selectedItem != nullptr) {
|
||||
this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>()->selected = false;
|
||||
}
|
||||
this->selectedItem = currentItem;
|
||||
if(this->selectedItem !=nullptr)
|
||||
emit displayLayerChange(this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper *>());
|
||||
else
|
||||
if (this->selectedItem != nullptr) {
|
||||
auto layer = this->selectedItem->data(0, Qt::UserRole).value<LayerWrapper*>();
|
||||
layer->selected = true;
|
||||
emit displayLayerChange(layer);
|
||||
}
|
||||
else {
|
||||
emit displayLayerChange(nullptr);
|
||||
}
|
||||
emit requireRefreshPreview();
|
||||
});
|
||||
// connect(this, &QTreeWidget::itemDoubleClicked, this, &LayerTreeWidget::onItemDoubleClicked);
|
||||
}
|
||||
|
|
|
@ -2,23 +2,22 @@
|
|||
#include <QOpenGLFunctions_4_5_Core>
|
||||
#include <QString>
|
||||
#include <vector>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLTexture>
|
||||
#include <QOpenGLWidget>
|
||||
#include <assimp/vector3.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include "Drawable.h"
|
||||
|
||||
namespace Renderer
|
||||
{
|
||||
struct Vertex
|
||||
{
|
||||
QVector3D Position;
|
||||
QVector3D Normal;
|
||||
QVector2D TexCoords;
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
glm::vec2 TexCoords;
|
||||
Vertex(const aiVector3D& position, const aiVector3D& Normal, const aiVector3D& TexCoords);
|
||||
};
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ void Renderer::Model::loadModel(QString path)
|
|||
directory = modelFile.dir();
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
const aiScene* scene = importer.ReadFile(modelFile.absoluteFilePath().toUtf8(), aiProcess_Triangulate /*| aiProcess_FlipUVs*/);
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
qCritical() << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
|
||||
|
@ -117,12 +117,8 @@ void Model::processNode(aiNode* node, const aiScene* scene, aiMatrix4x4 mat4)
|
|||
|
||||
std::unique_ptr<Drawable> Model::processMesh(aiMesh* mesh, const aiScene* scene, aiMatrix4x4 model)
|
||||
{
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
QMatrix4x4 modelQ((float*)&model);
|
||||
|
||||
aiString str;
|
||||
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
for (unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
|
@ -139,45 +135,59 @@ std::unique_ptr<Drawable> Model::processMesh(aiMesh* mesh, const aiScene* scene,
|
|||
maxZ = std::max(maxZ, worldPos.z);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> indices;
|
||||
for (auto face = mesh->mFaces; face < mesh->mFaces + mesh->mNumFaces; face++)
|
||||
indices.insert(indices.end(), face->mIndices, face->mIndices + face->mNumIndices);
|
||||
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
if (auto iter = paintingMap.find(std::string(str.C_Str())); paintingProgram != nullptr && iter != paintingMap.end())
|
||||
if (auto iter = paintingMap.find([&] {
|
||||
aiString str;
|
||||
material->GetTexture(aiTextureType_BASE_COLOR, 0, &str);
|
||||
return std::string(str.C_Str());
|
||||
}()); paintingProgram != nullptr && iter != paintingMap.end())
|
||||
{
|
||||
qDebug() << iter->first.c_str() << "Replaced";
|
||||
|
||||
auto mesh = std::make_unique<PaintingMesh>(glFunc, paintingProgram, shadowProgram, modelQ);
|
||||
|
||||
auto& [paintingPath, leftBottom, rightTop] = iter->second;
|
||||
qDebug() << str.C_Str() << "Replaced";
|
||||
|
||||
auto m_mesh = std::make_unique<PaintingMesh>(glFunc, paintingProgram, shadowProgram, modelQ);
|
||||
m_mesh->vertices = vertices;
|
||||
m_mesh->indices = indices;
|
||||
for (auto& v : vertices)
|
||||
{
|
||||
//qDebug() << v.TexCoords.x << v.TexCoords.y;
|
||||
v.TexCoords = (v.TexCoords - leftBottom) / (rightTop - leftBottom);
|
||||
qDebug() << v.TexCoords.x << v.TexCoords.y;
|
||||
}
|
||||
|
||||
m_mesh->paintingId = loadPainting(paintingPath);
|
||||
auto& handle = vtManager->getPaintingHandle(m_mesh->paintingId);
|
||||
m_mesh->textureBasecolor = handle.baseColor;
|
||||
m_mesh->textureMetallicRoughness = handle.metallicRoughness;
|
||||
m_mesh->setupMesh();
|
||||
return m_mesh;
|
||||
mesh->vertices = vertices;
|
||||
mesh->indices = indices;
|
||||
|
||||
mesh->paintingId = loadPainting(paintingPath);
|
||||
auto& handle = vtManager->getPaintingHandle(mesh->paintingId);
|
||||
mesh->textureBasecolor = handle.baseColor;
|
||||
mesh->textureMetallicRoughness = handle.metallicRoughness;
|
||||
mesh->setupMesh();
|
||||
return mesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto m_mesh = std::make_unique<Mesh>(glFunc, shaderProgram, shadowProgram, modelQ);
|
||||
m_mesh->vertices = vertices;
|
||||
m_mesh->indices = indices;
|
||||
auto mesh = std::make_unique<Mesh>(glFunc, shaderProgram, shadowProgram, modelQ);
|
||||
mesh->vertices = vertices;
|
||||
mesh->indices = indices;
|
||||
|
||||
// ´¦Àí²ÄÖÊ
|
||||
if (!(m_mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR)))
|
||||
if (!(mesh->textureBasecolor = loadMaterialTextures(material, aiTextureType_BASE_COLOR)))
|
||||
qWarning() << "Basecolor Texture Loading Failed!";
|
||||
if (!(m_mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
|
||||
if (!(mesh->textureMetallicRoughness = loadMaterialTextures(material, aiTextureType_METALNESS)))
|
||||
qWarning() << "MetallicRoughness Texture Loading Failed!";
|
||||
if (!(m_mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
|
||||
if (!(mesh->textureNormal = loadMaterialTextures(material, aiTextureType_NORMALS)))
|
||||
qWarning() << "Normal Texture Loading Failed!";
|
||||
|
||||
if (m_mesh->textureBasecolor && m_mesh->textureMetallicRoughness && m_mesh->textureNormal)
|
||||
if (mesh->textureBasecolor && mesh->textureMetallicRoughness && mesh->textureNormal)
|
||||
{
|
||||
m_mesh->setupMesh();
|
||||
return m_mesh;
|
||||
mesh->setupMesh();
|
||||
return mesh;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
|
@ -208,7 +218,7 @@ GLuint Model::loadMaterialTextures(aiMaterial* mat, aiTextureType type)
|
|||
texture.setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::Repeat);
|
||||
texture.setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::Repeat);
|
||||
texture.setMinMagFilters(QOpenGLTexture::LinearMipMapLinear, QOpenGLTexture::Linear);
|
||||
texture.setData(data);
|
||||
texture.setData(data.mirrored());
|
||||
return texture.textureId();
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,10 @@ namespace Renderer
|
|||
QOpenGLShaderProgram* shadowProgram = nullptr;
|
||||
VirtualTextureManager* vtManager = nullptr;
|
||||
|
||||
/**
|
||||
* @param key BaseColor路径
|
||||
* @param value json路径, 纹理坐标
|
||||
*/
|
||||
std::unordered_map<std::string, std::tuple<std::string, glm::vec2, glm::vec2>> paintingMap;
|
||||
std::unordered_map<std::string, GLuint> paintingLoaded;
|
||||
std::unordered_map<std::string, QOpenGLTexture> texturesLoaded;
|
||||
|
|
Loading…
Reference in New Issue