2016-06-15 4 views
1

Lightデータを制服を介してFragment Shaderに送信しようとしています。私は次の関数の問題を抱えています:以下GPUに一様データを正しく送信する

void glUniform3fv(GLint location, GLsizei count, const GLfloat *value); 

することに(クラスのシェーダー '内の固定サイズの配列として格納)全てのライトデータを送信するために意図されている、私が書かれている機能ですフラグメントシェーダ: (注意:Vector3Fクラスは自分であり、必要であれば、私はそのソースを提供することができます。)

void Shader::updateLights() 
{ 
    // this->lights[x].getPosR() returns a Vector3F reference. Same with getLightDirectionR() and getColourR(). 
    glUniform3fv(this->uniforms[LIGHT1POS_U], 3, &(this->lights[0].getPosR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT1LD_U], 3, &(this->lights[0].getLightDirectionR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT1COLOUR_U], 3, &(this->lights[0].getColourR().getXR())); 
    glUniform1f(this->uniforms[LIGHT1POW_U], this->lights[0].getPowerR()); 

    glUniform3fv(this->uniforms[LIGHT2POS_U], 3, &(this->lights[1].getPosR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT2LD_U], 3, &(this->lights[1].getLightDirectionR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT2COLOUR_U], 3, &(this->lights[1].getColourR().getXR())); 
    glUniform1f(this->uniforms[LIGHT2POW_U], this->lights[1].getPowerR()); 

    glUniform3fv(this->uniforms[LIGHT3POS_U], 3, &(this->lights[2].getPosR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT3LD_U], 3, &(this->lights[2].getLightDirectionR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT3COLOUR_U], 3, &(this->lights[2].getColourR().getXR())); 
    glUniform1f(this->uniforms[LIGHT3POW_U], this->lights[2].getPowerR()); 

    glUniform3fv(this->uniforms[LIGHT3POS_U], 3, &(this->lights[3].getPosR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT3LD_U], 3, &(this->lights[3].getLightDirectionR().getXR())); 
    glUniform3fv(this->uniforms[LIGHT3COLOUR_U], 3, &(this->lights[3].getColourR().getXR())); 
    glUniform1f(this->uniforms[LIGHT3POW_U], this->lights[3].getPowerR()); 

    // Print out all the information to ensure that data is correct. 
    std::cout << "Lights Info:\n"; 
    for(unsigned int i = 0; i < Shader::MAX_LIGHTS; i++) 
    { 
     Light* l = &(this->lights[i]); 
     std::cout << "Light Id " << i << ": "; 
     std::cout << "Position = [" << l->getPosR().getX() << ", " << l->getPosR().getY() << ", " << l->getPosR().getZ() << "], "; 
     std::cout << "Light Direction = [" << l->getLightDirectionR().getX() << ", " << l->getLightDirectionR().getY() << ", " << l->getLightDirectionR().getZ() << "], "; 
     std::cout << "Light Colour = [" << l->getColourR().getX() << ", " << l->getColourR().getY() << ", " << l->getColourR().getZ() << "], "; 
     std::cout << "Light Power = " << l->getPowerR() << " Watts.\n"; 
    } 
} 

しかし、制服は空です!私の問題はconst GLfloat *valueの私の試みにあると確信しています。ライトデータはクラス本体に格納されているので、スコープが問題ではないと思います。

次のテキストブロックは、実行時に出力されます。

Light Id 0: Position = [0, 15, 0], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts. 
Light Id 1: Position = [5, 15, 10], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts 
Light Id 2: Position = [10, 15, 20], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts. 
Light Id 3: Position = [15, 15, 30], Light Direction = [0, -1, 1], Light Colour = [1, 1, 1], Light Power = 200 Watts. 

私は今までGLM :: vec3オブジェクトを経由して呼び出され、この関数を見てきましたので、私は私が十分な情報を提供していたことを自信を持っていませんでした3番目のパラメータ(私はXYZの代わりにVector3FのX値を送信するようにしか見えません)。私はすべてのデータが送信されていることを確認するために関数内に浮動小数点数のリストを作成しようとしましたが、範囲外になるとすぐにデータが失われ、ランタイムがクラッシュしました。私は本当にこのシナリオでヒープ割り当てを避けたいと思います。すべてのデータが正しく送信されるようにデータをフォーマットするにはどうすればよいでしょうか? My Fragmentシェーダが動作し、Light Dataが有効です(私はそれを見なければならない)が、シーンはピッチ・ブラックです。

+0

"*すべてのデータが送信されていることを確認するために関数内に浮動小数点数のリストを作成しようとしましたが、範囲外になるとデータが失われてランタイムがクラッシュします。関数が戻るまでにこのデータにアクセスすることができます。](http://stackoverflow.com/questions/15697861)このメモリは、呼び出しを超えて持続する必要はありません。 –

+0

@NicolBolas私はこれが当てはまるとは思っていませんでした。ありがとうございました! – Harrand

答えて

3
glUniform3fv(this->uniforms[LIGHT1POS_U], 3, &(this->lights[0].getPosR().getXR())); 

countパラメータが書き込まれて均一における配列要素の数ではなく、ベクトルの要素数です。すでにベクトルの要素数を知っています。つまり、関数名には3fの意味があります。

this->uniforms[LIGHT1POS_U]uniform vec3 name[3];と定義されていない場合、このコードは正しく機能しません。そのような呼び出しのたびにGL_INVALID_OPERATIONエラーが発生するはずです。

もちろん、これはすべてgetXRが返すものは、3つの浮動小数点数の配列に相当するものであることを前提としています。あなたが私たちにコードを見せても気にしなかったので、それ以上のことは言えません。

+0

ああ、私のところに悪い仮定。ありがとうございました。また、getXR()はベクトルのX値を返す単なる非定数関数ですが、もちろん間違っています。私は今、各トリオを独自のフロート配列に入れています。 – Harrand

関連する問題