summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datavisualization/data/customrenderitem.cpp18
-rw-r--r--src/datavisualization/data/qcustom3ditem.cpp2
-rw-r--r--src/datavisualization/engine/shaders/texture3d.frag136
-rw-r--r--src/datavisualization/engine/shaders/texture3dslice.frag27
-rw-r--r--tests/volumetrictest/cubeFilledFlat.obj54
-rw-r--r--tests/volumetrictest/main.cpp3
-rw-r--r--tests/volumetrictest/volumetrictest.cpp293
-rw-r--r--tests/volumetrictest/volumetrictest.h7
-rw-r--r--tests/volumetrictest/volumetrictest.qrc1
9 files changed, 413 insertions, 128 deletions
diff --git a/src/datavisualization/data/customrenderitem.cpp b/src/datavisualization/data/customrenderitem.cpp
index b96a4957..3eb68845 100644
--- a/src/datavisualization/data/customrenderitem.cpp
+++ b/src/datavisualization/data/customrenderitem.cpp
@@ -52,13 +52,17 @@ void CustomRenderItem::setMesh(const QString &meshFile)
void CustomRenderItem::setColorTable(const QVector<QRgb> &colors)
{
- m_colorTable.resize(colors.size());
- for (int i = 0; i < m_colorTable.size(); i++) {
- const QRgb &rgb = colors.at(i);
- m_colorTable[i] = QVector4D(float(qRed(rgb)) / 255.0f,
- float(qGreen(rgb)) / 255.0f,
- float(qBlue(rgb)) / 255.0f,
- float(qAlpha(rgb)) / 255.0f);
+ m_colorTable.resize(256);
+ for (int i = 0; i < 256; i++) {
+ if (i < colors.size()) {
+ const QRgb &rgb = colors.at(i);
+ m_colorTable[i] = QVector4D(float(qRed(rgb)) / 255.0f,
+ float(qGreen(rgb)) / 255.0f,
+ float(qBlue(rgb)) / 255.0f,
+ float(qAlpha(rgb)) / 255.0f);
+ } else {
+ m_colorTable[i] = QVector4D(0.0f, 0.0f, 0.0f, 0.0f);
+ }
}
}
diff --git a/src/datavisualization/data/qcustom3ditem.cpp b/src/datavisualization/data/qcustom3ditem.cpp
index 1d419cee..cb843b62 100644
--- a/src/datavisualization/data/qcustom3ditem.cpp
+++ b/src/datavisualization/data/qcustom3ditem.cpp
@@ -367,6 +367,7 @@ QString QCustom3DItem::textureFile() const
QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q) :
q_ptr(q),
+ m_textureImage(QImage(1, 1, QImage::Format_ARGB32)),
m_position(QVector3D(0.0f, 0.0f, 0.0f)),
m_positionAbsolute(false),
m_scaling(QVector3D(0.1f, 0.1f, 0.1f)),
@@ -382,6 +383,7 @@ QCustom3DItemPrivate::QCustom3DItemPrivate(QCustom3DItem *q, const QString &mesh
const QVector3D &position, const QVector3D &scaling,
const QQuaternion &rotation) :
q_ptr(q),
+ m_textureImage(QImage(1, 1, QImage::Format_ARGB32)),
m_meshFile(meshFile),
m_position(position),
m_positionAbsolute(false),
diff --git a/src/datavisualization/engine/shaders/texture3d.frag b/src/datavisualization/engine/shaders/texture3d.frag
index e56506ff..90876596 100644
--- a/src/datavisualization/engine/shaders/texture3d.frag
+++ b/src/datavisualization/engine/shaders/texture3d.frag
@@ -12,78 +12,90 @@ uniform highp int sampleCount; // This is the maximum sample count
const highp float alphaThreshold = 0.0001;
void main() {
- // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
-
- // Find out where ray intersects the object
highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
- highp vec3 invRayDir = 1.0 / rayDir;
- highp vec3 minCorner = vec3(-1.0);
- highp vec3 maxCorner = vec3(1.0);
- highp vec3 t1 = invRayDir * (minCorner - pos);
- highp vec3 t2 = invRayDir * (maxCorner - pos);
- highp vec3 tmin = min(t1, t2);
- highp vec3 tmax = max(t1, t2);
- highp vec2 t = max(tmin.xx, tmin.yz);
- t = min(tmax.xx, tmax.yz);
- float tFar = min(t.x, t.y);
- highp vec3 rayStart = pos;
+ vec3 rayStart = pos;
// Flip Y and Z so QImage bits work directly for texture and first image is in the front
+ rayDir.yz = -rayDir.yz;
rayStart.yz = -rayStart.yz;
- highp vec3 rayStop = pos + rayDir * tFar;
- rayStop.yz = -rayStop.yz;
-
- // Convert intersections to texture coords
- rayStart = 0.5 * (rayStart + 1.0);
- rayStop = 0.5 * (rayStop + 1.0);
-
- highp vec3 ray = rayStop - rayStart;
- highp float fullDist = length(ray);
- highp float rayX = abs(ray.x) * textureDimensions.x;
- highp float rayY = abs(ray.y) * textureDimensions.y;
- highp float rayZ = abs(ray.z) * textureDimensions.z;
-
- highp float maxRayDim = max(rayX, rayY);
- maxRayDim = max(maxRayDim, rayZ);
-
- highp vec3 step = ray / maxRayDim;
- highp float stepSize = abs(fullDist / maxRayDim);
-
- // Offset a fraction of a step so we are not exactly on a texel boundary.
- highp vec3 curPos = rayStart - (0.5 * step);
- // Adjust alpha multiplier according to the step size to get uniform alpha effect
- // regardless of the ray angle.
- highp float alphaMultiplier = stepSize / (1.0 / sampleCount);
+ // Calculate ray intersection endpoint
+ vec3 rayStop;
+ if (rayDir.x == 0.0) {
+ rayStop.yz = rayStart.yz;
+ rayStop.x = -rayStart.x;
+ } else if (rayDir.y == 0.0) {
+ rayStop.xz = rayStart.xz;
+ rayStop.y = -rayStart.y;
+ } else if (rayDir.z == 0.0) {
+ rayStop.xy = rayStart.xy;
+ rayStop.z = -rayStart.z;
+ } else {
+ highp vec3 boxBounds = vec3(1.0, 1.0, 1.0);
+ highp vec3 invRayDir = 1.0 / rayDir;
+ if (rayDir.x < 0)
+ boxBounds.x = -1.0;
+ if (rayDir.y < 0)
+ boxBounds.y = -1.0;
+ if (rayDir.z < 0)
+ boxBounds.z = -1.0;
+ highp vec3 t = (boxBounds - rayStart) * invRayDir;
+ highp float minT = min(t.x, t.y);
+ minT = min(minT, t.z);
+ rayStop = rayStart + minT * rayDir;
+ }
- highp float totalDist = 0.0;
- highp float totalAlpha = 0.0;
highp vec4 destColor = vec4(0, 0, 0, 0);
- highp vec4 curColor = vec4(0, 0, 0, 0);
- highp vec3 curRgb = vec3(0, 0, 0);
- highp float curAlpha = 0.0;
-
- for (int i = 0; i < sampleCount; i++) {
- curColor = texture3D(textureSampler, curPos);
- if (color8Bit != 0)
- curColor = colorIndex[int(curColor.r * 255.0)];
+ highp float totalAlpha = 0.0;
- if (curColor.a == 1.0)
- curAlpha = 1.0;
- else
- curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
- if (curAlpha > alphaThreshold) {
- curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
- destColor.rgb += curRgb;
- totalAlpha += curAlpha;
- }
- curPos += step;
- totalDist += stepSize;
- if (totalDist > fullDist || totalAlpha >= 1.0) {
- break;
+ if (rayStart != rayStop) {
+ // Convert intersections to texture coords
+ rayStart = 0.5 * (rayStart + 1.0);
+ rayStop = 0.5 * (rayStop + 1.0);
+
+ highp vec3 ray = rayStop - rayStart;
+ highp float fullDist = abs(length(ray));
+ highp float rayX = abs(ray.x) * textureDimensions.x;
+ highp float rayY = abs(ray.y) * textureDimensions.y;
+ highp float rayZ = abs(ray.z) * textureDimensions.z;
+ highp float maxRayDim = max(rayX, rayY);
+ maxRayDim = max(maxRayDim, rayZ);
+ int maxCount = int(floor(maxRayDim));
+
+ highp vec3 step = ray / maxRayDim;
+ highp float stepSize = fullDist / maxRayDim;
+
+ rayStart += (step * 0.001);
+ highp vec3 curPos = rayStart;
+
+ // Adjust alpha multiplier according to the step size to get uniform alpha effect
+ // regardless of the ray angle.
+ highp float alphaMultiplier = stepSize / (1.0 / sampleCount);
+
+ highp vec4 curColor = vec4(0, 0, 0, 0);
+ highp vec3 curRgb = vec3(0, 0, 0);
+ highp float curAlpha = 0.0;
+
+ // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
+ for (int i = 0; i < sampleCount; i++) {
+ curColor = texture3D(textureSampler, curPos);
+ if (color8Bit != 0)
+ curColor = colorIndex[int(curColor.r * 255.0)];
+
+ if (curColor.a == 1.0)
+ curAlpha = 1.0;
+ else
+ curAlpha = clamp(curColor.a * alphaMultiplier, 0.0, 1.0);
+ if (curAlpha > alphaThreshold) {
+ curRgb = curColor.rgb * curAlpha * (1.0 - totalAlpha);
+ destColor.rgb += curRgb;
+ totalAlpha += curAlpha;
+ }
+ if (i == maxCount || totalAlpha >= 1.0)
+ break;
+ curPos += step;
}
}
destColor.a = totalAlpha;
gl_FragColor = clamp(destColor, 0.0, 1.0);
}
-
diff --git a/src/datavisualization/engine/shaders/texture3dslice.frag b/src/datavisualization/engine/shaders/texture3dslice.frag
index e095bc5f..409ab41d 100644
--- a/src/datavisualization/engine/shaders/texture3dslice.frag
+++ b/src/datavisualization/engine/shaders/texture3dslice.frag
@@ -15,24 +15,27 @@ const highp vec3 zPlaneNormal = vec3(0, 0, 1.0);
const highp float alphaThreshold = 0.0001;
void main() {
- // Raytrace into volume, need to sample pixels along the eye ray until we hit opacity 1
-
// Find out where ray intersects the slice planes
highp vec3 rayDir = -(cameraPositionRelativeToModel - pos);
+ rayDir = normalize(rayDir);
highp vec3 rayStart = pos;
// Flip Y and Z so QImage bits work directly for texture and first image is in the front
rayStart.yz = -rayStart.yz;
rayDir.yz = -rayDir.yz;
- highp vec3 invRayDir = 1.0 / rayDir;
- highp vec3 minCorner = vec3(-1.0);
- highp vec3 maxCorner = vec3(1.0);
- highp vec3 t1 = invRayDir * (minCorner - rayStart);
- highp vec3 t2 = invRayDir * (maxCorner - rayStart);
- highp vec3 tmin = min(t1, t2);
- highp vec3 tmax = max(t1, t2);
- highp vec2 t = max(tmin.xx, tmin.yz);
- t = min(tmax.xx, tmax.yz);
- float tFar = min(t.x, t.y);
+ highp float tFar = 2.0f;
+ if (rayDir.x != 0.0 && rayDir.y != 0.0 && rayDir.z != 0.0) {
+ highp vec3 boxBounds = vec3(1.0, 1.0, 1.0);
+ highp vec3 invRayDir = 1.0 / rayDir;
+ if (rayDir.x < 0)
+ boxBounds.x = -1.0;
+ if (rayDir.y < 0)
+ boxBounds.y = -1.0;
+ if (rayDir.z < 0)
+ boxBounds.z = -1.0;
+ highp vec3 t = (boxBounds - rayStart) * invRayDir;
+ tFar = max(t.x, t.y);
+ tFar = max(tFar, t.z);
+ }
highp vec3 xPoint = vec3(volumeSliceIndices.x, 0, 0);
highp vec3 yPoint = vec3(0, volumeSliceIndices.y, 0);
diff --git a/tests/volumetrictest/cubeFilledFlat.obj b/tests/volumetrictest/cubeFilledFlat.obj
new file mode 100644
index 00000000..108cf7ac
--- /dev/null
+++ b/tests/volumetrictest/cubeFilledFlat.obj
@@ -0,0 +1,54 @@
+# Blender v2.66 (sub 0) OBJ File: 'cube_filled.blend'
+# www.blender.org
+o Cube
+v -1.000000 -1.000000 1.000000
+v -1.000000 -1.000000 -1.000000
+v 1.000000 -1.000000 -1.000000
+v 1.000000 -1.000000 1.000000
+v -1.000000 1.000000 1.000000
+v -1.000000 1.000000 -1.000000
+v 1.000000 1.000000 -1.000000
+v 1.000000 1.000000 1.000000
+vt 0.666667 0.332314
+vt 0.334353 0.333333
+vt 0.665647 0.000000
+vt 0.001020 0.333333
+vt 0.000000 0.001020
+vt 0.333333 0.332314
+vt 0.333333 0.665647
+vt 0.001019 0.666667
+vt 0.000000 0.334353
+vt 0.334353 0.666667
+vt 0.333333 0.334353
+vt 0.665647 0.333333
+vt 0.333333 0.667686
+vt 0.665647 0.666667
+vt 0.666667 0.998980
+vt 0.667686 0.333333
+vt 0.666667 0.001019
+vt 0.998980 0.000000
+vt 0.333333 0.001019
+vt 0.332314 0.000000
+vt 0.332314 0.333333
+vt 0.666667 0.665647
+vt 0.334353 1.000000
+vt 1.000000 0.332314
+vn -1.000000 0.000000 0.000000
+vn 0.000000 0.000000 -1.000000
+vn 1.000000 -0.000000 0.000000
+vn 0.000000 0.000000 1.000000
+vn 0.000000 1.000000 0.000000
+vn -0.000000 -1.000000 -0.000000
+s off
+f 5/1/1 6/2/1 1/3/1
+f 6/4/2 7/5/2 2/6/2
+f 7/7/3 8/8/3 4/9/3
+f 8/10/4 5/11/4 1/12/4
+f 8/13/5 7/14/5 6/15/5
+f 2/16/6 3/17/6 4/18/6
+f 6/2/1 2/19/1 1/3/1
+f 7/5/2 3/20/2 2/6/2
+f 3/21/3 7/7/3 4/9/3
+f 4/22/4 8/10/4 1/12/4
+f 5/23/5 8/13/5 6/15/5
+f 1/24/6 2/16/6 4/18/6
diff --git a/tests/volumetrictest/main.cpp b/tests/volumetrictest/main.cpp
index 46edf576..a15caf88 100644
--- a/tests/volumetrictest/main.cpp
+++ b/tests/volumetrictest/main.cpp
@@ -35,7 +35,7 @@ int main(int argc, char **argv)
QWidget *container = QWidget::createWindowContainer(graph);
QSize screenSize = graph->screen()->size();
- container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5));
+ container->setMinimumSize(QSize(screenSize.width() / 4, screenSize.height() / 4));
container->setMaximumSize(screenSize);
container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
container->setFocusPolicy(Qt::StrongFocus);
@@ -47,6 +47,7 @@ int main(int argc, char **argv)
hLayout->addLayout(vLayout);
widget->setWindowTitle(QStringLiteral("Volumetric TEST"));
+ widget->resize(QSize(screenSize.width() / 1.5, screenSize.height() / 1.5));
QCheckBox *sliceXCheckBox = new QCheckBox(widget);
sliceXCheckBox->setText(QStringLiteral("Slice volume on X axis"));
diff --git a/tests/volumetrictest/volumetrictest.cpp b/tests/volumetrictest/volumetrictest.cpp
index 04aad052..701cfc04 100644
--- a/tests/volumetrictest/volumetrictest.cpp
+++ b/tests/volumetrictest/volumetrictest.cpp
@@ -34,11 +34,14 @@ const int imageCount = 512;
VolumetricModifier::VolumetricModifier(Q3DScatter *scatter)
: m_graph(scatter),
m_volumeItem(0),
+ m_volumeItem2(0),
+ m_volumeItem3(0),
m_sliceIndexX(0),
m_sliceIndexY(0),
m_sliceIndexZ(0)
{
m_graph->activeTheme()->setType(Q3DTheme::ThemeQt);
+ //m_graph->activeTheme()->setType(Q3DTheme::ThemeIsabelle);
m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualityNone);
m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
m_graph->setOrthoProjection(true);
@@ -46,15 +49,27 @@ VolumetricModifier::VolumetricModifier(Q3DScatter *scatter)
createVolume();
createAnotherVolume();
+ createYetAnotherVolume();
+
+ m_plainItem = new QCustom3DItem;
+ QImage texture(2, 2, QImage::Format_ARGB32);
+ texture.fill(QColor(200, 200, 200, 130));
+ m_plainItem->setMeshFile(QStringLiteral(":/mesh"));
+ m_plainItem->setTextureImage(texture);
+ m_plainItem->setRotation(m_volumeItem->rotation());
+ m_plainItem->setPosition(m_volumeItem->position() + QVector3D(0.8f, 0.0f, 0.0f));
+ m_plainItem->setScaling(m_volumeItem->scaling());
m_graph->addCustomItem(m_volumeItem);
m_graph->addCustomItem(m_volumeItem2);
- m_graph->setMeasureFps(true);
+ m_graph->addCustomItem(m_volumeItem3);
+ m_graph->addCustomItem(m_plainItem);
+ //m_graph->setMeasureFps(true);
- QObject::connect(m_graph->scene()->activeCamera(), &Q3DCamera::zoomLevelChanged, this,
- &VolumetricModifier::handleZoomLevelChange);
QObject::connect(m_graph, &QAbstract3DGraph::currentFpsChanged, this,
&VolumetricModifier::handleFpsChange);
+// QObject::connect(m_graph->scene(), &Q3DScene::viewportChanged, this,
+// &VolumetricModifier::handleFpsChange);
}
VolumetricModifier::~VolumetricModifier()
@@ -121,26 +136,23 @@ void VolumetricModifier::adjustSliceZ(int value)
}
}
-void VolumetricModifier::handleZoomLevelChange()
-{
- // Zooming inside volumetric object causes ugly clipping issues, so restrict zoom level a bit
- if (m_graph->scene()->activeCamera()->zoomLevel() > 220)
- m_graph->scene()->activeCamera()->setZoomLevel(220);
-}
-
-void VolumetricModifier::handleFpsChange(qreal fps)
+void VolumetricModifier::handleFpsChange()
{
const QString fpsFormat = QStringLiteral("Fps: %1");
- int fps10 = int(fps * 10.0);
+ int fps10 = int(m_graph->currentFps() * 10.0);
m_fpsLabel->setText(fpsFormat.arg(QString::number(qreal(fps10) / 10.0)));
+// const QString sceneDimensionsFormat = QStringLiteral("%1 x %2");
+// m_fpsLabel->setText(sceneDimensionsFormat
+// .arg(m_graph->scene()->viewport().width())
+// .arg(m_graph->scene()->viewport().height()));
}
void VolumetricModifier::createVolume()
{
m_volumeItem = new QCustom3DVolume;
m_volumeItem->setTextureFormat(QImage::Format_ARGB32);
- m_volumeItem->setRotation(QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 0.0f, 10.0f));
- m_volumeItem->setPosition(QVector3D(-0.5f, 0.0f, 0.0f));
+// m_volumeItem->setRotation(QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 0.0f, 10.0f));
+ m_volumeItem->setPosition(QVector3D(-0.5f, 0.6f, 0.0f));
QImage logo;
logo.load(QStringLiteral(":/logo.png"));
@@ -161,10 +173,24 @@ void VolumetricModifier::createVolume()
m_sliceIndexZ = m_volumeItem->textureWidth() / 2;
QVector<QRgb> colorTable = m_volumeItem->colorTable();
+
+ // Hack some alpha to the picture
+ for (int i = 0; i < colorTable.size(); i++) {
+ if (qAlpha(colorTable.at(i)) > 0) {
+ colorTable[i] = qRgba(qRed(colorTable.at(i)),
+ qGreen(colorTable.at(i)),
+ qBlue(colorTable.at(i)),
+ 50);
+ }
+ }
+
+ colorTable.append(qRgba(0, 0, 0, 0));
colorTable.append(qRgba(255, 0, 0, 255));
colorTable.append(qRgba(0, 255, 0, 255));
colorTable.append(qRgba(0, 0, 255, 255));
+
m_volumeItem->setColorTable(colorTable);
+ int alphaIndex = colorTable.size() - 4;
int redIndex = colorTable.size() - 3;
int greenIndex = colorTable.size() - 2;
int blueIndex = colorTable.size() - 1;
@@ -173,18 +199,44 @@ void VolumetricModifier::createVolume()
int depth = m_volumeItem->textureDepth();
int frameSize = width * height;
qDebug() << width << height << depth << m_volumeItem->textureData()->size();
- m_volumeItem->setScaling(QVector3D(float(width) / float(depth) * 2.0f,
- float(height) / float(depth) * 2.0f,
- 2.0f));
+// m_volumeItem->setScaling(QVector3D(float(width) / float(depth) * 2.0f,
+// float(height) / float(depth) * 2.0f,
+// 2.0f));
+ m_volumeItem->setScaling(QVector3D(0.4f, 0.4f, 0.4f));
uchar *data = m_volumeItem->textureData()->data();
uchar *p = data;
// Change one picture using subtexture replacement
- QImage flipped = logo.mirrored();
- m_volumeItem->setSubTextureData(101, flipped);
+// QImage flipped = logo.mirrored();
+// m_volumeItem->setSubTextureData(101, flipped);
+ // Clean up the two extra pixels
+ p = data + width - 1;
+ for (int k = 0; k < depth; k++) {
+ for (int j = 0; j < height; j++) {
+ *p = alphaIndex;
+ p += width;
+ }
+ }
+ p = data + width - 2;
+ for (int k = 0; k < depth; k++) {
+ for (int j = 0; j < height; j++) {
+ *p = alphaIndex;
+ p += width;
+ }
+ }
// Red first subtexture
+ p = data;
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ *p = redIndex;
+ p++;
+ }
+ }
+
+ // Red last subtexture
+// p = data + frameSize * (imageCount - 1);
// for (int j = 0; j < height; j++) {
// for (int i = 0; i < width; i++) {
// *p = redIndex;
@@ -192,45 +244,43 @@ void VolumetricModifier::createVolume()
// }
// }
- // Red last subtexture
- p = data + frameSize * (imageCount - 1);
- for (int j = 0; j < height; j++) {
- for (int i = 0; i < width; i++) {
- *p = redIndex;
- p++;
- }
- }
+// // Blue second to last subtexture
+// p = data + frameSize * (imageCount - 2);
+// for (int j = 0; j < height; j++) {
+// for (int i = 0; i < width; i++) {
+// *p = blueIndex;
+// p++;
+// }
+// }
// Blue x = 0
- p = data;
+// p = data;
+// for (int k = 0; k < depth; k++) {
+// for (int j = 0; j < height; j++) {
+// *p = blueIndex;
+// p += width;
+// }
+// }
+
+ // Blue x = max
+ p = data + width - 1;
for (int k = 0; k < depth; k++) {
for (int j = 0; j < height; j++) {
*p = blueIndex;
p += width;
}
}
-
- // Blue x = max
- p = data + width - 1;
+ // green x = max - 1
+ p = data + width - 2;
for (int k = 0; k < depth; k++) {
for (int j = 0; j < height; j++) {
- *p = blueIndex;
+ *p = greenIndex;
p += width;
}
}
// Green y = 0
-// p = data;
-// for (int k = 0; k < depth; k++) {
-// for (int i = 0; i < width; i++) {
-// *p = greenIndex;
-// p++;
-// }
-// p += (frameSize - width);
-// }
-
- // Green y = max
- p = data + frameSize - width;
+ p = data;
for (int k = 0; k < depth; k++) {
for (int i = 0; i < width; i++) {
*p = greenIndex;
@@ -238,13 +288,23 @@ void VolumetricModifier::createVolume()
}
p += (frameSize - width);
}
+
+ // Green y = max
+// p = data + frameSize - width;
+// for (int k = 0; k < depth; k++) {
+// for (int i = 0; i < width; i++) {
+// *p = greenIndex;
+// p++;
+// }
+// p += (frameSize - width);
+// }
}
void VolumetricModifier::createAnotherVolume()
{
m_volumeItem2 = new QCustom3DVolume;
m_volumeItem2->setTextureFormat(QImage::Format_ARGB32);
- m_volumeItem2->setPosition(QVector3D(0.5f, 0.0f, 0.0f));
+ m_volumeItem2->setPosition(QVector3D(0.5f, -0.5f, 0.0f));
QImage logo;
logo.load(QStringLiteral(":/logo.png"));
@@ -280,3 +340,148 @@ void VolumetricModifier::createAnotherVolume()
m_volumeItem2->setSubTextureData(101, flipped);
}
+void VolumetricModifier::createYetAnotherVolume()
+{
+ m_volumeItem3 = new QCustom3DVolume;
+ m_volumeItem3->setTextureFormat(QImage::Format_Indexed8);
+// m_volumeItem2->setRotation(QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 0.0f, 10.0f));
+ m_volumeItem3->setPosition(QVector3D(-0.5f, -0.6f, 0.0f));
+
+// m_volumeItem3->setTextureDimensions(m_volumeItem->textureDataWidth(),
+// m_volumeItem->textureHeight(),
+// m_volumeItem->textureDepth());
+ m_volumeItem3->setTextureDimensions(200, 200, 200);
+
+ QVector<uchar> *tdata = new QVector<uchar>(m_volumeItem3->textureDataWidth()
+ * m_volumeItem3->textureHeight()
+ * m_volumeItem3->textureDepth());
+ tdata->fill(0);
+ m_volumeItem3->setTextureData(tdata);
+
+ m_sliceIndexX = m_volumeItem3->textureWidth() / 2;
+ m_sliceIndexY = m_volumeItem3->textureWidth() / 2;
+ m_sliceIndexZ = m_volumeItem3->textureWidth() / 2;
+
+ QVector<QRgb> colorTable = m_volumeItem->colorTable();
+ colorTable[0] = qRgba(0, 0, 0, 0);
+ m_volumeItem3->setColorTable(colorTable);
+ int redIndex = colorTable.size() - 3;
+ int greenIndex = colorTable.size() - 2;
+ int blueIndex = colorTable.size() - 1;
+ int width = m_volumeItem3->textureDataWidth();
+ int height = m_volumeItem3->textureHeight();
+ int depth = m_volumeItem3->textureDepth();
+ int frameSize = width * height;
+ qDebug() << width << height << depth << m_volumeItem3->textureData()->size();
+ m_volumeItem3->setScaling(m_volumeItem->scaling());
+
+ uchar *data = tdata->data();
+ uchar *p = data;
+
+ // Red first subtexture
+// for (int j = 0; j < height; j++) {
+// for (int i = 0; i < width; i++) {
+// *p = redIndex;
+// p++;
+// }
+// }
+
+ // Red last subtexture
+ p = data + frameSize * (depth - 1);
+ for (int j = 0; j < height; j++) {
+ for (int i = 0; i < width; i++) {
+ *p = redIndex;
+ p++;
+ }
+ }
+
+ // green edge
+ p = data + frameSize * (depth - 1);
+ for (int i = 0; i < width; i++) {
+ *p = greenIndex;
+ p++;
+ }
+ for (int j = 2; j < height; j++) {
+ *p = greenIndex;
+ p += width - 1;
+ *p = j % 7 ? greenIndex : blueIndex;
+ p++;
+ }
+ for (int i = 0; i < width; i++) {
+ *p = greenIndex;
+ p++;
+ }
+
+// // Blue second to last subtexture
+// p = data + frameSize * (depth - 2);
+// for (int j = 0; j < height; j++) {
+// for (int i = 0; i < width; i++) {
+// *p = blueIndex;
+// p++;
+// }
+// }
+
+// // green third to last subtexture
+// p = data + frameSize * (depth - 3);
+// for (int j = 0; j < height; j++) {
+// for (int i = 0; i < width; i++) {
+// *p = greenIndex;
+// p++;
+// }
+// }
+
+ // Blue x = 0
+ p = data;
+ for (int k = 0; k < depth; k++) {
+ for (int j = 0; j < height; j++) {
+ *p = blueIndex;
+ p += width;
+ }
+ }
+
+// // Blue x = max
+// p = data + width - 1;
+// for (int k = 0; k < depth; k++) {
+// for (int j = 0; j < height; j++) {
+// *p = blueIndex;
+// p += width;
+// }
+// }
+
+ // Green y = 0
+// p = data;
+// for (int k = 0; k < depth; k++) {
+// for (int i = 0; i < width; i++) {
+// *p = greenIndex;
+// p++;
+// }
+// p += (frameSize - width);
+// }
+
+// // Green y = max
+ p = data + frameSize - width;
+ for (int k = 0; k < depth; k++) {
+ for (int i = 0; i < width; i++) {
+ *p = greenIndex;
+ p++;
+ }
+ p += (frameSize - width);
+ }
+
+
+// // Fill with alternating pixels
+// p = data;
+// for (int k = 0; k < (depth * width * height / 4); k++) {
+// *p = greenIndex;
+// p++;
+// *p = greenIndex;
+// p++;
+// *p = blueIndex;
+// p++;
+// *p = redIndex;
+// p++;
+// }
+
+
+}
+
diff --git a/tests/volumetrictest/volumetrictest.h b/tests/volumetrictest/volumetrictest.h
index 677a1231..40d88192 100644
--- a/tests/volumetrictest/volumetrictest.h
+++ b/tests/volumetrictest/volumetrictest.h
@@ -21,6 +21,7 @@
#include <QtDataVisualization/q3dscatter.h>
#include <QtDataVisualization/qcustom3dvolume.h>
+#include <QtDataVisualization/qcustom3ditem.h>
class QLabel;
@@ -42,16 +43,18 @@ public slots:
void adjustSliceX(int value);
void adjustSliceY(int value);
void adjustSliceZ(int value);
- void handleZoomLevelChange();
- void handleFpsChange(qreal fps);
+ void handleFpsChange();
private:
void createVolume();
void createAnotherVolume();
+ void createYetAnotherVolume();
Q3DScatter *m_graph;
QCustom3DVolume *m_volumeItem;
QCustom3DVolume *m_volumeItem2;
+ QCustom3DVolume *m_volumeItem3;
+ QCustom3DItem *m_plainItem;
int m_sliceIndexX;
int m_sliceIndexY;
int m_sliceIndexZ;
diff --git a/tests/volumetrictest/volumetrictest.qrc b/tests/volumetrictest/volumetrictest.qrc
index 90517ff1..5b9623f0 100644
--- a/tests/volumetrictest/volumetrictest.qrc
+++ b/tests/volumetrictest/volumetrictest.qrc
@@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/">
<file>logo.png</file>
+ <file alias="mesh">cubeFilledFlat.obj</file>
</qresource>
</RCC>