using Map3DRendering.Common; using OpenTK.Graphics.OpenGL4; using OpenTK.Mathematics; using OpenTK.Windowing.Common; using OpenTK.Windowing.Desktop; using OpenTK.Windowing.GraphicsLibraryFramework; namespace Map3DRendering { public class Window : GameWindow { private readonly Vector3 _lightPos = new Vector3(0x10, 0, 0x10); private MapRender mapRender; private AxesGizmo axesGizmo; private Shader _shader; private Texture _texture; private Camera _camera; private bool _firstMove = true; private Vector2 _lastPos; private Vector3 _lightPosVec; private double _time; private float tileSize = 64; private float cameraSpeed = 50f; private int maxTextures; public Window(GameWindowSettings gameWindowSettings, NativeWindowSettings nativeWindowSettings) : base(gameWindowSettings, nativeWindowSettings) { mapRender = new MapRender(); GL.GetInteger(GetPName.MaxTextureImageUnits, out maxTextures); } protected override void OnLoad() { base.OnLoad(); GL.ClearColor(0.2f, 0.3f, 0.3f, 1.0f); GL.Enable(EnableCap.DepthTest); int maxTextureUnits; GL.GetInteger(GetPName.MaxTextureImageUnits, out maxTextureUnits); Console.WriteLine($"Maximum number of texture units for fragment shaders: {maxTextureUnits}"); _shader = new Shader("Shaders/shader.vert", "Shaders/shader.frag"); _shader.Use(); mapRender.OnLoad(_shader); var file = Directory.EnumerateFiles(@"./terrains"); _texture = Texture.LoadFromArray(file.ToArray()); _texture.UseArray(TextureUnit.Texture0); axesGizmo = new AxesGizmo(); _camera = new Camera(Vector3.UnitY * 300, Size.X / (float)Size.Y); _camera.Fov = 60; //CursorState = CursorState.Grabbed; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); _lightPosVec = Vector3.UnitY * 1000; } protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); _time += 4.0 * e.Time; GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); _shader.Use(); _texture.UseArray(TextureUnit.Texture0); _shader.SetMatrix4("view", _camera.GetViewMatrix()); _shader.SetMatrix4("projection", _camera.GetProjectionMatrix()); //_shader.SetVector3("objectColor", new Vector3(0.5f, 0.5f, 0.5f)); _shader.SetVector3("lightColor", new Vector3(1.0f, 1.0f, 1.0f)); _shader.SetVector3("lightPos", _camera.Position); GL.LineWidth(5.0f); _shader.SetVector3("viewPos", _camera.Position); mapRender.UpdateBlocks(_camera.Position, _shader); mapRender.Render(_shader); axesGizmo.Render(Size.X, Size.Y, _camera); SwapBuffers(); } protected override void OnUpdateFrame(FrameEventArgs e) { base.OnUpdateFrame(e); if (!IsFocused) // Check to see if the window is focused { return; } var input = KeyboardState; if (input.IsKeyDown(Keys.Escape)) { Close(); } // Vitesse de déplacement de la lumière float lightSpeed = 300.0f; // Ajustez cette valeur selon les besoins // Mise à jour de la position de la lumière en fonction des entrées utilisateur if (input.IsKeyDown(Keys.Down)) { _lightPosVec += Vector3.UnitX * lightSpeed * (float)e.Time; // Déplace la lumière vers le bas } if (input.IsKeyDown(Keys.Up)) { _lightPosVec -= Vector3.UnitX * lightSpeed * (float)e.Time; // Déplace la lumière vers le haut } if (input.IsKeyDown(Keys.Left)) { _lightPosVec -= Vector3.UnitZ * lightSpeed * (float)e.Time; // Déplace la lumière vers la gauche } if (input.IsKeyDown(Keys.Right)) { _lightPosVec += Vector3.UnitZ * lightSpeed * (float)e.Time; // Déplace la lumière vers la droite } const float sensitivity = 0.2f; if (input.IsKeyDown(Keys.W)) { _camera.Position += _camera.Front * cameraSpeed * (float)e.Time; // Forward } if (input.IsKeyDown(Keys.S)) { _camera.Position -= _camera.Front * cameraSpeed * (float)e.Time; // Backwards } if (input.IsKeyDown(Keys.A)) { _camera.Position -= _camera.Right * cameraSpeed * (float)e.Time; // Left } if (input.IsKeyDown(Keys.D)) { _camera.Position += _camera.Right * cameraSpeed * (float)e.Time; // Right } if (input.IsKeyDown(Keys.Space)) { _camera.Position += Vector3.UnitY * cameraSpeed * (float)e.Time; // Up } if (input.IsKeyDown(Keys.LeftShift)) { _camera.Position -= Vector3.UnitY * cameraSpeed * (float)e.Time; // Down } // Get the mouse state var mouse = MouseState; // Check if the right mouse button is pressed if (mouse.IsButtonDown(MouseButton.Right)) { CursorState = CursorState.Grabbed; if (_firstMove) // This bool variable is initially set to true. { _lastPos = new Vector2(mouse.X, mouse.Y); _firstMove = false; } else { // Calculate the offset of the mouse position var deltaX = mouse.X - _lastPos.X; var deltaY = mouse.Y - _lastPos.Y; _lastPos = new Vector2(mouse.X, mouse.Y); // Apply the camera pitch and yaw (we clamp the pitch in the camera class) _camera.Yaw += deltaX * sensitivity; _camera.Pitch -= deltaY * sensitivity; // Reversed since y-coordinates range from bottom to top } } else { _firstMove = true; CursorState = CursorState.Normal; } } // In the mouse wheel function, we manage all the zooming of the camera. // This is simply done by changing the FOV of the camera. protected override void OnMouseWheel(MouseWheelEventArgs e) { base.OnMouseWheel(e); cameraSpeed -= e.OffsetY * 2f; } protected override void OnResize(ResizeEventArgs e) { base.OnResize(e); GL.Viewport(0, 0, Size.X, Size.Y); // We need to update the aspect ratio once the window has been resized. _camera.AspectRatio = Size.X / (float)Size.Y; } } }