はじめに
Qtは組み込みシステムからOSSと様々なシーンで採用されています。それでも3DCGを扱えることを知る人は、Qtでプログラミングしてみた人以外はあまり知られていないと思います。
以前、Qtで3次元データのポイントクラウド(点群)を表示する方法を調べ、実装例をGitHubに公開していました。
下記の4つの環境で、それぞれ実装例を作ってます。
- Qt Quick 3D 6.6
- Qt Quick 3D 5.15.2
- Qt 3D 5.15.2
- Qt Quick 5.15.2 + OpenGL
この記事でまとめて紹介していきます。情報が少なく苦労したものもあります。誰かの役に立てば幸いです。
なお普段使っているmacOS環境ベースで書いています。Windows 11で動作しましたが確認したのは1年くらい前です。2023年11月時点での最新版の動作確認はしていません。
Qt Quick 3D 6.6 環境のポイントクラウド
Qt 6のQt Quick 3Dを使って、ポイントサイズを変更するサンプルアプリです。
Features
あとに記載するQt5では、QMLだけでポイントクラウドのポイントサイズを変えられませんでした。Qt6からQuick 3DのDefaultMaterial
のプロパティpointSize
を変更するだけで、ポイントの大きさを表示が変えられるようになりました。 ポイントの形状は正方形になります。
Model {
id: cube
geometry: PointCloudCubeGeometry {
pointCount: 10000
}
materials: [
DefaultMaterial {
lighting: DefaultMaterial.NoLighting
pointSize: Screen.devicePixelRatio * 5
vertexColorsEnabled: true
}
]
}
Screen.devicePixelRatio
をかけることで、普通のディスプレイと高画素密度のディスプレイの双方同じ見え方になります。
Requirement
- Qt Creator
- CMake
- Qt 6.6.0
Qt Quick 3D 5.15.2 環境のポイントクラウド
Qt 5.15.2のQt Quick 3Dを使って、ポイントサイズを擬似的に変更するサンプルアプリです。
Features
Qt5のQt Quick 3Dでは、PrimitiveTypeがポイントに設定した時のサイズを簡単に変更することができません。 Qt Quick 3Dのソースコードを調べてみると、シェーダーコンパイラにわたす前にglPointSize
を削除しているようでした。そこでポイントの代わりにビルボードを作成し、Shaderでポイントサイズが可変したかのように見せています。やっていることはパーティクルと同じかと思います。
C++のコードでは、トライアングル2枚を生成しています。座標はすべて同じにしていて、Vertex shaderでポイントサイズにあわせて座標を変更しています。Fragment shaderで円を描画しています。お好みの形やテクスチャを貼るように書き換えてもいいと思います。
for (int i = 0; i < m_fPointCount; ++i) {
float x = randomFloat(-5.0f, +5.0f);
float y = randomFloat(-5.0f, +5.0f);
float z = randomFloat(-5.0f, +5.0f);
// vertex
for (int j = 0; j < 4; ++j) {
*p++ = x;
*p++ = y;
*p++ = z;
*p++ = float(((j+1) >> 1) & 1); // Texture u
*p++ = float(( j >> 1) & 1); // Texture v
}
// index
*idx++ = i * 4;
*idx++ = i * 4 + 1;
*idx++ = i * 4 + 2;
*idx++ = i * 4;
*idx++ = i * 4 + 2;
*idx++ = i * 4 + 3;
}
in vec3 attr_pos;
in vec2 attr_uv0;
uniform mat4 modelViewProjection;
out vec3 pos;
out vec2 uv0;
void main() {
float sx = sin(pitch);
float cx = cos(pitch);
mat3 mx = mat3(
1.0, 0.0, 0.0,
0.0, cx, -sx,
0.0, sx, cx);
float sy = sin(yaw);
float cy = cos(yaw);
mat3 my = mat3(
cy, 0.0, sy,
0.0, 1.0, 0.0,
-sy, 0.0, cy);
pos = attr_pos;
uv0 = attr_uv0;
float x = (float((((gl_VertexID+1) / 2) % 2) * 2.0) - 1.0) * length;
float y = (float((( gl_VertexID / 2) % 2) * 2.0) - 1.0) * length;
gl_Position = modelViewProjection * vec4(pos + mx * my * vec3(x, y, 0.0), 1.0);
}
Requirement
- Qt Creator
- CMake
- Qt 5.15.2
Note
通常のポイントサイズは、Perspective/Orthographic(透視投影/平行投影)のいずれでも大きさは一定です。 このサンプルアプリは擬似的にサイズを変更しているため、透視射影ではカメラからの距離によってサイズが変わってしまいます。
Qt3D 5.15.2 環境のポイントクラウド
QtのQt3Dを使って、ポイントサイズを変更するサンプルアプリです。
Features
Qt5のQt3Dを用いて、ポイントクラウドのポイントサイズを変更する方法を示しています。 Qt6.xでも多少の変更で可能と考えられます。Qt3DはQt Quick 3Dと比べてより低レベルのためちょっと難しいですが、ほとんどをqmlで記述できました。
PointSize
で大きさを設定しています。Screen.devicePixelRatio
をかけることで、普通のディスプレイと高画素密度のディスプレイの双方同じ見え方になります。
...
components: [
RenderSettings {
activeFrameGraph: RenderSurfaceSelector {
ForwardRenderer {
clearColor: Qt.rgba(0.95, 1.0, 1.0, 1.0)
CameraSelector {
camera: root.perspective == true ? perspectiveCamera : orthographicCamera
RenderStateSet {
renderStates: [
PointSize {
sizeMode: PointSize.Fixed
// Common values are 1.0 on normal displays and 2.0 on Apple "retina" displays.
value: root.pointSize * Screen.devicePixelRatio
},
DepthTest {
depthFunction: DepthTest.Less
}
]
}
}
}
}
},
InputSettings {}
]
...
Requirement
- Qt Creator
- CMake
- Qt 5.15.2
Qt 5.15.2 GLSE 環境のポイントクラウド
Qt 5.15.2のOpenGLを使って、ポイントサイズを変更するサンプルアプリです。
Features
Qt5のOpenGLのglPointSize()
を使って変更しています。m_devicePixelRatio
をかけることで、普通のディスプレイと高画素密度のディスプレイの双方同じ見え方になります。
glPointSize(m_fPointSize * m_devicePixelRatio);
Requirement
- Qt Creator
- qmake
- Qt 5.15.2
Note
-
/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/System/Library/Frameworks/OpenGL.framework
xcode-select --install
でインストールしたSDKにはglPointSize
が定義されていました。 -
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/System/Library/Frameworks/OpenGL.framework
XcodeのからインストールするSDKにはglPointSizeがありませんでした。 環境設定、OSによってビルドに失敗するかもしれません。 -
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.sdk/System/Library/Frameworks/OpenGL.framework
まだ調べてません。 -
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX15.sdk/System/Library/Frameworks/OpenGL.framework
まだ調べてません。
Build Settings for M1 mac
M1 macではarm64とx86_64を明示的に指定する必要があります。 ビルド設定のCMake > CMAKE_OSX_ARCHITECTURESにx86_64と記述します。 Qt 5.15.4以降はarm64にサポート外ながら一応対応していてUniversal Binaryになります。Qt 6.xを使っているのであれば、何も気にする必要はありません。
おわりに
時間をかけて調べ上げましたが、色々あって使い道を失ってしまいました。ここの記事にすることで供養したいと思います。