Windows OpenGL Example Using SkiaSharp
This article is a Windows graphics programming beginners tutorial. It shows how to program a simple C# graphics WinForm app using Visual Studio. It is a get-you-going example ready for more complex graphics programming in Windows.
Windows Graphics Libraries
When developing software there is usually more than one way to achieve the result. This is true for Microsoft Windows graphics programming. Windows supports different Application Programming Interfaces (APIs) for graphics:
- Graphics Device Interface Plus (GDI+)
- DirectX
- Open Graphics Library (OpenGL)
Then there are many third-party (non-Microsoft) graphics libraries and game engines. These are often developed to enable programs and games to support different platforms, i.e., enable a program with lots of graphics to run on Windows, Apple Macs, Linux and Smartphones. The Skia 2D Graphics Library is an example of a graphics engine that can support different platforms. The SkiaSharp library is a version of Skia for .NET platforms, making it great for developing Windows graphics programs that may need to run on other platforms. It is easy to incorporate into a Visual Studio solution because SkiaSharp can be managed with the NuGet package manager.
Getting Started with SkiaSharp
The example code in this tutorial was developed using Visual Studio 2022 Community Edition. The tutorial assumes Visual Studio is up to date. If you need any help copying the code from this tutorial see this link.
At the time of writing, SkiaSharp was still not yet using the newer .NET 6.0 and later versions, therefore, .NET Framework 4.8 was used. In Visual Studio use the Tools menu and then the Get Tools and Features option if you need to install .NET Framework 4.8:
Start a new Winforms project to try out Windows graphics programming with SkiaSharp. In the solution and project creation wizard use the filters to help find the Windows Forms App (.NET Framework) template:
In this tutorial, the project is called WindowsGraphics:
With the new project created and selected in the Solution Explorer, add the SkiaSharp NuGet package. Use the Visual Studio Project menu or use the context menu on the project in the Solution Explorer (normally the right-click mouse button), then select Manage NuGet Packages. Search for and install SkiaSharp:
You will need to acknowledge changes to the solution and accept licenses.
This tutorial will make use of the SkiaSharp WinForms control. To use the control install the SkiaSharp.Views.WindowsForms package:
Adding the SkiaSharp Control to a WinForm
Open the code file for the WinForm, Form1.cs. Add a using for SkiaSharp:
.
.
.
using System.Windows.Forms;
using SkiaSharp;
namespace WindowsGraphics
{
.
.
.
Run the project (click Start on the Visual Studio toolbar or press F5) to ensure the required references are correct. You can now add the SkiaSharpe control, SKGLControl, to the WinForm:
Using the SkiaSharp SKGLControl
The SkiaSharp SKGLControl
can be sized and anchored as required. In the Properties list (if not visible use the context menu on the control and select Properties), select the events (lightning symbol) and select the PaintSurface event. Press the enter key to create the event handler:
To check the control is functioning the Clear method of the SKGLControl Canvas is used to set a color (or colour in British English). The Canvas is obtained from the SKGLControl SKSurface
class, from the Surface property passed into the PaintSurface event. Here, LightSeaGreen is set. To see other defined colors look at the definition of SKColors (use the context menu on SKColors and click the link) or see the dropdown for the SKGLControl BackColor property.
.
.
.
private void skglControl1_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)
{
e.Surface.Canvas.Clear(SKColors.LightSeaGreen);
}
}
}
Run the project to see the SkiaSharp WinForm Control in the selected color:
Next, we'll set the SKGLControl to a random color on a button click. Drag a Button
onto the form from the Toolbox and set its Text property to Paint. Double-click the button to add the Click event. Use the SKGLControl Invalidate method to cause the control to repaint. In the PaintSurface event set a random color. The System.Random class is used to generate the byte values for the color which are used to generate a new SKColor
object:
.
.
.
private void button1_Click(object sender, EventArgs e)
{
skglControl1.Invalidate();
}
Random rng = new Random();
private void skglControl1_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)
{
e.Surface.Canvas.Clear(new SKColor(
red: (byte)rng.Next(255),
green: (byte)rng.Next(255),
blue: (byte)rng.Next(255),
alpha: (byte)rng.Next(255)));
}
}
}
Run the project and click the button to change the SkiaSharp control's color.
Now let's draw some random lines on the control. This will use a DrawLine method from the SLGLControl Canvas. DrawLine requires two x and y coordinates to define points between which the line will be drawn. Plus, it needs a SKPaint
object to define the color (as SKColor) and width (called StrokeWidth). Effectively, SKPaint defines a type of brush to draw on the surface of the SkiaSharp control. A PaintLines function is defined that randomly sets the color, width and points of a line to be drawn and calls the DrawLine function. It loops 100 times to draw 100 random lines. The PaintLines function is then called from the PaintSurface event. You can see the result at the top of this article. You can click the button to generate new random lines. Here is the full WinForm code:
using System;
using System.Windows.Forms;
using SkiaSharp;
namespace WindowsGraphics
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
skglControl1.Invalidate();
}
Random rng = new Random();
SKPaint paintInfo = new SKPaint();
private void PaintLines(SKCanvas canvas)
{
canvas.Clear(SKColors.LightSeaGreen);
for (int i = 0; i < 100; i++)
{
paintInfo.Color = new SKColor(
red: (byte)rng.Next(255),
green: (byte)rng.Next(255),
blue: (byte)rng.Next(255),
alpha: (byte)rng.Next(255));
paintInfo.StrokeWidth = rng.Next(1, 10);
paintInfo.IsAntialias = true; //For smooth lines
canvas.DrawLine(
x0: rng.Next(skglControl1.Width),
y0: rng.Next(skglControl1.Height),
x1: rng.Next(skglControl1.Width),
y1: rng.Next(skglControl1.Height),
paint: paintInfo);
}
}
private void skglControl1_PaintSurface(object sender, SkiaSharp.Views.Desktop.SKPaintGLSurfaceEventArgs e)
{
PaintLines(e.Surface.Canvas);
}
}
}
The Future of Graphics is Vulkan
OpenGL has been around for a very long time. This means it is in widespread use. However, the Vulkan graphics API was designed to replace OpenGL in order to use today's graphics hardware more efficiently. Vulkan is now well-established for cross-platform graphics development. It may be worth learning Vulkan instead of OpenGL. SkiaSharp can call into Vulkan. See also Silk.NET, a .NET Foundation project to cover many APIs, including Vulkan.
See Also
- What is .NET?
- Hello World in C#, A Starting WinForms Example
- .NET documentation at Microsoft.
- SkiaSharp on GitHub, see current status towards the next release.
- Skia Graphics Engine, the Skia Graphics Engine underpins SkiaSharp.
- OpenTK, the Open Toolkit bindings are used by SkiaSharp.
- Silk.NET, a .NET Foundation project to cover many APIs, including Vulkan.
- Bonk, a collision detection system for .NET.
- Stride, a C# games engine with tools.
- For a full list of the articles on Tek Eye see the website's index.
Author:Daniel S. Fowler Published: Updated: