/// <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); }
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); }
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); }
public void BufferSubData(long offset, long size, IntPtr data) { unsafe { Gl.BufferSubData(Target, (void *)offset, (void *)size, data.ToPointer()); GlHelper.GetError(); } }
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(); }
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); }
/// <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); } }
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); }
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"); }); }
/// <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(); }
/// <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); }
/// <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); }
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(); } }
/// <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; }
/// <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); }
/// <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); } }
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; } }
/// <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; }
public void ReplaceData(IntPtr data, uint size, IntPtr offset) { Gl.BufferSubData(BufferTarget.ElementArrayBuffer, offset, size, data); }
public void SubData(uint offset, uint size, IntPtr data) => Gl.BufferSubData(BufferTarget, new IntPtr(offset), size, data);