Skip to content

Instantly share code, notes, and snippets.

@chaojian-zhang
Last active August 13, 2022 14:36
Show Gist options
  • Save chaojian-zhang/36f065e77e34a076d310d6555b212167 to your computer and use it in GitHub Desktop.
Save chaojian-zhang/36f065e77e34a076d310d6555b212167 to your computer and use it in GitHub Desktop.
SFML window with OpenTK GL context - this allows using both SFML 2D routines and OpenTK for 3D stuff; Be cautious with potential conflicts.
// dotnet add package SFML.Net --version 2.5.0
// dotnet add package OpenTK --version 4.0.0-pre9.1
using OpenTK.Graphics.OpenGL;
using OpenTK.Windowing.Desktop;
using SFML.Graphics;
using SFML.Window;
namespace CSharpSFMLWithOpenTK
{
internal class Program
{
static RenderWindow SFMLWindow;
static int program;
static void Main(string[] args)
{
// Dummy OpenTK window we create to intialize the context
// Since we have only one OpenGL context throughout, it doesn't matter that later we didn't display this window
uint majorVersion = 4, minorVersion = 6;
GameWindow gameWindow = new GameWindow(new GameWindowSettings(), new NativeWindowSettings()
{
APIVersion = System.Version.Parse($"{majorVersion}.{minorVersion}"),
StartVisible = false,
Profile = OpenTK.Windowing.Common.ContextProfile.Any
})
{
IsVisible = false
};
SFMLWindow = new RenderWindow(new VideoMode(280, 280), "SFML.NET+OpenTK4", Styles.Default, new ContextSettings()
{
MajorVersion = majorVersion,
MinorVersion = minorVersion
});
SFMLWindow.Closed += (obj, e) => { SFMLWindow.Close(); };
SFMLWindow.Resized +=
(obj, e) =>
{
SFMLWindow.SetView(new View(new FloatRect(0, 0, e.Width, e.Height)));
GL.Viewport(0, 0, (int)e.Width, (int)e.Height);
};
SFMLWindow.SetActive(true);
GL.Viewport(0, 0, (int)SFMLWindow.Size.X, (int)SFMLWindow.Size.Y);
GL.ClearColor(0f, 0.3f, 0.1f, 1f);
program = LoadShaders();
float[] positions = new float[] {
0f, 1f, 0f,
-1f, 0f, 0f,
1f, 0f, 0f
};
float[] colors = new float[] {
1f, 0f, 0f,
1f, 0f, 0f,
1f, 0f, 0f
};
int vboPos;
GL.GenBuffers(1, out vboPos);
GL.BindBuffer(BufferTarget.ArrayBuffer, vboPos);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * positions.Length,
positions, BufferUsageHint.StaticDraw);
int aPositionLoc = GL.GetAttribLocation(program, "aPosition");
GL.VertexAttribPointer(aPositionLoc, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(aPositionLoc);
int vboColor;
GL.GenBuffers(1, out vboColor);
GL.BindBuffer(BufferTarget.ArrayBuffer, vboColor);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * colors.Length,
colors, BufferUsageHint.StaticDraw);
int aColorLoc = GL.GetAttribLocation(program, "aColor");
GL.VertexAttribPointer(aColorLoc, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(aColorLoc);
while (SFMLWindow.IsOpen)
{
SFMLWindow.DispatchEvents();
GL.Clear(ClearBufferMask.ColorBufferBit);
GL.DrawArrays(OpenTK.Graphics.OpenGL.PrimitiveType.Triangles, 0, 3);
SFMLWindow.Display();
}
}
private static int LoadShaders()
{
int vShader = GL.CreateShader(ShaderType.VertexShader);
int fShader = GL.CreateShader(ShaderType.FragmentShader);
#region Vertex Shader Loading
// string source = File.ReadAllText("Shaders/vShader.glsl");
string vSource = string.Join(
Environment.NewLine,
"#version 140",
"in vec3 aPosition;",
"in vec3 aColor;",
"out vec3 vColor;",
"void main()",
"{",
" gl_Position = vec4(aPosition, 1.0);",
" vColor = aColor;",
"}");
GL.ShaderSource(vShader, vSource);
GL.CompileShader(vShader);
int status;
GL.GetShader(vShader, ShaderParameter.CompileStatus, out status);
if (status == 0)
{
string info = GL.GetShaderInfoLog(vShader);
Console.WriteLine("Vertex Shader Error: " + info);
return -1;
}
#endregion
#region Fragment Shader Loading
// source = File.ReadAllText("Shaders/fShader.glsl");
string fSource = string.Join(
Environment.NewLine,
"#version 140",
"in vec3 vColor;",
"out vec4 fragColor;",
"void main()",
"{",
" fragColor = vec4(vColor, 1.0);",
"}");
GL.ShaderSource(fShader, fSource);
GL.CompileShader(fShader);
GL.GetShader(fShader, ShaderParameter.CompileStatus, out status);
if (status == 0)
{
string info = GL.GetShaderInfoLog(fShader);
Console.WriteLine("Fragment Shader Error: " + info);
return -1;
}
#endregion
#region Creating Shader Program
int program = GL.CreateProgram();
GL.AttachShader(program, vShader);
GL.AttachShader(program, fShader);
GL.LinkProgram(program);
GL.GetProgram(program, GetProgramParameterName.LinkStatus, out status);
if (status == 0)
{
string info = GL.GetProgramInfoLog(program);
Console.WriteLine("Program Error: " + info);
return -1;
}
#endregion
GL.UseProgram(program);
GL.DeleteShader(vShader);
GL.DeleteShader(fShader);
return program;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment