Example #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();
        }
Example #2
0
 /// <summary>
 /// Processes a resize operation for this texture.
 /// </summary>
 private void ProcessResize()
 {
     using (OpenGLState.ScopedBindTexture2D(texture, true))
     {
         gl.TexImage2D(gl.GL_TEXTURE_2D, 0, (int)internalformat,
                       width, height, 0, format, type, null);
     }
 }
Example #3
0
 /// <summary>
 /// Uploads texture data to the graphics device.
 /// </summary>
 private void Upload(Int32 level, Rectangle region, IntPtr ldata, Int32 offsetInBytes)
 {
     using (OpenGLState.ScopedBindTexture2D(OpenGLName))
     {
         var pData = ldata + offsetInBytes;
         gl.TextureSubImage2D(OpenGLName, gl.GL_TEXTURE_2D, level, region.X, region.Y,
                              region.Width, region.Height, format, type, (void *)pData);
         gl.ThrowIfError();
     }
 }
Example #4
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);
                }));
            }
        }
Example #5
0
        /// <summary>
        /// Creates the underlying native OpenGL texture with the specified format and data.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="internalformat">The texture's internal format.</param>
        /// <param name="width">The texture's width in pixels.</param>
        /// <param name="height">The texture's height in pixels.</param>
        /// <param name="format">The texel format.</param>
        /// <param name="type">The texel data type.</param>
        /// <param name="pixels">A pointer to the beginning of the texture's pixel data.</param>
        /// <param name="immutable">A value indicating whether to use immutable texture storage.</param>
        private void CreateNativeTexture(UltravioletContext uv, UInt32 internalformat, Int32 width, Int32 height, UInt32 format, UInt32 type, void *pixels, Boolean immutable)
        {
            if (uv.IsRunningInServiceMode)
            {
                throw new NotSupportedException(UltravioletStrings.NotSupportedInServiceMode);
            }

            this.width          = width;
            this.height         = height;
            this.internalformat = internalformat;
            this.format         = format;
            this.type           = type;
            this.immutable      = immutable;
            this.srgbEncoded    =
                internalformat == gl.GL_SRGB ||
                internalformat == gl.GL_SRGB_ALPHA ||
                internalformat == gl.GL_SRGB8 ||
                internalformat == gl.GL_SRGB8_ALPHA8;

            this.texture = uv.QueueWorkItem(state =>
            {
                uint glname;

                using (OpenGLState.ScopedCreateTexture2D(out glname))
                {
                    if (gl.IsTextureMaxLevelSupported)
                    {
                        gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAX_LEVEL, 0);
                        gl.ThrowIfError();
                    }

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, (int)gl.GL_LINEAR);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, (int)gl.GL_CLAMP_TO_EDGE);
                    gl.ThrowIfError();

                    gl.TextureParameteri(glname, gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, (int)gl.GL_CLAMP_TO_EDGE);
                    gl.ThrowIfError();

                    if (immutable)
                    {
                        if (gl.IsTextureStorageAvailable)
                        {
                            gl.TextureStorage2D(glname, gl.GL_TEXTURE_2D, 1, internalformat, width, height);
                            gl.ThrowIfError();

                            if (pixels != null)
                            {
                                gl.TextureSubImage2D(glname, gl.GL_TEXTURE_2D, 0, 0, 0, width, height, format, type, pixels);
                                gl.ThrowIfError();
                            }
                        }
                        else
                        {
                            gl.TextureImage2D(glname, gl.GL_TEXTURE_2D, 0, (int)internalformat, width, height, 0, format, type, pixels);
                            gl.ThrowIfError();
                        }
                    }
                }

                if (!immutable)
                {
                    using (OpenGLState.ScopedBindTexture2D(glname, true))
                    {
                        gl.TexImage2D(gl.GL_TEXTURE_2D, 0, (int)internalformat, width, height, 0, format, type, pixels);
                        gl.ThrowIfError();
                    }
                }

                return(glname);
            }).Result;
        }