Beispiel #1
0
        /// <summary>
        /// Sets the texture's data from managed memory.
        /// </summary>
        private unsafe void SetDataInternal <T>(Int32 level, Rectangle?rect, T[] data, Int32 startIndex, Int32 elementCount) where T : struct
        {
            var elementSizeInBytes = Marshal.SizeOf(typeof(T));

            var region       = rect ?? new Rectangle(0, 0, width, height);
            var regionWidth  = region.Width;
            var regionHeight = region.Height;

            var pixelSizeInBytes = (format == gl.GL_RGB || format == gl.GL_BGR) ? 3 : 4;

            if (pixelSizeInBytes * width * height != elementSizeInBytes * elementCount)
            {
                throw new ArgumentException(UltravioletStrings.BufferIsWrongSize);
            }

            Ultraviolet.QueueWorkItem(state =>
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    using (OpenGLState.ScopedBindTexture2D(OpenGLName))
                    {
                        var pData = dataHandle.AddrOfPinnedObject() + (startIndex * elementSizeInBytes);
                        gl.TextureSubImage2D(OpenGLName, gl.GL_TEXTURE_2D, level, region.X, region.Y,
                                             region.Width, region.Height, format, type, (void *)pData);
                        gl.ThrowIfError();
                    }
                }
                finally { dataHandle.Free(); }
            }, null, WorkItemOptions.ReturnNullOnSynchronousExecution)?.Wait();
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                var glname = framebuffer;
                if (glname != 0 && !Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteFramebuffer(glname);
                        gl.ThrowIfError();
                    }, null, WorkItemOptions.ReturnNullOnSynchronousExecution);
                }
                buffers.Clear();

                framebuffer = 0;
            }

            base.Dispose(disposing);
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    var glname = vao;
                    if (glname != 0)
                    {
                        Ultraviolet.QueueWorkItem((state) =>
                        {
                            gl.DeleteVertexArray(glname);
                            gl.ThrowIfError();

                            OpenGLState.DeleteVertexArrayObject(glname, glElementArrayBufferBinding ?? 0);
                        }, null, WorkItemOptions.ReturnNullOnSynchronousExecution);
                    }

                    vao = 0;
                }
                vbuffers.Clear();
                ibuffer = null;
            }

            base.Dispose(disposing);
        }
Beispiel #4
0
        /// <summary>
        /// Sets the texture's data from native memory.
        /// </summary>
        private unsafe void SetRawDataInternal(Int32 level, Rectangle?rect, IntPtr data, Int32 offsetInBytes, Int32 sizeInBytes)
        {
            var region       = rect ?? new Rectangle(0, 0, width, height);
            var regionWidth  = region.Width;
            var regionHeight = region.Height;

            var pixelSizeInBytes = (format == gl.GL_RGB || format == gl.GL_BGR) ? 3 : 4;

            if (pixelSizeInBytes * width * height != sizeInBytes)
            {
                throw new ArgumentException(UltravioletStrings.BufferIsWrongSize);
            }

            if (Ultraviolet.IsExecutingOnCurrentThread)
            {
                Upload(level, region, data, offsetInBytes);
            }
            else
            {
                Ultraviolet.QueueWorkItem(state =>
                {
                    Upload(level, region, data, offsetInBytes);
                }, null, WorkItemOptions.ReturnNullOnSynchronousExecution)?.Wait();
            }
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    if (vao != 0)
                    {
                        Ultraviolet.QueueWorkItem((state) =>
                        {
                            var vaoName = ((OpenGLGeometryStream)state).vao;

                            gl.DeleteVertexArray(vaoName);
                            gl.ThrowIfError();

                            OpenGLState.DeleteVertexArrayObject(vaoName, 0, glElementArrayBufferBinding ?? 0);
                        }, this);
                    }
                }
                vbuffers.Clear();
                ibuffer = null;
            }

            base.Dispose(disposing);
        }
        /// <inheritdoc/>
        public override void Resize(Int32 width, Int32 height, Int32 depth)
        {
            Contract.EnsureNotDisposed(this, Disposed);
            Contract.EnsureRange(width >= 1, nameof(width));
            Contract.EnsureRange(height >= 1, nameof(height));

            if (BoundForReading || BoundForWriting)
            {
                throw new InvalidOperationException(OpenGLStrings.InvalidOperationWhileBound);
            }

            this.width  = width;
            this.height = height;
            this.depth  = depth;

            if (immutable)
            {
                throw new InvalidOperationException(rbuffer ? OpenGLStrings.RenderBufferIsImmutable : OpenGLStrings.TextureIsImmutable);
            }

            if (Ultraviolet.IsExecutingOnCurrentThread)
            {
                ProcessResize();
            }
            else
            {
                Ultraviolet.QueueWorkItem((state) => { ((OpenGLTexture3D)state).ProcessResize(); }, this);
            }
        }
        /// <inheritdoc/>
        public override void Attach(RenderBuffer2D buffer)
        {
            Contract.Require(buffer, nameof(buffer));
            Contract.Ensure <ArgumentException>(
                buffer.Width == width &&
                buffer.Height == height, OpenGLStrings.RenderBufferIsWrongSize);
            Contract.EnsureNotDisposed(this, Disposed);

            Ultraviolet.ValidateResource(buffer);

            var oglBuffer = (OpenGLRenderBuffer2D)buffer;

            Ultraviolet.QueueWorkItem(state =>
            {
                using (OpenGLState.ScopedBindFramebuffer(framebuffer))
                {
                    AttachRenderBuffer(oglBuffer);

                    framebufferStatus = gl.CheckNamedFramebufferStatus(framebuffer, gl.GL_FRAMEBUFFER);
                    gl.ThrowIfError();
                }
            }).Wait();

            oglBuffer.MarkAttached();

            buffers.Add(oglBuffer);
        }
Beispiel #8
0
        /// <summary>
        /// Releases resources associated with the object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    ((OpenGLUltravioletGraphics)Ultraviolet.GetGraphics()).UnbindTexture(this);
                }

                if (willNotBeSampled)
                {
                    if (!Ultraviolet.Disposed && renderbuffer != 0)
                    {
                        Ultraviolet.QueueWorkItem((state) =>
                        {
                            gl.DeleteRenderBuffers(((OpenGLRenderBuffer2D)state).renderbuffer);
                            gl.ThrowIfError();
                        }, this);
                    }
                }
                else
                {
                    SafeDispose.Dispose(texture);
                }
            }

            base.Dispose(disposing);
        }
Beispiel #9
0
        /// <summary>
        /// Sets the texture's data.
        /// </summary>
        private void SetDataInternal <T>(Int32 level, Int32 left, Int32 top, Int32 right, Int32 bottom, Int32 front, Int32 back, T[] data, Int32 startIndex, Int32 elementCount) where T : struct
        {
            var elementSizeInBytes = Marshal.SizeOf(typeof(T));
            var width  = right - left;
            var height = bottom - top;
            var depth  = back - front;

            var pixelSizeInBytes = (format == gl.GL_RGB || format == gl.GL_BGR) ? 3 : 4;

            if (pixelSizeInBytes * width * height * depth != elementSizeInBytes * elementCount)
            {
                throw new ArgumentException(UltravioletStrings.BufferIsWrongSize);
            }

            Ultraviolet.QueueWorkItem(state =>
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    using (OpenGLState.ScopedBindTexture3D(OpenGLName))
                    {
                        var pData = dataHandle.AddrOfPinnedObject() + (startIndex * elementSizeInBytes);
                        gl.TextureSubImage3D(OpenGLName, gl.GL_TEXTURE_3D, level, left, top, front,
                                             right - left, bottom - top, back - front, format, type, (void *)pData);
                        gl.ThrowIfError();
                    }
                }
                finally { dataHandle.Free(); }
            }).Wait();
        }
        /// <summary>
        /// Sets the texture's data from native memory.
        /// </summary>
        private void SetRawDataInternal(Int32 level, Int32 left, Int32 top, Int32 right, Int32 bottom, Int32 front, Int32 back, IntPtr data, Int32 offsetInBytes, Int32 sizeInBytes)
        {
            var width  = right - left;
            var height = bottom - top;
            var depth  = back - front;

            var pixelSizeInBytes = (format == gl.GL_RGB || format == gl.GL_BGR) ? 3 : 4;

            if (pixelSizeInBytes * width * height * depth != sizeInBytes)
            {
                throw new ArgumentException(UltravioletStrings.BufferIsWrongSize);
            }

            if (Ultraviolet.IsExecutingOnCurrentThread)
            {
                Upload(level, left, top, right, bottom, front, back, data, offsetInBytes, sizeInBytes);
            }
            else
            {
                Ultraviolet.QueueWorkItem(state =>
                {
                    Upload(level, left, top, right, bottom, front, back, data, offsetInBytes, sizeInBytes);
                }, null, WorkItemOptions.ReturnNullOnSynchronousExecution)?.Wait();
            }
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                var glname = texture;
                if (glname != 0 && !Ultraviolet.Disposed)
                {
                    ((OpenGLUltravioletGraphics)Ultraviolet.GetGraphics()).UnbindTexture(this);
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteTexture(glname);
                        gl.ThrowIfError();
                    }, this, WorkItemOptions.ReturnNullOnSynchronousExecution);
                }

                texture = 0;
            }

            base.Dispose(disposing);
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (OpenGLState.GL_ARRAY_BUFFER_BINDING == buffer)
                {
                    OpenGLState.GL_ARRAY_BUFFER_BINDING.Update(0);
                }

                var glname = buffer;
                if (glname != 0 && !Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteBuffer(glname);
                        gl.ThrowIfError();
                    }, this, WorkItemOptions.ReturnNullOnSynchronousExecution);
                }

                buffer = 0;
            }

            base.Dispose(disposing);
        }
        /// <summary>
        /// Releases resources associated with the object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteProgram(((OpenGLShaderProgram)state).program);
                        gl.ThrowIfError();
                    }, this);
                }

                if (programOwnsShaders)
                {
                    SafeDispose.Dispose(vertexShader);
                    SafeDispose.Dispose(fragmentShader);
                }
            }

            base.Dispose(disposing);
        }
Beispiel #14
0
        /// <summary>
        /// Releases resources associated with this object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    var glname = buffer;

                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteBuffer(glname);
                        gl.ThrowIfError();
                    }, this, WorkItemOptions.ReturnNullOnSynchronousExecution);
                }

                buffer = 0;
            }

            base.Dispose(disposing);
        }
Beispiel #15
0
        /// <summary>
        /// Releases resources associated with the object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                var glname = program;
                if (glname != 0 && !Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteProgram(glname);
                        gl.ThrowIfError();
                    }, this, WorkItemOptions.ReturnNullOnSynchronousExecution);
                }

                if (programOwnsShaders)
                {
                    SafeDispose.Dispose(vertexShader);
                    SafeDispose.Dispose(fragmentShader);
                }

                program = 0;
            }

            base.Dispose(disposing);
        }
 /// <summary>
 /// Sets the buffer's data from native memory.
 /// </summary>
 private void SetRawDataInternal(IntPtr data, Int32 offsetInBytes, Int32 countInBytes, SetDataOptions options)
 {
     if (Ultraviolet.IsExecutingOnCurrentThread)
     {
         Upload(data, offsetInBytes, countInBytes, options);
     }
     else
     {
         Ultraviolet.QueueWorkItem(state =>
         {
             Upload(data, offsetInBytes, countInBytes, options);
         }, null, WorkItemOptions.ForceAsynchronousExecution)?.Wait();
     }
 }
Beispiel #17
0
        /// <summary>
        /// Releases resources associated with this object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteShader(((OpenGLVertexShader)state).shader);
                        gl.ThrowIfError();
                    }, this);
                }
            }

            base.Dispose(disposing);
        }
Beispiel #18
0
        /// <summary>
        /// Uploads texture data to the graphics device.
        /// </summary>
        private unsafe Task Upload(Int32 level, Rectangle region, IntPtr ldata, Int32 startIndex, Int32 elementSizeInBytes)
        {
            if (Ultraviolet.IsExecutingOnCurrentThread)
            {
                using (OpenGLState.ScopedBindTexture2D(OpenGLName))
                {
                    var pData = ldata + (startIndex * elementSizeInBytes);
                    gl.TextureSubImage2D(OpenGLName, gl.GL_TEXTURE_2D, level, region.X, region.Y,
                                         region.Width, region.Height, format, type, (void *)pData);
                    gl.ThrowIfError();
                }

                return(null);
            }
            else
            {
                return(Ultraviolet.QueueWorkItem(state =>
                {
                    Upload(level, region, ldata, startIndex, elementSizeInBytes);
                }));
            }
        }
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    ((OpenGLUltravioletGraphics)Ultraviolet.GetGraphics()).UnbindTexture(this);
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteTexture(((OpenGLTexture2D)state).texture);
                        gl.ThrowIfError();
                    }, this);
                }
            }

            base.Dispose(disposing);
        }
Beispiel #20
0
        /// <inheritdoc/>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    Ultraviolet.QueueWorkItem((state) =>
                    {
                        gl.DeleteFramebuffer(((OpenGLRenderTarget2D)state).framebuffer);
                        gl.ThrowIfError();
                    }, this);
                }
                buffers.Clear();
            }

            base.Dispose(disposing);
        }
Beispiel #21
0
        /// <summary>
        /// Releases resources associated with the object.
        /// </summary>
        /// <param name="disposing">true if the object is being disposed; false if the object is being finalized.</param>
        protected override void Dispose(Boolean disposing)
        {
            if (Disposed)
            {
                return;
            }

            if (disposing)
            {
                if (!Ultraviolet.Disposed)
                {
                    ((OpenGLUltravioletGraphics)Ultraviolet.GetGraphics()).UnbindTexture(this);
                }

                if (willNotBeSampled)
                {
                    var glname = renderbuffer;

                    if (!Ultraviolet.Disposed && glname != 0)
                    {
                        Ultraviolet.QueueWorkItem((state) =>
                        {
                            gl.DeleteRenderBuffers(glname);
                            gl.ThrowIfError();
                        }, null, WorkItemOptions.ReturnNullOnSynchronousExecution);
                    }

                    renderbuffer = 0;
                }
                else
                {
                    SafeDispose.Dispose(texture);
                }
            }

            base.Dispose(disposing);
        }
 /// <summary>
 /// Sets the buffer's data from native memory.
 /// </summary>
 private void SetDataInternal(Object data, Int32 srcOffsetInBytes, Int32 dstOffsetInBytes, Int32 countInBytes, SetDataOptions options)
 {
     if (Ultraviolet.IsExecutingOnCurrentThread)
     {
         var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
         try
         {
             Upload(pData.AddrOfPinnedObject() + srcOffsetInBytes, dstOffsetInBytes, countInBytes, options);
         }
         finally { pData.Free(); }
     }
     else
     {
         Ultraviolet.QueueWorkItem(state =>
         {
             var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
             try
             {
                 Upload(pData.AddrOfPinnedObject() + srcOffsetInBytes, dstOffsetInBytes, countInBytes, options);
             }
             finally { pData.Free(); }
         }, null, WorkItemOptions.ForceAsynchronousExecution)?.Wait();
     }
 }
 /// <summary>
 /// Sets the texture's data from managed memory.
 /// </summary>
 private void SetDataInternal(Int32 level, Int32 left, Int32 top, Int32 right, Int32 bottom, Int32 front, Int32 back, Object data, Int32 offsetInBytes, Int32 sizeInBytes)
 {
     if (Ultraviolet.IsExecutingOnCurrentThread)
     {
         var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
         try
         {
             SetRawDataInternal(level, left, top, right, bottom, front, back, pData.AddrOfPinnedObject(), offsetInBytes, sizeInBytes);
         }
         finally { pData.Free(); }
     }
     else
     {
         Ultraviolet.QueueWorkItem(state =>
         {
             var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
             try
             {
                 SetRawDataInternal(level, left, top, right, bottom, front, back, pData.AddrOfPinnedObject(), 0, sizeInBytes);
             }
             finally { pData.Free(); }
         }, null, WorkItemOptions.ReturnNullOnSynchronousExecution)?.Wait();
     }
 }
Beispiel #24
0
 /// <summary>
 /// Sets the texture's data from managed memory.
 /// </summary>
 private unsafe void SetDataInternal(Int32 level, Rectangle?rect, Object data, Int32 offsetInBytes, Int32 sizeInBytes)
 {
     if (Ultraviolet.IsExecutingOnCurrentThread)
     {
         var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
         try
         {
             SetRawDataInternal(level, rect, pData.AddrOfPinnedObject(), offsetInBytes, sizeInBytes);
         }
         finally { pData.Free(); }
     }
     else
     {
         Ultraviolet.QueueWorkItem(state =>
         {
             var pData = GCHandle.Alloc(data, GCHandleType.Pinned);
             try
             {
                 SetRawDataInternal(level, rect, pData.AddrOfPinnedObject(), 0, sizeInBytes);
             }
             finally { pData.Free(); }
         }, null, WorkItemOptions.ReturnNullOnSynchronousExecution)?.Wait();
     }
 }
Beispiel #25
0
        /// <summary>
        /// Creates the effect pass' collection of uniforms.
        /// </summary>
        /// <param name="ssmd">The source metadata for this program.</param>
        /// <returns>The collection of uniforms that was created.</returns>
        private OpenGLShaderUniformCollection CreateUniformCollection(ShaderSourceMetadata ssmd)
        {
            var result = Ultraviolet.QueueWorkItem(state =>
            {
                var programObject = ((OpenGLShaderProgram)state);
                var program       = programObject.program;
                var uniforms      = new List <OpenGLShaderUniform>();
                var samplerCount  = 0;

                var count = gl.GetProgrami(program, gl.GL_ACTIVE_UNIFORMS);
                gl.ThrowIfError();

                for (uint i = 0; i < count; i++)
                {
                    var type = 0u;
                    var name = gl.GetActiveUniform(program, i, out type);
                    gl.ThrowIfError();

                    var location = gl.GetUniformLocation(program, name);
                    gl.ThrowIfError();

                    var isSampler = false;
                    switch (type)
                    {
                    case gl.GL_SAMPLER_1D:
                    case gl.GL_SAMPLER_1D_ARRAY:
                    case gl.GL_SAMPLER_1D_ARRAY_SHADOW:
                    case gl.GL_SAMPLER_1D_SHADOW:
                    case gl.GL_SAMPLER_2D:
                    case gl.GL_SAMPLER_2D_ARRAY:
                    case gl.GL_SAMPLER_2D_ARRAY_SHADOW:
                    case gl.GL_SAMPLER_2D_MULTISAMPLE:
                    case gl.GL_SAMPLER_2D_MULTISAMPLE_ARRAY:
                    case gl.GL_SAMPLER_2D_RECT:
                    case gl.GL_SAMPLER_2D_RECT_SHADOW:
                    case gl.GL_SAMPLER_2D_SHADOW:
                    case gl.GL_SAMPLER_3D:
                    case gl.GL_SAMPLER_CUBE:
                    case gl.GL_SAMPLER_CUBE_MAP_ARRAY:
                    case gl.GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW:
                    case gl.GL_SAMPLER_CUBE_SHADOW:
                        isSampler = true;
                        break;
                    }

                    var sampler = isSampler ? samplerCount++ : -1;
                    if (isSampler && ssmd.PreferredSamplerIndices.ContainsKey(name))
                    {
                        samplerCount = ssmd.PreferredSamplerIndices[name];
                        sampler      = samplerCount++;
                    }
                    uniforms.Add(new OpenGLShaderUniform(programObject.Ultraviolet, name, type, program, location, sampler));
                }

                return(uniforms);
            }, this).Result;

            // Validation: make sure all preferred samplers correspond to an actual uniform
            var missingUniform = ssmd.PreferredSamplerIndices.Keys.Where(x => !result.Where(y => String.Equals(y.Name, x, StringComparison.Ordinal)).Any()).FirstOrDefault();

            if (missingUniform != null)
            {
                throw new ArgumentException(OpenGLStrings.SamplerDirectiveInvalidUniform.Format(missingUniform));
            }

            return(new OpenGLShaderUniformCollection(result));
        }