From 8e7a4ff9d168734533fa1f725b013c048e49b3e9 Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Thu, 7 Apr 2011 01:15:48 -0400 Subject: [PATCH] Add code to interpret and display binary vertex data. --- gui/CMakeLists.txt | 1 + gui/apitracecall.cpp | 28 ++++- gui/apitracecall.h | 4 + gui/mainwindow.cpp | 46 ++++++++ gui/mainwindow.h | 3 + gui/ui/mainwindow.ui | 162 ++++++++++++++++++++++++++- gui/vertexdatainterpreter.cpp | 204 ++++++++++++++++++++++++++++++++++ gui/vertexdatainterpreter.h | 39 +++++++ 8 files changed, 481 insertions(+), 6 deletions(-) create mode 100644 gui/vertexdatainterpreter.cpp create mode 100644 gui/vertexdatainterpreter.h diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 620f424..632a441 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -9,6 +9,7 @@ set(qapitrace_SRCS main.cpp retracer.cpp settingsdialog.cpp + vertexdatainterpreter.cpp ) qt4_automoc(${qapitrace_SRCS}) diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 4817eb3..8c6359c 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -24,8 +24,13 @@ QString apiVariantToString(const QVariant &variant) return QString::number(variant.toFloat()); } if (variant.userType() == QVariant::ByteArray) { - float kb = variant.toByteArray().size()/1024.; - return QObject::tr("[binary data, size = %1kb]").arg(kb); + if (variant.toByteArray().size() < 1024) { + int bytes = variant.toByteArray().size(); + return QObject::tr("[binary data, size = %1 bytes]").arg(bytes); + } else { + float kb = variant.toByteArray().size()/1024.; + return QObject::tr("[binary data, size = %1 kb]").arg(kb); + } } if (variant.userType() < QVariant::UserType) { @@ -311,6 +316,11 @@ QString ApiTraceCall::filterText() const for (int i = 0; i < argNames.count(); ++i) { m_filterText += argNames[i]; m_filterText += QString::fromLatin1(" = "); + + if (argValues[i].type() == QVariant::ByteArray) { + m_hasBinaryData = true; + m_binaryDataIndex = i; + } m_filterText += apiVariantToString(argValues[i]); if (i < argNames.count() - 1) m_filterText += QString::fromLatin1(", "); @@ -357,7 +367,9 @@ ApiTraceFrame::ApiTraceFrame() } ApiTraceCall::ApiTraceCall() - : ApiTraceEvent(ApiTraceEvent::Call) + : ApiTraceEvent(ApiTraceEvent::Call), + m_hasBinaryData(false), + m_binaryDataIndex(0) { } @@ -384,3 +396,13 @@ void ApiTraceEvent::setState(const QVariantMap &state) { m_state = state; } + +bool ApiTraceCall::hasBinaryData() const +{ + return m_hasBinaryData; +} + +int ApiTraceCall::binaryDataIndex() const +{ + return m_binaryDataIndex; +} diff --git a/gui/apitracecall.h b/gui/apitracecall.h index c69a484..809a6c1 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -143,10 +143,14 @@ public: QString filterText() const; QStaticText staticText() const; int numChildren() const; + bool hasBinaryData() const; + int binaryDataIndex() const; private: mutable QString m_richText; mutable QString m_filterText; mutable QStaticText m_staticText; + mutable bool m_hasBinaryData; + mutable int m_binaryDataIndex; }; Q_DECLARE_METATYPE(ApiTraceCall*); diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index f67b654..dee53d9 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -7,6 +7,7 @@ #include "apitracefilter.h" #include "retracer.h" #include "settingsdialog.h" +#include "vertexdatainterpreter.h" #include @@ -42,6 +43,24 @@ MainWindow::MainWindow() connect(m_retracer, SIGNAL(error(const QString&)), this, SLOT(replayError(const QString&))); + m_vdataInterpreter = new VertexDataInterpreter(this); + m_vdataInterpreter->setListWidget(m_ui.vertexDataListWidget); + m_vdataInterpreter->setStride( + m_ui.vertexStrideSB->value()); + m_vdataInterpreter->setComponents( + m_ui.vertexComponentsSB->value()); + m_vdataInterpreter->setTypeFromString( + m_ui.vertexTypeCB->currentText()); + + connect(m_ui.vertexInterpretButton, SIGNAL(clicked()), + m_vdataInterpreter, SLOT(interpretData())); + connect(m_ui.vertexTypeCB, SIGNAL(activated(const QString&)), + m_vdataInterpreter, SLOT(setTypeFromString(const QString&))); + connect(m_ui.vertexStrideSB, SIGNAL(valueChanged(int)), + m_vdataInterpreter, SLOT(setStride(int))); + connect(m_ui.vertexComponentsSB, SIGNAL(valueChanged(int)), + m_vdataInterpreter, SLOT(setComponents(int))); + m_model = new ApiTraceModel(); m_model->setApiTrace(m_trace); m_proxyModel = new ApiTraceFilter(); @@ -62,7 +81,11 @@ MainWindow::MainWindow() m_progressBar->hide(); m_ui.detailsDock->hide(); + m_ui.vertexDataDock->hide(); m_ui.stateDock->hide(); + setDockOptions(dockOptions() | QMainWindow::ForceTabbedDocks); + + tabifyDockWidget(m_ui.stateDock, m_ui.vertexDataDock); connect(m_ui.actionOpen, SIGNAL(triggered()), this, SLOT(openTrace())); @@ -120,6 +143,28 @@ void MainWindow::callItemSelected(const QModelIndex &index) ApiTraceCall *call = static_cast(event); m_ui.detailsWebView->setHtml(call->toHtml()); m_ui.detailsDock->show(); + if (call->hasBinaryData()) { + QByteArray data = + call->argValues[call->binaryDataIndex()].toByteArray(); + m_vdataInterpreter->setData(data); + + for (int i = 0; i < call->argNames.count(); ++i) { + QString name = call->argNames[i]; + if (name == QLatin1String("stride")) { + int stride = call->argValues[i].toInt(); + m_ui.vertexStrideSB->setValue(stride); + } else if (name == QLatin1String("size")) { + int components = call->argValues[i].toInt(); + m_ui.vertexComponentsSB->setValue(components); + } else if (name == QLatin1String("type")) { + QString val = call->argValues[i].toString(); + int textIndex = m_ui.vertexTypeCB->findText(val); + if (textIndex >= 0) + m_ui.vertexTypeCB->setCurrentIndex(textIndex); + } + } + } + m_ui.vertexDataDock->setVisible(call->hasBinaryData()); m_selectedEvent = call; } else { if (event && event->type() == ApiTraceEvent::Frame) { @@ -127,6 +172,7 @@ void MainWindow::callItemSelected(const QModelIndex &index) } else m_selectedEvent = 0; m_ui.detailsDock->hide(); + m_ui.vertexDataDock->hide(); } if (m_selectedEvent && !m_selectedEvent->state().isEmpty()) { fillStateForFrame(); diff --git a/gui/mainwindow.h b/gui/mainwindow.h index 9d0c15e..78a8d6f 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -15,6 +15,7 @@ class QLineEdit; class QModelIndex; class QProgressBar; class Retracer; +class VertexDataInterpreter; namespace QJson { class Parser; @@ -67,6 +68,8 @@ private: QJson::Parser *m_jsonParser; Retracer *m_retracer; + + VertexDataInterpreter *m_vdataInterpreter; }; diff --git a/gui/ui/mainwindow.ui b/gui/ui/mainwindow.ui index 76e0e8b..6c7e25e 100644 --- a/gui/ui/mainwindow.ui +++ b/gui/ui/mainwindow.ui @@ -6,13 +6,22 @@ 0 0 - 760 - 422 + 787 + 758 ApiTrace + + false + + + false + + + QMainWindow::AnimatedDocks|QMainWindow::ForceTabbedDocks + @@ -35,7 +44,7 @@ 0 0 - 760 + 787 21 @@ -104,6 +113,9 @@ + + QDockWidget::AllDockWidgetFeatures + Current State @@ -150,6 +162,148 @@ + + + Qt::AllDockWidgetAreas + + + Vertex Data + + + 2 + + + + + + + + + Type + + + + + + + 6 + + + + GL_BYTE + + + + + GL_UNSIGNED_BYTE + + + + + GL_SHORT + + + + + GL_UNSIGNED_SHORT + + + + + GL_INT + + + + + GL_UNSIGNED_INT + + + + + GL_FLOAT + + + + + + + + Stride + + + + + + + 1000 + + + 8 + + + + + + + Components + + + + + + + 256 + + + 4 + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Interpret + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Exit @@ -231,6 +385,8 @@ Options + stateDock + vertexDataDock diff --git a/gui/vertexdatainterpreter.cpp b/gui/vertexdatainterpreter.cpp new file mode 100644 index 0000000..e00466b --- /dev/null +++ b/gui/vertexdatainterpreter.cpp @@ -0,0 +1,204 @@ +#include "vertexdatainterpreter.h" + +#include +#include + +#include + +#include + +static int +sizeForType(int glType) +{ + switch(glType) { + case GL_FLOAT: + return sizeof(GLfloat); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_BYTE: + return sizeof(GLbyte); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_INT: + return sizeof(GLint); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + default: + return sizeof(GLint); + } +} + +template +static QStringList +convertData(const QByteArray &dataArray, + int type, + int stride, + int numComponents) +{ + QStringList strings; + + const char *data = dataArray.constData(); + int typeSize = sizeForType(type); + int sizePerAttribute = typeSize; + + if (stride) + sizePerAttribute = stride; + + int numElements = dataArray.size() / sizePerAttribute; + +#if 0 + qDebug() << "numElements = "<clear(); +} + +QByteArray VertexDataInterpreter::data() const +{ + return m_data; +} + +void VertexDataInterpreter::setType(int type) +{ + m_type = type; +} + +int VertexDataInterpreter::type() const +{ + return m_type; +} + +void VertexDataInterpreter::setStride(int stride) +{ + m_stride = stride; +} + +int VertexDataInterpreter::stride() const +{ + return m_stride; +} + +void VertexDataInterpreter::setComponents(int num) +{ + m_components = num; +} + +int VertexDataInterpreter::components() const +{ + return m_components; +} + +void VertexDataInterpreter::setListWidget(QListWidget *listWidget) +{ + m_listWidget = listWidget; +} + +void VertexDataInterpreter::interpretData() +{ + if (!m_listWidget) + return; + + m_listWidget->clear(); + + if (m_data.isEmpty() || !m_components) + return; + + QStringList lst; + switch(m_type) { + case GL_FLOAT: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_UNSIGNED_BYTE: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_BYTE: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_SHORT: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_UNSIGNED_SHORT: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_INT: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + case GL_UNSIGNED_INT: + lst = convertData(m_data, m_type, m_stride, m_components); + break; + default: + qDebug()<<"unkown gltype = "<addItems(lst); +} + + +void VertexDataInterpreter::setTypeFromString(const QString &str) +{ + if (str == QLatin1String("GL_FLOAT")) { + setType(GL_FLOAT); + } else if (str == QLatin1String("GL_INT")) { + setType(GL_INT); + } else if (str == QLatin1String("GL_UNSIGNED_INT")) { + setType(GL_UNSIGNED_INT); + } else if (str == QLatin1String("GL_SHORT")) { + setType(GL_SHORT); + } else if (str == QLatin1String("GL_UNSIGNED_SHORT")) { + setType(GL_UNSIGNED_SHORT); + } else if (str == QLatin1String("GL_BYTE")) { + setType(GL_BYTE); + } else if (str == QLatin1String("GL_UNSIGNED_BYTE")) { + setType(GL_UNSIGNED_BYTE); + } else { + qDebug()<<"unknown vertex data type"; + } +} + +#include "vertexdatainterpreter.moc" diff --git a/gui/vertexdatainterpreter.h b/gui/vertexdatainterpreter.h new file mode 100644 index 0000000..8492593 --- /dev/null +++ b/gui/vertexdatainterpreter.h @@ -0,0 +1,39 @@ +#ifndef VERTEXDATAINTERPRETER_H +#define VERTEXDATAINTERPRETER_H + +#include + +class QListWidget; + +class VertexDataInterpreter : public QObject +{ + Q_OBJECT +public: + VertexDataInterpreter(QObject *parent=0); + + QByteArray data() const; + + int type() const; + int stride() const; + int components() const; + + void setListWidget(QListWidget *listWidget); + +public slots: + void interpretData(); + + void setData(const QByteArray &data); + void setTypeFromString(const QString &str); + void setStride(int stride); + void setComponents(int num); + void setType(int type); + +private: + QListWidget *m_listWidget; + QByteArray m_data; + int m_type; + int m_stride; + int m_components; +}; + +#endif -- 2.43.0