270. Структура данных фреймбуфера
Создать чистую структуру данных фреймбуфера для конвейера рендеринга.
Урок 270 из 356 · tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py
Файлы для создания
emulator/rendering/
emulator/rendering/framebuffer.pyЗачем нужен этот шаг
Фаза 7 начинается с определения структуры данных, которую ядро эмулятора будет выдавать для визуального вывода. Это должны быть чистые данные Python, а не данные, специфичные для pygame.
Что такое фреймбуфер? Фреймбуфер — это блок пиксельных данных, представляющий одно законченное изображение/кадр.
Минимальный пример
A 256x240 NES framebuffer contains:
256 * 240 = 61440 pixelsКаждый пиксель представлен кортежем RGB
(red, green, blue)Пример
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)Распространённое заблуждение
Фреймбуфер — это не окно pygame. Фреймбуфер — это данные ядра эмулятора. Pygame позже может его отображать, но pygame не должен требоваться для создания или тестирования фреймбуфера.
Пример предлагаемой реализации
from dataclasses import dataclass, field
RGBColor = tuple[int, int, int]
NES_SCREEN_WIDTH = 256
NES_SCREEN_HEIGHT = 240
BLACK: RGBColor = (0, 0, 0)
@dataclass
class Framebuffer:
width: int = NES_SCREEN_WIDTH
height: int = NES_SCREEN_HEIGHT
pixels: list[RGBColor] = field(default_factory=list)
def __post_init__(self) -> None:
if not self.pixels:
self.pixels = [BLACK] * (self.width * self.height)
if len(self.pixels) != self.width * self.height:
raise ValueError("Framebuffer pixel count must be equal width * height")Важный инвариант
После создания
len(framebuffer.pixels) == framebuffer.width * framebuffer.heightВыходит за рамки
- методы get_pixel/set_pixel, тестируемые на следующем шаге
- проверка координат
- проверка компонентов RGB
- преобразование индексов палитры NES в RGB
- рендеринг данных CHR/nametable
- отображение pygame/фронтенда
Запустить этот урок
uv run pytest tests/chapter_05_rendering_pipeline/test_270_framebuffer_data_shape.py -v