2

編集: GLTextureUnitID を uint から int に変更したところ、エラーが表示されなくなりましたが、テクスチャの代わりに黒い四角がレンダリングされます。SetTexture の呼び出しをコメント アウトすると、その行の前にユニフォームを設定したことがなくても、正常にレンダリングされます。

Edit2: GLTextureUnitID の値は 1 ですが、設定されているテクスチャの ID は 0 です。

Edit3: SetTexture 関数を次のように変更すると、問題が解決したように見えますが、少し汚い解決策のように感じます。

GL.BindTexture(TextureTarget.Texture2D, (int)texture.GLTextureUnitID);
GL.Uniform1(GLTextureUnitLocation, 0);

元の質問: プロジェクトにテクスチャ ファイルのサポートを追加し始めましたが、テクスチャ シェーダ プログラムで GL.Uniform1 を呼び出すたびに、「InvalidOperation」エラーが発生します。さらに奇妙なことに、エラーの原因となった関数の呼び出しをコメントアウトしても、テクスチャは引き続きレンダリングされます。

テクスチャを含むクワッドがレンダリングされる RenderGUI 関数は次のとおりです。

    public override void RenderGUI()
    {
        // Translate Matrix to Position of GUI Element
        Matrices.Translate(SetMatrixParam.ModelViewMatrix, Position.X, Position.Y, 0);

        // Bind Shaders and Send Matrices
        Shader.Bind();
        Shader.SendMatrices();

        // Set Texture Information
        Shader.SetTexture(Texture); // <- This causes the error, it's just a call to Uniform1 using a property from the texture object, if commented out the error doesn't appear.
        Shader.SetTextureColor(Color4.White);

        GL.Begin(BeginMode.Triangles);

        // Render Quad
        Vector3 topLeft = new Vector3(0, 0, 0);
        Vector3 bottomLeft = new Vector3(0, Size.Y, 0);
        Vector3 topRight = new Vector3(Size.X, 0, 0);
        Vector3 bottomRight = new Vector3(Size.X, Size.Y, 0);

        Shader.SetTextureCoord(0, 0); GL.Vertex3(topLeft); // Top Left
        Shader.SetTextureCoord(0, 1); GL.Vertex3(bottomLeft); // Bottom Left
        Shader.SetTextureCoord(1, 1); GL.Vertex3(bottomRight); // Bottom Right

        Shader.SetTextureCoord(0, 0); GL.Vertex3(topLeft); // Top Left
        Shader.SetTextureCoord(1, 1); GL.Vertex3(bottomRight); // Bottom Right
        Shader.SetTextureCoord(1, 0); GL.Vertex3(topRight); // Top Right

        GL.End();
    }

そして、エラーが表示される原因となっている呼び出し中の関数:

    public void SetTexture(Texture2D texture)
    {
        if (texture.GLTextureUnitID == null)
            throw new ArgumentException();

        GL.Uniform1(GLTextureUnitLocation, (uint)texture.GLTextureUnitID);
    }

これは、このプロジェクトの github にもあります。Texture2Dクラスと、使用されている頂点およびフラグメントシェーダー、およびそれらのシェーダーを使用するシェーダー プログラムを処理するクラスと共に

4

2 に答える 2

1

テクスチャをプログラムのユニフォーム スロットにバインドするには、次のものが必要です。

  1. glGenTextures から返されるテクスチャの gl-name
  2. glGetUniformLocation から返された均一な位置
  3. テクスチャをバインドするテクスチャ ユニット (システムによって決定される必要があります。通常は、シェーダーにバインドするために必要なテクスチャの数によって異なります)

テクスチャ クラスで、テクスチャ ユニットと gl-name を混同していると思います。

以下は、テクスチャ バインディングの擬似コードです。

Int32 texunit = 0; // assume your shader only have 1 texture-type uniform
Shader.Bind();
GL.Uniform1( Shader.GetUniformLocation( "uniformName" ), texunit );
GL.ActiveTexture( texunit );
GL.BindTexture( TextureTarget.Texture2D, (int)tex.GLTextureUnitID ); // I recommend renaming tex.GLTextureUnitID to tex.GLName

お役に立てれば

于 2013-06-26T07:47:31.537 に答える