예제 #1
0
        public override void OnRenderFrame(RenderFrameEventArgs e)
        {
            GL.ClearColor(ClearColor);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.Enable(EnableCap.DepthTest);
            GL.PixelStore(PixelStoreParameter.UnpackAlignment, 1);

            UpdateProjection();

            #region Modelview
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            Glu.LookAt(camera.Position,
                       camera.Position + camera.Attitude.Direction,
                       camera.Attitude.Up);
            #endregion

            objects.Objects["Camera Position"] = camera.Position.ToString(2);
            objects.Objects["Camera Direction"] = camera.Attitude.Direction.ToString(2);
            objects.Objects["Camera Up"] = camera.Attitude.Up.ToString(2);
            objects.Objects["Camera Side"] = camera.Attitude.Side.ToString(2);

            Renderables.Render(GetRenderInfo());

            SwapBuffers();
        }
예제 #2
0
 /// <summary>
 /// Override in derived classes to render a frame.
 /// </summary>
 /// <param name="e">Contains information necessary for frame rendering.</param>
 /// <remarks>
 /// The base implementation (base.OnRenderFrame) is empty, there is no need to call it.
 /// </remarks>
 public virtual void OnRenderFrame(RenderFrameEventArgs e)
 {
 }
예제 #3
0
        /// <summary>
        /// Enters the game loop of the GameWindow updating and rendering at the specified frequency.
        /// </summary>
        /// <param name="updates_per_second">The frequency of UpdateFrame events.</param>
        /// <param name="frames_per_second">The frequency of RenderFrame events.</param>
        public void Run(double updates_per_second, double frames_per_second)
        {
            try
            {
                if (updates_per_second < 0.0 || updates_per_second > 200.0)
                    throw new ArgumentOutOfRangeException("updates_per_second", updates_per_second, "Parameter should be inside the range [0.0, 200.0]");
                if (frames_per_second < 0.0 || frames_per_second > 200.0)
                    throw new ArgumentOutOfRangeException("frames_per_second", frames_per_second, "Parameter should be inside the range [0.0, 200.0]");

                TargetUpdateFrequency = updates_per_second;
                TargetRenderFrequency = frames_per_second;

                Stopwatch update_watch = new Stopwatch(), render_watch = new Stopwatch();
                double time, next_render = 0.0, next_update = 0.0, update_time_counter = 0.0;
                int num_updates = 0;
                UpdateFrameEventArgs update_args = new UpdateFrameEventArgs();
                RenderFrameEventArgs render_args = new RenderFrameEventArgs();

                update_watch.Reset();
                render_watch.Reset();

                //double sleep_granularity;      // In seconds.

                //GC.Collect(2);
                //GC.WaitForPendingFinalizers();
                //GC.Collect(2);

                // Find the minimum granularity of the Thread.Sleep() function.
                // TODO: Disabled - see comment on Thread.Sleep() problems below.
                //update_watch.Start();
                //const int test_times = 5;
                //for (int i = test_times; --i > 0; )
                //    Thread.Sleep(1);
                //update_watch.Stop();
                //sleep_granularity = System.Math.Round(1000.0 * update_watch.Elapsed.TotalSeconds / test_times, MidpointRounding.AwayFromZero) / 1000.0;
                //update_watch.Reset();       // We don't want to affect the first UpdateFrame!

                //try
                //{
                    OnLoadInternal(EventArgs.Empty);
                //}
                //catch (Exception e)
                //{
                //    Trace.WriteLine(String.Format("OnLoad failed: {0}", e.ToString()));
                //    return;
                //}

                //Debug.Print("Elevating priority.");
                //Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

                Debug.Print("Entering main loop.");
                while (!isExiting)
                {
                    ProcessEvents();

                    // Raise UpdateFrame events
                    time = update_watch.Elapsed.TotalSeconds;
                    if (time > 1.0)
                        time = 1.0;
                    while (next_update - time <= 0.0)
                    {
                        next_update = next_update - time + TargetUpdatePeriod;
                        if (next_update < -1.0)       // Cap the maximum time drift, to avoid lengthy catch-up games.
                            next_update = -1.0;

                        update_time_counter += time;
                        ++num_updates;

                        update_watch.Reset();
                        update_watch.Start();

                        update_args.Time = time;
                        OnUpdateFrameInternal(update_args);
                        update_time = update_watch.Elapsed.TotalSeconds;

                        if (TargetUpdateFrequency == 0.0)
                            break;

                        time = update_watch.Elapsed.TotalSeconds;
                        next_update -= time;
                        update_time_counter += time;

                        // Allow up to 10 frames to be dropped. Prevents the application from hanging
                        // with very high update frequencies.
                        if (num_updates >= 10)
                            break;
                    }
                    if (num_updates > 0)
                    {
                        update_period = update_time_counter / (double)num_updates;
                        num_updates = 0;
                        update_time_counter = 0.0;
                    }

                    // Raise RenderFrame event
                    time = render_watch.Elapsed.TotalSeconds;
                    if (time > 1.0)
                        time = 1.0;
                    double time_left = next_render - time;
                    if (VSync == VSyncMode.Adaptive)
                    {
                        // Check if we have enough time for a vsync
                        if (RenderTime > 2.0 * TargetRenderPeriod)
                            Context.VSync = false;
                        else
                            Context.VSync = true;
                    }

                    if (time_left <= 0.0)
                    {
                        next_render = time_left + TargetRenderPeriod;
                        if (next_render < -1.0)       // Cap the maximum time drift, to avoid lengthy catch-up games.
                            next_render = -1.0;

                        render_watch.Reset();
                        render_watch.Start();

                        render_period = render_args.Time = time;
                        render_args.ScaleFactor = RenderPeriod / UpdatePeriod;
                        OnRenderFrameInternal(render_args);
                        render_time = render_watch.Elapsed.TotalSeconds;
                    }

                    // Yield CPU time, if the Thread.Sleep() granularity allows it.
                    // TODO: Disabled because it does not work reliably enough on all systems.
                    // Enable vsync as a workaround.
                    //if (AllowSleep && next_render > sleep_granularity && next_update > sleep_granularity)
                    //{
                    //    Thread.Sleep((int)(1000.0 * System.Math.Min(next_render - sleep_granularity, next_update - sleep_granularity)));
                    //}
                }
            }
            catch (GameWindowExitException)
            {
                Trace.WriteLine("GameWindowExitException caught - exiting main loop.");
            }
            finally
            {
                Debug.Print("Restoring priority.");
                Thread.CurrentThread.Priority = ThreadPriority.Normal;

                OnUnloadInternal(EventArgs.Empty);

                if (this.Exists)
                {
                    if (Exists)
                        glWindow.DestroyWindow();
                    while (this.Exists)
                        this.ProcessEvents();
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Raises the RenderFrame event, and calls the public function.
        /// </summary>
        /// <param name="e"></param>
        private void OnRenderFrameInternal(RenderFrameEventArgs e)
        {
            if (!this.Exists && !this.IsExiting)
            {
                Debug.Print("WARNING: RenderFrame event raised, without a valid render window. This may indicate a programming error. Creating render window.");
                mode = new DisplayMode(640, 480);
                this.CreateWindow(mode);
            }
            if (RenderFrame != null)
                RenderFrame(this, e);

            // Call the user's override.
            OnRenderFrame(e);
        }
        /// <summary>
        /// Called when it is time to render the next frame. Add your rendering code here.
        /// </summary>
        /// <param name="e">Contains timing information.</param>
        public override void OnRenderFrame(RenderFrameEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit);

            if (gv != null)
            {
                //GL.Viewport((int)gv.activeWindow.X, (int)gv.activeWindow.Y, (int)gv.activeWindow.Width, (int)gv.activeWindow.Height);
                GL.MatrixMode(MatrixMode.Projection);
                GL.LoadIdentity();
                Glu.Ortho2D(0, 800, gv.activeWindow.Y + 600, gv.activeWindow.Y);
                GL.MatrixMode(MatrixMode.Modelview);
                GL.LoadIdentity();

                // draw all the obstacles

                GL.Color3(Color.Black);
                GL.Begin(BeginMode.Quads);

                foreach (deathcave_logic.gameObjects.BaseGameObject bgo in gv.obstacles)
                {
                    DrawBGO(bgo);

                }

                GL.End();

                // draw the shots
                GL.Color3(Color.YellowGreen);
                GL.Begin(BeginMode.Quads);
                foreach (deathcave_logic.gameObjects.BaseGameObject bgo in gv.projectiles)
                {
                    DrawBGO(bgo);
                }
                GL.End();

                // draw explosions
                GL.Color3(Color.Red);
                GL.Begin(BeginMode.Quads);
                foreach (deathcave_logic.gameObjects.BaseGameObject bgo in gv.effects)
                {
                    DrawBGO(bgo);
                }
                GL.End();

                //draw the enemies
                GL.Begin(BeginMode.Quads);
                foreach (deathcave_logic.gameObjects.BaseGameObject bgo in gv.enemies)
                {

                    switch (bgo.ObjectType)
                    {
                        case GameObjectEnum.EnemyDropper:
                            GL.Color3(Color.Plum);
                            break;
                        case GameObjectEnum.EnemyShooter:
                            GL.Color3(Color.SeaShell);
                            break;
                        case GameObjectEnum.EnemySwooper:
                            GL.Color3(Color.BlanchedAlmond);
                            break;
                    }

                    DrawBGO(bgo);
                }
                GL.End();

                // draw the ship

                if (this.gv.safeTimer < 0.0f)
                    GL.Color3(Color.Blue);
                else
                    GL.Color3(Color.Yellow);

                GL.Begin(BeginMode.Quads);

                DrawBGO(gv.ship);

                GL.End();

            }

            SwapBuffers();
        }