GDI +游戏引擎(我可以做些什么来让我的引擎运行得更快?)

时间:2017-01-06 07:47:06

标签: c# bitmap gdi+ gdi

我目前正在使用GDI +开发2D游戏引擎。一切都运行得非常顺利,但我知道我必须做更多的事情才能让我的引擎更快地渲染图形。

目前,如果我将一个800x600像素的空位图渲染到屏幕上,我的速度大约为130fps。但是一旦我在位图上绘制了800x600像素的图像,我就会得到大约70fps。这根本不是问题,我实际上对结果感到自豪,我只知道它可能会更好。

我只是想知道是否有人对于什么可能使引擎运行得更快有任何建议?

这是我的窗口类的代码:

    using System;
using System.Windows.Forms;
using GameEngine.Graphics;
using System.Threading;
using System.Drawing;

namespace GameEngine.Core
{
    public class Game : Form
    {
        // Just a class that checks the fps and such
        private GameTime gameTime;
        private GraphicsEngine graphicsEngine;

        private bool isLoaded = false;
        private bool isRunning = false;

        public Game(int width, int height, string title)
        {
            this.Width = width;
            this.Height = height;
            this.Text = title;

            this.MaximizeBox = false;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

            this.Paint += Game_Paint;
            this.FormClosing += Game_FormClosing;

            gameTime = new GameTime();
            graphicsEngine = new GraphicsEngine(this);

            Show();
        }

        public void Run()
        {
            Initialize();
            Load();

            isRunning = true;

            while (isRunning && isLoaded)
            {
                // Yes I know, this is frowned upon
                Application.DoEvents();

                gameTime.Update();

                // Only update if the form is focused and if the GameTime class says we're allowed
                if (this.Focused && gameTime.Cycled)
                {
                    BeginUpdate();
                    UpdateGame();
                    LateUpdate();
                    Render();
                }
                else
                {
                    Thread.Sleep(1);
                }
            }

            Exit();
        }

        public void Exit()
        {
            Unload();
            this.Close();

            // Using console application, so lets exit the console
            Environment.Exit(0);
        }

        private void Initialize()
        {
            gameTime.Initialize();
        }

        private new void Load()
        {
            isLoaded = true;
        }

        private void Unload()
        {

        }

        private void BeginUpdate()
        {

        }

        private void UpdateGame()
        {
            this.Title = "FPS: " + gameTime.FPS;
        }

        private void LateUpdate()
        {

        }

        Bitmap bmp = new Bitmap("Test.jpg");

        private void Render()
        {
            // Draw the nice tree to the window
            graphicsEngine.DrawBitmap(bmp, 0, 0);

            // Cause the window to redraw it's self
            this.Invalidate();
        }

        private void Game_Paint(object sender, PaintEventArgs e)
        {
            // Lets just make sure once again that we're allowed to draw
            if (gameTime.Cycled)
            {
                // Render the graphics to the screen
                graphicsEngine.Render(e.Graphics);
            }
        }

        private void Game_FormClosing(object sender, FormClosingEventArgs e)
        {
            isLoaded = false;
        }

        public string Title
        {
            get { return Text; }
            set { Text = value; }
        }
    }
}

这里是图形引擎类:

    using System.Drawing;
using GameEngine.Core;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

namespace GameEngine.Graphics
{
    public class GraphicsEngine
    {
        private Game game;

        private System.Drawing.Graphics backBuffer;
        private System.Drawing.Bitmap backBufferBitmap;

        public GraphicsEngine(Game game)
        {
            this.game = game;

            backBufferBitmap = new Bitmap(800, 600);
            backBuffer = System.Drawing.Graphics.FromImage(backBufferBitmap);

            backBuffer.CompositingMode = CompositingMode.SourceOver;
            backBuffer.CompositingQuality = CompositingQuality.HighSpeed;
            backBuffer.SmoothingMode = SmoothingMode.None;
            backBuffer.InterpolationMode = InterpolationMode.Low;
            backBuffer.TextRenderingHint = TextRenderingHint.SystemDefault;
            backBuffer.PixelOffsetMode = PixelOffsetMode.Half;
        }

        public void Render(System.Drawing.Graphics g)
        {
            g.CompositingMode = CompositingMode.SourceCopy;
            g.CompositingQuality = CompositingQuality.AssumeLinear;
            g.SmoothingMode = SmoothingMode.None;
            g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.TextRenderingHint = TextRenderingHint.SystemDefault;
            g.PixelOffsetMode = PixelOffsetMode.HighSpeed;

            g.DrawImage(backBufferBitmap, new Rectangle(0, 0, game.Width, game.Height), new Rectangle(0, 0, game.Width, game.Height), GraphicsUnit.Pixel);

            backBuffer.Clear(Color.Black);
        }

        public void DrawString(string text, int x, int y)
        {
            backBuffer.DrawString(text, SystemFonts.DefaultFont, Brushes.White, x, y);
        }

        public void DrawBitmap(Bitmap bitmap, int x, int y)
        {
            backBuffer.DrawImage(bitmap, x, y);
        }

        public void DrawBitmap(Bitmap bitmap, int x, int y, int width, int height)
        {
            backBuffer.DrawImageUnscaled(bitmap, x, y, width, height);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你应该尝试操作一种与绘图线程分开的逻辑线程。也许用(tick management)替换逻辑中的线程。

正如下面的评论中所述,分离UI&不同线程中的逻辑可以帮助您在两个任务中获得更好的流程。困难的部分是保持UI和逻辑同步,但是你很少接触到会减慢UI的慢速方法/功能。

相关问题