Эффективный способ (не) рисовать пиксели под другими пикселями?

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

Это неэффективно, поскольку нет смысла устанавливать пиксель, если другой пиксель из другого спрайта просто рисует поверх этого. Когда больше спрайтов и больше спрайтов, проблема неэффективности только усугубляется.

Я могу думать только о двух традиционных способах сделать это:

1) Просто нарисуйте все снизу вверх и проигнорируйте проблему (не эффективно)

2) Проверьте, не был ли нарисован пиксель более высокого уровня, и затем нарисуйте. (также неэффективно, потому что вы должны проверять за каждый пиксель в каждом слое)

Есть мысли или комментарии?

PS: Этот вопрос касается рисования пикселей в целом.

0

Решение

Два «традиционных» способа сделать это довольно эффективно:

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

В любом случае: чтобы быть эффективным, если вы хотите избежать перерисовки, вы обычно рисуете свои слои / спрайты спереди назад и используете второй буфер в сочетании с некоторыми умными логическими операторами, чтобы выяснить, какой цвет рисовать.

например:

// This buffer contains a byte for each pixel. Either the byte is 0x00 for a free pixel
// or 0xFF for a colored pixel.
byte* overDrawBuffer;
// The colorbuffer is our rendertarget
byte* colorBuffer;
// The spritesource is where the pixeldata of our sprite resides
byte* spriteSource

for (int i = 0; i < numPixels; i++)
{
// will choose either the existing color or the new color depending on
// the value of the overDrawBuffer.
byte theColor = (*colorBuffer & *overDrawBuffer) | (*spriteSource & !*overDrawBuffer);
*colorBuffer = theColor;
// Mark the pixel
*overDrawBuffer = 0xFF;

//Move to the next pixel
*overdrawBuffer++;
*colorBuffer++;
*spriteSource++;
}

Примечание: этот код определенно не будет работать должным образом — он просто является иллюстрацией идеи. Код, подобный этому, без веток и очень небольшого числа операций должен производить очень быстрый машинный код.

1

Другие решения

Учитывая координаты и расположение потенциально перекрывающихся спрайтов, вы должны рассчитать, какие части каждого из них будут видны. И это те, которые вы должны нарисовать.

Если ваши спрайты не прямоугольные или прозрачные, это добавляет сложности, но идея остается прежней.

Вам может понадобиться:

  • перейти на уровень линии развертки (горизонтальные участки толщиной в 1 пиксель, составляющие весь спрайт) вместо уровня прямоугольника

  • использовать маски, указывающие, какие пиксели спрайтов прозрачны, а какие нет

  • использование quadtrees более эффективно обнаруживать перекрывающиеся спрайты

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector