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.
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#. –
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
"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? –