Last active
August 13, 2022 14:36
-
-
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.
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
// 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