Last active
July 11, 2024 02:54
-
-
Save bmitc/e4d4399a1d7b71e1036914b8be5e337e to your computer and use it in GitHub Desktop.
GLFW window with SkiaSharp rendering in F#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
The following creates a GLFW window and then draws to the window's OpenGL context using SkiaSharp, | |
which are .NET bindings for Skia. The bindings shown that look like `glfw<name>` are F# bindings to | |
GLFW and directly match the GLFW function names. So this example could even be used as a blueprint | |
for using GLFW and Skia together in other languages. | |
*) | |
open System | |
open SkiaSharp | |
open Windowing.GLFW.FSharp | |
open Windowing.GLFW.Native.OpenGL | |
open Windowing.GLFW.Native.Helpers | |
open Windowing.GLFW.Native.Initialization | |
open Windowing.GLFW.Native.Context | |
open Windowing.GLFW.Native.Window | |
let mutable width, height = 500, 500 | |
let mutable framebufferWidth, framebufferHeight = width, height | |
// Loads the GLFW DLL and then calls glfwInit | |
initialize() | |
|> Convert.ToBoolean | |
|> printfn "Initialized?: %A" | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4) | |
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6) | |
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE) | |
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE) | |
printfn "Starting to create window..." | |
let window = glfwCreateWindow(width, height, "Test Window", NULL_MONITOR, NULL_WINDOW) | |
printfn "Window: %A" window | |
printfn "Ending creating window..." | |
glfwMakeContextCurrent(window) | |
let grGlInterface = GRGlInterface.Create(glfwGetProcAddress) | |
if not (grGlInterface.Validate()) | |
then raise (System.Exception("Invalid GRGlInterface")) | |
let grContext = GRContext.CreateGl(grGlInterface) | |
let grGlFramebufferInfo = new GRGlFramebufferInfo(0u, uint32(GL_RGBA8)) | |
let draw(window, width, height) = | |
glfwPollEvents() | |
grContext.ResetContext() | |
let grBackendRenderTarget = new GRBackendRenderTarget(width, height, 1, 0, grGlFramebufferInfo) | |
let surface = SKSurface.Create(grContext, grBackendRenderTarget, GRSurfaceOrigin.BottomLeft, SKColorType.Rgba8888) | |
let canvas = surface.Canvas | |
canvas.Clear(SKColors.Cyan) | |
let red = new SKPaint(Color = SKColor(200uy, 100uy, 200uy, 255uy)) | |
canvas.DrawCircle(float32(width)/2.0f, float32(height)/2.0f, 100.0f, red) | |
canvas.Flush() | |
glfwSwapBuffers(window) | |
red.Dispose() | |
surface.Dispose() | |
grBackendRenderTarget.Dispose() | |
let resizeCallback (window, newWidth: int, newHeight: int) = | |
width <- newWidth | |
height <- newHeight | |
draw(window, newWidth, newHeight) | |
glfwSetFramebufferSizeCallback(window, GLFWframebuffersizefun(fun window width height -> resizeCallback(window, width, height))) | |
|> ignore | |
while glfwWindowShouldClose window <> 1 do | |
glfwGetFramebufferSize(window, &framebufferWidth, &framebufferHeight) | |
draw(window, framebufferWidth, framebufferHeight) | |
glfwDestroyWindow(window) | |
glfwTerminate() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment