protected VertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage, bool dynamic) { if (graphicsDevice == null) { throw new ArgumentNullException("Graphics Device Cannot Be null"); } this.GraphicsDevice = graphicsDevice; this.VertexDeclaration = vertexDeclaration; this.VertexCount = vertexCount; this.BufferUsage = bufferUsage; // Make sure the graphics device is assigned in the vertex declaration. if (vertexDeclaration.GraphicsDevice != graphicsDevice) { vertexDeclaration.GraphicsDevice = graphicsDevice; } _isDynamic = dynamic; #if DIRECTX // TODO: To use Immutable resources we would need to delay creation of // the Buffer until SetData() and recreate them if set more than once. var accessflags = SharpDX.Direct3D11.CpuAccessFlags.None; var usage = SharpDX.Direct3D11.ResourceUsage.Default; if (dynamic) { accessflags |= SharpDX.Direct3D11.CpuAccessFlags.Write; usage = SharpDX.Direct3D11.ResourceUsage.Dynamic; } _buffer = new SharpDX.Direct3D11.Buffer(graphicsDevice._d3dDevice, vertexDeclaration.VertexStride * vertexCount, usage, SharpDX.Direct3D11.BindFlags.VertexBuffer, accessflags, SharpDX.Direct3D11.ResourceOptionFlags.None, 0 // StructureSizeInBytes ); _binding = new SharpDX.Direct3D11.VertexBufferBinding(_buffer, VertexDeclaration.VertexStride, 0); #elif PSM //Do nothing, we cannot create the storage array yet #else Threading.BlockOnUIThread(GenerateIfRequired); #endif }
protected IndexBuffer(GraphicsDevice graphicsDevice, IndexElementSize indexElementSize, int indexCount, BufferUsage usage, bool dynamic) { if (graphicsDevice == null) { throw new ArgumentNullException("GraphicsDevice is null"); } this.GraphicsDevice = graphicsDevice; this.IndexElementSize = indexElementSize; this.IndexCount = indexCount; this.BufferUsage = usage; int num = (int)this.IndexElementSize; this._isDynamic = dynamic; Threading.BlockOnUIThread(new Action(this.GenerateIfRequired)); }
protected override void Dispose(bool disposing) { if (!IsDisposed) { Threading.BlockOnUIThread(() => { if (!IsDisposed) { GL.DeleteBuffers(1, ref vbo); GraphicsExtensions.CheckGLError(); base.Dispose(disposing); } }); } }
protected override void Dispose(bool disposing) { if (!IsDisposed) { #if OPENGL Threading.BlockOnUIThread(() => { GL.DeleteQueries(1, ref glQueryId); GraphicsExtensions.CheckGLError(); }); #elif DIRECTX #endif } base.Dispose(disposing); }
public VertexBuffer(VertexFormat vertexFormat, int size, BufferUsageHint usage = BufferUsageHint.StaticDraw, BeginMode beginMode = OpenTK.Graphics.OpenGL.BeginMode.Triangles) { if (vertexFormat == null) { _vertexFormat = new VertexFormat(); } else { _vertexFormat = vertexFormat; } _usageHint = usage; _count = size; _beginMode = beginMode; Threading.BlockOnUIThread(GenerateIfRequired); }
protected override void Dispose(bool disposing) { if (!IsDisposed) { if (GraphicsDevice != null) { Threading.BlockOnUIThread(() => { this.GraphicsDevice.PlatformDeleteRenderTarget(this); }); } } base.Dispose(disposing); }
public void GetData <T>(int level, Microsoft.Xna.Framework.Rectangle?rect, T[] data, int startIndex, int elementCount) where T : struct { Threading.BlockOnUIThread((Action)(() => { GL.BindTexture(TextureTarget.Texture2D, this.glTexture); if (rect.HasValue) { throw new NotImplementedException(); } if (this.glFormat == (OpenTK.Graphics.OpenGL.PixelFormat) 34467) { throw new NotImplementedException(); } GL.GetTexImage <T>(TextureTarget.Texture2D, level, this.glFormat, this.glType, data); })); }
protected VertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage, bool dynamic) { if (graphicsDevice == null) { throw new ArgumentNullException("Graphics Device Cannot Be null"); } this.GraphicsDevice = graphicsDevice; this.VertexDeclaration = vertexDeclaration; this.VertexCount = vertexCount; this.BufferUsage = bufferUsage; if (vertexDeclaration.GraphicsDevice != graphicsDevice) { vertexDeclaration.GraphicsDevice = graphicsDevice; } this._isDynamic = dynamic; Threading.BlockOnUIThread(new Action(this.GenerateIfRequired)); }
protected IndexBuffer(GraphicsDevice graphicsDevice, IndexElementSize indexElementSize, int indexCount, BufferUsage usage, bool dynamic) { if (graphicsDevice == null) { throw new ArgumentNullException("GraphicsDevice is null"); } this.GraphicsDevice = graphicsDevice; this.IndexElementSize = indexElementSize; this.IndexCount = indexCount; this.BufferUsage = usage; var sizeInBytes = indexCount * (this.IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4); _isDynamic = dynamic; #if DIRECTX // TODO: To use true Immutable resources we would need to delay creation of // the Buffer until SetData() and recreate them if set more than once. var accessflags = SharpDX.Direct3D11.CpuAccessFlags.None; var resUsage = SharpDX.Direct3D11.ResourceUsage.Default; if (dynamic) { accessflags |= SharpDX.Direct3D11.CpuAccessFlags.Write; resUsage = SharpDX.Direct3D11.ResourceUsage.Dynamic; } _buffer = new SharpDX.Direct3D11.Buffer(graphicsDevice._d3dDevice, sizeInBytes, resUsage, SharpDX.Direct3D11.BindFlags.IndexBuffer, accessflags, SharpDX.Direct3D11.ResourceOptionFlags.None, 0 // StructureSizeInBytes ); #elif PSM if (indexElementSize != IndexElementSize.SixteenBits) { throw new NotImplementedException("PSS Currently only supports ushort (SixteenBits) index elements"); } _buffer = new ushort[indexCount]; #else Threading.BlockOnUIThread(GenerateIfRequired); #endif }
private static Texture2D PlatformFromStream(GraphicsDevice graphicsDevice, Stream stream) { #if WINDOWS_PHONE WriteableBitmap bitmap = null; Threading.BlockOnUIThread(() => { try { BitmapImage bitmapImage = new BitmapImage(); bitmapImage.SetSource(stream); bitmap = new WriteableBitmap(bitmapImage); } catch { } }); // Convert from ARGB to ABGR ConvertToABGR(bitmap.PixelHeight, bitmap.PixelWidth, bitmap.Pixels); Texture2D texture = new Texture2D(graphicsDevice, bitmap.PixelWidth, bitmap.PixelHeight); texture.SetData <int>(bitmap.Pixels); return(texture); #endif #if !WINDOWS_PHONE if (!stream.CanSeek) { throw new NotSupportedException("stream must support seek operations"); } // For reference this implementation was ultimately found through this post: // http://stackoverflow.com/questions/9602102/loading-textures-with-sharpdx-in-metro Texture2D toReturn = null; SharpDX.WIC.BitmapDecoder decoder; using (var bitmap = LoadBitmap(stream, out decoder)) using (decoder) { SharpDX.Direct3D11.Texture2D sharpDxTexture = CreateTex2DFromBitmap(bitmap, graphicsDevice); toReturn = new Texture2D(graphicsDevice, bitmap.Size.Width, bitmap.Size.Height); toReturn._texture = sharpDxTexture; } return(toReturn); #endif }
private void PlatformGetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { #if GLES // Buffers are write-only on OpenGL ES 1.1 and 2.0. See the GL_OES_mapbuffer extension for more information. // http://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt throw new NotSupportedException("Vertex buffers are write-only on OpenGL ES platforms"); #endif #if !GLES if (Threading.IsOnUIThread()) { GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride); } else { Threading.BlockOnUIThread(() => GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride)); } #endif }
protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (Threading.IsOnUIThread()) { this.BufferData <T>(offsetInBytes, data, startIndex, elementCount, options); } else { Threading.BlockOnUIThread((Action)(() => this.BufferData <T>(offsetInBytes, data, startIndex, elementCount, options))); } }
private void PlatformSetData <T>(CubeMapFace face, int level, IntPtr dataPtr, int xOffset, int yOffset, int width, int height) { Threading.BlockOnUIThread(() => { GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); TextureTarget target = GetGLCubeFace(face); if (glFormat == (PixelFormat)All.CompressedTextureFormats) { throw new NotImplementedException(); } else { GL.TexSubImage2D(target, level, xOffset, yOffset, width, height, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } }); }
public RenderTarget2D(GraphicsDevice graphicsDevice, int width, int height, bool mipMap, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, int preferredMultiSampleCount, RenderTargetUsage usage) : base(graphicsDevice, width, height, mipMap, preferredFormat, true) { RenderTarget2D renderTarget2D = this; this.DepthStencilFormat = preferredDepthFormat; this.MultiSampleCount = preferredMultiSampleCount; this.RenderTargetUsage = usage; if (preferredDepthFormat == DepthFormat.None) { return; } Threading.BlockOnUIThread((Action)(() => { GL.GenRenderbuffers(1, out renderTarget2D.glDepthStencilBuffer); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, renderTarget2D.glDepthStencilBuffer); RenderbufferStorage local_0 = RenderbufferStorage.DepthComponent16; switch (preferredDepthFormat) { case DepthFormat.Depth24Stencil8: local_0 = RenderbufferStorage.Depth24Stencil8; break; case DepthFormat.Depth24: local_0 = RenderbufferStorage.DepthComponent24; break; case DepthFormat.Depth16: local_0 = RenderbufferStorage.DepthComponent16; break; } if (renderTarget2D.MultiSampleCount == 0) { GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, local_0, renderTarget2D.width, renderTarget2D.height); } else { GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, renderTarget2D.MultiSampleCount, local_0, renderTarget2D.width, renderTarget2D.height); } })); }
public void GetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (this.BufferUsage == BufferUsage.WriteOnly) { throw new NotSupportedException("This VertexBuffer was created with a usage type of BufferUsage.WriteOnly. Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if (vertexStride > this.VertexCount * this.VertexDeclaration.VertexStride || vertexStride < this.VertexDeclaration.VertexStride) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } Threading.BlockOnUIThread((Action)(() => { GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo); int local_0 = Marshal.SizeOf(typeof(T)); IntPtr local_1 = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.ReadOnly); local_1 = new IntPtr(local_1.ToInt64() + (long)offsetInBytes); if (data is byte[]) { byte[] local_2 = data as byte[]; Marshal.Copy(local_1, local_2, 0, local_2.Length); } else { byte[] local_2_1 = new byte[elementCount * vertexStride]; Marshal.Copy(local_1, local_2_1, 0, local_2_1.Length); GCHandle local_3 = GCHandle.Alloc((object)data, GCHandleType.Pinned); IntPtr local_4 = (IntPtr)(local_3.AddrOfPinnedObject().ToInt64() + (long)(startIndex * local_0)); Marshal.Copy(local_2_1, 0, local_4, local_2_1.Length); local_3.Free(); } GL.UnmapBuffer(BufferTarget.ArrayBuffer); })); }
public void Compile() { Threading.BlockOnUIThread(() => { ShaderHandle = GL.CreateShader(ShaderType); #if GLES GL.ShaderSource(ShaderHandle, 1, new string[] { _glslCode }, (int[])null); #else GL.ShaderSource(ShaderHandle, _glslCode); #endif GL.CompileShader(ShaderHandle); var compiled = 0; #if GLES GL.GetShader(ShaderHandle, ShaderParameter.CompileStatus, ref compiled); #else GL.GetShader(ShaderHandle, ShaderParameter.CompileStatus, out compiled); #endif if (compiled == (int)All.False) { #if GLES string log = ""; int length = 0; GL.GetShader(ShaderHandle, ShaderParameter.InfoLogLength, ref length); if (length > 0) { var logBuilder = new StringBuilder(length); GL.GetShaderInfoLog(ShaderHandle, length, ref length, logBuilder); log = logBuilder.ToString(); } #else var log = GL.GetShaderInfoLog(ShaderHandle); #endif Console.WriteLine(log); GL.DeleteShader(ShaderHandle); throw new InvalidOperationException("Shader Compilation Failed"); } }); }
private void PlatformSetData <T>(int level, int left, int top, int right, int bottom, int front, int back, T[] data, int startIndex, int elementCount, int width, int height, int depth) { #if GLES throw new NotSupportedException("OpenGL ES 2.0 doesn't support 3D textures."); #else Threading.BlockOnUIThread(() => { var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInByte); GL.BindTexture(glTarget, glTexture); GraphicsExtensions.CheckGLError(); GL.TexSubImage3D(glTarget, level, left, top, front, width, height, depth, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); dataHandle.Free(); }); #endif }
protected internal override Texture2D Read(ContentReader input, Texture2D existingInstance) { Texture2D texture = null; var surfaceFormat = (SurfaceFormat)input.ReadInt32(); int width = input.ReadInt32(); int height = input.ReadInt32(); int levelCount = input.ReadInt32(); int levelCountOutput = levelCount; if (levelCount > 1 && !input.GraphicsDevice.GraphicsCapabilities.SupportsNonPowerOfTwo) { levelCountOutput = 1; System.Diagnostics.Debug.WriteLine("Device does not support non Power of Two Textures.Skipping mipmaps."); } SurfaceFormat convertedFormat = surfaceFormat; switch (surfaceFormat) { case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1a: if (!input.GraphicsDevice.GraphicsCapabilities.SupportsDxt1) { convertedFormat = SurfaceFormat.Color; } break; } texture = existingInstance ?? new Texture2D(input.GraphicsDevice, width, height, levelCountOutput > 1, convertedFormat); Threading.BlockOnUIThread(() => { }); return(texture); }
protected IndexBuffer(GraphicsDevice graphicsDevice, IndexElementSize indexElementSize, int indexCount, BufferUsage bufferUsage, bool dynamic) { IndexBuffer indexBuffer = this; if (graphicsDevice == null) { throw new ArgumentNullException("Graphics Device Cannot Be Null"); } this.GraphicsDevice = graphicsDevice; this.IndexElementSize = indexElementSize; this.IndexCount = indexCount; this.BufferUsage = bufferUsage; int sizeInBytes = indexCount * (this.IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4); this._isDynamic = dynamic; Threading.BlockOnUIThread((Action)(() => { GL.GenBuffers(1, out indexBuffer.ibo); GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer.ibo); GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)sizeInBytes, IntPtr.Zero, dynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw); })); }
protected internal override Texture3D Read(ContentReader reader, Texture3D existingInstance) { Texture3D texture = null; SurfaceFormat format = (SurfaceFormat)reader.ReadInt32(); int width = reader.ReadInt32(); int height = reader.ReadInt32(); int depth = reader.ReadInt32(); int levelCount = reader.ReadInt32(); if (existingInstance == null) texture = new Texture3D(reader.GetGraphicsDevice(), width, height, depth, levelCount > 1, format); else texture = existingInstance; #if OPENGL Threading.BlockOnUIThread(() => { #endif for (int i = 0; i < levelCount; i++) { int dataSize = reader.ReadInt32(); byte[] data = ContentManager.ScratchBufferPool.Get(dataSize); reader.Read(data, 0, dataSize); texture.SetData(i, 0, 0, width, height, 0, depth, data, 0, dataSize); // Calculate dimensions of next mip level. width = Math.Max(width >> 1, 1); height = Math.Max(height >> 1, 1); depth = Math.Max(depth >> 1, 1); ContentManager.ScratchBufferPool.Return(data); } #if OPENGL }); #endif return texture; }
public void GetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (this.BufferUsage == BufferUsage.WriteOnly) { throw new NotSupportedException("This IndexBuffer was created with a usage type of BufferUsage.WriteOnly. Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if (Threading.IsOnUIThread()) { this.GetBufferData <T>(offsetInBytes, data, startIndex, elementCount); } else { Threading.BlockOnUIThread((Action)(() => this.GetBufferData <T>(offsetInBytes, data, startIndex, elementCount))); } }
/// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="level">多级渐远纹理的级别</param> /// <param name="arraySize"></param> /// <param name="rect"></param> /// <param name="data">图像数据</param> /// <param name="startIndex"></param> /// <param name="elementCount"></param> private void PlatformSetData <T>(int level, int arraySize, Rectangle rect, T[] data, int startIndex, int elementCount) where T : struct { Threading.BlockOnUIThread(() => { var elementSizeInByte = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); try { var startBytes = startIndex * elementSizeInByte; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); //Store the current bound texture var prevTexture = GraphicsExtensions.GetBoundTexture2D(); GenerateGLTextureIfRequired(); GL.BindTexture(TextureTarget.Texture2D, this.glTexture); GraphicsExtensions.CheckGLError(); if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats) { } else { GL.TexSubImage2D(TextureTarget.Texture2D, level, rect.X, rect.Y, rect.Width, rect.Height, glFormat, glType, dataPtr); GraphicsExtensions.CheckGLError(); } //Restore the bound texture. GL.BindTexture(TextureTarget.Texture2D, prevTexture); GraphicsExtensions.CheckGLError(); } finally { dataHandle.Free(); } }); }
private static Texture2D PlatformFromStream(GraphicsDevice graphicsDevice, Bitmap image) { var width = image.Width; var height = image.Height; int[] pixels = new int[width * height]; if ((width != image.Width) || (height != image.Height)) { using (Bitmap imagePadded = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888)) { Canvas canvas = new Canvas(imagePadded); canvas.DrawARGB(0, 0, 0, 0); canvas.DrawBitmap(image, 0, 0, null); imagePadded.GetPixels(pixels, 0, width, 0, 0, width, height); imagePadded.Recycle(); } } else { image.GetPixels(pixels, 0, width, 0, 0, width, height); } image.Recycle(); // Convert from ARGB to ABGR ConvertToABGR(height, width, pixels); Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, width, height, false, SurfaceFormat.Color); texture.SetData <int>(pixels); }); return(texture); }
protected VertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage, bool dynamic) { VertexBuffer vertexBuffer = this; if (graphicsDevice == null) { throw new ArgumentNullException("Graphics Device Cannot Be null"); } this.GraphicsDevice = graphicsDevice; this.VertexDeclaration = vertexDeclaration; this.VertexCount = vertexCount; this.BufferUsage = bufferUsage; if (vertexDeclaration.GraphicsDevice != graphicsDevice) { vertexDeclaration.GraphicsDevice = graphicsDevice; } this._isDynamic = dynamic; Threading.BlockOnUIThread((Action)(() => { GL.GenBuffers(1, out vertexBuffer.vbo); GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer.vbo); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertexDeclaration.VertexStride * vertexCount), IntPtr.Zero, dynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw); })); }
private static Texture2D PlatformFromStream(GraphicsDevice graphicsDevice, CGImage cgImage) { var width = cgImage.Width; var height = cgImage.Height; var data = new byte[width * height * 4]; var colorSpace = CGColorSpace.CreateDeviceRGB(); var bitmapContext = new CGBitmapContext(data, width, height, 8, width * 4, colorSpace, CGBitmapFlags.PremultipliedLast); bitmapContext.DrawImage(new RectangleF(0, 0, width, height), cgImage); bitmapContext.Dispose(); colorSpace.Dispose(); Texture2D texture = null; Threading.BlockOnUIThread(() => { texture = new Texture2D(graphicsDevice, (int)width, (int)height, false, SurfaceFormat.Color); texture.SetData(data); }); return(texture); }
protected VertexBuffer(GraphicsDevice graphicsDevice, VertexDeclaration vertexDeclaration, int vertexCount, BufferUsage bufferUsage, bool dynamic) { if (graphicsDevice == null) { throw new ArgumentNullException("Graphics Device Cannot Be null"); } this.graphicsDevice = graphicsDevice; this.VertexDeclaration = vertexDeclaration; this.VertexCount = vertexCount; this.BufferUsage = bufferUsage; // Make sure the graphics device is assigned in the vertex declaration. if (vertexDeclaration.GraphicsDevice != graphicsDevice) { vertexDeclaration.GraphicsDevice = graphicsDevice; } _isDynamic = dynamic; #if DIRECTX // TODO: To use Immutable resources we would need to delay creation of // the Buffer until SetData() and recreate them if set more than once. var accessflags = SharpDX.Direct3D11.CpuAccessFlags.None; var usage = SharpDX.Direct3D11.ResourceUsage.Default; if (dynamic) { accessflags |= SharpDX.Direct3D11.CpuAccessFlags.Write; usage = SharpDX.Direct3D11.ResourceUsage.Dynamic; } _buffer = new SharpDX.Direct3D11.Buffer(graphicsDevice._d3dDevice, vertexDeclaration.VertexStride * vertexCount, usage, SharpDX.Direct3D11.BindFlags.VertexBuffer, accessflags, SharpDX.Direct3D11.ResourceOptionFlags.None, 0 // StructureSizeInBytes ); _binding = new SharpDX.Direct3D11.VertexBufferBinding(_buffer, VertexDeclaration.VertexStride, 0); #elif PSS //Do nothing, we cannot create the storage array yet #else Threading.BlockOnUIThread(() => { //GLExt.Oes.GenVertexArrays(1, out this.vao); //GLExt.Oes.BindVertexArray(this.vao); #if IPHONE || ANDROID GL.GenBuffers(1, ref this.vbo); #else GL.GenBuffers(1, out this.vbo); #endif GraphicsExtensions.CheckGLError(); GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo); GraphicsExtensions.CheckGLError(); GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(vertexDeclaration.VertexStride * vertexCount), IntPtr.Zero, dynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw); GraphicsExtensions.CheckGLError(); }); #endif }
protected void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } var bufferSize = VertexCount * VertexDeclaration.VertexStride; if ((vertexStride > bufferSize) || (vertexStride < VertexDeclaration.VertexStride)) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } #if !PSS var elementSizeInBytes = Marshal.SizeOf(typeof(T)); #endif #if DIRECTX if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } SharpDX.DataStream stream; lock (graphicsDevice._d3dContext) { graphicsDevice._d3dContext.MapSubresource( _buffer, mode, SharpDX.Direct3D11.MapFlags.None, out stream); stream.Position = offsetInBytes; stream.WriteRange(data, startIndex, elementCount); graphicsDevice._d3dContext.UnmapSubresource(_buffer, 0); } } else { var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var box = new SharpDX.DataBox(dataPtr, 1, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); lock (graphicsDevice._d3dContext) graphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region); dataHandle.Free(); } #elif PSS if (_vertexArray == null) { _vertexArray = new T[VertexCount]; } Array.Copy(data, offsetInBytes / vertexStride, _vertexArray, startIndex, elementCount); #else Threading.BlockOnUIThread(() => { var sizeInBytes = elementSizeInBytes * elementCount; GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GraphicsExtensions.CheckGLError(); if (options == SetDataOptions.Discard) { // By assigning NULL data to the buffer this gives a hint // to the device to discard the previous content. GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)bufferSize, IntPtr.Zero, _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw); GraphicsExtensions.CheckGLError(); } GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, data); GraphicsExtensions.CheckGLError(); }); #endif }
public void GetData <T> (int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (BufferUsage == BufferUsage.WriteOnly) { throw new NotSupportedException("This VertexBuffer was created with a usage type of BufferUsage.WriteOnly. Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if ((vertexStride > (VertexCount * VertexDeclaration.VertexStride)) || (vertexStride < VertexDeclaration.VertexStride)) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } #if DIRECTX throw new NotImplementedException(); #elif PSS throw new NotImplementedException(); #else Threading.BlockOnUIThread(() => { GL.BindBuffer(BufferTarget.ArrayBuffer, vbo); GraphicsExtensions.CheckGLError(); var elementSizeInByte = Marshal.SizeOf(typeof(T)); #if IPHONE || ANDROID // I think the access parameter takes zero for read only or read/write. // The glMapBufferOES extension spec and gl2ext.h both only mention GL_WRITE_ONLY IntPtr ptr = GL.Oes.MapBuffer(All.ArrayBuffer, (All)0); #else IntPtr ptr = GL.MapBuffer(BufferTarget.ArrayBuffer, BufferAccess.ReadOnly); #endif // Pointer to the start of data to read in the index buffer ptr = new IntPtr(ptr.ToInt64() + offsetInBytes); if (data is byte[]) { byte[] buffer = data as byte[]; // If data is already a byte[] we can skip the temporary buffer // Copy from the vertex buffer to the destination array Marshal.Copy(ptr, buffer, 0, buffer.Length); } else { // Temporary buffer to store the copied section of data byte[] buffer = new byte[elementCount * vertexStride]; // Copy from the vertex buffer to the temporary buffer Marshal.Copy(ptr, buffer, 0, buffer.Length); // Copy from the temporary buffer to the destination array var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInByte); Marshal.Copy(buffer, 0, dataPtr, buffer.Length); dataHandle.Free(); //Buffer.BlockCopy(buffer, 0, data, startIndex * elementSizeInByte, elementCount * elementSizeInByte); } #if IPHONE || ANDROID GL.Oes.UnmapBuffer(All.ArrayBuffer); #else GL.UnmapBuffer(BufferTarget.ArrayBuffer); #endif }); #endif }
private void PlatformConstruct() { Threading.BlockOnUIThread(GenerateIfRequired); }
private void PlatformConstruct(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format, bool renderTarget) { this.glTarget = TextureTarget.TextureCubeMap; Threading.BlockOnUIThread(() => { GL.GenTextures(1, out this.glTexture); GraphicsExtensions.CheckGLError(); GL.BindTexture(TextureTarget.TextureCubeMap, this.glTexture); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, mipMap ? (int)TextureMinFilter.LinearMipmapLinear : (int)TextureMinFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); GraphicsExtensions.CheckGLError(); format.GetGLFormat(GraphicsDevice, out glInternalFormat, out glFormat, out glType); for (var i = 0; i < 6; i++) { var target = GetGLCubeFace((CubeMapFace)i); if (glFormat == (PixelFormat)GLPixelFormat.CompressedTextureFormats) { var imageSize = 0; switch (format) { case SurfaceFormat.RgbPvrtc2Bpp: case SurfaceFormat.RgbaPvrtc2Bpp: imageSize = (Math.Max(size, 16) * Math.Max(size, 8) * 2 + 7) / 8; break; case SurfaceFormat.RgbPvrtc4Bpp: case SurfaceFormat.RgbaPvrtc4Bpp: imageSize = (Math.Max(size, 8) * Math.Max(size, 8) * 4 + 7) / 8; break; case SurfaceFormat.Dxt1: case SurfaceFormat.Dxt1a: case SurfaceFormat.Dxt1SRgb: case SurfaceFormat.Dxt3: case SurfaceFormat.Dxt3SRgb: case SurfaceFormat.Dxt5: case SurfaceFormat.Dxt5SRgb: case SurfaceFormat.RgbEtc1: case SurfaceFormat.RgbaAtcExplicitAlpha: case SurfaceFormat.RgbaAtcInterpolatedAlpha: imageSize = (size + 3) / 4 * ((size + 3) / 4) * format.GetSize(); break; default: throw new NotSupportedException(); } GL.CompressedTexImage2D(target, 0, glInternalFormat, size, size, 0, imageSize, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } else { GL.TexImage2D(target, 0, glInternalFormat, size, size, 0, glFormat, glType, IntPtr.Zero); GraphicsExtensions.CheckGLError(); } } if (mipMap) { #if IOS || ANDROID GL.GenerateMipmap(TextureTarget.TextureCubeMap); #else GraphicsDevice.FramebufferHelper.Get().GenerateMipmap((int)glTarget); // This updates the mipmaps after a change in the base texture GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.GenerateMipmap, (int)Bool.True); #endif GraphicsExtensions.CheckGLError(); } }); }