initial commit to new instance
This commit is contained in:
113
src/Camera/Camera.cs
Normal file
113
src/Camera/Camera.cs
Normal file
@ -0,0 +1,113 @@
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace Engine_silk.NET;
|
||||
|
||||
public enum MovementDirection
|
||||
{
|
||||
Forward,
|
||||
Backward,
|
||||
Left,
|
||||
Right,
|
||||
Up,
|
||||
Down,
|
||||
}
|
||||
|
||||
public class Camera
|
||||
{
|
||||
private readonly Vector3D<float> _worldUp;
|
||||
private Vector3D<float> _position;
|
||||
private Vector3D<float> _front;
|
||||
private Vector3D<float> _right;
|
||||
private Vector3D<float> _up;
|
||||
private float _yaw;
|
||||
private float _pitch;
|
||||
private float _movementSpeed;
|
||||
|
||||
/// <summary>
|
||||
/// The view matrix according to the current camera position and rotation
|
||||
/// </summary>
|
||||
public Matrix4X4<float> ViewMatrix { get => Matrix4X4.CreateLookAt(_position, _position + _front, _worldUp); }
|
||||
public float MouseSensitivity { get; set; } = 0.1f;
|
||||
/// <summary>
|
||||
/// Controlls how fast the camera moves if a key is pressed
|
||||
/// </summary>
|
||||
public float MovementSpeed { get; set; } = 2.5f;
|
||||
public float Fov { get; set; }
|
||||
|
||||
public Camera(Vector3D<float> position, float yaw = -90.0f, float pitch = 0, float movementSpeed = 2.5f, float fov = 45.0f)
|
||||
{
|
||||
_position = position;
|
||||
_yaw = yaw;
|
||||
_pitch = pitch;
|
||||
_movementSpeed = movementSpeed;
|
||||
Fov = fov;
|
||||
_worldUp = Vector3D<float>.UnitY;
|
||||
|
||||
UpdateCameraVectors();
|
||||
}
|
||||
|
||||
public void ProcessKeyboard(float deltaTime, MovementDirection direction)
|
||||
{
|
||||
float velocity = MovementSpeed * deltaTime;
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case MovementDirection.Forward:
|
||||
_position += _front * velocity;
|
||||
break;
|
||||
case MovementDirection.Backward:
|
||||
_position -= _front * velocity;
|
||||
break;
|
||||
case MovementDirection.Left:
|
||||
_position -= _right * velocity;
|
||||
break;
|
||||
case MovementDirection.Right:
|
||||
_position += _right * velocity;
|
||||
break;
|
||||
case MovementDirection.Up:
|
||||
_position += _up * velocity;
|
||||
break;
|
||||
case MovementDirection.Down:
|
||||
_position -= _up * velocity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMouseMovement(float xOffset, float yOffset)
|
||||
{
|
||||
xOffset *= MouseSensitivity; yOffset *= MouseSensitivity;
|
||||
|
||||
_yaw += xOffset;
|
||||
_pitch += yOffset;
|
||||
|
||||
if (_pitch > 89.0f)
|
||||
_pitch = 89.0f;
|
||||
else if (_pitch < -89.0f)
|
||||
_pitch = -89.0f;
|
||||
|
||||
UpdateCameraVectors(); // Recalculate front, right and up vectors since the view angle has changed
|
||||
}
|
||||
|
||||
public void ProcessMouseScroll(float yOffset)
|
||||
{
|
||||
Fov -= yOffset;
|
||||
if (Fov < 1.0f)
|
||||
Fov = 1.0f;
|
||||
if (Fov > 90.0f)
|
||||
Fov = 90.0f;
|
||||
}
|
||||
|
||||
private void UpdateCameraVectors()
|
||||
{
|
||||
Vector3D<float> front = new(
|
||||
MathF.Cos(Maths.Convert.ToRadians(_yaw)) * MathF.Cos(Maths.Convert.ToRadians(_pitch)),
|
||||
MathF.Sin(Maths.Convert.ToRadians(_pitch)),
|
||||
MathF.Sin(Maths.Convert.ToRadians(_yaw)) * MathF.Cos(Maths.Convert.ToRadians(_pitch))
|
||||
);
|
||||
_front = Vector3D.Normalize(front);
|
||||
|
||||
_right = Vector3D.Normalize(Vector3D.Cross(_front, _worldUp));
|
||||
_up = Vector3D.Normalize(Vector3D.Cross(_right, _front));
|
||||
}
|
||||
|
||||
}
|
41
src/Engine_silk.NET.csproj
Normal file
41
src/Engine_silk.NET.csproj
Normal file
@ -0,0 +1,41 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Silk.NET.Input" Version="2.17.1" />
|
||||
<PackageReference Include="Silk.NET.OpenGL" Version="2.17.1" />
|
||||
<PackageReference Include="Silk.NET.Windowing" Version="2.17.1" />
|
||||
<PackageReference Include="StbImageSharp" Version="2.27.13" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="images\container.jpg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="images\container.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="shader.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="shader.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="images\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nebulix\Nebulix.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
40
src/Engine_silk.NET.sln
Normal file
40
src/Engine_silk.NET.sln
Normal file
@ -0,0 +1,40 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.7.34031.279
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Engine_silk.NET", "Engine_silk.NET.csproj", "{FDB52744-20D9-4ED3-AE8E-73466169E83D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nebulix", "..\Nebulix\Nebulix.csproj", "{0DEED1E3-932E-47C3-AF2D-FCA74000908E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nebulix.Test", "..\Nebulix.Test\Nebulix.Test.csproj", "{60B8C905-7AC4-45EE-BAB1-26D3F826124B}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0DEED1E3-932E-47C3-AF2D-FCA74000908E} = {0DEED1E3-932E-47C3-AF2D-FCA74000908E}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FDB52744-20D9-4ED3-AE8E-73466169E83D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FDB52744-20D9-4ED3-AE8E-73466169E83D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FDB52744-20D9-4ED3-AE8E-73466169E83D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FDB52744-20D9-4ED3-AE8E-73466169E83D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DEED1E3-932E-47C3-AF2D-FCA74000908E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DEED1E3-932E-47C3-AF2D-FCA74000908E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DEED1E3-932E-47C3-AF2D-FCA74000908E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DEED1E3-932E-47C3-AF2D-FCA74000908E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{60B8C905-7AC4-45EE-BAB1-26D3F826124B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{60B8C905-7AC4-45EE-BAB1-26D3F826124B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{60B8C905-7AC4-45EE-BAB1-26D3F826124B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{60B8C905-7AC4-45EE-BAB1-26D3F826124B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {43EA4F27-E976-465D-BBBB-C37937F0515E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
20
src/Maths/Convert.cs
Normal file
20
src/Maths/Convert.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Engine_silk.NET.Maths
|
||||
{
|
||||
public static class Convert
|
||||
{
|
||||
public static double ToRadians(double degrees)
|
||||
{
|
||||
return degrees * Math.PI / 180;
|
||||
}
|
||||
public static float ToRadians(float degrees)
|
||||
{
|
||||
return degrees * MathF.PI / 180f;
|
||||
}
|
||||
}
|
||||
}
|
233
src/Program.cs
Normal file
233
src/Program.cs
Normal file
@ -0,0 +1,233 @@
|
||||
namespace Engine_silk.NET;
|
||||
|
||||
using Engine_silk.NET.Textures;
|
||||
using Nebulix.InputSystem;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Numerics;
|
||||
|
||||
// Section: https://github.com/dotnet/Silk.NET/tree/main/examples/CSharp/OpenGL%20Tutorials
|
||||
// Chapter: Continue with 1.3
|
||||
|
||||
// Next to do will be cleaning this up by creating a shader class and maybe even an engine class
|
||||
// IEngine -> IEngine.Create(WindowOptions) -> return OpenGLEngine/VulkanEngine maybe?
|
||||
|
||||
public class Program
|
||||
{
|
||||
private const int Width = 800;
|
||||
private const int Height = 600;
|
||||
|
||||
private static IWindow _window;
|
||||
private static GL _gl;
|
||||
private static Shaders.Shader _shader;
|
||||
private static Texture2D _texture;
|
||||
private static Camera _cam;
|
||||
private static Vector2 _lastMousePosition;
|
||||
private static uint _vao, _vbo, _ebo;
|
||||
|
||||
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
WindowOptions options = WindowOptions.Default with
|
||||
{
|
||||
Size = new Vector2D<int>(Width, Height),
|
||||
Title = "My first Silk.NET application!"
|
||||
};
|
||||
_window = Window.Create(options);
|
||||
|
||||
_window.Load += OnLoad;
|
||||
_window.Update += OnUpdate;
|
||||
_window.Render += OnRender;
|
||||
|
||||
_window.Run();
|
||||
}
|
||||
|
||||
private static unsafe void OnLoad()
|
||||
{
|
||||
_gl = _window.CreateOpenGL();
|
||||
_gl.ClearColor(Color.CornflowerBlue);
|
||||
_gl.Enable(EnableCap.DepthTest);
|
||||
//_gl.PolygonMode(GLEnum.FrontAndBack, GLEnum.Fill);
|
||||
|
||||
_cam = new Camera(new(0.0f, 0.0f, 3.0f));
|
||||
IInputContext input = _window.CreateInput();
|
||||
Input.Init(input);
|
||||
|
||||
for (int i = 0; i < input.Keyboards.Count; i++)
|
||||
{
|
||||
input.Keyboards[i].KeyDown += OnKeyDown;
|
||||
}
|
||||
for (int i = 0; i < input.Mice.Count; i++)
|
||||
{
|
||||
input.Mice[i].MouseMove += OnMouseMove;
|
||||
input.Mice[i].Cursor.CursorMode = CursorMode.Disabled;
|
||||
}
|
||||
|
||||
_vao = _gl.GenVertexArray();
|
||||
_gl.BindVertexArray(_vao);
|
||||
|
||||
float[] vertices =
|
||||
{
|
||||
// positions // normals // texture coords
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
ReadOnlySpan<float> verticesData = new(vertices);
|
||||
//uint[] indices =
|
||||
//{
|
||||
// 0u, 1u, 3u,
|
||||
// 1u, 2u, 3u,
|
||||
|
||||
// 4u, 5u, 7u,
|
||||
// 5u, 6u, 7u,
|
||||
|
||||
// 3u, 2u, 7u,
|
||||
// 7u, 2u, 6u,
|
||||
|
||||
// 0u, 4u, 5u,
|
||||
// 0u, 5u, 1u,
|
||||
|
||||
// 0u, 3u, 7u,
|
||||
// 0u, 7u, 4u,
|
||||
|
||||
// 1u, 6u, 5u,
|
||||
// 1u, 2u, 6u
|
||||
//};
|
||||
|
||||
_vbo = _gl.GenBuffer();
|
||||
_gl.BindBuffer(BufferTargetARB.ArrayBuffer, _vbo);
|
||||
_gl.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(vertices.Length * sizeof(float)), verticesData, BufferUsageARB.StaticDraw);
|
||||
|
||||
//_ebo = _gl.GenBuffer();
|
||||
//_gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, _ebo);
|
||||
//fixed (uint* buffer = indices)
|
||||
// _gl.BufferData(BufferTargetARB.ElementArrayBuffer, (nuint)(indices.Length * sizeof(uint)), buffer, BufferUsageARB.StaticDraw);
|
||||
|
||||
_shader = new Shaders.Shader(_gl, "shader.vert", "shader.frag");
|
||||
|
||||
_gl.EnableVertexAttribArray(0);
|
||||
_gl.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), (void*)0);
|
||||
_gl.EnableVertexAttribArray(1);
|
||||
_gl.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 8 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
_gl.EnableVertexAttribArray(2);
|
||||
_gl.VertexAttribPointer(2, 2, VertexAttribPointerType.Float, false, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
||||
|
||||
_texture = new Texture2D(_gl, "images/container.png", ImageFormat.RGBA);
|
||||
}
|
||||
|
||||
private static void OnUpdate(double deltaTime)
|
||||
{
|
||||
if(Input.AnyKeyPressed())
|
||||
{
|
||||
const float movementSpeedMultiplier = 2;
|
||||
if(Input.IsKeyPressed(Key.ShiftLeft))
|
||||
_cam.MovementSpeed *= movementSpeedMultiplier;
|
||||
|
||||
if (Input.IsKeyPressed(Key.W))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Forward);
|
||||
if(Input.IsKeyPressed(Key.S))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Backward);
|
||||
if (Input.IsKeyPressed(Key.A))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Left);
|
||||
if(Input.IsKeyPressed(Key.D))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Right);
|
||||
if (Input.IsKeyPressed(Key.Space))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Up);
|
||||
if(Input.IsKeyPressed(Key.ControlLeft))
|
||||
_cam.ProcessKeyboard((float)deltaTime, MovementDirection.Down);
|
||||
|
||||
if (Input.IsKeyPressed(Key.ShiftLeft))
|
||||
_cam.MovementSpeed /= movementSpeedMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnRender(double deltaTime)
|
||||
{
|
||||
_gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
|
||||
|
||||
var difference = (float)(_window.Time * 10);
|
||||
var modelMatrix = Matrix4x4.CreateRotationY(Maths.Convert.ToRadians(difference)) * Matrix4x4.CreateRotationX(Maths.Convert.ToRadians(difference));
|
||||
var viewMatrix = _cam.ViewMatrix;
|
||||
var projectionMatrix = Matrix4X4.CreatePerspectiveFieldOfView(Maths.Convert.ToRadians(_cam.Fov), Width / Height, 0.1f, 100.0f);
|
||||
|
||||
_gl.BindVertexArray(_vao);
|
||||
|
||||
_shader.Use();
|
||||
_shader.SetMatrix("modelMatrix", modelMatrix);
|
||||
_shader.SetMatrix("projectionMatrix", projectionMatrix);
|
||||
_shader.SetMatrix("viewMatrix", viewMatrix);
|
||||
|
||||
_shader.SetInt("tex", 0);
|
||||
_texture.Bind();
|
||||
|
||||
_gl.DrawArrays(PrimitiveType.Triangles, 0, 36);
|
||||
}
|
||||
|
||||
private static void OnKeyDown(IKeyboard keyboard, Key key, int keyCode)
|
||||
{
|
||||
if (key == Key.Escape)
|
||||
{
|
||||
_window.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnMouseMove(IMouse mouse, Vector2 position)
|
||||
{
|
||||
if(_lastMousePosition == default)
|
||||
{
|
||||
_lastMousePosition = position;
|
||||
return;
|
||||
}
|
||||
|
||||
float xOffset = position.X - _lastMousePosition.X;
|
||||
float yOffset = _lastMousePosition.Y - position.Y;
|
||||
|
||||
_lastMousePosition = position;
|
||||
_cam.ProcessMouseMovement(xOffset, yOffset);
|
||||
}
|
||||
|
||||
}
|
94
src/Shaders/Shader.cs
Normal file
94
src/Shaders/Shader.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Engine_silk.NET.Shaders;
|
||||
|
||||
public class Shader
|
||||
{
|
||||
private readonly GL _glContext;
|
||||
private readonly uint _shaderProgramId;
|
||||
|
||||
public Shader(GL openGLContext, string pathToVertexShader, string pathToFragmentShader)
|
||||
{
|
||||
_glContext = openGLContext;
|
||||
var vertexCode = File.ReadAllText(pathToVertexShader);
|
||||
var fragmentCode = File.ReadAllText(pathToFragmentShader);
|
||||
|
||||
var vertexShader = CompileShader(vertexCode, ShaderType.VertexShader);
|
||||
var fragmentShader = CompileShader(fragmentCode, ShaderType.FragmentShader);
|
||||
|
||||
_shaderProgramId = CreateProgram(vertexShader, fragmentShader);
|
||||
}
|
||||
|
||||
public void Use() { _glContext.UseProgram(_shaderProgramId); }
|
||||
|
||||
#region Set uniforms
|
||||
public void SetInt(string name, int value)
|
||||
{
|
||||
_glContext.Uniform1(_glContext.GetUniformLocation(_shaderProgramId, name), value);
|
||||
}
|
||||
|
||||
public void SetFloat(string name, float value)
|
||||
{
|
||||
_glContext.Uniform1(_glContext.GetUniformLocation(_shaderProgramId, name), value);
|
||||
}
|
||||
|
||||
public unsafe void SetMatrix(string name, Matrix4x4 matrix)
|
||||
{
|
||||
_glContext.UniformMatrix4(_glContext.GetUniformLocation(_shaderProgramId, name), 1, false, (float*) &matrix);
|
||||
}
|
||||
public unsafe void SetMatrix(string name, Matrix4X4<float> matrix)
|
||||
{
|
||||
_glContext.UniformMatrix4(_glContext.GetUniformLocation(_shaderProgramId, name), 1, false, (float*) &matrix);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Compiles the given shadercode.
|
||||
/// </summary>
|
||||
/// <param name="shaderCode">The shadercode</param>
|
||||
/// <param name="shaderType">The type of shader to compile</param>
|
||||
/// <returns>Returns the id of the compiled shader.</returns>
|
||||
/// <exception cref="ShaderCompileException"></exception>
|
||||
protected uint CompileShader(string shaderCode, ShaderType shaderType)
|
||||
{
|
||||
uint shader = _glContext.CreateShader(shaderType);
|
||||
_glContext.ShaderSource(shader, shaderCode);
|
||||
_glContext.CompileShader(shader);
|
||||
|
||||
_glContext.GetShader(shader, ShaderParameterName.CompileStatus, out int status);
|
||||
|
||||
if (status != (int)GLEnum.True)
|
||||
throw new ShaderCompileException(shaderType, $"Failed to compile shader with message: \n {_glContext.GetShaderInfoLog(shader)}");
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shader program and links the vertex and fragment shader together.
|
||||
/// </summary>
|
||||
/// <returns>Returns the id of the created shader program</returns>
|
||||
/// <exception cref="ShaderLinkException"></exception>
|
||||
protected uint CreateProgram(uint vertexShader, uint fragmentShader)
|
||||
{
|
||||
uint program = _glContext.CreateProgram();
|
||||
_glContext.AttachShader(program, vertexShader);
|
||||
_glContext.AttachShader(program, fragmentShader);
|
||||
_glContext.LinkProgram(program);
|
||||
|
||||
_glContext.GetProgram(program, ProgramPropertyARB.LinkStatus, out int lStatus);
|
||||
if (lStatus != (int)GLEnum.True)
|
||||
throw new ShaderLinkException("Error occured while trying to link a shader with message: \n" + _glContext.GetProgramInfoLog(program));
|
||||
|
||||
// should be done right after compiling and linking
|
||||
_glContext.DetachShader(program, vertexShader);
|
||||
_glContext.DetachShader(program, fragmentShader);
|
||||
_glContext.DeleteShader(vertexShader);
|
||||
_glContext.DeleteShader(fragmentShader);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
}
|
27
src/Shaders/ShaderCompileException.cs
Normal file
27
src/Shaders/ShaderCompileException.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using Silk.NET.OpenGL;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Engine_silk.NET.Shaders;
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class ShaderCompileException : Exception
|
||||
{
|
||||
protected ShaderType _shaderType;
|
||||
|
||||
public ShaderCompileException(ShaderType shaderType) : base("Unable to compile shader.") { _shaderType = shaderType; }
|
||||
public ShaderCompileException(ShaderType shaderType, string message) : base(message) { _shaderType = shaderType; }
|
||||
public ShaderCompileException(ShaderType shaderType, string message, Exception inner) : base(message, inner) { _shaderType = shaderType; }
|
||||
protected ShaderCompileException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Type of Shader: '{_shaderType}'" + "\n" + Message;
|
||||
}
|
||||
}
|
19
src/Shaders/ShaderLinkException.cs
Normal file
19
src/Shaders/ShaderLinkException.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Engine_silk.NET.Shaders;
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class ShaderLinkException : Exception
|
||||
{
|
||||
public ShaderLinkException() : base("Error occured while trying to link a shader.") { }
|
||||
public ShaderLinkException(string message) : base(message) { }
|
||||
public ShaderLinkException(string message, Exception inner) : base(message, inner) { }
|
||||
protected ShaderLinkException(
|
||||
System.Runtime.Serialization.SerializationInfo info,
|
||||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
|
||||
}
|
28
src/Textures/Enums.cs
Normal file
28
src/Textures/Enums.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Silk.NET.OpenGL;
|
||||
using StbImageSharp;
|
||||
|
||||
namespace Engine_silk.NET.Textures;
|
||||
|
||||
public enum ImageFormat
|
||||
{
|
||||
Grey = ColorComponents.Grey,
|
||||
GreyAlpha = ColorComponents.GreyAlpha,
|
||||
RGB = ColorComponents.RedGreenBlue,
|
||||
RGBA = ColorComponents.RedGreenBlueAlpha,
|
||||
}
|
||||
|
||||
internal static class ConverterExtensions
|
||||
{
|
||||
internal static PixelFormat ImageFormatToPixelFormat(this ImageFormat imageFormat)
|
||||
{
|
||||
switch (imageFormat)
|
||||
{
|
||||
case ImageFormat.RGB:
|
||||
return PixelFormat.Rgb;
|
||||
case ImageFormat.RGBA:
|
||||
return PixelFormat.Rgba;
|
||||
default:
|
||||
throw new NotImplementedException($"Cannot map the given {nameof(ImageFormat)} '{imageFormat}' to a {nameof(PixelFormat)}");
|
||||
}
|
||||
}
|
||||
}
|
85
src/Textures/Texture2D.cs
Normal file
85
src/Textures/Texture2D.cs
Normal file
@ -0,0 +1,85 @@
|
||||
|
||||
using Silk.NET.OpenGL;
|
||||
using StbImageSharp;
|
||||
|
||||
namespace Engine_silk.NET.Textures;
|
||||
|
||||
public class Texture2D : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines how the texture should be wrapped if the uv-coordinates are out of bounds
|
||||
/// Default: Repeat
|
||||
/// </summary>
|
||||
public TextureWrapMode WrapMode { get; set; }
|
||||
/// <summary>
|
||||
/// Defines how a texel should be interpolated when zooming out of the texture.
|
||||
/// Default: BiLinear
|
||||
/// </summary>
|
||||
public TextureMinFilter MinifyingInterpolation { get; set; }
|
||||
/// <summary>
|
||||
/// Defines how a texel should be interpolated when zooming in to the texture.
|
||||
/// Default: Bilinear
|
||||
/// </summary>
|
||||
public TextureMagFilter MagnifyingInterpolation { get; set; }
|
||||
|
||||
protected GL _glContext;
|
||||
protected uint _textureId;
|
||||
private bool disposedValue;
|
||||
|
||||
public Texture2D(GL glContext, string pathToTexture, ImageFormat format = ImageFormat.RGB, TextureWrapMode wrapMode = TextureWrapMode.Repeat,
|
||||
TextureMinFilter minifyingInterpolation = TextureMinFilter.Linear, TextureMagFilter magnifyingInterpolation = TextureMagFilter.Linear)
|
||||
{
|
||||
_glContext = glContext;
|
||||
WrapMode = wrapMode;
|
||||
MinifyingInterpolation = minifyingInterpolation;
|
||||
MagnifyingInterpolation = magnifyingInterpolation;
|
||||
|
||||
byte[] buffer = File.ReadAllBytes(pathToTexture);
|
||||
ImageResult image = ImageResult.FromMemory(buffer, (ColorComponents)format);
|
||||
ReadOnlySpan<byte> imageData = new(image.Data);
|
||||
|
||||
_glContext.GenTextures(1, out _textureId);
|
||||
_glContext.BindTexture(TextureTarget.Texture2D, _textureId);
|
||||
_glContext.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgb, (uint)image.Width, (uint)image.Height, 0, format.ImageFormatToPixelFormat(), PixelType.UnsignedByte, imageData);
|
||||
_glContext.GenerateMipmap(TextureTarget.Texture2D);
|
||||
}
|
||||
|
||||
public void Bind(TextureUnit textureUnit = TextureUnit.Texture0)
|
||||
{
|
||||
_glContext.TexParameter(TextureTarget.Texture2D, GLEnum.TextureWrapT, (int)WrapMode);
|
||||
_glContext.TexParameter(TextureTarget.Texture2D, GLEnum.TextureMinFilter, (int)MinifyingInterpolation);
|
||||
_glContext.TexParameter(TextureTarget.Texture2D, GLEnum.TextureMagFilter, (int)MagnifyingInterpolation);
|
||||
|
||||
_glContext.ActiveTexture(textureUnit);
|
||||
_glContext.BindTexture(TextureTarget.Texture2D, _textureId);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_glContext.DeleteTexture(_textureId);
|
||||
}
|
||||
|
||||
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
|
||||
// TODO: set large fields to null
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources
|
||||
// ~Texture2D()
|
||||
// {
|
||||
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
// Dispose(disposing: false);
|
||||
// }
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
BIN
src/images/container.png
Normal file
BIN
src/images/container.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 457 KiB |
17
src/shader.frag
Normal file
17
src/shader.frag
Normal file
@ -0,0 +1,17 @@
|
||||
#version 330 core
|
||||
|
||||
out vec4 colour;
|
||||
|
||||
in vec2 TexCoords;
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
void main()
|
||||
{
|
||||
//vec3 col = vec3(1.0, 0.5, 0.2) * FragPos;
|
||||
|
||||
//colour = vec4(texture(tex, TexCoords).rgb, 1.0);
|
||||
colour = texture(tex, TexCoords);
|
||||
}
|
24
src/shader.vert
Normal file
24
src/shader.vert
Normal file
@ -0,0 +1,24 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location=0) in vec3 aPosition;
|
||||
layout (location = 1) in vec3 normalVector;
|
||||
layout (location = 2) in vec2 texCoords;
|
||||
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
uniform mat4 projectionMatrix;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(aPosition, 1.0);
|
||||
|
||||
// TODO: calculate the inverse of the model matrix since "inverse()" is very costly to calculate for every vertex
|
||||
Normal = mat3(transpose(inverse(modelMatrix))) * normalVector;
|
||||
FragPos = vec3(modelMatrix * pos);
|
||||
TexCoords = texCoords;
|
||||
gl_Position = projectionMatrix * viewMatrix * modelMatrix * pos;
|
||||
}
|
Reference in New Issue
Block a user