Beispiel #1
0
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }
            _disposed = true;

            _currentTiming = CurrentFrameTiming.OutOfFrameLoop;

            Layers.AbortAllLayers();

            TimingPoints.AbortAllEvents();
            Lights.Release();
            ContextAssociatedMemorySafety.EnsureCollect(OwnerScreen);   // Must be called before the opengl context is deleted.
            Disposed?.Invoke();
        }
Beispiel #2
0
        public void RenderFrame()
        {
            // ------------------------------------------------------------
            // Out of frame loop
            Debug.Assert(_currentTiming == CurrentFrameTiming.OutOfFrameLoop);
            var isCloseRequested = _isCloseRequested;
            var layers           = Layers;

            var frameTimingPoints = TimingPoints;

            Mouse.InitFrame();
            Keyboard.InitFrame();

            // ------------------------------------------------------------
            // First Frame initializing
            if (_state == RenderingAreaLifeState.Activating)
            {
                _currentTiming = CurrentFrameTiming.FirstFrameInitializing;
                try {
                    Initialized?.Invoke(OwnerScreen);
                }
                catch {
                    if (EngineSetting.UserCodeExceptionCatchMode == UserCodeExceptionCatchMode.Throw)
                    {
                        throw;
                    }
                    // Don't throw. (Ignore exceptions in user code)
                }
                finally {
                    _state = RenderingAreaLifeState.Alive;
                }
            }

            // ------------------------------------------------------------
            // Frame initializing
            _currentTiming = CurrentFrameTiming.FrameInitializing;
            if (isCloseRequested && _state == RenderingAreaLifeState.Alive)
            {
                _state = RenderingAreaLifeState.Terminating;
                _runningTokenSource.Cancel();
                layers.TerminateAllLayers(this,
                                          onDead: static self =>
                {
                    self._state = RenderingAreaLifeState.Dead;
                });
            }
            layers.ApplyAdd();
            frameTimingPoints.FrameInitializing.DoQueuedEvents();

            // ------------------------------------------------------------
            // Early update
            _currentTiming = CurrentFrameTiming.EarlyUpdate;
            frameTimingPoints.EarlyUpdate.DoQueuedEvents();
            layers.EarlyUpdate();

            // ------------------------------------------------------------
            // Update
            _currentTiming = CurrentFrameTiming.Update;
            frameTimingPoints.Update.DoQueuedEvents();
            layers.Update();

            // ------------------------------------------------------------
            // Late update
            _currentTiming = CurrentFrameTiming.LateUpdate;
            frameTimingPoints.LateUpdate.DoQueuedEvents();
            layers.LateUpdate();

            // ------------------------------------------------------------
            // Before rendering
            _currentTiming = CurrentFrameTiming.BeforeRendering;
            FBO.Bind(FBO.Empty, FBO.Target.FrameBuffer);
            ElffyGL.Clear(ClearMask.ColorBufferBit | ClearMask.DepthBufferBit);
            frameTimingPoints.BeforeRendering.DoQueuedEvents();

            // ------------------------------------------------------------
            // Rendering
            _currentTiming = CurrentFrameTiming.Rendering;
            layers.Render();

            // ------------------------------------------------------------
            // After rendering
            _currentTiming = CurrentFrameTiming.AfterRendering;
            frameTimingPoints.AfterRendering.DoQueuedEvents();

            // ------------------------------------------------------------
            // Frame finalizing
            _currentTiming = CurrentFrameTiming.FrameFinalizing;
            layers.ApplyRemove();

            // ------------------------------------------------------------
            // End of frame (only internal accessible)
            _currentTiming = CurrentFrameTiming.Internal_EndOfFrame;
            frameTimingPoints.InternalEndOfFrame.DoQueuedEvents();

            // ------------------------------------------------------------
            // Out of frame loop
            _currentTiming = CurrentFrameTiming.OutOfFrameLoop;
            ContextAssociatedMemorySafety.CollectIfExist(OwnerScreen);

            if (_state == RenderingAreaLifeState.Dead)
            {
                Dispose();
            }
        }