public unsafe void LoadData(IntPtr data, int size) { if (size < 0) { throw new ArgumentException("Size cannot be less than zero."); } NativeGraphicsBuffer prevBound = GetBound(this.type); Bind(this.type, this); uint target = ToOpenTKBufferType(this.type); if (data == IntPtr.Zero || size == 0) { // ToDo //GraphicsBackend.GL.BufferData(target, null, WebGLRenderingContextBase.STREAM_DRAW); } else { GraphicsBackend.GL.BufferData(target, TypedArray <Uint8ClampedArray, byte> .From(new Span <byte>(data.ToPointer(), size)), WebGLRenderingContextBase.STREAM_DRAW); } this.bufferSize = size; Bind(this.type, prevBound); }
public unsafe void LoadSubData(IntPtr offset, IntPtr data, int size) { if (size < 0) { throw new ArgumentException("Size cannot be less than zero."); } if (this.bufferSize == 0) { throw new InvalidOperationException(string.Format( "Cannot update {0}, because its storage was not initialized yet.", typeof(NativeGraphicsBuffer).Name)); } if ((uint)offset + size > this.bufferSize) { throw new ArgumentException(string.Format( "Cannot update {0} with offset {1} and size {2}, as this exceeds the internal " + "storage size {3}.", typeof(NativeGraphicsBuffer).Name, offset, size, this.bufferSize)); } NativeGraphicsBuffer prevBound = GetBound(this.type); Bind(this.type, this); uint target = ToOpenTKBufferType(this.type); GraphicsBackend.GL.BufferSubData(target, (uint)offset, TypedArray <Uint8ClampedArray, byte> .From(new Span <byte>(data.ToPointer(), size))); Bind(this.type, prevBound); }
unsafe void INativeTexture.LoadData(TexturePixelFormat format, int width, int height, IntPtr data, ColorDataLayout dataLayout, ColorDataElementType dataElementType) { // Removed thread guards because of performance //DefaultOpenTKBackendPlugin.GuardSingleThreadState(); WebGLTexture lastTexId = (WebGLTexture)GraphicsBackend.GL.GetParameter(WebGLRenderingContextBase.TEXTURE_BINDING_2D); GraphicsBackend.GL.BindTexture(WebGLRenderingContextBase.TEXTURE_2D, this.handle); // Load pixel data to video memory GraphicsBackend.GL.TexImage2D(WebGLRenderingContextBase.TEXTURE_2D, 0, ToOpenTKPixelInternalFormat(format), width, height, 0, dataLayout.ToOpenTK(), dataElementType.ToOpenTK(), TypedArray <Uint8ClampedArray, byte> .From(new Span <byte>(data.ToPointer(), /*ToDo*/ (width * height * 4)))); GraphicsBackend.GL.GenerateMipmap(WebGLRenderingContextBase.TEXTURE_2D); this.width = width; this.height = height; this.format = format; GraphicsBackend.GL.BindTexture(WebGLRenderingContextBase.TEXTURE_2D, lastTexId); }
void IGraphicsBackend.GetOutputPixelData(IntPtr buffer, ColorDataLayout dataLayout, ColorDataElementType dataElementType, int x, int y, int width, int height) { NativeRenderTarget lastRt = NativeRenderTarget.BoundRT; NativeRenderTarget.Bind(null); { // Use a temporary local buffer, since the image will be upside-down because // of OpenGL's coordinate system and we'll need to flip it before returning. byte[] byteData = new byte[width * height * 4]; // Retrieve pixel data GL.ReadPixels(x, y, width, height, dataLayout.ToOpenTK(), dataElementType.ToOpenTK(), TypedArray <Uint8ClampedArray, byte> .From(new Span <byte>(byteData))); // Flip the retrieved image vertically int bytesPerLine = width * 4; byte[] switchLine = new byte[width * 4]; for (int flipY = 0; flipY < height / 2; flipY++) { int lineIndex = flipY * width * 4; int lineIndex2 = (height - 1 - flipY) * width * 4; // Copy the current line to the switch buffer for (int lineX = 0; lineX < bytesPerLine; lineX++) { switchLine[lineX] = byteData[lineIndex + lineX]; } // Copy the opposite line to the current line for (int lineX = 0; lineX < bytesPerLine; lineX++) { byteData[lineIndex + lineX] = byteData[lineIndex2 + lineX]; } // Copy the switch buffer to the opposite line for (int lineX = 0; lineX < bytesPerLine; lineX++) { byteData[lineIndex2 + lineX] = switchLine[lineX]; } } // Copy the flipped data to the output buffer Marshal.Copy(byteData, 0, buffer, width * height * 4); } NativeRenderTarget.Bind(lastRt); }