В сентябре сходил на собеседование в некую компанию и получил тестовое задание сроком на семь дней. При этом работу предлагали в офисе. Но есть нюансы!
Во-первых, за время работы в «Газпром-Медиа» я отвык работать в офисе. Во-вторых, я уверен, что выполнение тестового задания должно быть оплачено, тем более это целый проект. В-третьих, что-то мне подсказывало, что тестовое задание не примут в любом случае, потому что я не сказал способ нахождения пересечения луча со сферой, да и манера общения в целом мне не понравилась. Тем не менее, с целью узнать что-то новое и в качестве разминки для мозгов, тестовое задание таки взялся выполнять. Ниже расскажу, как это было.
Суббота (утро, за шесть дней до дедлайна)
- В основном составлял план решения задачи.
- Загуглил, как работать с OpenGL на Desktop: с помощью GLUT (который устарел и вместо него берут FreeGLUT) и GLEW. Всегда использовал только мобильную embedded версию OpenGL на мобильных девайсах или WebGL. Для загрузки картинок выбрал библиотеку stb, потому что ранее с ней работал и в ней всего один хедер-файл.
- Создал проект с помощью CMake и скомпилировал его в QtCreator, потому что в компании использовали в основном его.
- Сделал пустое окошко и загрузку пиксельных данных из любого файла с изображением с помощью stb.
- В десктопном OpenGL в отличие от ES версии по ходу дела можно использовать как современные шейдеры, так и устаревшие
glBegin/glEndодновременно. На мобильных устройствах OpenGL ES такого делать не позволяет.
Понедельник (вечер, за четыре дня до дедлайна)
- Понял, что QtCreator использует какие-то свои библиотеки плюс какие-то из msys2, а я больше привык к Visual Studio. Скачал FreeGLUT и прописал его в CMakeLists.txt.
- Сделал проект для Visual Studio и заставил его работать. Это получилось только после того, как я переставил свой Visual Studio, потому что там не было основного сборщика и он подцеплял какие-то настройки из msys2. Удалось исправить только после обнуления переменной окружения Path и запуска генератора cmake из-под vcvarsall.bat.
Вторник (три дня до дедлайна)
- Разбил программу на компоненты:
Application,Sprite,Image,Texture,Mesh,Shaderи так далее. - Окошко всё ещё пустое, ничего не рисуется, долго думал, как «прикрутить» нестатический C++ метод
Application::renderкак Сишный callback в методеglutDisplayFunc(). Кстати, через пару месяцев нашёл метод — передать указатель на экземпляр своего класса черезglutSetWindowData()/glutGetWindowData(), чтобы не использовать синглтон.
Среда (с утра до обеда, два дня до дедлайна)
- Наконец-то нарисовал спрайт с текстурой по нужным мне пиксельным координатам. Решил на этом остановиться: закрашиваю фон красным, рисую один спрайт.
- Подключил библиотеку glm, чтобы не умножать матрицы с векторами руками.
- Создал класс
Camera. - Сначала хотел сделать стандартный макрос
CHECK_GL_CHECK(glFunction), но в итоге прикрутил вывод ошибок в консоль с помощьюglDebugMessageCallback(). - Вечером добавил вычисление и рисование FPS и frametime. Очень странная установка позиции для вывода текста с помощью
glutBitmapString(). С цветом текста разобраться не удалось. Было бы здорово делать через freetype, про которую у меня написано много статей, но время поджимает, да не очень-то и хочется.
Четверг (один день до дедлайна)
- накануне много думал про вращающееся колесо с картинками. Хотел сделать физическое колесо с массой и инерцией для запуска и остановки, но решил не заморачиваться и сделать горизонтальную модель ленты с индексами текущей ячейки от 0 до n, индекс типа float, целая часть которого — текущая ячейка, а дробная — её смещение от нуля до единицы. Отдельно идёт класс View, который по данным от модели рисует иконки. Для эффекта закруглённости решил сверху наложить маску с затенением сверху/снизу и бликом посередине. Вроде должно сработать.
- под вечер сделал подобие колеса из четырёх иконок и решил собрать программу из того, что было.
- для этого привлёк настоящего проектировщика зданий для рисования маски с отверстием посередине, включил поддержку RGBA и цвет для вершин, добавил надпись START со сменой цвета, про маску с тенью успешно забыл.
Пятница (дедлайн)
- С утра пораньше сделал вращение колеса с плавной остановкой. Накануне придумал способ — крутимся с постоянной скоростью, за секунду до финала начинаем замедление с помощью формулы равнозамедленного движения.
- Вынес создание спрайтов с кешированием текстур в отдельный класс.
- Добавил обработку клика на кнопку.
- В итоге поставил Ubuntu на Hyper V виртуальную машину, установил нужные библиотеки через apt, написал инструкцию в Readme, убедился, что всё работает, загрузил изменения с виртуальной машины через SFTP на винду и в GitHub.
- Под винду включил статическую линковку в MSVC, чтобы не было нужды в .dll-файлах.
- Собрал исходники, собрал бинарники, отдал на проверку, гештальт закрыт!
Вторник (отклик от компании)
- Используются шейдеры, но при этом нет эффектов.
- Сторонние библиотеки STB и GLM, при этом GLM используется только для одной функции,
а STB для другой.
Оставлю эти замечания без комментариев, менять ничего не буду.
Для представления о том, что получилось, приведу скриншот (работает под любыми современными ОС):

Теперь это ещё один мёртвый проект на GitHub, по которому будут учиться AI, хе-хе-хе. Вы тоже можете составить своё мнение по этому «проекту» здесь в комментариях или в виде Merge Request к проекту. Для желающих увидеть ту самую версию, полученную «заказчиком», я поставил тег first_release в репозитории.