Пример #1
0
        /// <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());
                    }
                });
            }
        }
Пример #2
0
        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();
            });
        }
Пример #3
0
        /// <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();
            }));
        }
Пример #4
0
 public void SwapBuffers()
 {
     ProfilerTimer.Profile(() =>
     {
         Glfw.PollEvents();
         Glfw.SwapBuffers(window);
     });
 }
Пример #5
0
        public void Shutdown()
        {
            ProfilerTimer.Profile(() =>
            {
                window.Dispose();
                windowCount--;

                if (windowCount == 0)
                {
                    Glfw.Terminate();
                }
            });
        }
Пример #6
0
        /// <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;
            });
        }
Пример #7
0
        /// <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();
            });
        }
Пример #8
0
        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();
                    });
                }
            });
        }
Пример #9
0
        /// <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();
                }
            });
        }
Пример #10
0
        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
                }
            });
        }
Пример #11
0
        /// <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);
            });
        }
Пример #12
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
        }
Пример #13
0
        /// <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();
        }
Пример #14
0
        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);
            });
        }