GDI +游戏引擎(我可以做些啥来让我的引擎运行得更快?)[重复]

Posted

技术标签:

【中文标题】GDI +游戏引擎(我可以做些啥来让我的引擎运行得更快?)[重复]【英文标题】:GDI+ Game Engine (What can I do to make my engine run faster?) [duplicate]GDI +游戏引擎(我可以做些什么来让我的引擎运行得更快?)[重复] 【发布时间】:2017-05-20 22:51:00 【问题描述】:

我目前正在使用 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);
        
    

【问题讨论】:

我认为这更适合codereview.stackexchange.com,因为它专注于改进已经工作的代码。 【参考方案1】:

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

正如下面 cmets 所问的,在不同线程中分离 UI 和逻辑的事实可以帮助您在这两个任务中获得更好的流程。困难的部分是保持 UI 和逻辑同步,但您较少接触会降低 UI 速度的缓慢方法/功能。

【讨论】:

确实分离绘图和游戏逻辑是一个明智的做法,但它可能需要一些同步(更新过程中可能存在不一致的游戏状态)。如果你能详细说明你的答案,OP 可能会看到价值。 我知道这会有什么帮助,但是由于它本身的代码已经呈现缓慢,这意味着它会在不同的线程上呈现缓慢。 渲染和游戏逻辑是两个不同的东西。您是否在资产中混合了逻辑和绘图功能(在这种情况下,应用建议的改进会很痛苦)?

以上是关于GDI +游戏引擎(我可以做些啥来让我的引擎运行得更快?)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

查询很慢,我可以做些啥来改进?

我可以做些啥来加快这个 SQL 查询的速度?

我正在运行一个 REST API 服务器,但我不太确定基础架构。另外,我可以做些啥来基准测试和提高速度?

我可以做些啥来优化适用于 Postgres 和 MySQL 的 SQL 查询?

在尝试将我的 iOS 应用程序提交到 App Store 时,我可以做些啥来克服下面列出的多个错误?

可以做些啥来防止类似论坛的应用程序中的垃圾邮件?