/// <summary>
        /// Upload partial data to the buffer.
        /// </summary>
        /// <param name="data">The data to upload.</param>
        /// <param name="size">The data's size in bytes.</param>
        /// <param name="offset">The offset to upload from.</param>
        public void UploadPartial(IntPtr data, uint size, uint offset = 0)
        {
            var offsetPtr = (IntPtr)offset;

            EnsureBound(Pointer, Type);
            Gl.BufferSubData(Type, offsetPtr, size, data);
        }
Exemple #2
0
    public void BufferData()
    {
        Gl.BindVertexArray(arrayHandle);

        if (used > 0 && dirty)
        {
            unsafe
            {
                fixed(int *p = data)
                {
                    Gl.BindBuffer(BufferTarget.ArrayBuffer, bufferHandle);

                    // BufferSubData if we can
                    if (used <= lastUsed < used)
                    {
                        Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (uint)(used * vertexSize), (IntPtr)p);
                    }
                    else
                    {
                        Gl.BufferData(BufferTarget.ArrayBuffer, (uint)(used * vertexSize), (IntPtr)p, BufferUsage.StaticDraw);
                        lastUsed = used;
                    }

                    Gl.BindBuffer(BufferTarget.ArrayBuffer, 0);
                }
            }

            dirty = false;

            // Clear the data from memory as it is now stored on the GPU
            data = null;
        }

        Gl.BindVertexArray(0);
    }
Exemple #3
0
 public void ReplaceData(int[] data, IntPtr offset)
 {
     if (data == null)
     {
         throw new ArgumentNullException(nameof(data));
     }
     Gl.BufferSubData(BufferTarget.ElementArrayBuffer, offset, sizeof(int) * (uint)data.Length, data);
 }
Exemple #4
0
 public void BufferSubData(long offset, long size, IntPtr data)
 {
     unsafe
     {
         Gl.BufferSubData(Target, (void *)offset, (void *)size, data.ToPointer());
         GlHelper.GetError();
     }
 }
Exemple #5
0
        static void Main(string[] args)
        {
            Glfw.Init();

            Glfw.WindowHint(Hint.ContextVersionMajor, 4);
            Glfw.WindowHint(Hint.ContextVersionMinor, 6);
            Glfw.WindowHint(Hint.OpenglProfile, Profile.Compatibility);
            Window window = Glfw.CreateWindow(1080, 720, "Yeet", Monitor.None, Window.None);

            // `Gl.Initialize()` has to be don before `Glfw.MakeContextCurrent(window)`
            // [How Do I Initialize OpenGL.NET with GLFW.Net?](https://stackoverflow.com/questions/61318104/how-do-i-initialize-opengl-net-with-glfw-net/61319044?noredirect=1#comment108476826_61319044)
            Gl.Initialize();
            Glfw.MakeContextCurrent(window);

            var v = Gl.GetString(StringName.Version);

            Console.WriteLine(v);

            uint vao = Gl.CreateVertexArray();

            Gl.BindVertexArray(vao);

            uint vbo = Gl.GenBuffer();

            Gl.BindBuffer(BufferTarget.ArrayBuffer, vbo);

            var vertices = new float[] { -0.5f, -0.5f, 0.5f, -0.5f, 0.0f, 0.5f };

            Gl.BufferData(BufferTarget.ArrayBuffer, (uint)(4 * vertices.Length), null, BufferUsage.StaticDraw);

            IntPtr unmanagedPointer = Marshal.AllocHGlobal(4 * vertices.Length);

            Marshal.Copy(vertices, 0, unmanagedPointer, vertices.Length);
            Gl.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(0), (uint)(4 * vertices.Length), unmanagedPointer);
            Marshal.FreeHGlobal(unmanagedPointer);

            //Gl.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(0), (uint)(4 * vertices.Length), vertices);

            Gl.VertexAttribPointer(0, 2, VertexAttribType.Float, false, 0, null);

            while (!Glfw.WindowShouldClose(window))
            {
                Glfw.PollEvents();

                Gl.ClearColor(0.0f, 1.0f, 1.0f, 1.0f);
                Gl.Clear(ClearBufferMask.ColorBufferBit);
                Gl.BindVertexArray(vao);
                Gl.EnableVertexAttribArray(0);
                Gl.DrawArrays(PrimitiveType.Triangles, 0, 3);
                Gl.DisableVertexAttribArray(0);
                Gl.BindVertexArray(0);

                Glfw.SwapBuffers(window);
            }

            Glfw.DestroyWindow(window);
            Glfw.Terminate();
        }
Exemple #6
0
        public void Update(IEnumerable <T> newData, int offset)
        {
            var array = newData.ToArray();

            offset = Math.Clamp(offset, 0, array.Length);
            int dataSize = Math.Min(array.Length - offset, Count) * size;

            Gl.BindBuffer(BufferTarget.ArrayBuffer, Handle);
            Gl.BufferSubData(BufferTarget.ArrayBuffer, new IntPtr(byteOffset + offset * size), (uint)dataSize, array);
            Gl.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Exemple #7
0
        /// <summary>
        /// Upload partial data to the buffer.
        /// </summary>
        /// <param name="data">The data to upload.</param>
        /// <param name="size">The data's size in bytes.</param>
        /// <param name="offset">The offset to upload to.</param>
        public void UploadPartial(IntPtr data, uint size, uint offset = 0)
        {
            var offsetPtr = (IntPtr)offset;

            if (Engine.Renderer.Dsa)
            {
                Gl.NamedBufferSubData(Pointer, offsetPtr, size, data);
            }
            else
            {
                EnsureBound(Pointer, Type);
                Gl.BufferSubData(Type, offsetPtr, size, data);
            }
        }
Exemple #8
0
 public void CreateString(VAO <Vector3, Vector2> vao, string text, Vector3 color, BMFont.Justification justification = BMFont.Justification.Left, float scale = 1f)
 {
     if (vao == null || (int)vao.vaoID == 0)
     {
         return;
     }
     if (vao.VertexCount != text.Length * 6)
     {
         throw new InvalidOperationException("Text length did not match the length of the current vertex array object.");
     }
     this.CreateStringInternal(text, color, justification, scale);
     Gl.BufferSubData <Vector3>(vao.vbos[0].vboID, BufferTarget.ArrayBuffer, BMFont.vertices, text.Length * 4);
     Gl.BufferSubData <Vector2>(vao.vbos[1].vboID, BufferTarget.ArrayBuffer, BMFont.uvs, text.Length * 4);
 }
Exemple #9
0
        public void UpdateUVs(Vector2[] uvs)
        {
            Gl.BindVertexArray(ID);
            Gl.BindBuffer(BufferTarget.ArrayBuffer, uvsID);
            GCHandle data_ptr = GCHandle.Alloc(uvs, GCHandleType.Pinned);

            try {
                Gl.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, new IntPtr(2 * sizeof(float) * uvs.Length), data_ptr.AddrOfPinnedObject());
            } finally {
                data_ptr.Free();
            }
            Gl.BindBuffer(BufferTarget.ArrayBuffer, 0);
            Gl.BindVertexArray(0);
        }
 public void PrepareDrawCall()
 {
     // Bind OpenGL objects.
     Gl.UseProgram(ShaderProgram);
     for (int i = 0; i < Renderer.TextureSlotIndex; i++)
     {
         Gl.ActiveTexture((TextureUnit)(TextureUnit.Texture0 + i));
         Gl.BindTexture(TextureTarget.Texture2d, (uint)Renderer.TextureSlots[i]);
     }
     Gl.BindVertexArray(VertexArray);
     Gl.BindBuffer(BufferTarget.ArrayBuffer, VertexBuffer);
     // Upload the new vertex buffer data to VRAM.
     Gl.BufferSubData(BufferTarget.ArrayBuffer, IntPtr.Zero, (uint)(Renderer.VertexIndex * Marshal.SizeOf <Vertex>()), Renderer.Vertices);
 }
        /// <inheritdoc />
        public override void MapIndexBuffer(IntPtr data, uint size, uint offset = 0)
        {
            if (BoundIndexBuffer == 0)
            {
                Engine.Log.Warning("You are trying to map data, but no index buffer is bound.", MessageSource.GL);
            }
            IntPtr offsetPtr = (IntPtr)offset;

            GLThread.ExecuteGLThread(() =>
            {
                Gl.BufferSubData(BufferTarget.ElementArrayBuffer, offsetPtr, size, data);
                CheckError("after uploading index buffer data from pointer");
            });
        }
Exemple #12
0
        /// <summary>
        /// Invalidate a range of the content of this Buffer.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> that created this Buffer.
        /// </param>
        public void Invalidate(GraphicsContext ctx, IntPtr offset, uint length)
        {
            if (ctx.Extensions.InvalidateSubdata_ARB || ctx.Version.IsCompatible(Gl.Version_430))
            {
                Gl.InvalidateBufferSubData(ObjectName, offset, length);
            }
            else
            {
                if (!Immutable && RequiresName(ctx))
                {
                    ctx.Bind(this);
                    Gl.BufferSubData(Target, offset, length, IntPtr.Zero);
                }
            }

            Gl.CheckErrors();
        }
Exemple #13
0
        /// <summary>
        /// Creates a string over top of an old string VAO of the same length.
        /// Does not overwrite the indices, since those should be consistent
        /// across VAOs of the same length when describing text.
        /// </summary>
        /// <param name="vao">The current vao object.</param>
        /// <param name="text">The text to use when overwriting the old VAO.</param>
        /// <param name="color">The color of the text.</param>
        /// <param name="justification">The justification of the text.</param>
        /// <param name="scale">The scaling of the text.</param>
        public void CreateString(VAO <Vector3, Vector2> vao, string text, Vector3 color, Justification justification = Justification.Left, float scale = 1f)
        {
            if (vao == null || vao.vaoID == 0)
            {
                return;
            }
            if (vao.VertexCount != text.Length * 6)
            {
                throw new InvalidOperationException("Text length did not match the length of the current vertex array object.");
            }

            CreateStringInternal(text, color, justification, scale);

            // simply update the underlying VBOs (indices shouldn't be modified)
            Gl.BufferSubData(vao.vbos[0].vboID, BufferTarget.ArrayBuffer, vertices, text.Length * 4);
            Gl.BufferSubData(vao.vbos[1].vboID, BufferTarget.ArrayBuffer, uvs, text.Length * 4);
        }
Exemple #14
0
        /// <inheritdoc cref="UploadPartial(IntPtr, uint, uint)"/>
        public void UploadPartial <T>(T[] data, uint offset = 0)
        {
            // Finish mapping - if it was.
            FinishMapping();

            int byteSize  = Marshal.SizeOf(data[0]);
            var offsetPtr = (IntPtr)offset;
            var partSize  = (uint)(data.Length * byteSize);

            if (offset > Size || offset + partSize > Size)
            {
                Engine.Log.Warning("Tried to map buffer out of range.", MessageSource.GL);
                Debug.Assert(false);
                return;
            }

            EnsureBound(Pointer, Type);
            Gl.BufferSubData(Type, offsetPtr, partSize, data);
        }
Exemple #15
0
        public void updateGlBuffers()
        {
            {
                GCHandle handle  = GCHandle.Alloc(positions_, GCHandleType.Pinned);
                IntPtr   pointer = handle.AddrOfPinnedObject();

                Gl.BindBuffer(BufferTarget.ArrayBuffer, positionsId_);
                Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (IntPtr)(numVertices_ * Marshal.SizeOf(typeof(Neutrino._math.vec3))), pointer);

                handle.Free();
            }

            {
                GCHandle handle  = GCHandle.Alloc(colors_, GCHandleType.Pinned);
                IntPtr   pointer = handle.AddrOfPinnedObject();

                Gl.BindBuffer(BufferTarget.ArrayBuffer, colorsId_);
                Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0, (IntPtr)(numVertices_ * Marshal.SizeOf(typeof(uint))), pointer);

                handle.Free();
            }

            for (uint texIndex = 0; texIndex < texChannels_.Length; ++texIndex)
            {
                TexChannel texChannel = texChannels_[texIndex];

                GCHandle handle  = GCHandle.Alloc(texChannel.data_, GCHandleType.Pinned);
                IntPtr   pointer = handle.AddrOfPinnedObject();

                Gl.BindBuffer(BufferTarget.ArrayBuffer, texChannel.id_);
                Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)0,
                                 (IntPtr)(numVertices_ * texChannel.dimensions_ * Marshal.SizeOf(typeof(float))), pointer);

                handle.Free();
            }
        }
Exemple #16
0
        /// <summary>
        /// Reset the allocated GPU buffer for this Buffer.
        /// </summary>
        /// <param name="ctx">
        ///
        /// </param>
        /// <param name="size">
        /// A <see cref="UInt32"/> that determine the size of the buffer object GPU buffer, in bytes.
        /// </param>
        /// <param name="data">
        ///
        /// </param>
        protected void CreateGpuBuffer(GraphicsContext ctx, uint size, IntPtr data)
        {
            if (Immutable && _GpuBufferSize > 0)
            {
                throw new InvalidOperationException("buffer is immutable");
            }

            if (Immutable && ctx.Extensions.BufferStorage_ARB)
            {
                Gl.BufferStorage(Target, size, data, (uint)_UsageMask);
                Gl.CheckErrors();
            }
            else
            {
                Gl.BufferData(Target, size, data, Hint);
                if (CpuBufferAddress != IntPtr.Zero)
                {
                    Gl.BufferSubData(Target, IntPtr.Zero, _GpuBufferSize, CpuBufferAddress);
                }
            }

            // Store GPU buffer size
            _GpuBufferSize = size;
        }
Exemple #17
0
 /// <summary>
 /// Update the reference Buffer, using this technique.
 /// </summary>
 /// <param name="ctx">
 /// A <see cref="GraphicsContext"/> used for allocating resources.
 /// </param>
 public override void Create(GraphicsContext ctx)
 {
     Gl.BufferSubData(Buffer.Target, new IntPtr(_BufferOffset), (uint)_Array.Length, _Array);
 }
Exemple #18
0
        /// <summary>
        /// Flush all the entities that has not been flushed
        /// </summary>
        private void Flush()
        {
            renderableComponents = EntityManager.Instance.GetEntitiesComponent <Renderable>();

            if (renderableComponents.Length == 0)
            {
                return;
            }

            for (int i = 0; i < renderableComponents.Length; i++)
            {
                if (renderableComponents[i].IsSubmitted)
                {
                    continue;
                }

                renderableComponents[i].BufferOffset = lastEntityOffset;

                List <float> vertexData = new List <float>();

                for (int j = 0; j < renderableComponents[i].Vertices.Length; j++)
                {
                    // XY
                    vertexData.Add(renderableComponents[i].Vertices[j].X);
                    vertexData.Add(renderableComponents[i].Vertices[j].Y);

                    // RGBA
                    vertexData.Add(renderableComponents[i].Colors[j].R);
                    vertexData.Add(renderableComponents[i].Colors[j].G);
                    vertexData.Add(renderableComponents[i].Colors[j].B);
                    vertexData.Add(renderableComponents[i].Colors[j].A);

                    int currentQuad = j / 4;

                    // Tx Ty
                    if (renderableComponents[i].TextureOffsets != null)
                    {
                        vertexData.Add(renderableComponents[i].TextureOffsets[currentQuad, j % 4].X);
                        vertexData.Add(renderableComponents[i].TextureOffsets[currentQuad, j % 4].Y);
                    }
                    else
                    {
                        vertexData.Add(0);
                        vertexData.Add(0);
                    }


                    // Texture id
                    if (renderableComponents[i].Texture == null || renderableComponents[i].TextureOffsets[currentQuad, j % 4].X == -1)
                    {
                        vertexData.Add(1024);
                    }
                    else
                    {
                        vertexData.Add(renderableComponents[i].Texture.Id);
                    }
                }

                // Add data to vbo
                vbo.Bind();
                Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)lastEntityOffset, (uint)(renderableComponents[i].Vertices.Length * vbo.VertexSize), vertexData.ToArray());
                vbo.Unbind();

                Debug.Log("Flushed 1 Entity with " + renderableComponents[i].Vertices.Length.ToString() + " Vertices at bufferLayout " + lastEntityOffset, Debug.DebugLayer.Render, Debug.DebugLevel.Information);

                renderableComponents[i].IsSubmitted = true;
                lastEntityOffset += (uint)(renderableComponents[i].Vertices.Length * vbo.VertexSize);
            }
        }
Exemple #19
0
        internal void UpdateData()
        {
            if (renderableComponents.Length == 0)
            {
                return;
            }

            for (int i = 0; i < renderableComponents.Length; i++)
            {
                Renderable curRend = renderableComponents[i];

                if (!curRend.HasChanged)
                {
                    continue;
                }

                List <float> vertexData = new List <float>();

                for (int j = 0; j < renderableComponents[i].Vertices.Length; j++)
                {
                    // XY
                    vertexData.Add(curRend.Vertices[j].X);
                    vertexData.Add(curRend.Vertices[j].Y);

                    // RGBA
                    vertexData.Add(curRend.Colors[j].R);
                    vertexData.Add(curRend.Colors[j].G);
                    vertexData.Add(curRend.Colors[j].B);
                    vertexData.Add(curRend.Colors[j].A);

                    int currentQuad = j / 4;

                    // Tx Ty
                    if (curRend.TextureOffsets != null)
                    {
                        vertexData.Add(curRend.TextureOffsets[currentQuad, j % 4].X);
                        vertexData.Add(curRend.TextureOffsets[currentQuad, j % 4].Y);
                    }
                    else
                    {
                        vertexData.Add(0);
                        vertexData.Add(0);
                    }


                    // Texture id
                    if (curRend.Texture == null || curRend.TextureOffsets[currentQuad, j % 4].X == -1)
                    {
                        vertexData.Add(1024);
                    }
                    else
                    {
                        vertexData.Add(curRend.Texture.Id);
                    }
                }

                vbo.Bind();
                Gl.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)curRend.BufferOffset, (uint)(curRend.Vertices.Length * vbo.VertexSize), vertexData.ToArray());
                vbo.Unbind();

                curRend.HasChanged = false;
            }
        }
Exemple #20
0
        /// <summary>
        /// Actually create this BufferObject resources.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctx"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="ctx"/> is not current on the calling thread.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject has not client memory allocated and the hint is different from
        /// <see cref="BufferObjectHint.StaticCpuDraw"/> or <see cref="BufferObjectHint.DynamicCpuDraw"/>.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject is currently mapped.
        /// </exception>
        protected override void CreateObject(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            if ((ClientBufferAddress == IntPtr.Zero) && ((Hint != BufferObjectHint.StaticCpuDraw) && (Hint != BufferObjectHint.DynamicCpuDraw)))
            {
                throw new InvalidOperationException("no client buffer");
            }

            // Determine the client buffer size
            uint clientBufferSize = _ClientBufferSize;

            if (ClientBufferAddress != IntPtr.Zero)
            {
                clientBufferSize = ClientBufferSize;
            }

            Debug.Assert(clientBufferSize > 0);

            // Buffer must be bound
            ctx.Bind(this, true);

            if (ctx.Extensions.VertexBufferObject_ARB)
            {
                if (IsMapped)
                {
                    throw new InvalidOperationException("mapped");
                }

                // Define buffer object (type, size and hints)
                AllocateGpuBuffer(clientBufferSize, null);

                // Define buffer object contents
                if (ClientBufferAddress != IntPtr.Zero)
                {
                    // Provide buffer contents
                    Gl.BufferSubData(BufferType, IntPtr.Zero, _GpuBufferSize, ClientBufferAddress);
                    // Release memory, if it is not required anymore
                    if (_MemoryBufferAutoDispose)
                    {
                        ReleaseClientBuffer();
                    }
                }
            }
            else
            {
                // Discard previous GPU buffer, if any
                if (_GpuBuffer != null)
                {
                    _GpuBuffer.Dispose();
                }

                if (ClientBufferAddress == IntPtr.Zero)
                {
                    // Note: GPU buffer size specified by _ClientBufferSize
                    Debug.Assert(_ClientBufferSize > 0);
                    // Allocate simulated GPU buffer
                    _GpuBuffer = new AlignedMemoryBuffer(_ClientBufferSize, MinimumBufferAlignment);
                }
                else
                {
                    // Let a virtual implementation decide how pass information from the client buffer and the "GPU" buffer
                    UploadClientBuffer();
                }

                // Store GPU buffer size
                _GpuBufferSize = _GpuBuffer.Size;
            }

            // Reset requested client buffer size
            _ClientBufferSize = 0;
        }
Exemple #21
0
 public void ReplaceData(IntPtr data, uint size, IntPtr offset)
 {
     Gl.BufferSubData(BufferTarget.ElementArrayBuffer, offset, size, data);
 }
Exemple #22
0
 public void SubData(uint offset, uint size, IntPtr data)
 => Gl.BufferSubData(BufferTarget, new IntPtr(offset), size, data);