Exemplo n.º 1
0
        /// <summary>
        /// GetTexture/GetTextureSolid用のhelper
        /// </summary>
        /// <remarks>
        /// isBlendedの値に応じて、DrawBlendedUnicodeとDrawTextureSolidとを切り替えて描画する。
        /// </remarks>
        /// <param name="letter"></param>
        /// <param name="style"></param>
        /// <param name="isBlended"></param>
        /// <returns></returns>
        private ITexture GetTextureHelper(char letter, int style, bool isBlended)
        {
            if (loader == null)
            {
                return(null);                     // うんこーヽ(`Д´)ノ
            }
            int index = int.MaxValue;             // fail safe

            //	探してみる
            for (int i = 0; i < fonts.Count; ++i)
            {
                if ((fonts[i].Letter == letter) &&
                    (fonts[i].Style == style) &&
                    (fonts[i].FontLoader == loader) &&
                    (fonts[i].FontNo == fontNo))
                {
                    //	みっけ!
                    index = i;
                    goto Exit;
                }
            }

            // 見つからなかったので生成してみる

            ITexture texture = factory();

            if (texture == null)
            {
                return(null);                // factory設定されとらん(´ω`)
            }
            Font font = loader.GetFont(fontNo);

            if (font != null)
            {
                Surface surface =
                    isBlended
                                        ? font.DrawBlendedUnicode(letter.ToString())
                                        : font.DrawSolidUnicode(letter.ToString());
                texture.SetSurface(surface);
                surface.Dispose();                 // 解放しとかなきゃ
            }
            else
            {
                // なんやー。読み込まれへんかったわ
                return(null);               // 生成失敗
            }

            // 生成できた。次に空き場所を確定させる

            if (fonts.Count == max)
            {
                //	場所が空いてないので、一番最後に参照された
                //	オブジェクトを解放する
                long t = long.MaxValue;
                for (int i = 0; i < fonts.Count; ++i)
                {
                    if (fonts[i].LastAccessTime < t)
                    {
                        t     = fonts[i].LastAccessTime;
                        index = i;
                    }
                }
                ITexture tt = fonts[index].Texture;
                if (tt != null)
                {
                    tt.Dispose();                     // 一応解放しておく
                }
            }
            else
            {
                index = fonts.Count;
                fonts.Add(new Info());                 // ひとつ確保
            }

            // このlocal copy、最適化で消えるやろか?
            Info info = new Info();

            info.Letter     = letter;
            info.FontLoader = loader;
            info.FontNo     = fontNo;
            info.Style      = style;
            info.Texture    = texture;

            fonts[index] = info;

Exit:
            //	これ参照したので、時刻をずらしておく。
            fonts[index].LastAccessTime = ++time;
            return(fonts[index].Texture);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Screenの画像をサーフェスにする。
        /// ただし、画面の上に載せている.NET Frameworkのコントロールは
        /// キャプチャできないので注意。
        /// </summary>
        public Surface GetSurface()
        {
            Surface surface = new Surface();

            if (surface.CreateDIB(Width, Height, false) != YanesdkResult.NoError)
            {
                surface.Dispose();
                return(null);
            }

            // 読み出し元を設定。
            // デフォルトでバックバッファだが念のため設定。
            //Gl.glReadBuffer(Gl.GL_FRONT);
            Gl.glReadBuffer(Gl.GL_BACK);

            //*

            Gl.glReadPixels(0, 0, surface.Width, surface.Height,
                            surface.Alpha ? Gl.GL_RGBA : Gl.GL_RGB,
                            Gl.GL_UNSIGNED_BYTE,
                            surface.Pixels);

            // glReadPixels()で取得したピクセルが上下逆で、
            // 反転させる方法が分からなかったので、
            // 仕方なくこちら側で反転させるコードを書いてみた。(´ω`)
            unsafe
            {
                int   height = surface.Height;
                int   pitch  = surface.Pitch;
                byte *pixels = (byte *)surface.Pixels;
                byte *buffer = (byte *)Marshal.AllocHGlobal(pitch);

                for (int y = 0; y < height / 2; y++)
                {
                    byte *y1 = pixels + y * pitch;
                    byte *y2 = pixels + (height - y - 1) * pitch;
                    CopyMemory(buffer, y1, (uint)pitch);
                    CopyMemory(y1, y2, (uint)pitch);
                    CopyMemory(y2, buffer, (uint)pitch);
                }

                Marshal.FreeHGlobal((IntPtr)buffer);
            }

            /*/
             *
             * // ↓こっちの方が微妙に重い。
             * // 排他処理かなにかでもしてるのかも?
             * unsafe {
             *      byte* p = (byte*)surface.Pixels;
             *      uint format = surface.Alpha ? Gl.GL_RGBA : Gl.GL_RGB;
             *      for (int y = 0, h = surface.Height; y < h; y++) {
             *              // 1行ずつ読む。
             *              Gl.glReadPixels(0, h - y - 1, surface.Width, 1,
             *                      format, Gl.GL_UNSIGNED_BYTE, (IntPtr)p);
             *              p += surface.Pitch;
             *      }
             * }
             *
             * //*/

            return(surface);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Screenの画像をサーフェスにする。
        /// ただし、画面の上に載せている.NET Frameworkのコントロールは
        /// キャプチャできないので注意。
        /// </summary>
        public Surface GetSurface()
        {
            Surface surface = new Surface();
            if (surface.CreateDIB(Width, Height, false) != YanesdkResult.NoError)
            {
                surface.Dispose();
                return null;
            }

            // 読み出し元を設定。
            // デフォルトでバックバッファだが念のため設定。
            //Gl.glReadBuffer(Gl.GL_FRONT);
            Gl.glReadBuffer(Gl.GL_BACK);

            //*

            Gl.glReadPixels(0, 0, surface.Width, surface.Height,
                surface.Alpha ? Gl.GL_RGBA : Gl.GL_RGB,
                Gl.GL_UNSIGNED_BYTE,
                surface.Pixels);

            // glReadPixels()で取得したピクセルが上下逆で、
            // 反転させる方法が分からなかったので、
            // 仕方なくこちら側で反転させるコードを書いてみた。(´ω`)
            unsafe
            {
                int height = surface.Height;
                int pitch = surface.Pitch;
                byte* pixels = (byte*)surface.Pixels;
                byte* buffer = (byte*)Marshal.AllocHGlobal(pitch);

                for (int y = 0; y < height / 2; y++)
                {
                    byte* y1 = pixels + y * pitch;
                    byte* y2 = pixels + (height - y - 1) * pitch;
                    CopyMemory(buffer, y1, (uint)pitch);
                    CopyMemory(y1, y2, (uint)pitch);
                    CopyMemory(y2, buffer, (uint)pitch);
                }

                Marshal.FreeHGlobal((IntPtr)buffer);
            }

            /*/

            // ↓こっちの方が微妙に重い。
            // 排他処理かなにかでもしてるのかも?
            unsafe {
                byte* p = (byte*)surface.Pixels;
                uint format = surface.Alpha ? Gl.GL_RGBA : Gl.GL_RGB;
                for (int y = 0, h = surface.Height; y < h; y++) {
                    // 1行ずつ読む。
                    Gl.glReadPixels(0, h - y - 1, surface.Width, 1,
                        format, Gl.GL_UNSIGNED_BYTE, (IntPtr)p);
                    p += surface.Pitch;
                }
            }

            //*/

            return surface;
        }