2 つのベクトルを含むライト パラメータの構造体を定義しました。構造体は、C++ と GLSL の両方で同様の方法で定義されます (注: s ではなくQVector3D
3 つの s をカプセル化します)。float
double
C++ ホスト プログラム:
struct LightParameters {
QVector3D pos;
QVector3D intensity;
};
フラグメント シェーダー:
struct LightParameters {
vec3 pos;
vec3 intensity;
};
フラグメント シェーダーでは、次のユニフォームも定義します。ライトの数は 8 に制限されているため、uniform 配列のサイズは一定です (ただし、numLights
実際に使用されるのは 1 つだけです)。
const int maxLights = 8;
uniform int numLights;
uniform LightParameters lights[maxLights];
ホスト プログラムでは、ライトを定義してシェーダーに渡します ( QGLShaderProgram
)。
static const int maxLights = 8;
LightParameters lights[maxLights];
int numLights = 1;
lights[0].pos = {0, 1, 0};
lights[0].intensity = {1, 1, 1};
shaderProgram->bind();
shaderProgram->setUniformValue("numLights", numLights);
shaderProgram->setUniformValueArray("lights", reinterpret_cast<GLfloat*>(lights), maxLights, 6);
shaderProgram->release();
最後のパラメーターの6
は、各配列要素がGLfloat
生の float 配列 (別名「タプル サイズ」) から 6 を使用することを示す必要があります。
Qt のドキュメントによると、6 のタプル サイズを使用することはできないはずです (1、2、3、4 のみが許可されています)。一方、QGLShaderProgram では、最大 4x4 のエントリを持つマトリックスを渡すことができます。GLSL では、4 つ以上の float を持つユニフォームの構造体も使用できます (この例によると)。
これは、次の質問につながります。
Qtを使用してフロート/ベクトルの構造体を均一な配列として渡すにはどうすればよいですか? Qt でできない場合は GL 関数を呼び出してこれを行いますが、Qt がこれを便利に実行できるかどうかに興味があります。
もちろん、とにかく上記のコードを試しました。構造体のすべてのベクトルが 0 に設定されます。
構造体の 2 番目のパラメーターを削除して 3 のタプル サイズを使用しても、コードは機能しません。ただし、vec3
シェーダーで使用するだけの場合 (ホスト プログラムで 1 つの QVector3D を持つ構造体、タプル サイズ = 3) は機能します。
したがって、OpenGL ホスト プログラム API ではカスタム タイプの処理が異なることが問題のようですが、Qt はそれをサポートしていないようです。現在、回避策として 2 つの一様な配列 (1 つは位置用、もう 1 つは強度用) を使用しています。