Example #1
0
        /// <summary>
        /// イメージデータからテクスチャの作成を行います。
        /// </summary>
        public bool Create(Bitmap image, bool toPremultipliedAlpha = false)
        {
            if (image == null)
            {
                throw new ArgumentNullException("image");
            }

            ValidateContext();

            int[] textureMaxSize = { 0 };
            GLWrap.Wrap(() => GL.GetInteger(GetPName.MaxTextureSize, textureMaxSize));

            // 2のn乗値の中から、元の画像サイズを超えるような
            // 一番小さな値を探します。
            int targetWidth = textureMaxSize[0];

            for (int size = 1; size <= textureMaxSize[0]; size *= 2)
            {
                if (image.Width < size)
                {
                    targetWidth = size;
                    break;
                }
            }

            int targetHeight = textureMaxSize[0];

            for (int size = 1; size <= textureMaxSize[0]; size *= 2)
            {
                if (image.Height < size)
                {
                    targetHeight = size;
                    break;
                }
            }

            // 画像のリサイズが必要な場合
            var result = false;

            if (image.Width != targetWidth || image.Height != targetHeight)
            {
                using (var newImage = new Bitmap(targetWidth, targetHeight))
                {
                    DrawHighQuality(
                        newImage, image,
                        Math.Min(image.Width, newImage.Width),
                        Math.Min(image.Height, newImage.Height));
                    result = CreateInternal(newImage, image.Size, toPremultipliedAlpha);
                }
            }
            else
            {
                // imageの内容が変わる可能性があるため、ここでCloneしています。
                using (var newImage = (Bitmap)image.Clone())
                {
                    result = CreateInternal(newImage, image.Size, toPremultipliedAlpha);
                }
            }

            GC.Collect();
            return(result);
        }
Example #2
0
        /// <summary>
        /// テクスチャデータの作成を行います。
        /// </summary>
        /// <remarks>
        /// イメージからテクスチャを作成するのみで
        /// サイズの変更などの余計なことは一切行いません。
        ///
        /// またこのメソッドには所有権を渡してもよいイメージオブジェクトを
        /// 与えてください。
        /// </remarks>
        private bool CreateInternal(Bitmap image, Size originalSize,
                                    bool toPremultipliedAlpha)
        {
            uint texture = 0;

            GLWrap.Wrap(() => GL.GenTextures(1, out texture));

            //  Lock the image bits (so that we can pass them to OGL).
            var bitmapData = image.LockBits(
                new Rectangle(0, 0, image.Width, image.Height),
                ImageLockMode.ReadOnly,
                Imaging.PixelFormat.Format32bppArgb);

            try
            {
                if (toPremultipliedAlpha)
                {
                    MakePremutipliedAlpha(bitmapData);
                }

                GLWrap.Wrap(() => GL.BindTexture(TextureTarget.Texture2D, texture));

                // TexParameterのGenerateMipmapを使う場合
                if (GenerateMipmapSupportLevel == 1)
                {
                    // glTexImage2Dの前にmipmapの使用設定を行う
                    //GLWrap.Wrap(() => GL.Hint(HintTarget.GenerateMipmapHint, HintMode.Nicest));
                    GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1));
                }

                //  テクスチャデータをセットします。
#if true
                GLWrap.Wrap(() => GL.TexImage2D(
                                TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba8,
                                image.Width, image.Height, 0,
                                OpenTK.Graphics.OpenGL.PixelFormat.Bgra,
                                PixelType.UnsignedByte,
                                bitmapData.Scan0));
#else
                GLWrap.Wrap(() => GL.Build2DMipmaps(
                                TextureTarget.Texture2D, (int)OpenGL.GL_RGBA,
                                image.Width, image.Height,
                                OpenTK.Graphics.OpenGL.GL_BGRA, GL.GL_UNSIGNED_BYTE,
                                bitmapData.Scan0));
#endif
            }
            finally
            {
                image.UnlockBits(bitmapData);
            }

            GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp));
            GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp));

            // glGenerateMipmapを使う場合
            if (GenerateMipmapSupportLevel == 2)
            {
                GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
            }

            if (GenerateMipmapSupportLevel > 0)
            {
                // Mipmapを使う場合はフィルターを設定
                GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear));
                GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear));
            }
            else
            {
                GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear));
                GLWrap.Wrap(() => GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear));
            }

            GL.BindTexture(TextureTarget.Texture2D, 0);

            // テクスチャの作成に成功したら、古いテクスチャを削除します。
            Destroy();

            this.glTexture       = texture;
            Width                = image.Width;
            Height               = image.Height;
            OriginalWidth        = originalSize.Width;
            OriginalHeight       = originalSize.Height;
            IsPremultipliedAlpha = toPremultipliedAlpha;
            return(true);
        }