Chris
Chris

Reputation: 187

How do I grab an OpenGL render as a bitmap using OpenTK in Xamarin for Android?

I've attempted two different methods to achieve this, the first being an Android-style method and the second being an OpenGL style method. From my activity, I create a view which contains the OpenGL (1.1) code.

The first method (android):

Bitmap b = gameView.GetDrawingCache (true); // this is always null

And the second method (opengl):

public Bitmap GrabScreenshot()
{
        int size = Width * Height * 4;
        byte[] bytes = new byte[size];
        GL.ReadPixels<byte>(0, 0, Width, Height, All.Rgba, All.UnsignedByte, bytes);
        Bitmap bmp = BitmapFactory.DecodeByteArray (bytes, 0, size);
        return bmp;
}

Upvotes: 2

Views: 1748

Answers (2)

pauldendulk
pauldendulk

Reputation: 1598

Here a version that works on Xamarin.Android:

    private static Bitmap GraphicsContextToBitmap(int width, int height)
    {
        GL.Flush();
        GL.PixelStore (PixelStoreParameter.PackAlignment, 1);

        var bitmap = Bitmap.CreateBitmap(width, height, Bitmap.Config.Argb8888);

        var data = bitmap.LockPixels();     
        GL.ReadPixels(0, 0, width, height, PixelFormat.Rgba, PixelType.UnsignedByte, data);
        GL.Finish();  
        bitmap.UnlockPixels();

        return bitmap;
    }

Upvotes: 1

Viider Storm
Viider Storm

Reputation: 189

I have not tested this code. I was thinking you might be able to use it as a guide.

How about trying something like this (derived from: OpenTK Forums):

    public Bitmap GrabScreenshot()
    {

        Bitmap bmp = new Bitmap(Width, Height);
        System.Drawing.Imaging.BitmapData data =
            bmp.LockBits(otkViewport.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly,
                         System.Drawing.Imaging.PixelFormat.Format24bppRgb);

        GL.Finish();
        GL.ReadPixels(0, 0, this.otkViewport.Width, this.otkViewport.Height, PixelFormat.Bgr, PixelType.UnsignedByte,  data.Scan0);
        bmp.UnlockBits(data);
        bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
        return bmp;
    }

I believe a problem might occur due to the formatting of the bytes. In the example, they explicitly state the beginning to the array of data with

data.Scan0

However, you just sends in a byte array.

Upvotes: 2

Related Questions