From 2507634df980526fb00a9483f5e9782b6fa50bb7 Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 10 Oct 2016 18:48:38 +0200 Subject: [PATCH] Add filterable texture list to texture viewer --- qrenderdoc/Widgets/RDListView.cpp | 23 +++ qrenderdoc/Widgets/RDListView.h | 24 +++ qrenderdoc/Windows/TextureViewer.cpp | 209 +++++++++++++++++++- qrenderdoc/Windows/TextureViewer.h | 16 +- qrenderdoc/Windows/TextureViewer.ui | 100 ++++++++++ qrenderdoc/qrenderdoc.pro | 6 +- qrenderdoc/qrenderdoc_local.vcxproj | 3 + qrenderdoc/qrenderdoc_local.vcxproj.filters | 9 + 8 files changed, 377 insertions(+), 13 deletions(-) create mode 100644 qrenderdoc/Widgets/RDListView.cpp create mode 100644 qrenderdoc/Widgets/RDListView.h diff --git a/qrenderdoc/Widgets/RDListView.cpp b/qrenderdoc/Widgets/RDListView.cpp new file mode 100644 index 000000000..dda63f11c --- /dev/null +++ b/qrenderdoc/Widgets/RDListView.cpp @@ -0,0 +1,23 @@ +#include "RDListView.h" +#include + +RDListView::RDListView(QWidget *parent) : QListView(parent) +{ + setMouseTracking(true); +} + +void RDListView::mouseMoveEvent(QMouseEvent *e) +{ + emit mouseMove(e); + + if(indexAt(e->pos()).isValid() && m_Shape != Qt::ArrowCursor) + { + setCursor(QCursor(m_Shape)); + } + else if(m_Shape != Qt::ArrowCursor) + { + unsetCursor(); + } + + QListView::mouseMoveEvent(e); +} diff --git a/qrenderdoc/Widgets/RDListView.h b/qrenderdoc/Widgets/RDListView.h new file mode 100644 index 000000000..8841c953c --- /dev/null +++ b/qrenderdoc/Widgets/RDListView.h @@ -0,0 +1,24 @@ +#ifndef RDLISTVIEW_H +#define RDLISTVIEW_H + +#include + +class RDListView : public QListView +{ + Q_OBJECT +public: + explicit RDListView(QWidget *parent = 0); + + void setHoverCursor(Qt::CursorShape shape) { m_Shape = shape; } +signals: + void mouseMove(QMouseEvent *e); + +public slots: + +private: + void mouseMoveEvent(QMouseEvent *e) override; + + Qt::CursorShape m_Shape = Qt::ArrowCursor; +}; + +#endif // RDLISTVIEW_H diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 216784f5c..e6c12893a 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "3rdparty/toolwindowmanager/ToolWindowManagerArea.h" #include "Code/CaptureContext.h" #include "Widgets/ResourcePreview.h" @@ -317,6 +319,140 @@ ShaderBindpointMapping Following::GetMapping(CaptureContext *ctx) return GetMapping(ctx, Stage); } +class TextureListItemModel : public QAbstractItemModel +{ +public: + enum FilterType + { + Textures, + RenderTargets, + String + }; + + TextureListItemModel(QObject *parent) : QAbstractItemModel(parent) {} + void reset(FilterType type, const QString &filter, CaptureContext *ctx) + { + const rdctype::array src = ctx->GetTextures(); + + texs.clear(); + texs.reserve(src.count); + + emit beginResetModel(); + + int rtFlags = eTextureCreate_RTV | eTextureCreate_DSV; + + for(const FetchTexture &t : src) + { + if(type == Textures) + { + if((t.creationFlags & rtFlags) == 0) + texs.push_back(t); + } + else if(type == RenderTargets) + { + if((t.creationFlags & rtFlags)) + texs.push_back(t); + } + else + { + if(filter.isEmpty()) + texs.push_back(t); + else if(QString(t.name).contains(filter, Qt::CaseInsensitive)) + texs.push_back(t); + } + } + + emit endResetModel(); + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override + { + if(row < 0 || row >= rowCount()) + return QModelIndex(); + + return createIndex(row, 0); + } + + QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); } + int rowCount(const QModelIndex &parent = QModelIndex()) const override { return texs.count(); } + int columnCount(const QModelIndex &parent = QModelIndex()) const override { return 1; } + Qt::ItemFlags flags(const QModelIndex &index) const override + { + if(!index.isValid()) + return 0; + + return QAbstractItemModel::flags(index); + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override + { + if(index.isValid()) + { + if(role == Qt::DisplayRole) + { + if(index.row() >= 0 && index.row() < texs.count()) + return QVariant(texs[index.row()].name); + } + + if(role == Qt::UserRole) + { + return QVariant::fromValue(texs[index.row()].ID); + } + + if(role == Qt::DecorationRole) + { + QIcon goArrow; + goArrow.addFile(QStringLiteral(":/Resources/RightArrow_Gray_16x16.png"), QSize(), + QIcon::Normal, QIcon::Off); + goArrow.addFile(QStringLiteral(":/Resources/RightArrow_Green_16x16.png"), QSize(), + QIcon::Active, QIcon::Off); + return QVariant(goArrow); + } + } + + return QVariant(); + } + +private: + QVector texs; +}; + +class TextureListItemDelegate : public QItemDelegate +{ +public: + TextureListItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {} + void paint(QPainter *painter, const QStyleOptionViewItem &opt, const QModelIndex &index) const override + { + if(index.isValid()) + { + QStyleOptionViewItem option = opt; + option.decorationAlignment = Qt::AlignBaseline | Qt::AlignRight; + painter->eraseRect(option.rect); + + QIcon icon = index.model()->data(index, Qt::DecorationRole).value(); + + drawBackground(painter, option, index); + if(option.state & QStyle::State_MouseOver) + drawDecoration(painter, option, option.rect, + icon.pixmap(option.decorationSize, QIcon::Active)); + else + drawDecoration(painter, option, option.rect, + icon.pixmap(option.decorationSize, QIcon::Normal)); + drawDisplay(painter, option, option.rect, + index.model()->data(index, Qt::DisplayRole).toString()); + drawFocus(painter, option, option.rect); + + if(option.state & QStyle::State_MouseOver) + { + QRect r = option.rect; + r.adjust(0, 0, -1, -1); + + painter->drawRect(r); + } + } + } +}; + FetchTexture *TextureViewer::GetCurrentTexture() { if(!m_Ctx->LogLoaded()) @@ -395,6 +531,8 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) ui->dockarea->areaOf(ui->outputThumbs), 0.25f)); ui->dockarea->setToolWindowProperties(ui->pixelContextLayout, ToolWindowManager::HideCloseButton); + ui->dockarea->addToolWindow(ui->textureListFrame, ToolWindowManager::NoArea); + ui->dockarea->setAllowFloatingWindow(false); ui->dockarea->setRubberBandLineWidth(50); @@ -402,6 +540,9 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) ui->pixelContextLayout->setWindowTitle(tr("Pixel Context")); ui->outputThumbs->setWindowTitle(tr("Outputs")); ui->inputThumbs->setWindowTitle(tr("Inputs")); + ui->textureListFrame->setWindowTitle(tr("Texture List")); + + ui->textureList->setHoverCursor(Qt::PointingHandCursor); m_Goto = new TextureGoto(this, [this](QPoint p) { GotoLocation(p.x(), p.y()); }); @@ -464,6 +605,12 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) tr("Quad Overdraw (Pass)"), tr("Quad Overdraw (Draw)"), tr("Triangle Size (Pass)"), tr("Triangle Size (Draw)")}); + ui->textureListFilter->addItems({"", "Textures", "Render Targets"}); + + ui->textureList->setModel(new TextureListItemModel(this)); + ui->textureList->setItemDelegate(new TextureListItemDelegate(ui->textureList)); + ui->textureList->viewport()->setAttribute(Qt::WA_Hover); + ui->zoomOption->setCurrentText(""); ui->fitToWindow->toggle(); @@ -1986,7 +2133,7 @@ void TextureViewer::render_mouseMove(QMouseEvent *e) if(e->buttons() == Qt::NoButton) { - ui->render->setCursor(QCursor(Qt::ArrowCursor)); + ui->render->unsetCursor(); } UI_UpdateStatusText(); @@ -2247,6 +2394,10 @@ void TextureViewer::OnLogfileLoaded() WId renderID = ui->render->winId(); WId contextID = ui->pixelContext->winId(); + TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); + + model->reset(TextureListItemModel::String, "", m_Ctx); + m_TexDisplay.darkBackgroundColour = FloatVector(darkBack.redF(), darkBack.greenF(), darkBack.blueF(), 1.0f); m_TexDisplay.lightBackgroundColour = @@ -2734,10 +2885,58 @@ void TextureViewer::on_viewTexBuffer_clicked() { } -void TextureViewer::on_texListShow_clicked() -{ -} - void TextureViewer::on_saveTex_clicked() { } + +void TextureViewer::on_texListShow_clicked() +{ + if(ui->textureListFrame->isVisible()) + { + ui->dockarea->moveToolWindow(ui->textureListFrame, ToolWindowManager::NoArea); + } + else + { + ui->textureListFilter->setCurrentText(""); + ui->dockarea->moveToolWindow( + ui->textureListFrame, + ToolWindowManager::AreaReference(ToolWindowManager::LeftOf, + ui->dockarea->areaOf(ui->renderContainer), 0.2f)); + } +} + +void TextureViewer::on_cancelTextureListFilter_clicked() +{ + ui->textureListFilter->setCurrentText(""); +} + +void TextureViewer::on_textureListFilter_editTextChanged(const QString &text) +{ + TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); + + if(model == NULL) + return; + + model->reset(TextureListItemModel::String, text, m_Ctx); +} + +void TextureViewer::on_textureListFilter_currentIndexChanged(int index) +{ + TextureListItemModel *model = (TextureListItemModel *)ui->textureList->model(); + + if(model == NULL) + return; + + if(ui->textureListFilter->currentIndex() == 1) + model->reset(TextureListItemModel::Textures, "", m_Ctx); + else if(ui->textureListFilter->currentIndex() == 2) + model->reset(TextureListItemModel::RenderTargets, "", m_Ctx); + else + model->reset(TextureListItemModel::String, ui->textureListFilter->currentText(), m_Ctx); +} + +void TextureViewer::on_textureList_clicked(const QModelIndex &index) +{ + ResourceId id = index.model()->data(index, Qt::UserRole).value(); + ViewTexture(id, false); +} diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index 35a2b0efd..29b04843e 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -145,7 +145,6 @@ private slots: void on_mipLevel_currentIndexChanged(int index); void on_sliceFace_currentIndexChanged(int index); - void on_overlay_currentIndexChanged(int index); void on_zoomRange_clicked(); @@ -155,6 +154,16 @@ private slots: void on_backcolorPick_clicked(); void on_checkerBack_clicked(); + void on_locationGoto_clicked(); + void on_viewTexBuffer_clicked(); + void on_texListShow_clicked(); + void on_saveTex_clicked(); + + void on_cancelTextureListFilter_clicked(); + void on_textureListFilter_editTextChanged(const QString &text); + void on_textureListFilter_currentIndexChanged(int index); + void on_textureList_clicked(const QModelIndex &index); + // manual slots void render_mouseClick(QMouseEvent *e); void render_mouseMove(QMouseEvent *e); @@ -175,11 +184,6 @@ private slots: void channelsWidget_toggled(bool checked) { UI_UpdateChannels(); } void channelsWidget_selected(int index) { UI_UpdateChannels(); } - void on_locationGoto_clicked(); - void on_viewTexBuffer_clicked(); - void on_texListShow_clicked(); - void on_saveTex_clicked(); - private: void RT_FetchCurrentPixel(uint32_t x, uint32_t y, PixelValue &pickValue, PixelValue &realValue); void RT_PickPixelsAndUpdate(IReplayRenderer *); diff --git a/qrenderdoc/Windows/TextureViewer.ui b/qrenderdoc/Windows/TextureViewer.ui index c4104c545..6002efc70 100644 --- a/qrenderdoc/Windows/TextureViewer.ui +++ b/qrenderdoc/Windows/TextureViewer.ui @@ -1089,6 +1089,101 @@ + + + + 480 + 60 + 274 + 244 + + + + QFrame::NoFrame + + + QFrame::Plain + + + + 6 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 0 + + + + + + 0 + 0 + + + + true + + + + + + + + + + + :/Resources/cross.png:/Resources/cross.png + + + true + + + + + + + + + QFrame::Box + + + QFrame::Sunken + + + QAbstractItemView::NoEditTriggers + + + false + + + Qt::CopyAction + + + QAbstractItemView::NoSelection + + + QListView::ListMode + + + true + + + + + @@ -1107,6 +1202,11 @@
Widgets/ThumbnailStrip.h
1
+ + RDListView + QListView +
Widgets/RDListView.h
+
diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 310ed2ad7..28c6a3a85 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -98,7 +98,8 @@ SOURCES += Code/qrenderdoc.cpp \ Widgets/ThumbnailStrip.cpp \ Code/CommonPipelineState.cpp \ Widgets/TextureGoto.cpp \ - Widgets/RDDoubleSpinBox.cpp + Widgets/RDDoubleSpinBox.cpp \ + Widgets/RDListView.cpp HEADERS += Windows/MainWindow.h \ Windows/EventBrowser.h \ @@ -118,7 +119,8 @@ HEADERS += Windows/MainWindow.h \ Widgets/ThumbnailStrip.h \ Code/CommonPipelineState.h \ Widgets/TextureGoto.h \ - Widgets/RDDoubleSpinBox.h + Widgets/RDDoubleSpinBox.h \ + Widgets/RDListView.h FORMS += Windows/MainWindow.ui \ Windows/EventBrowser.ui \ diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index 3cc6644ad..7c464b326 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -286,6 +286,7 @@ + @@ -296,6 +297,7 @@ + @@ -332,6 +334,7 @@ + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index 7b68db6cf..ccc803e4f 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -148,6 +148,12 @@ Widgets + + Generated Files + + + Widgets + @@ -213,6 +219,9 @@ Widgets + + Widgets +