/// <summary> /// Runs the main application loop /// </summary> internal void Run() { while (isRunning) { ProfilerTimer.Profile("Engine Loop", () => { float time = window.GetTime(); TimeStep timeStep = new TimeStep(time - lastTime); lastTime = time; //LayerStack update { ProfilerTimer.Profile("LayerStack.OnUpdate", () => { if (!minimized) { foreach (ILayer layer in layerStack.GetLayers()) { layer.OnUpdate(timeStep); } } }); } //Window update { ProfilerTimer.Profile("Window.OnUpdate", () => window.OnUpdate()); } }); } }
public Application() { ProfilerTimer.Profile("Application Create", () => { if (app != null) { Debug.Assert(false, "A running app already exists!"); #if !DEBUG Logging.Logger.Error("A running app already exists!"); return; #endif } app = this; //Creates a new window window = IWindow.CreateWindow(new WindowProperties { Title = "Voltstro Engine", Width = 1280, Height = 720, VSync = true }); window.OnEvent += WindowOnOnEvent; layerStack = new LayerStack(); }); }
/// <summary> /// Sets up Eto.Forms /// </summary> internal static void Init() { ProfilerTimer.Profile((() => { etoForms = new List <Form>(); Thread appThread = new Thread(() => { try { app = new Application(); app.Run(); } catch (Exception e) { Debug.Assert(false, $"An error occured in the Eto.Forms system!\n{e}"); #if !DEBUG Logger.Error("An error occured in the Eto.Forms system!\n{@Message}", e); #endif } }); appThread.SetApartmentState(ApartmentState.STA); appThread.Start(); })); }
public void SwapBuffers() { ProfilerTimer.Profile(() => { Glfw.PollEvents(); Glfw.SwapBuffers(window); }); }
public void Shutdown() { ProfilerTimer.Profile(() => { window.Dispose(); windowCount--; if (windowCount == 0) { Glfw.Terminate(); } }); }
/// <summary> /// Initializes the rendering system /// </summary> /// <exception cref="InitializationException"></exception> internal static void Init() { ProfilerTimer.Profile(() => { if (initialized) { throw new InitializationException("The rendering system is already initialized!"); } RenderingAPI.Init(); Renderer2D.Init(); initialized = true; }); }
/// <summary> /// Shuts down the Eto.Forms system /// </summary> internal static void Shutdown() { ProfilerTimer.Profile(() => { // ReSharper disable once ForCanBeConvertedToForeach for (int i = 0; i < etoForms.Count; i++) { DestroyForm(etoForms[i]); } app.Quit(); app.Dispose(); etoForms.Clear(); }); }
public void OnUpdate(TimeStep ts) { ProfilerTimer.Profile("Sandbox.OnUpdate", () => { //Update { ProfilerTimer.Profile("Sandbox Update", () => cameraController.OnUpdate(ts)); } //Render { ProfilerTimer.Profile("Renderer Prep", () => { RenderingAPI.SetClearColor(0.1f, 0.1f, 0.1f); RenderingAPI.Clear(); }); } { ProfilerTimer.Profile("Renderer Draw", () => { Renderer2D.BeginScene(cameraController.GetCamera()); { Renderer2D.DrawRotatedQuad(new Transform { Position = new Vector3(-1.0f, 0.0f, 0.0f), Scale = new Vector2(0.8f, 0.8f), Rotation = 45.0f }, new Vector4(0.8f, 0.2f, 0.3f, 1.0f)); Renderer2D.DrawQuad(new Transform { Position = new Vector3(0.5f, -0.5f, 1.0f), Scale = new Vector2(0.5f, 0.75f) }, new Vector4(0.2f, 0.3f, 0.8f, 1.0f)); Renderer2D.DrawQuad(new Transform { Position = new Vector3(0f, 0f, -0.1f), Scale = new Vector2(10f, 10f) }, birdiTexture, new Vector4(1.0f, 0.9f, 0.9f, 1.0f), 10.0f); } Renderer2D.EndScene(); }); } }); }
/// <summary> /// Adds a form to be displayed /// </summary> /// <param name="form"></param> /// <param name="dontShow"></param> /// <exception cref="ArgumentNullException"></exception> public static void AddForm(Form form, bool dontShow = false) { if (form == null) { throw new ArgumentNullException(nameof(form), "Form cannot be null!"); } ProfilerTimer.Profile(() => { etoForms.Add(form); if (!dontShow) { form.Show(); } }); }
public void Init() { ProfilerTimer.Profile(() => { try { Gl.Enable(EnableCap.Blend); Gl.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); Gl.Enable(EnableCap.DepthTest); } catch (Exception ex) { Debug.Assert(false, $"An error occured while enabling OpenGL!\n{ex}"); #if !DEBUG Core.Logging.Logger.Error("Am error occured while initializing OpenGL!\n{@Message}", ex); #endif } }); }
/// <summary> /// Initializes the 2D rendering system /// </summary> internal static void Init() { ProfilerTimer.Profile(() => { rendererData = new Renderer2DStorage { QuadVertexArray = IVertexArray.Create() }; float[] squareVertices = { -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.5f, 0.5f, 0.0f, 1.0f, 1.0f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f }; IVertexBuffer squareVertexBuffer = IVertexBuffer.Create(squareVertices, squareVertices.GetBytes()); BufferLayout squareBufferLayout = new BufferLayout(new[] { new BufferElement("a_Position", ShaderDataType.Float3), new BufferElement("a_TexCoord", ShaderDataType.Float2) }); squareVertexBuffer.SetLayout(squareBufferLayout); rendererData.QuadVertexArray.AddVertexBuffer(squareVertexBuffer); uint[] squareIndices = { 0, 1, 2, 2, 3, 0 }; IIndexBuffer squareIndexBuffer = IIndexBuffer.Create(squareIndices, squareIndices.GetBytes() / sizeof(uint)); rendererData.QuadVertexArray.SetIndexBuffer(squareIndexBuffer); rendererData.WhiteTexture = I2DTexture.Create(1, 1); uint whiteTextureData = 0xffffffff; rendererData.WhiteTexture.SetData(whiteTextureData, sizeof(uint)); rendererData.TextureShader = IShader.Create("Shaders/Texture.glsl"); rendererData.TextureShader.Bind(); rendererData.TextureShader.SetInt("u_Texture", 0); }); }
public void Init() { ProfilerTimer.Profile(() => { Logger.Info("Initializing OpenGL context..."); try { Gl.Initialize(); Glfw.MakeContextCurrent(window); } catch (Exception ex) { Debug.Assert(false, $"Some error occured while initializing OpenGL for GLFW!\n{ex}"); #if !DEBUG Logger.Error("An error occured while initializing OpenGL for GLFW!\n{@Message}", ex); #endif } }); Logger.Info("OpenGL context initialized!"); Logger.Info("OpenGL Info:"); Logger.Info(" Vendor: {@Vendor}", Gl.GetString(StringName.Vendor)); Logger.Info(" Renderer: {@Renderer}", Gl.GetString(StringName.Renderer)); Logger.Info(" Version: {@Version}", Gl.GetString(StringName.Version)); Gl.GetInteger(GetPName.MajorVersion, out int versionMajor); Gl.GetInteger(GetPName.MinorVersion, out int versionMinor); Logger.Info("Running OpenGL Version {@VersionMajor}.{@VersionMinor}", versionMajor, versionMinor); if (versionMajor >= 4 && (versionMajor != 4 || versionMinor >= 5)) { return; } Debug.Assert(false, "Voltstro Engine excepts at least OpenGL version 4.5!"); #if !DEBUG Logger.Error("Voltstro Engine excepts at least OpenGL version 4.5!"); System.Environment.Exit(-1); #endif }
/// <summary> /// Init, and runs the game /// </summary> /// <param name="entry"></param> /// <param name="noWindow"></param> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="NullReferenceException"></exception> public static void Init(IEntryPoint entry, bool noWindow = false) { //Make sure the entry isn't null, or that there is no game name if (entry == null) { throw new ArgumentNullException(nameof(entry), "Entry cannot be null!"); } if (string.IsNullOrWhiteSpace(entry.GetGameName())) { throw new NullReferenceException("Game name cannot be null!"); } //Initiate the logger first Logger.Init(); Profiler.BeginSession("Startup", "VoltstroEngineProfile-Startup.json"); Application app = null; ProfilerTimer.Profile(() => { //Setup render RenderingAPI.Create(); //Set game name, since we load all our game related files from that path //So if the game requests for a texture, we load it from the game's bin parent directory, allowing for multiple games, but all using the same copy of the engine //E.G: // - Engine Stuff (Launcher/VoltstroEngine.dll) // - | // - Sandbox // - - Textures/ GameName = entry.GetGameName(); if (!noWindow) { //Init our forms system EtoFormsSystem.Init(); //Create the app Logger.Info("Creating {@GameName}'s application...", GameName); app = entry.CreateApplication(); if (app == null) { throw new NullReferenceException("The app cannot be null!"); } //Init the render Renderer.Init(); } else { //Init the render Renderer.Init(); } }); Profiler.EndSession(); //Run the main loop if (!noWindow) { Profiler.BeginSession("Runtime", "VoltstroEngineProfile-Runtime.json"); { ProfilerTimer.Profile("Game Loop", () => { app.Run(); }); } Profiler.EndSession(); } //Shutdown stuff Profiler.BeginSession("Shutdown", "VoltstroEngineProfile-Shutdown.json"); { ProfilerTimer.Profile("Shutdown", () => { Application.Shutdown(); Renderer.Shutdown(); EtoFormsSystem.Shutdown(); }); Logger.Shutdown(); } Profiler.EndSession(); }
private void Init(WindowProperties properties) { ProfilerTimer.Profile(() => { Logger.Info("Initializing a window for Windows..."); //Initialize glfw if it hasn't already if (windowCount == 0) { bool success = Glfw.Init(); Debug.Assert(success, "GLFW failed to init!"); Glfw.SetErrorCallback(ErrorHandler); } #if DEBUG if (RenderingAPI.GetRenderingAPI() == RenderingAPIType.OpenGL) { Glfw.WindowHint(Hint.OpenglDebugContext, true); } #endif //Set the properties and create the window windowProperties = properties; { ProfilerTimer.Profile("GLFW Create Window", () => { window = new NativeWindow(properties.Width, properties.Height, properties.Title); windowCount++; }); } //Create context context = RenderingAPI.GetRenderingAPI() switch { RenderingAPIType.OpenGL => new OpenGLContext(window), _ => throw new ArgumentOutOfRangeException() }; //Init the context context.Init(); SetVSync(properties.VSync); //Setup input Input.KeyInputImpl = new WindowsInput(window); //GLFW callbacks window.Closed += (sender, args) => OnEvent?.Invoke(new WindowCloseEvent()); window.SizeChanged += delegate(object sender, SizeChangeEventArgs args) { windowProperties.Width = args.Size.Width; windowProperties.Height = args.Size.Height; OnEvent?.Invoke(new WindowResizedEvent(args.Size.Width, args.Size.Height)); }; window.KeyAction += delegate(object sender, KeyEventArgs args) { switch (args.State) { case InputState.Release: OnEvent?.Invoke(new KeyReleasedEvent((KeyCode)args.Key)); break; case InputState.Press: OnEvent?.Invoke(new KeyPressedEvent((KeyCode)args.Key)); break; case InputState.Repeat: OnEvent?.Invoke(new KeyPressedEvent((KeyCode)args.Key, 1)); break; default: throw new ArgumentOutOfRangeException(nameof(args.State), args.State, null); } }; window.MouseButton += delegate(object sender, MouseButtonEventArgs args) { switch (args.Action) { case InputState.Press: OnEvent?.Invoke(new MouseButtonPressedEvent((int)args.Button)); break; case InputState.Release: OnEvent?.Invoke(new MouseButtonReleasedEvent((int)args.Button)); break; } }; window.MouseScroll += (sender, args) => OnEvent?.Invoke(new MouseScrollEvent((float)args.X, (float)args.Y)); window.MouseMoved += (sender, args) => OnEvent?.Invoke(new MouseMovedEvent((float)args.X, (float)args.Y)); Logger.Debug("Created a window for Windows ({@Width}x{@Height}, {@VSync})", properties.Width, properties.Height, properties.VSync); }); }