メインメニューを開く

Xamarin.MacのNSOpenGLViewをRetina Displayに対応させる。

目次

実装1編集

NSOpenGLViewを貼る編集

Interface Builder でNSOpenGLViewを継承したカスタムコントロールを貼る。 既にあるものをRetina対応させる場合は読み飛ばしてよい。

Retina対応を有効にする編集

Interface Builder のアトリビュートインスペクターで「Support Hi-Res Backing」の項目にチェックを入れる。 これでNSOpenGLViewはRetinaに対応する。

Retinaを考慮して描画する編集

Retinaを有効にした場合はRetinaを考慮せず描画処理を行うとグダグダになるので注意しよう。 図形への影響は小さいが文字列の場合は悲惨なことになるので特に注意すること。

この例ではConvertRectToBackingメソッドとGL.Viewportでサイズをあわせている。 Retina環境で変数の中身を見ると以下のような感じ。非Retina環境では同じ数字になる。

  • this.Bounds
    {X=0,Y=0,Width=300,Height=160}
  • this.ConvertRectToBacking(this.Bounds)
    {X=0,Y=0,Width=600,Height=320}

Retinaと非Retinaでマルチディスプレイした状態でウインドウを移動してみると効果のほどがよくわかる。

    public class MBOpenGLView : NSOpenGLView
    {
        // 〜〜〜省略〜〜〜

        public override void DrawRect(CoreGraphics.CGRect dirtyRect)
        {
            // Retinaを考慮して描画する
            var backingBounds = this.ConvertRectToBacking(this.Bounds);
            GL.Viewport(0, 0, (int)backingBounds.Width, (int)backingBounds.Height);

            using (var glc = this.OpenGLContext)
            {
                // コンテキストを有効化する
                glc.MakeCurrentContext();

                // 描画コマンド群
                GL.Color3(0.7f, 0.2f, 0.2f);
                GL.Begin(BeginMode.Triangles);
                {
                    GL.Vertex3( 0.0f,  0.5f,  0.0f);
                    GL.Vertex3(-0.5f, -0.5f,  0.0f);
                    GL.Vertex3( 0.5f, -0.5f,  0.0f);
                }
                GL.End();

                // キューに入ってる描画コマンド群を実行する
                GL.Flush();

            }// C#だとglc.Disposeのタイミングで画面描画を行うglc.FlushBafferも走る模様
        }
    }

関連項目編集

参考文献編集