SkiaSharp is a cross-platform 2D graphics API for .NET platforms based on the Skia Graphics Library of Google. It provides a comprehensive 2D API that is used across mobiles, servers, and desktop models to render images.

In an OpenTK app, you can use SkiaSharp to draw geometries, texts, or images. For more information about the SkiaSharp APIs, see the SkiaSharp API document.

To draw a text using SkiaSharp in the OpenTK application, use the following guidelines:

  • Allocate a memory block as a canvas for SkiaSharp.
  • Create a SKCanvas on this memory block, and render text or image that you want on this SKCanvas.
  • Create a 2D texture from this memory block.
  • Draw a 2D texture with graphics APIs of OpenTK.

Allocate memory block

Allocate a specific size of the memory block. The size of the memory block must be same as the size of the canvas you want:

private IntPtr pBitMap; // memory handle private int rowByte; // bytes of one row private int bitmapHeight, bitmapWidth; // height and width of the canvas private void CreateBitmap() { bitmapHeight = (int)(skiaPercent * mainWindow.Height); bitmapWidth = (int)(skiaPercent * mainWindow.Width); pBitMap = Marshal.AllocHGlobal(bitmapWidth * bitmapHeight * 4); // allocate a memory block rowByte = bitmapWidth * 4; } private void FreeBitmap() { if (pBitMap != IntPtr.Zero) { Marshal.FreeHGlobal(pBitMap); // free the allocated memory block pBitMap = IntPtr.Zero; } }

Create SKCanvas on memory block

Create SKSurface on the memory block and then you can get the SKCanvas from the SKSurface:

private SKSurface surface; private SKCanvas canvas; private void CreateSKCanvas() { GL.PixelStore(All.UnpackAlignment, 4); // create the surface var info = new SKImageInfo(bitmapWidth, bitmapHeight, SKImageInfo.PlatformColorType, SKAlphaType.Premul); surface = SKSurface.Create(info, pBitMap, rowByte); if (surface != null) { canvas = surface.Canvas; } }

Draw text on SKCanvas

Set a color and draw text on the canvas:

private void DrawTextBySkiaSharp(SKCanvas canvas, int canvasWidth, int canvasHeight) { canvas.DrawColor(SKColors.White); // Change the canvas as white using (var paint = new SKPaint()) { paint.TextSize = 64.0f; paint.IsAntialias = true; paint.Color = SKColors.Red; paint.IsStroke = false; paint.TextAlign = SKTextAlign.Center; canvas.DrawText("SkiaSharp", width / 2f, 144.0f, paint); // Draw text "SkiaSharp" on the canvas } } private void DrawTextOnSkCanvas() { if (canvas != null) { DrawTextBySkiaSharp(canvas, bitmapWidth, bitmapHeight); canvas.Flush(); } }

Create 2D texture from memory block

Call GL.TexImage2D of OpenTK.Graphics.ES20 to generate 2D texture from the memory block:

private void Create2DTextureFromMemory() { GL.TexImage2D( All.Texture2D, 0, All.BgraExt, bitmapWidth, bitmapHeight, 0, All.BgraExt, All.UnsignedByte, pBitMap ); GL.TexParameter(All.Texture2D, All.TextureMinFilter, (float)All.LinearMipmapLinear); GL.TexParameter(All.Texture2D, All.TextureMagFilter, (float)All.Linear); GL.GenerateMipmap(All.Texture2D); }

Draw 2D texture

Draw a 2D texture with graphics APIs of OpenTK:

private IGameWindow mainWindow; // window private float[] vertices; // vertex array private float[] textCoord; // texture coordinate array private int mProgramHandle; // program handle protected override void OnCreate() { mainWindow = Window; mainWindow.RenderFrame += OnRenderFrame; } private void OnRenderFrame(Object sender, FrameEventArgs e) { GL.Viewport(0, 0, mainWindow.Width, mainWindow.Height); GL.ClearColor(Color4.CornflowerBlue); GL.Enable(All.DepthTest); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.UseProgram(mProgramHandle); positionLoc = GL.GetAttribLocation(mProgramHandle, "a_position"); texCoordLoc = GL.GetAttribLocation(mProgramHandle, "a_texCoord"); textureLoc = GL.GetUniformLocation(mProgramHandle, "s_texture"); GL.Uniform1(textureLoc, 0); unsafe { fixed (float* pvertices = vertices) { // Prepare the triangle coordinate data GL.VertexAttribPointer(positionLoc, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), new IntPtr(pvertices)); GL.EnableVertexAttribArray(positionLoc); } fixed (float* texCoord = textCoord) { GL.VertexAttribPointer(texCoordLoc, 2, VertexAttribPointerType.Float, false, 2 * sizeof(float), new IntPtr(texCoord)); GL.EnableVertexAttribArray(texCoordLoc); } } mvpLoc = GL.GetUniformLocation(mProgramHandle, "u_mvpMatrix"); // Apply the projection and view transformation GL.UniformMatrix4(mvpLoc, false, ref mvpMatrix); GL.DrawArrays(All.Triangles, 0, 36); GL.Finish(); // Disable vertex array GL.DisableVertexAttribArray(positionLoc); GL.DisableVertexAttribArray(inColorLoc); mainWindow.SwapBuffers(); }

Sample application

There is a OpenTK sample application that uses SkiaSharp to draw text on a rotating cube.

Figure: Sample application running on TV emulator


For more information, see Tizen-CSharp-Samples repository on GitHub.

  • Dependencies
    • Tizen 5.0 and Higher
Window of OpenTK
Next Third Party Libraries for Tizen .NET Application
Submit your feedback to GitHub