Qt Quick 3D - プロシージャルテクスチャの例
C++ または QML からカスタムテクスチャデータを提供する方法を示します。
この例では、QQuick3DTextureData とthe textureData property of Texture を利用して、静的アセットから読み込むのではなく、実行時に動的に生成されるテクスチャデータを提供します。こ の演示のために、 こ の例では 2 つのグ ラデ ィ ン グ テ キ ス ト をそれぞれ C++ と QML で生成 し ます。
まず、テクスチャデータ用の C++ クラスを定義します。このクラスはQQuick3DTextureData のサブクラスで す。 仮想関数はないので、厳密には必要ではありませんが、すべてを1つのクラスにまとめたほうがずっと便利です。使用するプロパティを定義し、QML_NAMED_ELEMENT を追加して QML から利用できるようにします:
class GradientTexture : public QQuick3DTextureData { Q_OBJECT Q_PROPERTY(int height READ height WRITE setHeight NOTIFY heightChanged) Q_PROPERTY(int width READ width WRITE setWidth NOTIFY widthChanged) Q_PROPERTY(QColor startColor READ startColor WRITE setStartColor NOTIFY startColorChanged) Q_PROPERTY(QColor endColor READ endColor WRITE setEndColor NOTIFY endColorChanged) QML_NAMED_ELEMENT(GradientTexture) ...
テクスチャを更新する関数を追加します。setSize と setFormat を使ってテクスチャを設定し、 setTextureData を使って画像データを設定します:
void GradientTexture::updateTexture() { setSize(QSize(m_width, m_height)); setFormat(QQuick3DTextureData::RGBA8); setHasTransparency(false); setTextureData(generateTexture()); }
関数generateTexture
は正しいサイズのQByteArray を作成し、画像データで埋めます:
QByteArray GradientTexture::generateTexture() { QByteArray imageData; // Create a horizontal gradient between startColor and endColor // Create a single scanline and reuse that data for each QByteArray gradientScanline; gradientScanline.resize(m_width * 4); // RGBA8 for (int x = 0; x < m_width; ++x) { QColor color = linearInterpolate(m_startColor, m_endColor, x / float(m_width)); int offset = x * 4; gradientScanline.data()[offset + 0] = char(color.red()); gradientScanline.data()[offset + 1] = char(color.green()); gradientScanline.data()[offset + 2] = char(color.blue()); gradientScanline.data()[offset + 3] = char(255); } for (int y = 0; y < m_height; ++y) imageData += gradientScanline; return imageData; }
プロパティが変更されるたびにupdateTexture
を呼び出します:
void GradientTexture::setStartColor(QColor startColor) { if (m_startColor == startColor) return; m_startColor = startColor; emit startColorChanged(m_startColor); updateTexture(); }
最後に、QMLから新しいテクスチャを使うことができます:
Texture { id: textureFromCpp minFilter: applicationState.filterMode magFilter: applicationState.filterMode textureData: gradientTexture GradientTexture { id: gradientTexture startColor: applicationState.startColor endColor: applicationState.endColor width: applicationState.size height: width } }
同じテクスチャデータをQMLで生成することも可能です。この場合、ProceduralTextureData コンポーネントを使います:
Texture { id: textureFromQML minFilter: applicationState.filterMode magFilter: applicationState.filterMode textureData: gradientTextureDataQML ProceduralTextureData { id: gradientTextureDataQML property color startColor: applicationState.startColor property color endColor: applicationState.endColor width: applicationState.size height: width textureData: generateTextureData() function linearInterpolate(startColor : color, endColor : color, fraction : real) : color{ return Qt.rgba( startColor.r + (endColor.r - startColor.r) * fraction, startColor.g + (endColor.g - startColor.g) * fraction, startColor.b + (endColor.b - startColor.b) * fraction, startColor.a + (endColor.a - startColor.a) * fraction ); } function generateTextureData() { let dataBuffer = new ArrayBuffer(width * height * 4) let data = new Uint8Array(dataBuffer) let gradientScanline = new Uint8Array(width * 4); for (let x = 0; x < width; ++x) { let color = linearInterpolate(startColor, endColor, x / width); let offset = x * 4; gradientScanline[offset + 0] = color.r * 255; gradientScanline[offset + 1] = color.g * 255; gradientScanline[offset + 2] = color.b * 255; gradientScanline[offset + 3] = color.a * 255; } for (let y = 0; y < height; ++y) { data.set(gradientScanline, y * width * 4); } return dataBuffer; } } }
C++と同じように、テクスチャのサイズとフォーマットを反映した画像データをQByteArray 。QMLからこれを行う場合は、不要な型変換を避けるためにArrayBuffer型を使用します。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.