/// <summary> /// Link a <see cref="ShaderStorageBuffer"/> to this ShaderProgram. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for operations. /// </param> /// <param name="storageBufferName"> /// A <see cref="String"/> that specify the variable name in the shader source. /// </param> /// <param name="storageBuffer"> /// The <see cref="Buffer"/> to be linked to <paramref name="storageBufferName"/>. /// </param> public void SetStorageBuffer(GraphicsContext ctx, string storageBufferName, Buffer storageBuffer) { CheckCurrentContext(ctx); if (storageBufferName == null) { throw new ArgumentNullException(nameof(storageBufferName)); } CheckThisExistence(ctx); CheckThatExistence(ctx, storageBuffer); if (!ctx.Extensions.ShaderStorageBufferObject_ARB) { throw new InvalidOperationException("GL_ARB_shader_storage_buffer_object not supported"); } StorageBufferBinding storageBufferBinding; if (!_StorageBufferMap.TryGetValue(storageBufferName, out storageBufferBinding)) { throw new InvalidOperationException($"unrecognized storage buffer '{storageBufferName}'"); } // Bind to the most appropriate binding index IBindingIndexResource bindingIndexResource = storageBuffer; ctx.BindIndex(bindingIndexResource); // Avoid unnecessary glShaderStorageBlockBinding call //if (storageBufferBinding.BufferBinding == bindingIndexResource.BindingIndex) // return; Gl.ShaderStorageBlockBinding(ObjectName, storageBufferBinding.Index, bindingIndexResource.BindingIndex); storageBufferBinding.BufferBinding = bindingIndexResource.BindingIndex; }