2011-08-15 3 views
1

J'essaie de créer un objet tampon uniforme (UBO), et j'ai besoin de remplir le tableau avec des uniformes. La façon dont je le fais actuellement est avec une structure codée en dur.Comment créer un shader uniforme plus dynamique?

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

Puis-je utiliser Marshaling pour obtenir le tableau d'octets de cette structure, et je remplis mon UBO avec ce tableau.

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); 


     } 

je me demandais s'il y avait une façon plus dynamique de tenir l'information uniforme, sans avoir à utiliser System.Reflection pour créer la structure de la demande. Quand j'ai fait le fragment et les vertex shaders, j'ai pu utiliser une chaîne, puis GL.CreateShader() et GL.ShaderSource. Le seul mince que je peux penser est que ShaderType.GeometryShader est en fait le shader Uniform et il est label différemment.

Toutes les méthodes seraient appréciées, même si cela signifie le faire complètement différent. Si j'ai omis toute information, je m'excuse, et j'essaierai de l'ajouter sur demande.

+0

Je suis confus par beaucoup de choses dans cette question. Je ne comprends pas comment vous pouvez appeler glBufferData avant de lier l'objet tampon avec glBindBuffer. Le texte après votre code parle de création de shader, mais cela a très peu à voir avec les blocs uniformes. En fin de compte, OpenGL a été conçu pour C et C++, pas géré C#. C'est une API de bas niveau, donc beaucoup de parties nécessiteront des interactions qui ne sont pas naturelles pour C#. –

+0

Le mélange glBindBuffer/BufferData est une petite erreur de ma part. Je suppose que la meilleure question aurait été, "Quels sont tous les moyens de créer un objet uniforme?". Comme je ne veux pas avoir cette structure codée en dur. (Faire la modification dans le code fourni pour refléter le mélange tampon/liaison). – Zaneo

+0

"ShaderType.GeometryShader est en fait le shader uniforme", hein? Qu'est-ce que ça veut dire? Non, la géométrie shader n'est pas un autre terme pour un shader uniforme, qu'est-ce qu'un shader uniforme de toute façon? –

Répondre

0

Quels sont tous les moyens de créer un objet uniforme?

Il n'existe pas d'objet uniforme. Il n'y a que des objets tampon, qui peuvent être utilisés pour stocker des données uniformes. Ils peuvent également être utilisés pour stocker des données de vertex, des données de pixels et divers autres éléments. Mais ils sont tous du même type: objet buffer. Et vous les créez tous de la même manière.

Les moyens de fournir des données à un objet tampon sont assez simples. glBuffer (Sub) Data et glMapBuffer (Range). Votre problème n'est pas tant avec l'interface que C#, qui n'est pas une API native. Donc, vous devez sauter à travers les cerceaux pour télécharger vos données. Honnêtement, je suggère d'utiliser un peu de C++/CLI comme une interface pour gérer le téléchargement des données de votre objet tampon. Il est plus facile et moins verbeux de gérer les données dans les objets natifs que dans les objets gérés.

Questions connexes