2011-08-15 6 views
1

私は均一なバッファオブジェクト(UBO)を作成しようとしていますが、私はユニフォームで配列を埋める必要があります。私が現在やっているのは、ハードコーディングされた構造です。よりダイナミックな均一シェーダを作成するにはどうすればよいですか?

[Serializable,StructLayout(LayoutKind.Sequential, Pack = 1)] 
     public struct MaterialBlock 
     { 
      private Vector4 uniform; 
     }; 

次に、構造体からバイト配列を取得するためにマーシャリングを使用し、その配列でUBOを埋めます。

public void SetUniformShader(MaterialBlock block, int count) { 
      int maxSizeMaterialUniformBuffer; 
      int sizeMaterialBlock = Marshal.SizeOf(typeof (MaterialBlock)); 
      int sizeUniformInstance = sizeMaterialBlock*count; 
      int uniformInstancesPerBlock; 
      int numberOfBlocks; 
      int activeUniformBlocks; 
      byte[] mtlBuffer; 
      int uniformBlockIndex; 

      GL.GetActiveUniformBlock(ProgramId, 0, ActiveUniformBlockParameter.UniformBlockBinding, 
            out uniformBlockIndex); 
      GL.GetProgram(ProgramId, ProgramParameter.ActiveUniformBlocks, out activeUniformBlocks); 
      GL.GetInteger(GetPName.MaxUniformBlockSize, out maxSizeMaterialUniformBuffer); 


      uniformInstancesPerBlock = maxSizeMaterialUniformBuffer/sizeMaterialBlock; 
      numberOfBlocks = 
       (int) Math.Ceiling(((double) sizeUniformInstance/uniformInstancesPerBlock*sizeMaterialBlock)); 
      mtlBuffer = new byte[maxSizeMaterialUniformBuffer]; 

      IntPtr buffer = Marshal.AllocHGlobal(sizeMaterialBlock); 
      Marshal.StructureToPtr(block, buffer, false); 
      for (int i = 0; i < uniformInstancesPerBlock; i++) { 
       Marshal.Copy(buffer, mtlBuffer, i*sizeMaterialBlock, sizeMaterialBlock); 
      } 
      Marshal.FreeHGlobal(buffer); 
      GL.GenBuffers(1, out _iUniform); 
      GL.BindBuffer(BufferTarget.UniformBuffer, _iUniform); 
      GL.BufferData(BufferTarget.UniformBuffer, new IntPtr(sizeMaterialBlock), mtlBuffer, 
          BufferUsageHint.DynamicDraw); 


     } 

オンデマンド構造を作成するするSystem.Reflectionを使用することなく、均一な情報を保持するために、より動的な方法があった場合、私は思っていました。フラグメントと頂点シェーダを実行したときに、文字列を使用してからGL.CreateShader()とGL.ShaderSourceを使用できました。 ShaderType.GeometryShaderは実際には統一シェーダであり、ラベルは異なっています。

完全に異なることを意味していても、どのような方法でも理解できます。私が何らかの情報を残しておけば、謝罪し、要請に応じて追加しようとします。

+0

私はこの質問で多くのことを混乱しています。 glBindBufferでバッファオブジェクトをバインドする前にglBufferDataを呼び出す方法がわかりません。あなたのコードの後のテキストは、シェーダーの作成について語っていますが、それは統一ブロックとはほとんど関係がありません。結局のところ、OpenGLはCとC++用に設計されており、C#では管理されていませんでした。これは非常に低レベルのAPIなので、その多くの部分でC#の自然ではない相互作用が必要になります。 –

+0

glBindBuffer/BufferDataのミックスアップは、私の間違いです。私はもっ​​と良い質問があると思います。「均一なオブジェクトを作成するにはどうすればよいのですか?」私はそのハードコーディングされた構造を持つ必要はありません。 (バッファ/バインドミックスアップを反映するために提供されたコードを変更する)。 – Zaneo

+0

"ShaderType.GeometryShaderは実際には統一シェーダです"、そうですか?どう言う意味ですか?いいえ、ジオメトリシェーダは、統一シェーダの別の用語ではありません。とにかく均一シェーダは何ですか? –

答えて

0

均一なオブジェクトを作成するにはどうすればよいですか?

"均一なオブジェクト"のようなものはありません。均一なデータを格納するために使用できるバッファオブジェクトのみが存在します。頂点データ、ピクセルデータ、およびその他のさまざまなものを格納するために使用することもできます。しかし、それらはすべて同じオブジェクトタイプです。バッファオブジェクトです。そしてあなたはそれらをまったく同じように作ります。

バッファオブジェクトにデータを供給する方法はかなり簡単です。 glBuffer(Sub)データ、およびglMapBuffer(Range)を含む。あなたの問題は、ネイティブAPIではないC#ほどインターフェイスに問題がありません。だからあなたはデータをアップロードするためにフープを飛ばしなければなりません。

ちょっとC++/CLIをバッファオブジェクトデータのアップロードを処理するためのインターフェイスとして使用することをお勧めします。ネイティブオブジェクトのデータを管理対象オブジェクトよりも扱う方が簡単で簡単です。