diff --git a/qrenderdoc/Widgets/RangeHistogram.cpp b/qrenderdoc/Widgets/RangeHistogram.cpp new file mode 100644 index 000000000..95addef0c --- /dev/null +++ b/qrenderdoc/Widgets/RangeHistogram.cpp @@ -0,0 +1,308 @@ +#include "RangeHistogram.h" +#include +#include + +RangeHistogram::RangeHistogram(QWidget *parent) : QWidget(parent) +{ + setMouseTracking(true); +} + +RangeHistogram::~RangeHistogram() +{ +} + +// sets the range of data where the histogram data was calculated. +void RangeHistogram::setHistogramRange(float min, float max) +{ + m_HistogramMin = min; + m_HistogramMax = max; +} + +// sets the minimum and maximum as well as the black and white points +void RangeHistogram::setRange(float min, float max) +{ + m_RangeMin = min; + if(min < 0.0f) + m_RangeMax = qMax((min - FLT_EPSILON) * (1.0f - m_MinRangeSize), max); + else + m_RangeMax = qMax((min + FLT_EPSILON) * (1.0f + m_MinRangeSize), max); + + m_BlackPoint = m_RangeMin; + m_WhitePoint = m_RangeMax; + + update(); + emit rangeUpdated(); +} + +bool RangeHistogram::ValidRange() const +{ + if(isinf(m_WhitePoint) || isnan(m_WhitePoint) || isinf(m_BlackPoint) || isnan(m_BlackPoint) || + isinf(m_RangeMax) || isnan(m_RangeMax) || isinf(m_RangeMin) || isnan(m_RangeMin) || + isinf(m_RangeMax - m_RangeMin) || isnan(m_RangeMax - m_RangeMin) || + isinf(m_WhitePoint - m_BlackPoint) || isnan(m_WhitePoint - m_BlackPoint)) + { + return false; + } + + return true; +} + +void RangeHistogram::setHistogramData(const QVector &histogram) +{ + m_HistogramData = histogram; + + update(); +} + +void RangeHistogram::setBlackPoint(float val) +{ + if(val <= m_RangeMin) + m_BlackPoint = m_RangeMin = val; + else + m_BlackPoint = val; + + update(); + emit rangeUpdated(); +} + +void RangeHistogram::setWhitePoint(float val) +{ + if(val >= m_RangeMax) + m_WhitePoint = m_RangeMax = val; + else + m_WhitePoint = val; + + update(); + emit rangeUpdated(); +} + +float RangeHistogram::blackDelta() +{ + if(!ValidRange()) + return 0.0f; + + return delta(m_BlackPoint); +} + +void RangeHistogram::setBlackDelta(float value) +{ + setBlackPoint(qMin(m_WhitePoint - m_MinRangeSize, value * (m_RangeMax - m_RangeMin) + m_RangeMin)); +} + +float RangeHistogram::whiteDelta() +{ + if(!ValidRange()) + return 0.0f; + + return delta(m_WhitePoint); +} + +void RangeHistogram::setWhiteDelta(float value) +{ + setWhitePoint(qMax(m_BlackPoint + m_MinRangeSize, value * (m_RangeMax - m_RangeMin) + m_RangeMin)); +} + +float RangeHistogram::delta(float val) const +{ + return (val - m_RangeMin) / (m_RangeMax - m_RangeMin); +} + +void RangeHistogram::mousePressEvent(QMouseEvent *e) +{ + if(e->button() != Qt::LeftButton || !ValidRange()) + return; + + QRect r = rect(); + + r.marginsRemoved(QMargins(totalSpace(), totalSpace(), totalSpace(), totalSpace())); + + int whiteX = (int)(whiteDelta() * r.width()); + int blackX = (int)(blackDelta() * r.width()); + + QPointF whiteVec(whiteX - e->pos().x(), rect().height() - e->pos().y()); + QPointF blackVec(blackX - e->pos().x(), e->pos().y()); + + float whitedist = (float)sqrt(whiteVec.x() * whiteVec.x() + whiteVec.y() * whiteVec.y()); + float blackdist = (float)sqrt(blackVec.x() * blackVec.x() + blackVec.y() * blackVec.y()); + + if(whitedist < blackdist && whitedist < 18.0f) + m_DragMode = DraggingMode::White; + else if(blackdist < whitedist && blackdist < 18.0f) + m_DragMode = DraggingMode::Black; + else if(e->pos().x() > whiteX) + m_DragMode = DraggingMode::White; + else if(e->pos().x() < blackX) + m_DragMode = DraggingMode::Black; + + if(m_DragMode == DraggingMode::White) + { + float newWhite = (float)(e->pos().x() - totalSpace()) / (float)regionWidth(); + + setWhiteDelta(qBound(blackDelta() + m_MinRangeSize, newWhite, 1.0f)); + } + else if(m_DragMode == DraggingMode::Black) + { + float newBlack = (float)(e->pos().x() - totalSpace()) / (float)regionWidth(); + + setBlackDelta(qBound(0.0f, newBlack, whiteDelta() - m_MinRangeSize)); + } + + emit rangeUpdated(); + + if(m_DragMode != DraggingMode::None) + update(); + + m_MousePrev = e->pos(); +} + +void RangeHistogram::mouseReleaseEvent(QMouseEvent *e) +{ + m_DragMode = DraggingMode::None; + + m_MousePrev = QPoint(-1, -1); +} + +void RangeHistogram::mouseMoveEvent(QMouseEvent *e) +{ + QPoint pos = e->pos(); + if(ValidRange() && (e->buttons() & Qt::LeftButton) && pos != m_MousePrev) + { + if(m_DragMode == DraggingMode::White) + { + float newWhite = (float)(pos.x() - totalSpace()) / (float)regionWidth(); + + setWhiteDelta(qBound(blackDelta() + m_MinRangeSize, newWhite, 1.0f)); + } + else if(m_DragMode == DraggingMode::Black) + { + float newBlack = (float)(pos.x() - totalSpace()) / (float)regionWidth(); + + setBlackDelta(qBound(0.0f, newBlack, whiteDelta() - m_MinRangeSize)); + } + + emit rangeUpdated(); + + if(m_DragMode != DraggingMode::None) + update(); + + m_MousePrev = pos; + } +} + +void RangeHistogram::enterEvent(QEvent *e) +{ +} + +void RangeHistogram::leaveEvent(QEvent *e) +{ +} + +void RangeHistogram::paintEvent(QPaintEvent *e) +{ + QPainter p(this); + const QBrush blackBrush(QColor(0, 0, 0)); + const QBrush grayBrush(QColor(180, 180, 180)); + const QBrush redBrush(QColor(60, 0, 0)); + const QBrush greenBrush(QColor(0, 128, 0)); + const QBrush whiteBrush(QColor(255, 255, 255)); + + QRect r = this->rect(); + + p.eraseRect(r); + + r = r.marginsRemoved(QMargins(m_Margin, m_Margin, m_Margin, m_Margin)); + + p.fillRect(r, blackBrush); + + r = r.marginsRemoved(QMargins(m_Border, m_Border, m_Border, m_Border)); + + p.fillRect(r, ValidRange() ? grayBrush : redBrush); + + int whiteX = (int)(whiteDelta() * r.width()); + int blackX = (int)(blackDelta() * r.width()); + + QRect blackPoint(r.topLeft(), QSize(blackX, r.height())); + QRect whitePoint(r.left() + whiteX, r.top(), r.width() - whiteX, r.height()); + + p.fillRect(whitePoint, whiteBrush); + p.fillRect(blackPoint, blackBrush); + + if(!ValidRange()) + return; + + if(!m_HistogramData.isEmpty()) + { + float minx = delta(m_HistogramMin); + float maxx = delta(m_HistogramMax); + + uint32_t maxval = 0; + for(int i = 0; i < m_HistogramData.count(); i++) + { + float x = (float)i / (float)m_HistogramData.count(); + + float xdelta = minx + x * (maxx - minx); + + if(xdelta >= 0.0f && xdelta <= 1.0f) + { + maxval = qMax(maxval, m_HistogramData[i]); + } + } + + if(maxval == 0) + maxval = 1; + + for(int i = 0; i < m_HistogramData.count(); i++) + { + float x = (float)i / (float)m_HistogramData.count(); + float y = (float)m_HistogramData[i] / (float)maxval; + + float xdelta = minx + x * (maxx - minx); + + if(xdelta >= 0.0f && xdelta <= 1.0f) + { + float segwidth = qMax(r.width() * (maxx - minx) / (float)m_HistogramData.count(), 1.0f); + + QRectF barRect(QPointF(r.left() + r.width() * (minx + x * (maxx - minx)), + r.bottom() - r.height() * y + 1), + QSizeF(segwidth, r.height() * y)); + + p.fillRect(barRect, greenBrush); + } + } + } + + QVector blackTriangle = {QPoint(blackPoint.right() + 1, m_MarkerSize * 2), + QPoint(blackPoint.right() + m_MarkerSize + 1, 0), + QPoint(blackPoint.right() - m_MarkerSize + 1, 0)}; + + QPainterPath blackPath; + blackPath.addPolygon(QPolygon(blackTriangle)); + + p.fillPath(blackPath, grayBrush); + + QVector whiteTriangle = { + QPoint(whitePoint.left(), whitePoint.bottom() - m_MarkerSize * 2 + m_Margin), + QPoint(whitePoint.left() + m_MarkerSize, whitePoint.bottom() + m_Margin), + QPoint(whitePoint.left() - m_MarkerSize, whitePoint.bottom() + m_Margin)}; + + QPainterPath whitePath; + whitePath.addPolygon(QPolygon(whiteTriangle)); + p.fillPath(whitePath, grayBrush); + + blackTriangle[0] -= QPoint(0, 2); + blackTriangle[1] += QPoint(-2, 1); + blackTriangle[2] += QPoint(2, 1); + + blackPath = QPainterPath(); + blackPath.addPolygon(QPolygon(blackTriangle)); + + whiteTriangle[0] += QPoint(0, 2); + whiteTriangle[1] -= QPoint(2, 1); + whiteTriangle[2] += QPoint(2, -1); + + whitePath = QPainterPath(); + whitePath.addPolygon(QPolygon(whiteTriangle)); + + p.fillPath(blackPath, blackBrush); + p.fillPath(whitePath, whiteBrush); +} diff --git a/qrenderdoc/Widgets/RangeHistogram.h b/qrenderdoc/Widgets/RangeHistogram.h new file mode 100644 index 000000000..c9e03793b --- /dev/null +++ b/qrenderdoc/Widgets/RangeHistogram.h @@ -0,0 +1,75 @@ +#ifndef RANGEHISTOGRAM_H +#define RANGEHISTOGRAM_H + +#include + +class RangeHistogram : public QWidget +{ + Q_OBJECT + +public: + explicit RangeHistogram(QWidget *parent = 0); + ~RangeHistogram(); + + void setHistogramRange(float min, float max); + void setRange(float min, float max); + + void setHistogramData(const QVector &histogram); + + float blackPoint() { return m_BlackPoint; } + void setBlackPoint(float val); + + float whitePoint() { return m_WhitePoint; } + void setWhitePoint(float val); + + float rangeMin() { return m_RangeMin; } + float rangeMax() { return m_RangeMax; } +signals: + void rangeUpdated(); + +protected: + void mousePressEvent(QMouseEvent *e) override; + void mouseReleaseEvent(QMouseEvent *e) override; + void mouseMoveEvent(QMouseEvent *e) override; + void enterEvent(QEvent *e) override; + void leaveEvent(QEvent *e) override; + void paintEvent(QPaintEvent *e) override; + +private: + bool ValidRange() const; + float delta(float val) const; + + static const int m_Margin = 4; + static const int m_Border = 1; + static const int m_MarkerSize = 6; + + int totalSpace() const { return m_Margin + m_Border; } + int regionWidth() const { return rect().width() - totalSpace() * 2; } + float blackDelta(); + void setBlackDelta(float value); + float whiteDelta(); + void setWhiteDelta(float value); + + QPoint m_MousePrev = QPoint(-1, -1); + + enum class DraggingMode + { + None, + White, + Black, + } m_DragMode; + + QVector m_HistogramData; + float m_HistogramMin = 0.0f; + float m_HistogramMax = 1.0f; + + float m_RangeMin = 0.0f; + float m_RangeMax = 1.0f; + + float m_BlackPoint = 0.0f; + float m_WhitePoint = 1.0f; + + float m_MinRangeSize = 1.0e-6f; +}; + +#endif // RANGEHISTOGRAM_H diff --git a/qrenderdoc/Windows/TextureViewer.cpp b/qrenderdoc/Windows/TextureViewer.cpp index 1e3a767f1..5b8b59118 100644 --- a/qrenderdoc/Windows/TextureViewer.cpp +++ b/qrenderdoc/Windows/TextureViewer.cpp @@ -506,6 +506,16 @@ TextureViewer::TextureViewer(CaptureContext *ctx, QWidget *parent) &TextureViewer::channelsWidget_selected); QObject::connect(ui->customShader, QOverload::of(&QComboBox::currentIndexChanged), this, &TextureViewer::channelsWidget_selected); + QObject::connect(ui->rangeHistogram, &RangeHistogram::rangeUpdated, this, + &TextureViewer::range_rangeUpdated); + QObject::connect(ui->rangeBlack, &RDLineEdit::textChanged, this, + &TextureViewer::rangePoint_textChanged); + QObject::connect(ui->rangeBlack, &RDLineEdit::leave, this, &TextureViewer::rangePoint_leave); + QObject::connect(ui->rangeBlack, &RDLineEdit::keyPress, this, &TextureViewer::rangePoint_keyPress); + QObject::connect(ui->rangeWhite, &RDLineEdit::textChanged, this, + &TextureViewer::rangePoint_textChanged); + QObject::connect(ui->rangeWhite, &RDLineEdit::leave, this, &TextureViewer::rangePoint_leave); + QObject::connect(ui->rangeWhite, &RDLineEdit::keyPress, this, &TextureViewer::rangePoint_keyPress); QWidget *renderContainer = ui->renderContainer; @@ -685,6 +695,43 @@ void TextureViewer::RT_UpdateAndDisplay(IReplayRenderer *) GUIInvoke::call([this]() { ui->render->update(); }); } +void TextureViewer::RT_UpdateVisualRange(IReplayRenderer *) +{ + FetchTexture *texptr = GetCurrentTexture(); + + if(!m_Visualise || texptr == NULL || m_Output == NULL) + return; + + ResourceFormat fmt = texptr->format; + + if(m_TexDisplay.CustomShader != ResourceId()) + fmt.compCount = 4; + + bool success = true; + + bool channels[] = { + m_TexDisplay.Red ? true : false, m_TexDisplay.Green && fmt.compCount > 1, + m_TexDisplay.Blue && fmt.compCount > 2, m_TexDisplay.Alpha && fmt.compCount > 3, + }; + + rdctype::array histogram; + success = m_Output->GetHistogram(ui->rangeHistogram->rangeMin(), ui->rangeHistogram->rangeMax(), + channels, &histogram); + + if(success) + { + QVector histogramVec(histogram.count); + if(histogram.count > 0) + memcpy(histogramVec.data(), histogram.elems, histogram.count * sizeof(uint32_t)); + + GUIInvoke::call([this, histogramVec]() { + ui->rangeHistogram->setHistogramRange(ui->rangeHistogram->rangeMin(), + ui->rangeHistogram->rangeMax()); + ui->rangeHistogram->setHistogramData(histogramVec); + }); + } +} + void TextureViewer::UI_UpdateStatusText() { FetchTexture *texptr = GetCurrentTexture(); @@ -992,8 +1039,8 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) m_TextureSettings[m_TexDisplay.texid].mip = ui->mipLevel->currentIndex(); m_TextureSettings[m_TexDisplay.texid].slice = ui->sliceFace->currentIndex(); - m_TextureSettings[m_TexDisplay.texid].minrange = 0.0f; // rangeHistogram->blackPoint(); - m_TextureSettings[m_TexDisplay.texid].maxrange = 1.0f; // rangeHistogram->whitePoint(); + m_TextureSettings[m_TexDisplay.texid].minrange = ui->rangeHistogram->blackPoint(); + m_TextureSettings[m_TexDisplay.texid].maxrange = ui->rangeHistogram->whitePoint(); m_TextureSettings[m_TexDisplay.texid].typeHint = m_Following.GetTypeHint(m_Ctx); } @@ -1196,10 +1243,10 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) ui->depthDisplay->setChecked(m_TextureSettings[tex.ID].depth); ui->stencilDisplay->setChecked(m_TextureSettings[tex.ID].stencil); - // norangePaint = true; - // rangeHistogram.SetRange(m_TextureSettings[m_TexDisplay.texid].minrange, - // m_TextureSettings[m_TexDisplay.texid].maxrange); - // norangePaint = false; + m_NoRangePaint = true; + ui->rangeHistogram->setRange(m_TextureSettings[m_TexDisplay.texid].minrange, + m_TextureSettings[m_TexDisplay.texid].maxrange); + m_NoRangePaint = false; } else if(m_Ctx->Config.TextureViewer_PerTexSettings) { @@ -1216,15 +1263,15 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) ui->depthDisplay->setChecked(true); ui->stencilDisplay->setChecked(false); - // norangePaint = true; - // UI_SetHistogramRange(tex, m_TexDisplay.typeHint); - // norangePaint = false; + m_NoRangePaint = true; + UI_SetHistogramRange(texptr, m_TexDisplay.typeHint); + m_NoRangePaint = false; } // reset the range if desired if(m_Ctx->Config.TextureViewer_ResetRange) { - // UI_SetHistogramRange(tex, m_TexDisplay.typeHint); + UI_SetHistogramRange(texptr, m_TexDisplay.typeHint); } } @@ -1232,11 +1279,11 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) UI_UpdateTextureDetails(); UI_UpdateChannels(); - // if (ui->autoFit->isChecked()) - // AutoFitRange(); + if(ui->autoFit->isChecked()) + AutoFitRange(); m_Ctx->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { - // RT_UpdateVisualRange(r); + RT_UpdateVisualRange(r); RT_UpdateAndDisplay(r); @@ -1247,6 +1294,14 @@ void TextureViewer::UI_OnTextureSelectionChanged(bool newdraw) }); } +void TextureViewer::UI_SetHistogramRange(const FetchTexture *tex, FormatComponentType typeHint) +{ + if(tex != NULL && (tex->format.compType == eCompType_SNorm || typeHint == eCompType_SNorm)) + ui->rangeHistogram->setRange(-1.0f, 1.0f); + else + ui->rangeHistogram->setRange(0.0f, 1.0f); +} + void TextureViewer::UI_UpdateChannels() { FetchTexture *tex = GetCurrentTexture(); @@ -1445,7 +1500,7 @@ void TextureViewer::UI_UpdateChannels() m_TexDisplay.FlipY = ui->flip_y->isChecked(); INVOKE_MEMFN(RT_UpdateAndDisplay); - // INVOKE_MEMFN(RT_UpdateVisualRange); + INVOKE_MEMFN(RT_UpdateVisualRange); } void TextureViewer::SetupTextureTabs() @@ -2423,6 +2478,8 @@ void TextureViewer::OnLogfileClosed() { m_Output = NULL; + ui->rangeHistogram->setRange(0.0f, 1.0f); + UI_RecreatePanels(); ui->inputThumbs->clearThumbs(); @@ -2714,20 +2771,192 @@ void TextureViewer::on_overlay_currentIndexChanged(int index) INVOKE_MEMFN(RT_UpdateAndDisplay); } +void TextureViewer::range_rangeUpdated() +{ + m_TexDisplay.rangemin = ui->rangeHistogram->blackPoint(); + m_TexDisplay.rangemax = ui->rangeHistogram->whitePoint(); + + ui->rangeBlack->setText(Formatter::Format(m_TexDisplay.rangemin)); + ui->rangeWhite->setText(Formatter::Format(m_TexDisplay.rangemax)); + + if(m_NoRangePaint) + return; + + INVOKE_MEMFN(RT_UpdateAndDisplay); + + if(m_Output == NULL) + { + ui->render->update(); + ui->pixelcontextgrid->update(); + } +} + +void TextureViewer::rangePoint_textChanged(QString text) +{ + m_RangePoint_Dirty = true; +} + +void TextureViewer::rangePoint_Update() +{ + float black = ui->rangeHistogram->blackPoint(); + float white = ui->rangeHistogram->whitePoint(); + + bool ok = false; + double d = ui->rangeBlack->text().toDouble(&ok); + + if(ok) + black = d; + + d = ui->rangeWhite->text().toDouble(&ok); + + if(ok) + white = d; + + ui->rangeHistogram->setRange(black, white); + + INVOKE_MEMFN(RT_UpdateVisualRange); +} + +void TextureViewer::rangePoint_leave() +{ + if(!m_RangePoint_Dirty) + return; + + rangePoint_Update(); + + m_RangePoint_Dirty = false; +} + +void TextureViewer::rangePoint_keyPress(QKeyEvent *e) +{ + // escape key + if(e->key() == Qt::Key_Escape) + { + m_RangePoint_Dirty = false; + ui->rangeHistogram->setRange(ui->rangeHistogram->blackPoint(), ui->rangeHistogram->whitePoint()); + } + if(e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) + { + rangePoint_Update(); + } +} + void TextureViewer::on_zoomRange_clicked() { + float black = ui->rangeHistogram->blackPoint(); + float white = ui->rangeHistogram->whitePoint(); + + ui->autoFit->setChecked(false); + + ui->rangeHistogram->setRange(black, white); + + INVOKE_MEMFN(RT_UpdateVisualRange); } void TextureViewer::on_autoFit_clicked() { + AutoFitRange(); } void TextureViewer::on_reset01_clicked() { + UI_SetHistogramRange(GetCurrentTexture(), m_TexDisplay.typeHint); + + ui->autoFit->setChecked(false); + + INVOKE_MEMFN(RT_UpdateVisualRange); } void TextureViewer::on_visualiseRange_clicked() { + if(ui->visualiseRange->isChecked()) + { + ui->rangeHistogram->setMinimumSize(QSize(300, 90)); + + m_Visualise = true; + INVOKE_MEMFN(RT_UpdateVisualRange); + } + else + { + m_Visualise = false; + ui->rangeHistogram->setMinimumSize(QSize(200, 0)); + + ui->rangeHistogram->setHistogramData({}); + } +} + +void TextureViewer::AutoFitRange() +{ + // no log loaded or buffer/empty texture currently being viewed - don't autofit + if(!m_Ctx->LogLoaded() || GetCurrentTexture() == NULL || m_Output == NULL) + return; + + m_Ctx->Renderer()->AsyncInvoke([this](IReplayRenderer *r) { + PixelValue min, max; + bool success = m_Output->GetMinMax(&min, &max); + + if(success) + { + float minval = FLT_MAX; + float maxval = -FLT_MAX; + + bool changeRange = false; + + ResourceFormat fmt = GetCurrentTexture()->format; + + if(m_TexDisplay.CustomShader != ResourceId()) + { + fmt.compType = eCompType_Float; + } + + for(int i = 0; i < 4; i++) + { + if(fmt.compType == eCompType_UInt) + { + min.value_f[i] = min.value_u[i]; + max.value_f[i] = max.value_u[i]; + } + else if(fmt.compType == eCompType_SInt) + { + min.value_f[i] = min.value_i[i]; + max.value_f[i] = max.value_i[i]; + } + } + + if(m_TexDisplay.Red) + { + minval = qMin(minval, min.value_f[0]); + maxval = qMax(maxval, max.value_f[0]); + changeRange = true; + } + if(m_TexDisplay.Green && fmt.compCount > 1) + { + minval = qMin(minval, min.value_f[1]); + maxval = qMax(maxval, max.value_f[1]); + changeRange = true; + } + if(m_TexDisplay.Blue && fmt.compCount > 2) + { + minval = qMin(minval, min.value_f[2]); + maxval = qMax(maxval, max.value_f[2]); + changeRange = true; + } + if(m_TexDisplay.Alpha && fmt.compCount > 3) + { + minval = qMin(minval, min.value_f[3]); + maxval = qMax(maxval, max.value_f[3]); + changeRange = true; + } + + if(changeRange) + { + GUIInvoke::call([this, minval, maxval]() { + ui->rangeHistogram->setRange(minval, maxval); + INVOKE_MEMFN(RT_UpdateVisualRange); + }); + } + } + }); } void TextureViewer::on_backcolorPick_clicked() @@ -2827,7 +3056,7 @@ void TextureViewer::on_mipLevel_currentIndexChanged(int index) return; } - // INVOKE_MEMFN(RT_UpdateVisualRange); + INVOKE_MEMFN(RT_UpdateVisualRange); if(m_Output != NULL && m_PickedPoint.x() >= 0 && m_PickedPoint.y() >= 0) { @@ -2849,7 +3078,7 @@ void TextureViewer::on_sliceFace_currentIndexChanged(int index) if(tex.depth > 1) m_TexDisplay.sliceFace = (uint32_t)(index << (int)m_TexDisplay.mip); - // INVOKE_MEMFN(RT_UpdateVisualRange); + INVOKE_MEMFN(RT_UpdateVisualRange); if(m_Output != NULL && m_PickedPoint.x() >= 0 && m_PickedPoint.y() >= 0) { diff --git a/qrenderdoc/Windows/TextureViewer.h b/qrenderdoc/Windows/TextureViewer.h index 29b04843e..3acec98a7 100644 --- a/qrenderdoc/Windows/TextureViewer.h +++ b/qrenderdoc/Windows/TextureViewer.h @@ -182,6 +182,11 @@ private slots: void zoomOption_returnPressed(); + void range_rangeUpdated(); + void rangePoint_textChanged(QString text); + void rangePoint_leave(); + void rangePoint_keyPress(QKeyEvent *e); + void channelsWidget_toggled(bool checked) { UI_UpdateChannels(); } void channelsWidget_selected(int index) { UI_UpdateChannels(); } private: @@ -189,6 +194,7 @@ private: void RT_PickPixelsAndUpdate(IReplayRenderer *); void RT_PickHoverAndUpdate(IReplayRenderer *); void RT_UpdateAndDisplay(IReplayRenderer *); + void RT_UpdateVisualRange(IReplayRenderer *); void UI_RecreatePanels(); @@ -196,6 +202,8 @@ private: void UI_UpdateTextureDetails(); void UI_OnTextureSelectionChanged(bool newdraw); + void UI_SetHistogramRange(const FetchTexture *tex, FormatComponentType typeHint); + void UI_UpdateChannels(); void SetupTextureTabs(); @@ -215,6 +223,9 @@ private: void AddResourceUsageEntry(QMenu &menu, uint32_t start, uint32_t end, ResourceUsage usage); void OpenResourceContextMenu(ResourceId id, const rdctype::array &usage); + void AutoFitRange(); + void rangePoint_Update(); + bool currentTextureIsLocked() { return m_LockedId != ResourceId(); } void setFitToWindow(bool checked); @@ -262,6 +273,10 @@ private: bool m_ShowEmpty = false; bool m_ShowDisabled = false; + bool m_Visualise = false; + bool m_NoRangePaint = false; + bool m_RangePoint_Dirty = false; + ResourceId m_LockedId; QMap m_LockedTabs; diff --git a/qrenderdoc/Windows/TextureViewer.ui b/qrenderdoc/Windows/TextureViewer.ui index 6002efc70..78516bfd9 100644 --- a/qrenderdoc/Windows/TextureViewer.ui +++ b/qrenderdoc/Windows/TextureViewer.ui @@ -47,9 +47,9 @@ - 20 - 190 - 255 + 10 + 120 + 558 28 @@ -89,7 +89,7 @@ - + 0 @@ -98,7 +98,7 @@ - 50 + 100 16777215 @@ -108,7 +108,23 @@ - + + + + 200 + 0 + + + + + 0 + 0 + + + + + + 0 @@ -117,7 +133,7 @@ - 50 + 100 16777215 @@ -128,6 +144,12 @@ + + + 0 + 0 + + @@ -142,6 +164,12 @@ + + + 0 + 0 + + @@ -156,6 +184,12 @@ + + + 0 + 0 + + ... @@ -170,6 +204,12 @@ + + + 0 + 0 + + ... @@ -190,8 +230,8 @@ - 240 - 140 + 490 + 40 129 28 @@ -243,8 +283,8 @@ - 3 - 145 + 10 + 80 221 28 @@ -885,8 +925,8 @@ - 290 - 190 + 250 + 220 291 241 @@ -1072,8 +1112,8 @@ - 300 - 460 + 40 + 470 120 80 @@ -1082,8 +1122,8 @@ - 440 - 460 + 210 + 470 120 80 @@ -1092,9 +1132,9 @@ - 480 - 60 - 274 + 550 + 210 + 221 244 @@ -1202,11 +1242,22 @@
Widgets/ThumbnailStrip.h
1 + + RDLineEdit + QLineEdit +
Widgets/RDLineEdit.h
+
RDListView QListView
Widgets/RDListView.h
+ + RangeHistogram + QWidget +
Widgets/RangeHistogram.h
+ 1 +
diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 28c6a3a85..731fac1ab 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -99,7 +99,8 @@ SOURCES += Code/qrenderdoc.cpp \ Code/CommonPipelineState.cpp \ Widgets/TextureGoto.cpp \ Widgets/RDDoubleSpinBox.cpp \ - Widgets/RDListView.cpp + Widgets/RDListView.cpp \ + Widgets/RangeHistogram.cpp HEADERS += Windows/MainWindow.h \ Windows/EventBrowser.h \ @@ -120,7 +121,8 @@ HEADERS += Windows/MainWindow.h \ Code/CommonPipelineState.h \ Widgets/TextureGoto.h \ Widgets/RDDoubleSpinBox.h \ - Widgets/RDListView.h + Widgets/RDListView.h \ + Widgets/RangeHistogram.h FORMS += Windows/MainWindow.ui \ Windows/EventBrowser.ui \ diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index 7c464b326..fbdefcb3d 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -282,6 +282,7 @@ + @@ -295,6 +296,7 @@ + @@ -332,6 +334,7 @@ + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index ccc803e4f..91a4da68c 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -38,6 +38,9 @@ {633cf7bf-24ec-4927-835b-f6e96e21c288} + + {42a491e9-4e18-4220-8de2-e07b7cde26bc} + @@ -100,9 +103,6 @@ Windows - - Widgets - Code @@ -112,9 +112,6 @@ Generated Files - - Widgets - Generated Files @@ -145,15 +142,27 @@ Generated Files - - Widgets - Generated Files - + Widgets + + Generated Files + + + Widgets\Extended + + + Widgets\Extended + + + Widgets\Extended + + + Widgets\Extended + @@ -171,9 +180,6 @@ Windows - - Widgets - Windows @@ -192,9 +198,6 @@ Widgets - - Widgets - Widgets @@ -216,11 +219,20 @@ Widgets - + Widgets + + Widgets\Extended + + + Widgets\Extended + + + Widgets\Extended + - Widgets + Widgets\Extended