2016-11-25 5 views
1

Мне просто интересно, может ли кто-нибудь пролить свет на это для меня. Я кодировал C# в течение многих лет, но даже не затрагивал ничего в пространстве имен System.Drawing, кроме класса bitmap, и я следил за некоторыми учебниками и придумывал какой-то код, который работает. Я разрабатываю 2D Game Engine, а приведенный ниже код предназначен для графического движка, который использует GDI. Однако я просто не понимаю, как работает этот код. Вот он:Как работает этот код? (GDI, C#)

private Graphics frontBuffer; 
    private Graphics backBuffer; 
    private Bitmap backBufferBitmap; 

    public void Initialize() 
    { 
     backBufferBitmap = new Bitmap(game.Form.Width, game.Form.Height); 
     frontBuffer = game.Form.CreateGraphics(); 
     backBuffer = Graphics.FromImage(backBufferBitmap);   
    } 

    public void Update() 
    { 
     try 
     { 
     frontBuffer.DrawImageUnscaled(backBufferBitmap,0,0); 
     backBuffer.Clear(Color.Black); 
     } 
     catch(Exception e) 
     { 
     throw e; 
     } 
    } 

Итак, основная часть меня сбивает с толку;

Как обновляется растровое изображение заднего буфера? и почему буфер обратно очищается, а не передний буфер?

Кроме того, метод initialize вызывается один раз, и метод обновления вызывается один раз для каждого кадра в цикле while.

+1

Только для записи. У меня есть некоторые сомнения относительно кода, который вы нашли или написал как 'game.Form.CreateGraphics();' обычно это плохая идея, как и буферизация объекта Graphics. – TaW

+0

Но почему? Все, что я делаю, действительно ссылается на объект графических форм? –

+0

Нет такой вещи. Вы (sic!) Создаете один. Но вы не должны. Это событие «Paint» для этого! (Если вам не нужен один в другом месте, потому что вы хотите измерить вещи или хотите нарисовать графику __non-persistent__ как линию резиновых полос ..) - Также: Frontbuffer очищается неявно, поскольку он ничего не содержит при создании его растрового изображения. – TaW

ответ

1

После инициализации графических объектов backBuffer из растрового изображения каждый раз, когда вы говорите, например, backBuffer.DrawLine(...) GDI + будет выполнять манипуляции с пикселями непосредственно на этом растровом изображении. Они связаны определенным образом. Подумайте об backBufferBitmap как о холсте, а о backBuffer как о кисти.

frontBuffer Инициализирован вместо формы. Таким образом, форма - это холст, и все, что вы делаете с frontBuffer, обращается к форме - в этом случае здесь она рисует backBufferBitmap.

Это в основном схема с двойной буферизацией, которая имеет множество преимуществ перед прямым рисованием линий и кругов в форме, например. меньше мерцания. Всякий раз, когда вы рисуете что-то в форме, помните, что она удаляется очень часто (например, когда вы перемещаете форму за пределы области экрана). Вам нужно будет обновить его, используя событие формы Paint.

После Update() называется, вам нужно будет перерисовывать сцену, чтобы backBuffer, прежде чем вызывать Update снова, потому что битовая затемнены вашей Clear() после того, как он обращается к экрану.

+0

Большое спасибо! Это было очень информативно. Я понял, что основной причиной, по которой я был смущен, является то, что я не знал, что после того, как я инициализировал буфера, я не знал, что он будет рисовать именно в растровое изображение. Спасибо, что прояснили это. У меня было такое чувство, что это продолжалось, но я не был уверен. Просто, чтобы вы знали, я не использую событие paint, и вместо этого я использую свои собственные методы, вызывая Application.DoEvents для каждого кадра. Большое спасибо! –

+0

Кажется, вы довольны этим ответом @ MathewO'Dwyer? Если это так, отметьте его как принятое, чтобы другие могли найти правильный ответ быстро, если они ищут помощь в той же области, а также отдать должное Йенсу. – MrApnea

+0

@FSDaniel Хорошо, первый раз это жаль :). –

0

frontBuffer становится обновляется, потому что каждый раз, когда вы звоните в frontBuffer.DrawImageUnscaled(backBufferBitmap,0,0);update()

backBuffer является gettting очищается, потому что вы звоните backBuffer.Clear(Color.Black);

Кроме того, initialize() должен вызываться только один раз. Во время создания объекта. И я считаю, что это часть более крупной программы, где родитель звонит update() ребенка.

+0

вы уверены, что были ваши сомнения? – Prajwal

+0

эй, спасибо за ваш ответ. Однако инициализация и обновление - это мои собственные методы, которые я создал. Я не понимаю, как обновляется растровое изображение? –

+0

Также я имел в виду, почему я вызываю backBuffer.clear, а не frontBuffer.clear? Почему я должен это делать? –