Files
SlaveMatrix-SDL/2DGAMELIB/_2DGAMELIB/WPFImage.cs

292 lines
9.1 KiB
C#

using GLFW;
using Silk.NET.OpenGL;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
namespace _2DGAMELIB
{
public enum MouseButtons {
None = 0,
Left = 1,
Right = 2,
Middle = 4,
Button4 = 8,
Button5 = 16
}
public class GlImage
{
Silk.NET.OpenGL.GL gl;
//yeah this is a little bit sketchy
public static unsafe GLFW.Window PtrToWindow(IntPtr source)
{
var sourceRef = __makeref(source);
var dest = default(GLFW.Window);
var destRef = __makeref(dest);
*(IntPtr*)&destRef = *(IntPtr*)&sourceRef;
return __refvalue(destRef, GLFW.Window);
}
public GLFW.Window window;
private uint shader_program;
private uint texture;
private uint vertex_buf;
private uint vao;
public int texW = 0;
public int texH = 0;
public GlImage() { }
public void SetViewport(uint vpW, uint vpH, int vpX, int vpY)
{
gl.Viewport(vpX, vpY, vpW, vpH);
}
public Vector2D GetCursorPoint() {
double x, y;
Glfw.GetCursorPosition(window, out x, out y);
return new Vector2D(x, y);
}
public void SetCursorPoint(Vector2D pos) {
Glfw.SetCursorPosition(window, pos.X, pos.Y);
}
public MouseButtons GetMouseButtons() {
MouseButtons btns = 0;
if (Glfw.GetMouseButton(window, MouseButton.Left) == InputState.Press)
btns |= MouseButtons.Left;
if (Glfw.GetMouseButton(window, MouseButton.Right) == InputState.Press)
btns |= MouseButtons.Right;
if (Glfw.GetMouseButton(window, MouseButton.Middle) == InputState.Press)
btns |= MouseButtons.Middle;
if (Glfw.GetMouseButton(window, MouseButton.Button4) == InputState.Press)
btns |= MouseButtons.Button4;
if (Glfw.GetMouseButton(window, MouseButton.Button5) == InputState.Press)
btns |= MouseButtons.Button5;
return btns;
}
public delegate void ShouldCloseCallback();
public ShouldCloseCallback Closing = delegate () { };
public MouseButtonCallback Click = delegate (IntPtr window, MouseButton button, InputState state, ModifierKeys modifiers) { };
public MouseCallback Move = delegate (IntPtr window, double x, double y) { };
public SizeCallback Resize = delegate (IntPtr window, int width, int height) { };
public MouseCallback Scroll = delegate (IntPtr window, double x, double y) { };
public MouseEnterCallback Leave = delegate (IntPtr window, bool entered) { };
public void SetTitle(string title) {
Glfw.SetWindowTitle(window, title);
}
public void PollEvents() {
Glfw.PollEvents();
if (Glfw.WindowShouldClose(window))
Closing();
}
public unsafe void SetBitmap(Bitmap bmp)
{
gl.UseProgram(shader_program);
gl.ActiveTexture(Silk.NET.OpenGL.GLEnum.Texture0);
gl.BindTexture(Silk.NET.OpenGL.GLEnum.Texture2D, texture);
if (bmp.Width != texW || bmp.Height != texH)
{
gl.TexImage2D(
Silk.NET.OpenGL.GLEnum.Texture2D,
0,
InternalFormat.Rgba8,
(uint)bmp.Width,
(uint)bmp.Height,
0,
Silk.NET.OpenGL.GLEnum.Bgra,
Silk.NET.OpenGL.GLEnum.UnsignedByte,
null);
texW = bmp.Width;
texH = bmp.Height;
}
BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
gl.PixelStore(GLEnum.UnpackAlignment, 1);
gl.TexSubImage2D(
Silk.NET.OpenGL.GLEnum.Texture2D,
0,
0,
0,
(uint)bmp.Width,
(uint)bmp.Height,
Silk.NET.OpenGL.GLEnum.Bgra,
Silk.NET.OpenGL.GLEnum.UnsignedByte,
(void*)data.Scan0);
bmp.UnlockBits(data);
gl.BindVertexArray(vao);
gl.DrawArrays(GLEnum.TriangleStrip, 0, 4);
gl.BindVertexArray(0);
Glfw.SwapBuffers(window);
}
public unsafe void BitmapSetting(Bitmap bmp)
{
Glfw.WindowHint(Hint.ClientApi, ClientApi.OpenGL);
Glfw.WindowHint(Hint.ContextVersionMajor, 3);
Glfw.WindowHint(Hint.ContextVersionMinor, 3);
Glfw.WindowHint(Hint.OpenglProfile, Profile.Core);
Glfw.WindowHint(Hint.Doublebuffer, true);
Glfw.WindowHint(Hint.Decorated, true);
Glfw.WindowHint(Hint.OpenglForwardCompatible, true);
window = Glfw.CreateWindow(bmp.Width, bmp.Height, "yayy", Monitor.None, GLFW.Window.None);
Glfw.SetWindowSizeCallback(window, Resize);
Glfw.SetMouseButtonCallback(window, Click);
Glfw.SetCursorPositionCallback(window, Move);
Glfw.SetScrollCallback(window, Scroll);
Glfw.SetCursorEnterCallback(window, Leave);
GCHandle handle = GCHandle.Alloc(this);
Glfw.SetWindowUserPointer(window, GCHandle.ToIntPtr(handle));
Glfw.MakeContextCurrent(window);
Glfw.SwapInterval(0);
gl = Silk.NET.OpenGL.GL.GetApi(Glfw.GetProcAddress);
string vertexShaderSource =
@"
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aUV;
out vec2 vUV;
void main()
{
gl_Position = vec4(aPos, 0.0f, 1.0f);
vUV = aUV;
}
";
string fragmentShaderSource =
@"
#version 330 core
in vec2 vUV;
out vec4 FragColor;
uniform sampler2D sTexture;
void main()
{
FragColor = texture(sTexture, vUV);
}
";
uint vertexShader = gl.CreateShader(Silk.NET.OpenGL.GLEnum.VertexShader);
gl.ShaderSource(vertexShader, vertexShaderSource);
gl.CompileShader(vertexShader);
uint fragmentShader = gl.CreateShader(Silk.NET.OpenGL.GLEnum.FragmentShader);
gl.ShaderSource(fragmentShader, fragmentShaderSource);
gl.CompileShader(fragmentShader);
shader_program = gl.CreateProgram();
gl.AttachShader(shader_program, vertexShader);
gl.AttachShader(shader_program, fragmentShader);
gl.LinkProgram(shader_program);
System.Diagnostics.Debug.WriteLine(gl.GetShaderInfoLog(fragmentShader));
System.Diagnostics.Debug.WriteLine(gl.GetShaderInfoLog(vertexShader));
System.Diagnostics.Debug.WriteLine(gl.GetProgramInfoLog(shader_program));
gl.UseProgram(shader_program);
gl.Uniform1(gl.GetUniformLocation(shader_program, "sTexture"), 0);
texture = gl.GenTexture();
gl.ActiveTexture(Silk.NET.OpenGL.GLEnum.Texture0);
gl.BindTexture(Silk.NET.OpenGL.GLEnum.Texture2D, texture);
gl.TexParameterI(Silk.NET.OpenGL.GLEnum.Texture2D, Silk.NET.OpenGL.GLEnum.TextureWrapS, new int[] {(int)TextureWrapMode.ClampToEdge});
gl.TexParameterI(Silk.NET.OpenGL.GLEnum.Texture2D, Silk.NET.OpenGL.GLEnum.TextureWrapT, new int[] {(int)TextureWrapMode.ClampToEdge});
gl.TexParameterI(Silk.NET.OpenGL.GLEnum.Texture2D, Silk.NET.OpenGL.GLEnum.TextureMagFilter, new int[] {(int)TextureMagFilter.Nearest});
gl.TexParameterI(Silk.NET.OpenGL.GLEnum.Texture2D, Silk.NET.OpenGL.GLEnum.TextureMinFilter, new int[] {(int)TextureMinFilter.Nearest});
gl.TexImage2D(
Silk.NET.OpenGL.GLEnum.Texture2D,
0,
InternalFormat.Rgba8,
(uint)bmp.Width,
(uint)bmp.Height,
0,
Silk.NET.OpenGL.GLEnum.Bgra,
Silk.NET.OpenGL.GLEnum.UnsignedByte,
null
);
texW = bmp.Width;
texH = bmp.Height;
float[] buf = {
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 1.0f, 0.0f
};
vertex_buf = gl.GenBuffer();
gl.BindBuffer(Silk.NET.OpenGL.GLEnum.ArrayBuffer, vertex_buf);
fixed (float* buf_ = buf) gl.BufferData(Silk.NET.OpenGL.GLEnum.ArrayBuffer, (uint)(sizeof(float) * buf.Length), buf_, Silk.NET.OpenGL.GLEnum.StaticDraw);
vao = gl.GenVertexArray();
gl.BindVertexArray(vao);
gl.BindBuffer(GLEnum.ArrayBuffer, vertex_buf);
gl.VertexAttribPointer(
0,
2,
GLEnum.Float,
false,
4 * sizeof(float),
IntPtr.Zero
);
gl.EnableVertexAttribArray(0);
gl.VertexAttribPointer(
1,
2,
GLEnum.Float,
false,
4 * sizeof(float),
(void*)(2 * sizeof(float))
);
gl.EnableVertexAttribArray(1);
gl.BindVertexArray(0);
}
}
}