From 952e9d4fe14932da90c8478ed8883bb043d702ff Mon Sep 17 00:00:00 2001 From: Zack Rusin Date: Sat, 9 Apr 2011 23:37:21 -0400 Subject: [PATCH] Read the surface data from json. --- gui/CMakeLists.txt | 1 + gui/apisurface.cpp | 110 +++++++++++++++++++++++++++++++++++++++++++ gui/apisurface.h | 48 +++++++++++++++++++ gui/apitracecall.cpp | 46 ++++++++++++++++++ gui/apitracecall.h | 4 ++ 5 files changed, 209 insertions(+) create mode 100644 gui/apisurface.cpp create mode 100644 gui/apisurface.h diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index f5d9859..f1f1a7f 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -2,6 +2,7 @@ include( ${QT_USE_FILE} ) set(qapitrace_SRCS + apisurface.cpp apitrace.cpp apicalldelegate.cpp apitracecall.cpp diff --git a/gui/apisurface.cpp b/gui/apisurface.cpp new file mode 100644 index 0000000..105532e --- /dev/null +++ b/gui/apisurface.cpp @@ -0,0 +1,110 @@ +#include "apisurface.h" + +#include +#include + +ApiSurface::ApiSurface() +{ +} + +QSize ApiSurface::size() const +{ + return m_size; +} + +void ApiSurface::setSize(const QSize &size) +{ + m_size = size; +} + +static inline int +rgbaf2argb(float r, float g, float b, float a) +{ + quint8 rb = r * 255; + quint8 gb = g * 255; + quint8 bb = b * 255; + quint8 ab = a * 255; + + return (ab << 24 | rb << 16 | gb << 8 | bb); +} + +void ApiSurface::contentsFromBase64(const QByteArray &base64) +{ + QByteArray dataArray = QByteArray::fromBase64(base64); + const float *data = (const float*)dataArray.data(); + int width = m_size.width(); + int height = m_size.height(); + + if (width <= 0 || height <= 0) + return; + + int *pixelData = (int*)malloc(sizeof(int) * width * height); + + //XXX not sure if this will work when + // QSysInfo::ByteOrder == QSysInfo::BigEndian + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + int pixel = rgbaf2argb(data[(y * width + x) * 4 + 0], + data[(y * width + x) * 4 + 1], + data[(y * width + x) * 4 + 2], + data[(y * width + x) * 4 + 3]); + pixelData[y * width + x] = pixel; + } + } + + m_image = QImage((uchar*)pixelData, + width, height, + QImage::Format_ARGB32).mirrored(); + m_thumb = m_image.scaled(64, 64, Qt::KeepAspectRatio); + //m_image.save("testoutput.png"); + + free(pixelData); +} + +QImage ApiSurface::image() const +{ + return m_image; +} + +QImage ApiSurface::thumb() const +{ + return m_thumb; +} + +ApiTexture::ApiTexture() + : ApiSurface(), + m_unit(0), + m_level(0) +{ +} + +int ApiTexture::unit() const +{ + return m_unit; +} + +void ApiTexture::setUnit(int un) +{ + m_unit = un; +} + +QString ApiTexture::target() const +{ + return m_target; +} + +void ApiTexture::setTarget(const QString &str) +{ + m_target = str; +} + +int ApiTexture::level() const +{ + return m_level; +} + +void ApiTexture::setLevel(int l) +{ + m_level = l; +} diff --git a/gui/apisurface.h b/gui/apisurface.h new file mode 100644 index 0000000..50dd5d0 --- /dev/null +++ b/gui/apisurface.h @@ -0,0 +1,48 @@ +#ifndef APISURFACE_H +#define APISURFACE_H + +#include +#include +#include + +class ApiSurface +{ +public: + ApiSurface(); + + QSize size() const; + void setSize(const QSize &size); + + void contentsFromBase64(const QByteArray &base64); + + QImage image() const; + QImage thumb() const; + +private: + QSize m_size; + QImage m_image; + QImage m_thumb; +}; + + +class ApiTexture : public ApiSurface +{ +public: + ApiTexture(); + + int unit() const; + void setUnit(int un); + + int level() const; + void setLevel(int l); + + QString target() const; + void setTarget(const QString &str); + +private: + int m_unit; + int m_level; + QString m_target; +}; + +#endif diff --git a/gui/apitracecall.cpp b/gui/apitracecall.cpp index 1327283..70cc3f7 100644 --- a/gui/apitracecall.cpp +++ b/gui/apitracecall.cpp @@ -440,6 +440,47 @@ ApiTraceState::ApiTraceState(const QVariantMap &parsedJson) m_shaderSources.append( var[QLatin1String("source")].toString()); } + + QVariantList textureUnits = + parsedJson[QLatin1String("textures")].toList(); + for (int i = 0; i < textureUnits.count(); ++i) { + QVariantMap unit = textureUnits[i].toMap(); + QVariantMap::const_iterator itr; + for (itr = unit.constBegin(); itr != unit.constEnd(); ++itr) { + QVariantMap target = itr.value().toMap(); + if (target.count()) { + QVariantList levels = target[QLatin1String("levels")].toList(); + for (int j = 0; j < levels.count(); ++j) { + QVariantMap level = levels[j].toMap(); + QVariantMap image = level[QLatin1String("image")].toMap(); + QSize size(image[QLatin1String("__width__")].toInt(), + image[QLatin1String("__height__")].toInt()); + QString cls = image[QLatin1String("__class__")].toString(); + QString type = image[QLatin1String("__type__")].toString(); + int numChannels = + image[QLatin1String("__channels__")].toInt(); + QString encoding = + image[QLatin1String("__encoding__")].toString(); + + Q_ASSERT(numChannels == 4); + Q_ASSERT(encoding == QLatin1String("base64")); + Q_ASSERT(type == QLatin1String("float")); + + QByteArray dataArray = + image[QLatin1String("__data__")].toByteArray(); + + ApiTexture tex; + tex.setSize(size); + tex.setLevel(j); + tex.setUnit(i); + tex.setTarget(itr.key()); + tex.contentsFromBase64(dataArray); + + m_textures.append(tex); + } + } + } + } } QVariantMap ApiTraceState::parameters() const @@ -457,4 +498,9 @@ bool ApiTraceState::isEmpty() const return m_parameters.isEmpty(); } +QList ApiTraceState::textures() const +{ + return m_textures; +} + diff --git a/gui/apitracecall.h b/gui/apitracecall.h index 7af0e7d..94bd234 100644 --- a/gui/apitracecall.h +++ b/gui/apitracecall.h @@ -1,6 +1,8 @@ #ifndef APITRACECALL_H #define APITRACECALL_H +#include "apisurface.h" + #include #include #include @@ -109,10 +111,12 @@ public: bool isEmpty() const; QVariantMap parameters() const; QStringList shaderSources() const; + QList textures() const; private: QVariantMap m_parameters; QStringList m_shaderSources; + QList m_textures; }; class ApiTraceEvent -- 2.43.0