Движок с нуля
Как пользоваться · глава 0.1

О курсе и как его читать

Откуда взялся этот курс, кто пишет курс, как устроены страницы и что можно делать с кодом движка.

Откуда взялся этот курс

Меня зовут Дима Иванов, и этот курс начался с идеи сайта. Я давно хотел сделать интерактивный конспект, в котором можно быстро вспомнить, как работает конкретная функция, понятие или кусок кода. Однажды ты разобрался в теме, со временем забыл подробности, открываешь страницу и за несколько минут вспоминаешь всё, что понимал раньше.

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

Первой темой сайта должна была стать Shadow Map. Я как раз добавлял Shadow Map в свой игровой движок и захотел показать на интерактивной странице, как работает этот приём. Когда я начал писать объяснение, оказалось, что объяснение ни на что не опирается: Shadow Map в движке построена на шейдерах, матрицах и буферах кадра, а на сайте ни шейдеров, ни матриц ещё не было. Тогда я решил пройти с читателем весь путь, которым сам дошёл до Shadow Map.

Этот путь и стал курсом. Здесь я заново, с пустого проекта, пишу движок и простыми словами показываю каждый шаг, а ты пишешь свой движок вместе со мной.

Для кого этот курс

Курс для тех, кто уже писал небольшие программы на C++ и запускал программы в Visual Studio, но свой движок ещё не делал. Основам C++ курс не учит: переменные, функции и циклы здесь считаются знакомыми. Шаг за шагом мы напишем 3D-движок на C++ и OpenGL, начиная с пустого окна. Новые главы курса появляются постепенно: в оглавлении курса стоят только главы, которые я уже проверил и считаю готовыми.

Кто делает курс

Курс делаю я, но не в одиночку, и лучше сказать об этом прямо. Код движка я пишу сам, а ошибки, которые встретил при написании кода, разбираю в тех главах, где эти ошибки возникли. Тексты и интерактивные схемы сайта я делаю вместе с AI: сначала работал с Codex, теперь работаю с Claude. Я говорю, что хочу объяснить и увидеть на странице, AI пишет страницу, а я читаю каждую главу и правлю текст.

Если нашёл ошибку в главе или остался вопрос, напиши мне в Telegram: @chiter28. Мои проекты лежат на GitHub.

Понятия раскрываются на месте

На многие слова на страницах курса можно навести мышь или нажать. Начнём с понятий. Оранжевое полужирное слово со знаком ? в кружке — это понятие. Наведи мышь, чтобы прочитать коротко, или нажми, чтобы открыть статью справочника сбоку. Полужирное слово цвета индиго со знаком i в кружке — пояснение к месту: наведи мышь, и рядом появится короткая карточка. Например: всё, что делает OpenGL, происходит внутри контекста, а рисует OpenGL в буфер кадра.

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

Связанные обозначения подсвечиваются

Наведи на swap или на очистку — подсветится то же самое в сцене, в коде и в тексте. Цветные обозначения работают так же: вектор v всегда оранжевый, ось x — жёлтая.

Сцены идут по шагам

Сцена — это короткое «видео» из реплик. Следующая реплика открывается кнопкой «Дальше». Нажми на прошлую реплику — сцена вернётся к её моменту.

Как движок рисует кадр: главный цикл и два буфера

Каждый кадр движок проходит один и тот же цикл из четырёх шагов. Справа — два буфера кадра: передний сейчас показан на мониторе, а задний спрятан от зрителя.
Сначала движок забирает у Windows события, которые накопились с прошлого кадра: нажатые клавиши, движение мыши, изменение размера окна.
Затем задний буфер очищается: после прошлой смены буферов в заднем буфере остался кадр, который показывали до этого, то есть позапрошлый.
Теперь в задний буфер рисуется сцена. Монитор этого не видит: на мониторе по-прежнему старый кадр из переднего буфера.
Кадр готов — буферы меняются местами. Новый кадр появляется на экране сразу целиком.
И так каждые ~16 мс, 60 раз в секунду. Такой приём — рисовать в спрятанный буфер и показывать готовый кадр сменой буферов — называется двойная буферизация.

Если режим вверху переключить на «справочник», все реплики видны сразу — удобно, когда возвращаешься к главе повторно.

Код — настоящий, из движка

Фрагменты кода берутся прямо из репозитория движка. Вот главный цикл — тот самый, что в сцене выше. Наведи на вызовы PollEvents, glClear, OnRender и SwapBuffers:

engine/Core/Application.cppстроки 54–84коммит 5167f24
	while (m_Running && !m_Window->ShouldClose())	{		// deltaTime		const std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();		const float deltaTime = std::chrono::duration<float>(currentTime - previousTime).count();		previousTime = currentTime;		m_Window->PollEvents();		m_EventQueue.Flush(			[this](Event& event) {				App::OnEvent(event);				m_Camera->OnEvent(event);				m_CurrentDemo->OnEvent(event);			}		);		if (!m_Minimized)		{			m_Camera->OnUpdate();			m_CurrentDemo->OnUpdate(deltaTime);						glClearColor(0.01f, 0.02f, 0.03f, 1.0f);			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);						m_CurrentDemo->OnRender(*m_Camera);			m_Window->SwapBuffers();		}

Формулы тоже связаны

Время одного кадра при частоте f=60\hl{x}{f} = 60 кадров в секунду:

t=1f=160≈16,7 мс\hl{y}{t} = \frac{1}{\hl{x}{f}} = \frac{1}{60} \approx 16{,}7 \text{ мс}

Наведи на f или t в тексте — подсветятся буквы в формуле.

Почему 60, а не 100?

Это частота обновления большинства мониторов. Рисовать чаще бессмысленно: монитор всё равно покажет только 60 кадров в секунду. Игровые мониторы бывают на 144 и 240 Гц — тогда и кадр короче.

Задания

После каждого небольшого блока — задание, которое ты делаешь сам в своём движке или прямо на странице.

Лицензия

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

Код движка можно брать свободно. Речь о коде в двух репозиториях: game-engine-for-site, это движок, который мы пишем в курсе, и OpenGL, это мой готовый движок, из которого взяты примеры. Этот код и фрагменты этого кода на страницах курса доступны по лицензии MIT. Код можно переписывать в свой движок и использовать в своих программах, в том числе платных. Условие одно: если ты передаёшь другим людям программу или исходный код, где есть значительная часть этого кода, приложи текст файла LICENSE.md из репозитория.

Всё остальное принадлежит автору курса. Тексты, интерактивные схемы (сцены), рисунки и код самого сайта: © 2026 Дима Иванов, все права защищены. Небольшие отрывки можно цитировать со ссылкой на страницу курса. Выкладывать главы, сцены или весь курс на других сайтах и в других курсах нельзя.

Лицензия MIT действует только на код, который написал автор курса. У шрифтов сайта и у библиотек движка, например у GLFW, свои лицензии: условия этих лицензий задают авторы шрифтов и библиотек.

Какие данные хранит сайт

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

Страницы курса отправляет читателям сервис Cloudflare. Для этого Cloudflare видит твой IP-адрес, то есть адрес компьютера в интернете, браузер и открытую страницу. Что Cloudflare делает с этими данными, написано в политике конфиденциальности Cloudflare.