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 +游戏引擎(我可以做些啥来让我的引擎运行得更快?)[重复]的主要内容,如果未能解决你的问题,请参考以下文章
我正在运行一个 REST API 服务器,但我不太确定基础架构。另外,我可以做些啥来基准测试和提高速度?
我可以做些啥来优化适用于 Postgres 和 MySQL 的 SQL 查询?