From 3ec1be62ff5a9c1c6324eaa8495740e37ec08abc Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 7 Oct 2016 18:02:38 +0200 Subject: [PATCH] Paint custom render widgets properly without output, recreate as needed --- qrenderdoc/Widgets/CustomPaintWidget.cpp | 35 +++++++- qrenderdoc/Widgets/CustomPaintWidget.h | 19 ++++- qrenderdoc/Widgets/ResourcePreview.cpp | 10 ++- qrenderdoc/Widgets/ThumbnailStrip.cpp | 10 +-- qrenderdoc/Widgets/ThumbnailStrip.h | 8 +- qrenderdoc/Windows/TextureViewer.cpp | 104 ++++++++++++++++------- qrenderdoc/Windows/TextureViewer.h | 2 + qrenderdoc/Windows/TextureViewer.ui | 13 ++- 8 files changed, 144 insertions(+), 57 deletions(-) diff --git a/qrenderdoc/Widgets/CustomPaintWidget.cpp b/qrenderdoc/Widgets/CustomPaintWidget.cpp index 3ee985590..e6c64e312 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.cpp +++ b/qrenderdoc/Widgets/CustomPaintWidget.cpp @@ -29,7 +29,18 @@ CustomPaintWidget::CustomPaintWidget(QWidget *parent) : QWidget(parent) { + m_Ctx = NULL; m_Output = NULL; + setAttribute(Qt::WA_OpaquePaintEvent); + setAttribute(Qt::WA_PaintOnScreen); + setMouseTracking(true); +} + +CustomPaintWidget::CustomPaintWidget(CaptureContext *c, QWidget *parent) : QWidget(parent) +{ + m_Ctx = c; + m_Output = NULL; + setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_PaintOnScreen); setMouseTracking(true); } @@ -65,14 +76,30 @@ void CustomPaintWidget::keyPressEvent(QKeyEvent *e) void CustomPaintWidget::paintEvent(QPaintEvent *e) { - if(m_Output) + if(m_Ctx) { - m_Ctx->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { m_Output->Display(); }); + if(m_Output != NULL) + m_Ctx->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { m_Output->Display(); }); + } + else if(m_Dark == m_Light) + { + QPainter p(this); + p.fillRect(rect(), m_Dark); } else { + int numX = (int)ceil((float)rect().width() / 64.0f); + int numY = (int)ceil((float)rect().height() / 64.0f); + QPainter p(this); - p.setBrush(QBrush(Qt::black)); - p.drawRect(rect()); + for(int x = 0; x < numX; x++) + { + for(int y = 0; y < numY; y++) + { + QColor &col = ((x % 2) == (y % 2)) ? m_Dark : m_Light; + + p.fillRect(QRect(x * 64, y * 64, 64, 64), col); + } + } } } diff --git a/qrenderdoc/Widgets/CustomPaintWidget.h b/qrenderdoc/Widgets/CustomPaintWidget.h index 0d646e4b9..6764cf1f0 100644 --- a/qrenderdoc/Widgets/CustomPaintWidget.h +++ b/qrenderdoc/Widgets/CustomPaintWidget.h @@ -35,13 +35,22 @@ private: Q_OBJECT public: explicit CustomPaintWidget(QWidget *parent = 0); + explicit CustomPaintWidget(CaptureContext *c, QWidget *parent = 0); ~CustomPaintWidget(); - void SetOutput(CaptureContext *c, IReplayOutput *out) + // this is needed to solve a chicken-and-egg problem. We need to recreate the widget + // whenever we go from custom rendering to painting (e.g. log loaded or closed). But + // we need the widget to have been recreated before we create the output, so we can + // pass in the winId. + // So we go by whether or not we have a CaptureContext * and go on faith that the + // output will be set before any painting work has to happen. + void setOutput(IReplayOutput *out) { m_Output = out; } + void setColours(QColor dark, QColor light) { - m_Ctx = c; - m_Output = out; + m_Dark = dark; + m_Light = light; } + signals: void clicked(QMouseEvent *e); void mouseMove(QMouseEvent *e); @@ -60,7 +69,9 @@ public slots: protected: void paintEvent(QPaintEvent *e); - QPaintEngine *paintEngine() const { return NULL; } + QPaintEngine *paintEngine() const { return m_Ctx ? NULL : QWidget::paintEngine(); } CaptureContext *m_Ctx; IReplayOutput *m_Output; + QColor m_Dark; + QColor m_Light; }; diff --git a/qrenderdoc/Widgets/ResourcePreview.cpp b/qrenderdoc/Widgets/ResourcePreview.cpp index 44d1962da..98be13535 100644 --- a/qrenderdoc/Widgets/ResourcePreview.cpp +++ b/qrenderdoc/Widgets/ResourcePreview.cpp @@ -31,7 +31,15 @@ ResourcePreview::ResourcePreview(CaptureContext *c, IReplayOutput *output, QWidg { ui->setupUi(this); - ui->thumbnail->SetOutput(c, output); + CustomPaintWidget *thumb = new CustomPaintWidget(c, this); + thumb->setOutput(output); + thumb->setObjectName(ui->thumbnail->objectName()); + thumb->setSizePolicy(ui->thumbnail->sizePolicy()); + thumb->setMinimumSize(QSize(0, 0)); + + delete ui->thumbnail; + ui->thumbnail = thumb; + ui->gridLayout->addWidget(ui->thumbnail, 0, 0, 1, 2); QPalette Pal(ui->slotLabel->palette()); diff --git a/qrenderdoc/Widgets/ThumbnailStrip.cpp b/qrenderdoc/Widgets/ThumbnailStrip.cpp index 2c73ea52d..18e0ff42a 100644 --- a/qrenderdoc/Widgets/ThumbnailStrip.cpp +++ b/qrenderdoc/Widgets/ThumbnailStrip.cpp @@ -43,13 +43,13 @@ ThumbnailStrip::~ThumbnailStrip() delete ui; } -void ThumbnailStrip::AddPreview(ResourcePreview *prev) +void ThumbnailStrip::addThumb(ResourcePreview *prev) { layout->addWidget(prev); m_Thumbnails.push_back(prev); } -void ThumbnailStrip::ClearThumbnails() +void ThumbnailStrip::clearThumbs() { for(ResourcePreview *p : m_Thumbnails) { @@ -62,7 +62,7 @@ void ThumbnailStrip::ClearThumbnails() void ThumbnailStrip::resizeEvent(QResizeEvent *event) { - RefreshLayout(); + refreshLayout(); } void ThumbnailStrip::mousePressEvent(QMouseEvent *event) @@ -72,10 +72,10 @@ void ThumbnailStrip::mousePressEvent(QMouseEvent *event) void ThumbnailStrip::showEvent(QShowEvent *event) { - RefreshLayout(); + refreshLayout(); } -void ThumbnailStrip::RefreshLayout() +void ThumbnailStrip::refreshLayout() { QRect avail = geometry(); avail.adjust(6, 6, -6, -6); diff --git a/qrenderdoc/Widgets/ThumbnailStrip.h b/qrenderdoc/Widgets/ThumbnailStrip.h index 87fabd565..d84a0e762 100644 --- a/qrenderdoc/Widgets/ThumbnailStrip.h +++ b/qrenderdoc/Widgets/ThumbnailStrip.h @@ -43,11 +43,11 @@ public: explicit ThumbnailStrip(QWidget *parent = 0); ~ThumbnailStrip(); - void AddPreview(ResourcePreview *prev); + void addThumb(ResourcePreview *prev); - void ClearThumbnails(); - const QVector &GetThumbs() { return m_Thumbnails; } - void RefreshLayout(); + void clearThumbs(); + const QVector &thumbs() { return m_Thumbnails; } + void refreshLayout(); signals: void mouseClick(QMouseEvent *event); diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 2c470d688..388cc2c65 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -318,9 +318,6 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) { ui->setupUi(this); - ui->render->SetOutput(m_Ctx, NULL); - ui->pixelContext->SetOutput(m_Ctx, NULL); - m_Ctx->AddLogViewer(this); memset(&m_TexDisplay, 0, sizeof(m_TexDisplay)); @@ -330,18 +327,6 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) on_checkerBack_clicked(); - QWidget *renderContainer = ui->renderContainer; - - QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::render_mouseClick); - QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::render_mouseMove); - QObject::connect(ui->render, &CustomPaintWidget::mouseWheel, this, - &TextureViewer::render_mouseWheel); - QObject::connect(ui->render, &CustomPaintWidget::resize, this, &TextureViewer::render_resize); - QObject::connect(ui->render, &CustomPaintWidget::keyPress, this, &TextureViewer::render_keyPress); - - QObject::connect(ui->pixelContext, &CustomPaintWidget::keyPress, this, - &TextureViewer::render_keyPress); - QObject::connect(ui->zoomOption->lineEdit(), &QLineEdit::returnPressed, this, &TextureViewer::zoomOption_returnPressed); @@ -367,6 +352,8 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) QObject::connect(ui->customShader, QOverload::of(&QComboBox::currentIndexChanged), this, &TextureViewer::channelsWidget_selected); + QWidget *renderContainer = ui->renderContainer; + ui->dockarea->addToolWindow(ui->renderContainer, ToolWindowManager::EmptySpace); ui->dockarea->setToolWindowProperties(renderContainer, ToolWindowManager::DisallowUserDocking | ToolWindowManager::HideCloseButton | @@ -1331,13 +1318,13 @@ ResourcePreview *TextureViewer::UI_CreateThumbnail(ThumbnailStrip *strip) QObject::connect(prev, &ResourcePreview::clicked, this, &TextureViewer::thumb_clicked); prev->setActive(false); - strip->AddPreview(prev); + strip->addThumb(prev); return prev; } void TextureViewer::UI_CreateThumbnails() { - if(!ui->outputThumbs->GetThumbs().isEmpty()) + if(!ui->outputThumbs->thumbs().isEmpty()) return; // these will expand, but we make sure that there is a good set reserved @@ -1519,9 +1506,9 @@ void TextureViewer::InitStageResourcePreviews(ShaderStageType stage, ResourcePreview *prev = NULL; - if(prevIndex < prevs->GetThumbs().size()) + if(prevIndex < prevs->thumbs().size()) { - prev = prevs->GetThumbs()[prevIndex]; + prev = prevs->thumbs()[prevIndex]; // don't use it if we're not actually going to show it if(!show && !prev->isActive()) @@ -1551,10 +1538,10 @@ void TextureViewer::thumb_clicked(QMouseEvent *e) Following follow = prev->property("f").value(); - for(ResourcePreview *p : ui->outputThumbs->GetThumbs()) + for(ResourcePreview *p : ui->outputThumbs->thumbs()) p->setSelected(false); - for(ResourcePreview *p : ui->inputThumbs->GetThumbs()) + for(ResourcePreview *p : ui->inputThumbs->thumbs()) p->setSelected(false); m_Following = follow; @@ -1829,8 +1816,50 @@ void TextureViewer::on_renderVScroll_valueChanged(int position) ScrollUpdateScrollbars = true; } +void TextureViewer::UI_RecreatePanels() +{ + CaptureContext *ctx = m_Ctx; + + // while a log is loaded, pass NULL into the widget + if(!ctx->LogLoaded()) + ctx = NULL; + + { + CustomPaintWidget *render = new CustomPaintWidget(ctx, ui->renderContainer); + render->setObjectName(ui->render->objectName()); + render->setSizePolicy(ui->render->sizePolicy()); + delete ui->render; + ui->render = render; + ui->gridLayout->addWidget(render, 1, 0, 1, 1); + } + + { + CustomPaintWidget *pixelContext = new CustomPaintWidget(ctx, ui->pixelContextLayout); + pixelContext->setObjectName(ui->pixelContext->objectName()); + pixelContext->setSizePolicy(ui->pixelContext->sizePolicy()); + delete ui->pixelContext; + ui->pixelContext = pixelContext; + ui->pixelcontextgrid->addWidget(pixelContext, 0, 0, 1, 2); + } + + ui->render->setColours(darkBack, lightBack); + ui->pixelContext->setColours(darkBack, lightBack); + + QObject::connect(ui->render, &CustomPaintWidget::clicked, this, &TextureViewer::render_mouseClick); + QObject::connect(ui->render, &CustomPaintWidget::mouseMove, this, &TextureViewer::render_mouseMove); + QObject::connect(ui->render, &CustomPaintWidget::mouseWheel, this, + &TextureViewer::render_mouseWheel); + QObject::connect(ui->render, &CustomPaintWidget::resize, this, &TextureViewer::render_resize); + QObject::connect(ui->render, &CustomPaintWidget::keyPress, this, &TextureViewer::render_keyPress); + + QObject::connect(ui->pixelContext, &CustomPaintWidget::keyPress, this, + &TextureViewer::render_keyPress); +} + void TextureViewer::OnLogfileLoaded() { + UI_RecreatePanels(); + WId renderID = ui->render->winId(); WId contextID = ui->pixelContext->winId(); @@ -1845,7 +1874,8 @@ void TextureViewer::OnLogfileLoaded() m_Output->SetPixelContext(m_Ctx->m_CurWinSystem, m_Ctx->FillWindowingData(contextID)); - ui->render->SetOutput(m_Ctx, m_Output); + ui->render->setOutput(m_Output); + ui->pixelContext->setOutput(m_Output); OutputConfig c = {eOutputType_TexDisplay}; m_Output->SetOutputConfig(c); @@ -1855,7 +1885,10 @@ void TextureViewer::OnLogfileLoaded() void TextureViewer::OnLogfileClosed() { m_Output = NULL; - ui->render->SetOutput(m_Ctx, NULL); + + UI_RecreatePanels(); + + ui->inputThumbs->clearThumbs(); m_TextureSettings.clear(); @@ -1887,8 +1920,8 @@ void TextureViewer::OnEventSelected(uint32_t eventID) { ResourcePreview *prev; - if(outIndex < ui->outputThumbs->GetThumbs().size()) - prev = ui->outputThumbs->GetThumbs()[outIndex]; + if(outIndex < ui->outputThumbs->thumbs().size()) + prev = ui->outputThumbs->thumbs()[outIndex]; else prev = UI_CreateThumbnail(ui->outputThumbs); @@ -1906,8 +1939,8 @@ void TextureViewer::OnEventSelected(uint32_t eventID) { ResourcePreview *prev; - if(outIndex < ui->outputThumbs->GetThumbs().size()) - prev = ui->outputThumbs->GetThumbs()[outIndex]; + if(outIndex < ui->outputThumbs->thumbs().size()) + prev = ui->outputThumbs->thumbs()[outIndex]; else prev = UI_CreateThumbnail(ui->outputThumbs); @@ -1951,7 +1984,7 @@ void TextureViewer::OnEventSelected(uint32_t eventID) } // hide others - const QVector &outThumbs = ui->outputThumbs->GetThumbs(); + const QVector &outThumbs = ui->outputThumbs->thumbs(); for(; outIndex < outThumbs.size(); outIndex++) { @@ -1961,9 +1994,9 @@ void TextureViewer::OnEventSelected(uint32_t eventID) prev->setSelected(false); } - ui->outputThumbs->RefreshLayout(); + ui->outputThumbs->refreshLayout(); - const QVector &inThumbs = ui->inputThumbs->GetThumbs(); + const QVector &inThumbs = ui->inputThumbs->thumbs(); for(; inIndex < inThumbs.size(); inIndex++) { @@ -1973,7 +2006,7 @@ void TextureViewer::OnEventSelected(uint32_t eventID) prev->setSelected(false); } - ui->inputThumbs->RefreshLayout(); + ui->inputThumbs->refreshLayout(); INVOKE_MEMFN(RT_UpdateAndDisplay); @@ -2014,6 +2047,9 @@ void TextureViewer::setPersistData(const QVariant &persistData) m_TexDisplay.lightBackgroundColour = FloatVector(lightBack.redF(), lightBack.greenF(), lightBack.blueF(), 1.0f); + ui->render->setColours(darkBack, lightBack); + ui->pixelContext->setColours(darkBack, lightBack); + ui->dockarea->restoreState(state); } @@ -2168,6 +2204,9 @@ void TextureViewer::on_backcolorPick_clicked() darkBack = lightBack = col; + ui->render->setColours(darkBack, lightBack); + ui->pixelContext->setColours(darkBack, lightBack); + ui->backcolorPick->setChecked(true); ui->checkerBack->setChecked(false); @@ -2196,6 +2235,9 @@ void TextureViewer::on_checkerBack_clicked() int(m_TexDisplay.lightBackgroundColour.y * 255.0f), int(m_TexDisplay.lightBackgroundColour.z * 255.0f)); + ui->render->setColours(darkBack, lightBack); + ui->pixelContext->setColours(darkBack, lightBack); + INVOKE_MEMFN(RT_UpdateAndDisplay); if(m_Output == NULL) diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index e876f24ff..e7278ddbb 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -170,6 +170,8 @@ private: void RT_PickHoverAndUpdate(IReplayRenderer *); void RT_UpdateAndDisplay(IReplayRenderer *); + void UI_RecreatePanels(); + void UI_UpdateStatusText(); void UI_UpdateTextureDetails(); void UI_OnTextureSelectionChanged(bool newdraw); diff --git a/qrenderdoc/Windows/TextureViewer.ui b/qrenderdoc/Windows/TextureViewer.ui index fb10b5984..52195e697 100644 --- a/qrenderdoc/Windows/TextureViewer.ui +++ b/qrenderdoc/Windows/TextureViewer.ui @@ -932,9 +932,6 @@ 0 - - - @@ -1094,16 +1091,16 @@ - - CustomPaintWidget - QWidget -
Widgets/CustomPaintWidget.h
-
ToolWindowManager QWidget
ToolWindowManager.h
+ + CustomPaintWidget + QWidget +
Widgets/CustomPaintWidget.h
+
ThumbnailStrip QWidget