Removed Subrepository
This commit is contained in:
66
C#/OpenGLTutorial/Rendering/Display/DisplayManager.cs
Normal file
66
C#/OpenGLTutorial/Rendering/Display/DisplayManager.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using GLFW;
|
||||
using OpenGLTutorial.GameLoop;
|
||||
using StbiSharp;
|
||||
using static OpenGL.GL;
|
||||
using Image = GLFW.Image;
|
||||
|
||||
namespace OpenGLTutorial.Rendering.Display {
|
||||
public static class DisplayManager {
|
||||
|
||||
public static NativeWindow Window { get; set; }
|
||||
public static Size WindowSize { get; set; }
|
||||
|
||||
public static void CreateWindow(int width, int height, string title, bool vsync) {
|
||||
WindowSize = new Size(width, height);
|
||||
Glfw.Init();
|
||||
|
||||
Glfw.WindowHint(Hint.ContextVersionMajor, 3);
|
||||
Glfw.WindowHint(Hint.ContextVersionMinor, 3);
|
||||
Glfw.WindowHint(Hint.OpenglProfile, Profile.Core);
|
||||
|
||||
Glfw.WindowHint(Hint.Focused, true);
|
||||
Glfw.WindowHint(Hint.Resizable, true);
|
||||
|
||||
Window = new NativeWindow(width, height, title);
|
||||
Window.CenterOnScreen();
|
||||
Window.MakeCurrent();
|
||||
Import(Glfw.GetProcAddress);
|
||||
glViewport(0, 0, width, height);
|
||||
Glfw.SwapInterval(vsync ? 1 : 0);
|
||||
|
||||
Window.SizeChanged += OnResize;
|
||||
Window.KeyAction += OnKey;
|
||||
Window.MouseButton += OnMouse;
|
||||
Window.MouseMoved += OnMouseMove;
|
||||
Window.MouseScroll += OnMouseScroll;
|
||||
|
||||
}
|
||||
|
||||
private static void OnResize(object sender, SizeChangeEventArgs e) {
|
||||
WindowSize = e.Size;
|
||||
glViewport(0, 0, WindowSize.Width, WindowSize.Height);
|
||||
}
|
||||
|
||||
private static void OnKey(object sender, KeyEventArgs e) => Input.Keys[e.Key] = e.State != InputState.Release;
|
||||
|
||||
private static void OnMouse(object sender, MouseButtonEventArgs e) => Input.MouseButtons[e.Button] = e.Action != InputState.Release;
|
||||
private static void OnMouseMove(object sender, MouseMoveEventArgs e) => Input.MousePosition = e.Position;
|
||||
private static void OnMouseScroll(object sender, MouseMoveEventArgs e) => Input.MouseScroll = e.Position.Y;
|
||||
|
||||
public static unsafe void SetWindowIcon(this NativeWindow window, string file) {
|
||||
using var stream = File.OpenRead(file);
|
||||
using var memoryStream = new MemoryStream();
|
||||
stream.CopyTo(memoryStream);
|
||||
StbiImage image = Stbi.LoadFromMemory(memoryStream, 0);
|
||||
|
||||
fixed (byte* data = &image.Data[0]) {
|
||||
window.SetIcons(new Image(image.Width, image.Height, new IntPtr(data)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
154
C#/OpenGLTutorial/Rendering/Display/Shape.cs
Normal file
154
C#/OpenGLTutorial/Rendering/Display/Shape.cs
Normal file
@@ -0,0 +1,154 @@
|
||||
using System.Drawing;
|
||||
using static OpenGL.GL;
|
||||
|
||||
namespace OpenGLTutorial.Rendering.Display {
|
||||
public class Shape {
|
||||
|
||||
public int Mode { get; set; }
|
||||
public uint Vao { get; private set; }
|
||||
private uint Vbo { get; set; }
|
||||
private float[] Vertices { get; set; }
|
||||
private bool _loaded = false;
|
||||
|
||||
public Shape(float[] vertices, int mode = GL_STATIC_DRAW) {
|
||||
Vertices = vertices;
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
public unsafe void Load() {
|
||||
if (_loaded || Vertices.Length == 0) return;
|
||||
_loaded = true;
|
||||
|
||||
Vao = glGenVertexArray();
|
||||
Vbo = glGenBuffer();
|
||||
|
||||
glBindVertexArray(Vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
|
||||
|
||||
fixed (float* v = &Vertices[0]) {
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * Vertices.Length, v, Mode);
|
||||
}
|
||||
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, false, 8 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, false, 8 * sizeof(float), (void*)(2 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, false, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public void Delete() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
glDeleteBuffer(Vbo);
|
||||
glDeleteVertexArray(Vao);
|
||||
}
|
||||
|
||||
public unsafe void SetVertices(float[] vertices) {
|
||||
Vertices = vertices;
|
||||
if (vertices.Length == 0) return;
|
||||
glBindVertexArray(Vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, Vbo);
|
||||
|
||||
fixed (float* v = &Vertices[0]) {
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * Vertices.Length, v, Mode);
|
||||
}
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public int GetVertexCount() => Vertices.Length / 8;
|
||||
|
||||
}
|
||||
|
||||
public static class Shapes {
|
||||
|
||||
public static float[] Rectangle => new[] {
|
||||
-0.5f, 0.5f, 1f, 1f, 1f, 1f, 0.0f, 1.0f, // top left
|
||||
0.5f, 0.5f, 1f, 1f, 1f, 1f, 1.0f, 1.0f, // top right
|
||||
-0.5f, -0.5f, 1f, 1f, 1f, 1f, 0.0f, 0.0f, // bottom left
|
||||
|
||||
0.5f, 0.5f, 1f, 1f, 1f, 1f, 1.0f, 1.0f, // top right
|
||||
0.5f, -0.5f, 1f, 1f, 1f, 1f, 1.0f, 0.0f, // bottom right
|
||||
-0.5f, -0.5f, 1f, 1f, 1f, 1f, 0.0f, 0.0f, // bottom left
|
||||
};
|
||||
|
||||
public static float[] Triangle => new[] {
|
||||
0.0f, -0.5f, 1f, 1f, 1f, 1f, 0.5f, 1.0f, // top center
|
||||
0.5f, 0.5f, 1f, 1f, 1f, 1f, 1.0f, 0.0f, // bottom right
|
||||
-0.5f, 0.5f, 1f, 1f, 1f, 1f, 0.0f, 0.0f, // bottom left
|
||||
};
|
||||
|
||||
public static float[] CreateRectangle(Dimensions position, Color color, Dimensions uv) => new[] {
|
||||
position.X, position.MaxY, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.X, uv.MaxY, // top left
|
||||
position.MaxX, position.MaxY, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.MaxX, uv.MaxY, // top right
|
||||
position.X, position.Y, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.X, uv.Y, // bottom left
|
||||
|
||||
position.MaxX, position.MaxY, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.MaxX, uv.MaxY, // top right
|
||||
position.MaxX, position.Y, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.MaxX, uv.Y, // bottom right
|
||||
position.X, position.Y, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.X, uv.Y, // bottom left
|
||||
};
|
||||
|
||||
public static float[] CreateTriangle(Dimensions position, Color color, Dimensions uv) => new[] {
|
||||
position.CenterX, position.Y, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.CenterX, uv.MaxY, // top center
|
||||
position.MaxX, position.MaxY, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.MaxX, uv.Y, // bottom right
|
||||
position.X, position.MaxY, color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha(), uv.X, uv.Y, // bottom left
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public readonly struct Dimensions {
|
||||
public static Dimensions Identity => new (0.0f, 0.0f, 1.0f, 1.0f);
|
||||
public static Dimensions Centered => new (-0.5f, -0.5f, 1.0f, 1.0f);
|
||||
|
||||
public float X { get; }
|
||||
public float Y { get; }
|
||||
public float Width { get; }
|
||||
public float Height { get; }
|
||||
|
||||
public Dimensions(float x, float y, float width, float height) {
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
public float MaxX => X + Width;
|
||||
public float MaxY => Y + Height;
|
||||
|
||||
public float CenterX => X + (Width / 2.0f);
|
||||
public float CenterY => Y + (Height / 2.0f);
|
||||
}
|
||||
|
||||
public static class ColorExtensions {
|
||||
|
||||
private static float Map(float value, float min, float max, float mMin, float mMax) {
|
||||
float norm = (value - min) / (max - min);
|
||||
return (mMax - mMin) * norm + mMin;
|
||||
}
|
||||
|
||||
public static float GetRed(this Color color) {
|
||||
return Map(color.R, 0, 255, 0, 1);
|
||||
}
|
||||
|
||||
public static float GetGreen(this Color color) {
|
||||
return Map(color.G, 0, 255, 0, 1);
|
||||
}
|
||||
|
||||
public static float GetBlue(this Color color) {
|
||||
return Map(color.B, 0, 255, 0, 1);
|
||||
}
|
||||
|
||||
public static float GetAlpha(this Color color) {
|
||||
return Map(color.A, 0, 255, 0, 1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
73
C#/OpenGLTutorial/Rendering/Display/Texture.cs
Normal file
73
C#/OpenGLTutorial/Rendering/Display/Texture.cs
Normal file
@@ -0,0 +1,73 @@
|
||||
using System.IO;
|
||||
using StbiSharp;
|
||||
using static OpenGL.GL;
|
||||
|
||||
namespace OpenGLTutorial.Rendering.Display {
|
||||
public class Texture {
|
||||
|
||||
public static Texture Empty => new(null);
|
||||
|
||||
public int Width { get; private set; }
|
||||
public int Height { get; private set; }
|
||||
|
||||
private uint Address { get; set; }
|
||||
private string Path { get; }
|
||||
private bool _loaded = false;
|
||||
|
||||
public Texture(string path) {
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public unsafe void Load() {
|
||||
if (_loaded) return;
|
||||
_loaded = true;
|
||||
Address = glGenTexture();
|
||||
glBindTexture(GL_TEXTURE_2D, Address);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
if (string.IsNullOrEmpty(Path)) {
|
||||
LoadEmpty();
|
||||
return;
|
||||
}
|
||||
|
||||
using var stream = File.OpenRead(Path);
|
||||
using var memoryStream = new MemoryStream();
|
||||
stream.CopyTo(memoryStream);
|
||||
StbiImage image = Stbi.LoadFromMemory(memoryStream, 0);
|
||||
int format = image.NumChannels == 3 ? GL_RGB : GL_RGBA;
|
||||
fixed(byte* data = &image.Data[0])
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, image.Width, image.Height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
Width = image.Width;
|
||||
Height = image.Height;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
private unsafe void LoadEmpty() {
|
||||
byte[] pixels = {255, 255, 255, 255};
|
||||
|
||||
fixed (byte* data = &pixels[0]) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
|
||||
Width = 1;
|
||||
Height = 1;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
public void Use() {
|
||||
glBindTexture(GL_TEXTURE_2D, Address);
|
||||
}
|
||||
|
||||
public void Delete() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDeleteTexture(Address);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user