Esempio n. 1
0
        public void RenderLight <T>(GameObject root, int vertsperdraw) where T : Light
        {
            int number = root.GetCount <T>();

            if (number > 0)
            {
                float[] data  = null;
                int     index = 0;
                root.Foreach <T>((GameObject go, T dl) => {
                    if (index == 0)
                    {
                        data = new float[number * dl.Data.Length];
                    }
                    float[] lightdata = dl.Data;
                    for (int j = 0; j < lightdata.Length; j++)
                    {
                        data[index] = lightdata[j];
                        index++;
                    }
                });

                GL.BindBuffer(BufferTarget.UniformBuffer, buffer);
                GL.BufferData(BufferTarget.UniformBuffer, data.Length * sizeof(float), data, BufferUsageHint.StreamDraw);

                GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, buffer);
                GL.DrawArraysInstanced(PrimitiveType.Triangles, 0, vertsperdraw, number);
            }
        }
        //-----------------------------------------------------------------------------------------
        //Our rendering function
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            GL.Enable(EnableCap.Blend);
            GL.BlendEquation(BlendEquationMode.FuncAdd);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            //           Matrix4 mvp = _projectionMatrix * ... * Matrix4.Identity;
            //Matrix4 mvp = GetTransform();
            //mvp.Transpose();

            GL.BindBuffer(BufferTarget.UniformBuffer, Buffers.Name(Buffers.Type.TRANSFORM));
            //GL.BufferSubData( BufferTarget.UniformBuffer, IntPtr.Zero, (IntPtr)(sizeof(float) * 16), ref mvp.Row0.X );
            GL.BufferSubData(BufferTarget.UniformBuffer, IntPtr.Zero, (IntPtr)(sizeof(float) * 16), GetTransform());

            uint data = 0;

            GL.BindBuffer(BufferTarget.AtomicCounterBuffer, Buffers.Name(Buffers.Type.ATOMIC_COUNTER));
            GL.ClearBufferSubData(BufferTarget.AtomicCounterBuffer, PixelInternalFormat.R8ui, IntPtr.Zero, (IntPtr)sizeof(uint),
                                  PixelFormat.Rgba, All.UnsignedInt, (IntPtr)data);

            GL.ViewportIndexed(0, 0, 0, ClientRectangle.X, ClientRectangle.Y);
            GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });

            GL.UseProgram(_programName);
            GL.BindVertexArray(_vertexArrayName);
            GL.BindBufferBase(BufferRangeTarget.AtomicCounterBuffer, 0, Buffers.Name(Buffers.Type.ATOMIC_COUNTER));
            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, (int)Bindings.TRANSFORM0, Buffers.Name(Buffers.Type.TRANSFORM));

            GL.DrawElementsInstancedBaseVertexBaseInstance(PrimitiveType.Triangles, _ElementData.Length,
                                                           DrawElementsType.UnsignedShort, (IntPtr)0,
                                                           5, 0, 0);
            SwapBuffers();
        }
Esempio n. 3
0
 public void Createssbo(ref int ssbo, float[] data, int bind)
 {
     ssbo = GL.GenBuffer();
     GL.BindBuffer(BufferTarget.ShaderStorageBuffer, ssbo);
     GL.BufferData <float>(BufferTarget.ShaderStorageBuffer, data.Length * 4, data, BufferUsageHint.DynamicDraw);
     GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, bind, ssbo);
 }
Esempio n. 4
0
        private void BindConstBuffers(GalPipelineState New)
        {
            int FreeBinding = OGLShader.ReservedCbufCount;

            void BindIfNotNull(OGLShaderStage Stage)
            {
                if (Stage != null)
                {
                    foreach (ShaderDeclInfo DeclInfo in Stage.ConstBufferUsage)
                    {
                        long Key = New.ConstBufferKeys[(int)Stage.Type][DeclInfo.Cbuf];

                        if (Key != 0 && Buffer.TryGetUbo(Key, out int UboHandle))
                        {
                            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, FreeBinding, UboHandle);
                        }

                        FreeBinding++;
                    }
                }
            }

            BindIfNotNull(Shader.Current.Vertex);
            BindIfNotNull(Shader.Current.TessControl);
            BindIfNotNull(Shader.Current.TessEvaluation);
            BindIfNotNull(Shader.Current.Geometry);
            BindIfNotNull(Shader.Current.Fragment);
        }
Esempio n. 5
0
        public void Bind(int program)
        {
            int blockIndex = GL.GetUniformBlockIndex(program, name);

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, port, Handle);
            GL.UniformBlockBinding(program, blockIndex, port);
        }
Esempio n. 6
0
        public Camera()
        {
            gl = GL.GetApi();
            Program.Window.OnResize += OnResize;

            //Program.Window.OnCursorMove += OnCursorMove;
            //MovementController = new MovementControllerWASD(2.5f, GetDirection);

            Position = new vec3(0, 0, 3);

            matricesBuffer = gl.CreateBuffer();
            gl.BindBuffer(BufferTargetARB.UniformBuffer, matricesBuffer);
            gl.BufferData(BufferTargetARB.UniformBuffer, (uint)(3 * sizeof(mat4)), null, BufferUsageARB.StaticDraw);
            gl.BindBufferBase(BufferTargetARB.UniformBuffer, 0, matricesBuffer);

            Size  windowSize  = Program.Window.GetSize();
            float aspectRatio = (float)windowSize.Height / (float)windowSize.Width;
            float orthoSize   = 5f;
            mat4  orthoMatrix = mat4.Ortho(-orthoSize, orthoSize, -orthoSize * aspectRatio, orthoSize * aspectRatio, NearZ, FarZ);

            ProjectionMatrix = mat4.PerspectiveFov(Util.ToRad(Fov), windowSize.Width, windowSize.Height, NearZ, FarZ);
            var pm = ProjectionMatrix;

            gl.BufferSubData(BufferTargetARB.UniformBuffer, 0, (uint)sizeof(mat4), &pm);
            gl.BufferSubData(BufferTargetARB.UniformBuffer, sizeof(mat4), (uint)sizeof(mat4), &orthoMatrix);
        }
Esempio n. 7
0
 /// <summary>
 /// Binds <see cref="GLObject.Id"/> to an indexed buffer target.
 /// </summary>
 /// <param name="target">The target for the bind</param>
 /// <param name="index">The index of the binding point</param>
 public void BindBase(BufferRangeTarget target, int index)
 {
     if (index != -1)
     {
         GL.BindBufferBase(target, index, Id);
     }
 }
Esempio n. 8
0
 public void Rebind()
 {
     if (_implUBO != null)
     {
         GL.BindBufferBase(BufferRangeTarget.UniformBuffer, _index, (int)_implUBO !.ObjectHandle);
     }
 }
Esempio n. 9
0
        public void bindBuffer(int index, string name, int uboIndex, BufferRangeTarget Target)
        {
            int uniformBlockIndex = GL.GetUniformBlockIndex(_program, name);

            GL.BindBufferBase(Target, index, uboIndex);
            GL.UniformBlockBinding(_program, uniformBlockIndex, index);
        }
Esempio n. 10
0
        //-----------------------------------------------------------------------------------------
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            float currentTime = (float)Program.ElapsedTimeSeconds;

            GL.Viewport(0, 0, Width, Height);
            GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit
                             | MemoryBarrierFlags.AtomicCounterBarrierBit
                             | MemoryBarrierFlags.ShaderStorageBarrierBit);

            GL.UseProgram(_shaderPrograms.Clear);
            GL.BindVertexArray(_vao);
            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);

            GL.UseProgram(_shaderPrograms.Append);

            Matrix4 modelMatrix  = Matrix4.CreateScale(7.0f);
            Vector3 viewPosition = new Vector3((float)Math.Cos(currentTime * 0.35f) * 120.0f,
                                               (float)Math.Cos(currentTime * 0.4f) * 30.0f,
                                               (float)Math.Sin(currentTime * 0.35f) * 120.0f);
            Matrix4 viewMatrix = Matrix4.LookAt(viewPosition,
                                                new Vector3(0.0f, 30.0f, 0.0f),
                                                new Vector3(0.0f, 1.0f, 0.0f));
            Matrix4 projMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(50.0f),
                                                                      (float)Width / (float)Height,
                                                                      0.1f, 1000.0f);
            Matrix4 mvpMatrix = modelMatrix * viewMatrix * projMatrix;

            GL.UniformMatrix4(_uniformNames.mvp, false, ref mvpMatrix);

            uint zero = 0;

            GL.BindBufferBase(BufferRangeTarget.AtomicCounterBuffer, 0, _buffers.AtomicCounter);
            GL.BufferSubData(BufferTarget.AtomicCounterBuffer, IntPtr.Zero, (IntPtr)sizeof(uint), ref zero);

            GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _buffers.Fragment);

            GL.BindImageTexture(0, _textures.HeadPointerImage, 0, false, 0,
                                TextureAccess.ReadWrite, SizedInternalFormat.R32ui);

            GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit
                             | MemoryBarrierFlags.AtomicCounterBarrierBit
                             | MemoryBarrierFlags.ShaderStorageBarrierBit);

            _models.Dragon.Render();

            GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit
                             | MemoryBarrierFlags.AtomicCounterBarrierBit
                             | MemoryBarrierFlags.ShaderStorageBarrierBit);

            GL.UseProgram(_shaderPrograms.Resolve);

            GL.BindVertexArray(_vao);
            GL.MemoryBarrier(MemoryBarrierFlags.ShaderImageAccessBarrierBit
                             | MemoryBarrierFlags.AtomicCounterBarrierBit
                             | MemoryBarrierFlags.ShaderStorageBarrierBit);

            GL.DrawArrays(PrimitiveType.TriangleStrip, 0, 4);

            SwapBuffers();
        }
Esempio n. 11
0
        public void SquishGrassSwing(Vector4 swinger)
        {
            if (!TheClient.CVars.r_compute.ValueB)
            {
                return;
            }
            Location spos    = new Location(swinger.X, swinger.Y, swinger.Z);
            double   maxdist = (swinger.W + Chunk.CHUNK_SIZE) * (swinger.W + Chunk.CHUNK_SIZE) * 4;

            GL.UseProgram(Shader_Compute_Grass_Swing);
            foreach (Chunk chk in LoadedChunks.Values)
            {
                Location cwor = chk.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE;
                Location wpos = cwor + new Location(Chunk.CHUNK_SIZE * 0.5);
                if (chk.Plant_C > 0 && chk.Plant_VAO > 0 && wpos.DistanceSquared(spos) < maxdist)
                {
                    Location relp = spos - cwor;
                    GL.Uniform1(11, (uint)chk.Plant_C);
                    GL.Uniform4(12, new Vector4(ClientUtilities.Convert(relp), swinger.W));
                    GL.Uniform1(13, (float)GlobalTickTimeLocal);
                    GL.Uniform1(14, (float)Delta);
                    GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, chk.Plant_VBO_Pos);
                    GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, chk.Plant_VBO_Tcs);
                    GL.DispatchCompute(chk.Plant_C / 90 + 1, 1, 1);
                }
            }
            GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 1, 0);
            GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 2, 0);
            GraphicsUtil.CheckError("Squishing Grass");
        }
Esempio n. 12
0
        public void ActivateBind(int index)
        {
            Activate();
            BufferRangeTarget target = (BufferRangeTarget)BufferTarget;

            GL.BindBufferBase​(target, index, _bufferId);
        }
Esempio n. 13
0
        public void SetBuffer(uint index, IBuffer buffer)
        {
            if (transformFeedbackBuffers[index] == buffer)
            {
                return;
            }
            context.Bindings.TransformFeedback.Set(this);
            GL.BindBufferBase((int)BufferTarget.TransformFeedback, index, buffer.SafeGetHandle());
            transformFeedbackBuffers[index] = buffer;

            if (buffer != null)
            {
                if (index >= enabledBufferRange)
                {
                    enabledBufferRange = index + 1;
                }
            }
            else
            {
                if (index == enabledBufferRange - 1)
                {
                    while (enabledBufferRange > 0 && transformFeedbackBuffers[enabledBufferRange - 1] == null)
                    {
                        enabledBufferRange--;
                    }
                }
            }
        }
Esempio n. 14
0
        private void BindOrCreateShaderUniform(ref DrawCommand command)
        {
            // If the uniform was already buffered, we'll just reuse that buffered uniform
            // Currently these material uniforms never change at runtime - if this changes
            // there will have to be some sort of invalidation to ensure they're updated
            if (command.ShaderUniformHandle != -1)
            {
                if (command.ShaderUniformHandle != currentlyBoundShaderUniform)
                {
                    GL.BindBufferBase(BufferRangeTarget.UniformBuffer, UniformIndices.Shader, command.ShaderUniformHandle);
                }
            }
            else
            {
                if (MaterialUniforms.TryGetValue(command.Mesh.Material, out var uniforms) == false)
                {
                    uniforms = new int[(int)Shader.MAX_VALUE];
                    MaterialUniforms[command.Mesh.Material] = uniforms;
                }

                var bindings = SetupTextures(command.Mesh.Material);
                command.ShaderUniformHandle = GenerateShaderUniform(command, bindings);
                uniforms[(int)activeShader] = command.ShaderUniformHandle;
            }
        }
Esempio n. 15
0
 public override void Bind()
 {
     base.Bind();
     //
     Debug.Assert(UniformBufferBlockIndex != -1);
     GL.BindBufferBase(BufferRangeTarget.UniformBuffer, UniformBufferBlockIndex, bufferObject);
 }
Esempio n. 16
0
        /// <summary>
        /// Activates the bind.
        /// </summary>
        /// <param name="index">The index.</param>
        public void ActivateBind(int index) //todo: more than one bound buffer is not working, but have different indices; test: glUniformBlockBinding
        {
            Activate();
            BufferRangeTarget target = (BufferRangeTarget)BufferTarget;

            GL.BindBufferBase​(target, index, bufferID);
        }
Esempio n. 17
0
        private unsafe void CreateMiscGLObjects()
        {
            // Quad drawing.
            {
                var quadVertices = new[]
                {
                    new Vertex2D(1, 0, 1, 1),
                    new Vertex2D(0, 0, 0, 1),
                    new Vertex2D(1, 1, 1, 0),
                    new Vertex2D(0, 1, 0, 0)
                };

                QuadVBO = new GLBuffer <Vertex2D>(this, BufferTarget.ArrayBuffer, BufferUsageHint.StaticDraw, quadVertices,
                                                  nameof(QuadVBO));

                QuadVAO = new GLHandle((uint)GL.GenVertexArray());
                GL.BindVertexArray(QuadVAO.Handle);
                ObjectLabelMaybe(ObjectLabelIdentifier.VertexArray, QuadVAO, nameof(QuadVAO));
                // Vertex Coords
                GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
                GL.EnableVertexAttribArray(0);
                // Texture Coords.
                GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
                GL.EnableVertexAttribArray(1);
            }

            // Batch rendering
            {
                BatchVBO = new GLBuffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw,
                                        Vertex2D.SizeOf * BatchVertexData.Length, nameof(BatchVBO));

                BatchVAO = new GLHandle(GL.GenVertexArray());
                GL.BindVertexArray(BatchVAO.Handle);
                ObjectLabelMaybe(ObjectLabelIdentifier.VertexArray, BatchVAO, nameof(BatchVAO));
                // Vertex Coords
                GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 0);
                GL.EnableVertexAttribArray(0);
                // Texture Coords.
                GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Vertex2D.SizeOf, 2 * sizeof(float));
                GL.EnableVertexAttribArray(1);

                BatchEBO = new GLBuffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw,
                                        sizeof(ushort) * BatchIndexData.Length, nameof(BatchEBO));
            }

            ProjViewUBO = new GLBuffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw, nameof(ProjViewUBO));
            ProjViewUBO.Reallocate(sizeof(ProjViewMatrices));

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, ProjViewBindingIndex, ProjViewUBO.ObjectHandle);

            UniformConstantsUBO = new GLBuffer(this, BufferTarget.UniformBuffer, BufferUsageHint.StreamDraw,
                                               nameof(UniformConstantsUBO));
            UniformConstantsUBO.Reallocate(sizeof(UniformConstants));

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, UniformConstantsBindingIndex,
                              UniformConstantsUBO.ObjectHandle);

            EntityPostRenderTarget = CreateRenderTarget(Vector2i.One * 4 * EyeManager.PIXELSPERMETER,
                                                        RenderTargetColorFormat.Rgba8Srgb, name: nameof(EntityPostRenderTarget), hasStencilBuffer: true);
        }
Esempio n. 18
0
        private void BindUniformBuffers(int ProgramHandle)
        {
            int FreeBinding = 0;

            int BindUniformBuffersIfNotNull(ShaderStage Stage)
            {
                if (Stage != null)
                {
                    foreach (ShaderDeclInfo DeclInfo in Stage.UniformUsage)
                    {
                        OGLStreamBuffer Buffer = GetConstBuffer(Stage.Type, DeclInfo.Cbuf);

                        GL.BindBufferBase(BufferRangeTarget.UniformBuffer, FreeBinding, Buffer.Handle);

                        FreeBinding++;
                    }
                }

                return(FreeBinding);
            }

            BindUniformBuffersIfNotNull(Current.Vertex);
            BindUniformBuffersIfNotNull(Current.TessControl);
            BindUniformBuffersIfNotNull(Current.TessEvaluation);
            BindUniformBuffersIfNotNull(Current.Geometry);
            BindUniformBuffersIfNotNull(Current.Fragment);
        }
Esempio n. 19
0
        private void BindConstBuffers(GalPipelineState New)
        {
            int freeBinding = OglShader.ReservedCbufCount;

            void BindIfNotNull(OglShaderStage stage)
            {
                if (stage != null)
                {
                    foreach (CBufferDescriptor desc in stage.ConstBufferUsage)
                    {
                        long key = New.ConstBufferKeys[(int)stage.Type][desc.Slot];

                        if (key != 0 && _buffer.TryGetUbo(key, out int uboHandle))
                        {
                            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, freeBinding, uboHandle);
                        }

                        freeBinding++;
                    }
                }
            }

            BindIfNotNull(_shader.Current.Vertex);
            BindIfNotNull(_shader.Current.TessControl);
            BindIfNotNull(_shader.Current.TessEvaluation);
            BindIfNotNull(_shader.Current.Geometry);
            BindIfNotNull(_shader.Current.Fragment);
        }
Esempio n. 20
0
 public void bindStorageBuffer(int bufferId, int location)
 {
     if (myBoundStorageBuffers[location] != bufferId)
     {
         GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, location, bufferId);
         myBoundStorageBuffers[location] = bufferId;
     }
 }
Esempio n. 21
0
 public void bindUniformBuffer(int bufferId, int location)
 {
     if (myBoundUniformBuffers[location] != bufferId)
     {
         GL.BindBufferBase(BufferRangeTarget.UniformBuffer, location, bufferId);
         myBoundUniformBuffers[location] = bufferId;
     }
 }
Esempio n. 22
0
        public override void Use()
        {
            GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 4, ssbo0);

            GL.UseProgram(Handle);
            GL.DispatchCompute(groups, 1, 1);
            GL.MemoryBarrier(MemoryBarrierFlags.ShaderStorageBarrierBit);
        }
Esempio n. 23
0
 /// <summary>
 /// Unbinds any buffer from this binding point.
 /// </summary>
 public void Unbind()
 {
     if (!Active)
     {
         return;
     }
     GL.BindBufferBase(BindingTarget, Binding, 0);
 }
Esempio n. 24
0
 public override void Bind()
 {
     GL.BindBuffer(BufferTarget.UniformBuffer, _buffer);
     GL.BufferData(BufferTarget.UniformBuffer, sizeof(Light) * MAX_LIGHTS, LightData, BufferUsageHint.DynamicDraw);
     GL.BindBuffer(BufferTarget.UniformBuffer, 0);
     GL.BindBufferBase(BufferRangeTarget.UniformBuffer, _bindingpoint, _buffer);
     GL.UniformBlockBinding(Program.ID, _index, _bindingpoint);
 }
Esempio n. 25
0
        public void Initialize(Renderer renderer)
        {
            _supportBuffer = new SupportBufferUpdater(renderer);
            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, Unsafe.As <BufferHandle, int>(ref _supportBuffer.Handle));

            _supportBuffer.UpdateFragmentIsBgra(_fpIsBgra, 0, SupportBuffer.FragmentIsBgraCount);
            _supportBuffer.UpdateRenderScale(_renderScale, 0, SupportBuffer.RenderScaleMaxCount);
        }
Esempio n. 26
0
        public void Initialize()
        {
            _supportBuffer = Buffer.Create(SupportBuffer.RequiredSize);
            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, Unsafe.As <BufferHandle, int>(ref _supportBuffer));

            SetSupportBufferData <Vector4 <int> >(SupportBuffer.FragmentIsBgraOffset, _fpIsBgra, SupportBuffer.FragmentIsBgraCount);
            SetSupportBufferData <Vector4 <float> >(SupportBuffer.FragmentRenderScaleOffset, _renderScale, SupportBuffer.RenderScaleMaxCount);
        }
Esempio n. 27
0
 public static void UnbindIdentity(int binding, int oldBinding = -1)
 {
     GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, binding, 0);
     if (oldBinding >= 0)
     {
         GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, oldBinding, 0);
     }
 }
Esempio n. 28
0
        /// <summary>
        /// Initialises a new <see cref="UniformBuffer{Data}"/> instance.
        /// </summary>
        public UniformBuffer() : base(BufferTarget.UniformBuffer, 1)
        {
            m_bindingPoint = BlockManager.GetBindingPoint(typeof(TData).Name);

            m_count = 1;

            GL.BindBufferBase(BufferRangeTarget.UniformBuffer, m_bindingPoint, this);
        }
Esempio n. 29
0
 public static void SetUniformBufferBinding(UniformBuffer buf, int index)
 {
     if (buf == null)
     {
         return;
     }
     GL.BindBufferBase(BufferRangeTarget.UniformBuffer, index, (int)buf);
 }
Esempio n. 30
0
 public override void UnbindMotion(int binding, int oldBinding = -1)
 {
     GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, binding, 0);
     if (oldBinding >= 0)
     {
         GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, oldBinding, 0);
     }
 }