Skip to content

Instantly share code, notes, and snippets.

@weebs
Last active March 27, 2023 23:58
Show Gist options
  • Save weebs/0d266df1d9d6ce781b3e29bfe4344285 to your computer and use it in GitHub Desktop.
Save weebs/0d266df1d9d6ce781b3e29bfe4344285 to your computer and use it in GitHub Desktop.
F# + Silk.NET
open Microsoft.FSharp.NativeInterop
open Silk.NET.Maths
open Silk.NET.Windowing
open Silk.NET.Input;
open Silk.NET.OpenGL
open System
let VertexShaderSource = """
#version 330 core //Using version GLSL version 3.3
layout (location = 0) in vec4 vPos;
void main()
{
gl_Position = vec4(vPos.x, vPos.y, vPos.z, 1.0);
}
"""
let FragmentShaderSource = """
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
"""
let mutable options = WindowOptions.Default
options.Size <- Vector2D<int>(800, 600)
options.Title <- "Learn OpenGL with Silk.NET"
let window = Window.Create(options)
let mutable Gl = Unchecked.defaultof<GL>
let mutable Vao = 0u
let mutable Vbo = 0u
let mutable Shader = 0u
let mutable Ebo = 0u
let Verticies = [|
0.5f; 0.5f; 0.0f
0.5f; -0.5f; 0.0f
-0.5f; -0.5f; 0.0f
-0.5f; 0.5f; 0.5f
|]
let Indices = [|
0u; 1u; 3u
1u; 2u; 3u
|]
window.add_Load (fun () -> (
let input = window.CreateInput()
Gl <- GL.GetApi(window)
Vao <- Gl.GenVertexArray()
Gl.BindVertexArray(Vao)
Vbo <- Gl.GenBuffer()
Gl.BindBuffer(BufferTargetARB.ArrayBuffer, Vbo)
do
use v = fixed Verticies
Gl.BufferData(BufferTargetARB.ArrayBuffer, unativeint (Verticies.Length * sizeof<uint>), ReadOnlySpan<float32>(NativePtr.toVoidPtr v, Verticies.Length), BufferUsageARB.StaticDraw)
Ebo <- Gl.GenBuffer()
Gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, Ebo)
do
use i = fixed Indices
Gl.BufferData(BufferTargetARB.ElementArrayBuffer, unativeint (Indices.Length * sizeof<uint>), ReadOnlySpan<int>(NativePtr.toVoidPtr i, Indices.Length), BufferUsageARB.StaticDraw)
let vertexShader = Gl.CreateShader(ShaderType.VertexShader)
Gl.ShaderSource(vertexShader, VertexShaderSource)
Gl.CompileShader(vertexShader)
let infoLog = Gl.GetShaderInfoLog(vertexShader)
if not (String.IsNullOrWhiteSpace(infoLog)) then
printfn $"Error compiling vertex shader {infoLog}"
let fragmentShader = Gl.CreateShader(ShaderType.FragmentShader)
Gl.ShaderSource(fragmentShader, FragmentShaderSource)
Gl.CompileShader(fragmentShader)
let infoLog = Gl.GetShaderInfoLog(fragmentShader)
if not (String.IsNullOrWhiteSpace(infoLog)) then
printfn $"Error compiling vertex shader {infoLog}"
Shader <- Gl.CreateProgram()
Gl.AttachShader(Shader, vertexShader)
Gl.AttachShader(Shader, fragmentShader)
Gl.LinkProgram(Shader)
let mutable status = 0
Gl.GetProgram(Shader, GLEnum.LinkStatus, &status)
if status = 0 then
printfn $"Error linking shader {Gl.GetProgramInfoLog(Shader)}"
Gl.DetachShader(Shader, vertexShader)
Gl.DetachShader(Shader, fragmentShader)
Gl.DeleteShader(vertexShader)
Gl.DeleteShader(fragmentShader)
Gl.VertexAttribPointer(0u, 3, VertexAttribPointerType.Float, false, 3u * uint sizeof<float32>, NativePtr.nullPtr<unativeint> |> NativePtr.toVoidPtr)
Gl.EnableVertexAttribArray(0u)
))
window.add_Render (fun t ->
Gl.Clear(uint ClearBufferMask.ColorBufferBit)
Gl.BindVertexArray(Vao)
Gl.UseProgram(Shader)
Gl.DrawElements(PrimitiveType.Triangles, uint Indices.Length, DrawElementsType.UnsignedInt, NativePtr.nullPtr<unativeint> |> NativePtr.toVoidPtr)
)
window.add_Update (fun t -> ())
window.add_Closing (fun () ->
Gl.DeleteBuffer(Vbo)
Gl.DeleteBuffer(Ebo)
Gl.DeleteVertexArray(Vao)
Gl.DeleteProgram(Shader)
)
window.Run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment