/// <summary>
        /// Creates a new Cube <see cref="Texture" /> from a initial data..
        /// </summary>
        /// <typeparam name="T">Type of a pixel data</typeparam>
        /// <param name="device">The <see cref="GraphicsDevice" />.</param>
        /// <param name="size">The size (in pixels) of the top-level faces of the cube texture.</param>
        /// <param name="format">Describes the format to use.</param>
        /// <param name="textureData">an array of 6 textures. See remarks</param>
        /// <param name="textureFlags">The texture flags.</param>
        /// <param name="usage">The usage.</param>
        /// <returns>A new instance of Cube <see cref="Texture" /> class.</returns>
        /// <exception cref="System.ArgumentException">Invalid texture datas. First dimension must be equal to 6;textureData</exception>
        /// <remarks>The first dimension of mipMapTextures describes the number of array (TextureCube Array), the second is the texture data for a particular cube face.</remarks>
        public unsafe static Texture NewCube <T>(GraphicsDevice device, int size, PixelFormat format, T[][] textureData, TextureFlags textureFlags = TextureFlags.ShaderResource, GraphicsResourceUsage usage = GraphicsResourceUsage.Immutable) where T : struct
        {
            if (textureData.Length != 6)
            {
                throw new ArgumentException("Invalid texture datas. First dimension must be equal to 6", "textureData");
            }

            var dataBoxes = new DataBox[6];

            dataBoxes[0] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[0]));
            dataBoxes[1] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[1]));
            dataBoxes[2] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[2]));
            dataBoxes[3] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[3]));
            dataBoxes[4] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[4]));
            dataBoxes[5] = GetDataBox(format, size, size, 1, textureData[0], (IntPtr)Interop.Fixed(textureData[5]));

            return(new Texture(device).InitializeFrom(TextureDescription.NewCube(size, format, textureFlags, usage), dataBoxes));
        }
Example #2
0
        private void CreateTexture2DArray(bool compressed, int width, int height, int mipLevel, int arrayIndex, DataBox dataBox)
        {
            // We create all array slices at once, but upload them one by one
            if (arrayIndex == 0)
            {
                if (compressed)
                {
                    GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, mipLevel, (CompressedInternalFormat3D)TextureInternalFormat, width, height, ArraySize, 0, 0, IntPtr.Zero);
                }
                else
                {
                    GL.TexImage3D((TextureTarget3d)TextureTarget, mipLevel, (TextureComponentCount3D)TextureInternalFormat, width, height, ArraySize, 0, TextureFormat, TextureType, IntPtr.Zero);
                }
            }

            if (dataBox.DataPointer != IntPtr.Zero)
            {
                if (compressed)
                {
                    GL.CompressedTexSubImage3D((TextureTarget3d)TextureTarget, mipLevel, 0, 0, arrayIndex, width, height, 1, TextureFormat, dataBox.SlicePitch, dataBox.DataPointer);
                }
                else
                {
                    GL.TexSubImage3D((TextureTarget3d)TextureTarget, mipLevel, 0, 0, arrayIndex, width, height, 1, TextureFormat, TextureType, dataBox.DataPointer);
                }
            }
        }
Example #3
0
 private void CreateTexture3D(bool compressed, int width, int height, int depth, int mipLevel, DataBox dataBox)
 {
     if (compressed)
     {
         GL.CompressedTexImage3D((TextureTarget3d)TextureTarget, mipLevel, (CompressedInternalFormat3D)TextureInternalFormat, width, height, depth, 0, dataBox.SlicePitch, dataBox.DataPointer);
     }
     else
     {
         GL.TexImage3D((TextureTarget3d)TextureTarget, mipLevel, (TextureComponentCount3D)TextureInternalFormat, width, height, depth, 0, TextureFormat, TextureType, dataBox.DataPointer);
     }
 }
Example #4
0
        private void CreateTexture2D(bool compressed, int width, int height, int mipLevel, int arrayIndex, DataBox dataBox)
        {
            if (IsMultisample)
            {
                throw new InvalidOperationException("Currently if multisampling is on, a renderbuffer will be created (not a texture) in any case and this code will not be reached." +
                                                    "Therefore if this place is reached, it means something went wrong. Once multisampling has been implemented for OpenGL textures, you can remove this exception.");

                if (IsRenderbuffer)
                {
#if !XENKO_PLATFORM_IOS
                    // MSAA is not supported on iOS currently because OpenTK doesn't expose "GL.BlitFramebuffer()" on iOS for some reason.
                    GL.RenderbufferStorageMultisample(RenderbufferTarget.Renderbuffer, (int)Description.MultisampleCount, (RenderbufferStorage)TextureInternalFormat, width, height);
#endif
                }
                else
                {
#if XENKO_GRAPHICS_API_OPENGLES
                    throw new NotSupportedException("Multisample textures are not supported on OpenGL ES.");
#else
                    GL.TexImage2DMultisample(TextureTargetMultisample.Texture2DMultisample, (int)Description.MultisampleCount, (TextureComponentCount2D)TextureInternalFormat, width, height, false);
#endif
                }
            }
            else
            {
                var dataSetTarget = GetTextureTargetForDataSet2D(TextureTarget, arrayIndex);
                if (compressed)
                {
                    GL.CompressedTexImage2D(dataSetTarget, mipLevel, (CompressedInternalFormat2D)TextureInternalFormat, width, height, 0, dataBox.SlicePitch, dataBox.DataPointer);
                }
                else
                {
                    GL.TexImage2D(dataSetTarget, mipLevel, (TextureComponentCount2D)TextureInternalFormat, width, height, 0, TextureFormat, TextureType, dataBox.DataPointer);
                }
            }
        }
Example #5
0
        private void InitializeFromImpl(DataBox[] dataBoxes = null)
        {
            if (ParentTexture != null)
            {
                CopyParentAttributes();
            }

            if (TextureId == 0)
            {
                TextureTarget = GetTextureTarget(Dimension);

                bool compressed;
                OpenGLConvertExtensions.ConvertPixelFormat(GraphicsDevice, ref textureDescription.Format, out TextureInternalFormat, out TextureFormat, out TextureType, out TexturePixelSize, out compressed);

                DepthPitch = Description.Width * Description.Height * TexturePixelSize;
                RowPitch   = Description.Width * TexturePixelSize;

                IsDepthBuffer = ((Description.Flags & TextureFlags.DepthStencil) != 0);
                if (IsDepthBuffer)
                {
                    HasStencil = InternalHasStencil(Format);
                }
                else
                {
                    HasStencil = false;
                }

                if ((Description.Flags & TextureFlagsCustomResourceId) != 0)
                {
                    return;
                }

                using (var openglContext = GraphicsDevice.UseOpenGLCreationContext())
                {
                    TextureTotalSize = ComputeBufferTotalSize();

                    if (Description.Usage == GraphicsResourceUsage.Staging)
                    {
                        InitializeStagingPixelBufferObject(dataBoxes);
                        return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay?
                    }

                    // Depth textures are renderbuffers for now // TODO: PERFORMANCE: Why? I think we should change that so we can sample them directly.
                    // TODO: enable switch  // TODO: What does this comment even mean?

                    IsRenderbuffer = !Description.IsShaderResource;

                    // Force to renderbuffer if MSAA is on because we don't support MSAA textures ATM (and they don't exist on OpenGL ES).
                    if (Description.IsMultisample)
                    {
                        // TODO: Ideally the caller of this method should be aware of this "force to renderbuffer",
                        //       because the caller won't be able to bind it as a texture.
                        IsRenderbuffer = true;
                    }

                    if (IsRenderbuffer)
                    {
                        CreateRenderbuffer();
                        return; // TODO: This return causes "GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);" not to get entered. Is that okay?
                    }

                    GL.GenTextures(1, out TextureId);
                    GL.BindTexture(TextureTarget, TextureId);
                    SetFilterMode();

                    if (Description.MipLevels == 0)
                    {
                        throw new NotImplementedException();
                    }

                    var setSize = TextureSetSize(TextureTarget);

                    for (var arrayIndex = 0; arrayIndex < Description.ArraySize; ++arrayIndex)
                    {
                        int offsetArray = arrayIndex * Description.MipLevels;

                        for (int mipLevel = 0; mipLevel < Description.MipLevels; ++mipLevel)
                        {
                            DataBox dataBox;
                            Int3    dimensions = new Int3(CalculateMipSize(Description.Width, mipLevel),
                                                          CalculateMipSize(Description.Height, mipLevel),
                                                          CalculateMipSize(Description.Depth, mipLevel));
                            if (dataBoxes != null && mipLevel < dataBoxes.Length)
                            {
                                if (setSize > 1 && !compressed && dataBoxes[mipLevel].RowPitch != dimensions.X * TexturePixelSize)
                                {
                                    throw new NotSupportedException("Can't upload texture with pitch in glTexImage2D/3D.");
                                }
                                // Might be possible, need to check API better.
                                dataBox = dataBoxes[offsetArray + mipLevel];
                            }
                            else
                            {
                                dataBox = new DataBox();
                            }

                            switch (TextureTarget)
                            {
                            case TextureTarget.Texture1D:
                                CreateTexture1D(compressed, dimensions.X, mipLevel, dataBox);
                                break;

                            case TextureTarget.Texture2D:
                            case TextureTarget.TextureCubeMap:
                                CreateTexture2D(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox);
                                break;

                            case TextureTarget.Texture3D:
                                CreateTexture3D(compressed, dimensions.X, dimensions.Y, dimensions.Z, mipLevel, dataBox);
                                break;

                            case TextureTarget.Texture2DArray:
                                CreateTexture2DArray(compressed, dimensions.X, dimensions.Y, mipLevel, arrayIndex, dataBox);
                                break;
                            }
                        }
                    }

                    GL.BindTexture(TextureTarget, 0);   // This unbinds the texture.
                    if (openglContext.CommandList != null)
                    {
                        // If we messed up with some states of a command list, mark dirty states
                        openglContext.CommandList.boundShaderResourceViews[openglContext.CommandList.activeTexture] = null;
                    }
                }

                GraphicsDevice.RegisterTextureMemoryUsage(SizeInBytes);
            }
        }
Example #6
0
 internal unsafe void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
 {
     if (resource == null)
     {
         throw new ArgumentNullException("resource");
     }
     NativeDeviceContext.UpdateSubresource(*(SharpDX.DataBox *)Interop.Cast(ref databox), resource.NativeResource, subResourceIndex, *(SharpDX.Direct3D11.ResourceRegion *)Interop.Cast(ref region));
 }
Example #7
0
 internal void UpdateSubresource(GraphicsResource resource, int subResourceIndex, DataBox databox, ResourceRegion region)
 {
     NullHelper.ToImplement();
 }