Home News

Development Archives

01.09.2018

видео Development Archives

WATCH THIS EVERY DAY - Motivational Speech By Navy Seal Admiral William H. McRaven

Благодаря LORу узнал о менеджере пакетов Conan C/C++ package manager . Это консольныя, децентрализованаая и кроссплатформенная (заявлена поддержка Windows, Linux, OSX, FreeBSD, и SunOS) утилита предназначенная для упрощения жизни разработчика.



Поддеживаются различные билд-системы – Visual Studio MSBuild, CMake, Makefiles, SCons, и многие другие. Как сказано в документации, Conan’у вообще монопенисуально, какую били-систему вы используете.

И все это под лицензией MIT. То, чего так давно ждут разрабочики от “нового” стандарта C++.

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


Moving Past Failure in Game Development

По-умолчанию этот параметр установлен в TRUE. И сегодня я получил слайд-шоу, установив его в значение по-умолчанию.

EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); attr.alpha = EM_FALSE; attr.depth = EM_FALSE; attr.stencil = EM_FALSE; attr.antialias = EM_FALSE; // <-- this should be set to FALSE! attr.preserveDrawingBuffer = EM_FALSE; attr.preferLowPowerToHighPerformance = EM_FALSE; attr.failIfMajorPerformanceCaveat = EM_FALSE; attr.enableExtensionsByDefault = EM_TRUE; attr.premultipliedAlpha = EM_TRUE; attr.majorVersion = 1; attr.minorVersion = 0; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(nullptr, &attr); emscripten_webgl_make_context_current(ctx);

На HiDPI мониторах downscaled текстуры выглядят мягко говоря не очень красиво. Искал способ решить эту проблему. В итоге мои исследования привели к такому не самому легковесному решению.


AT&T Archives: Submarine Cable Systems Development

Получить device pixel ratio для настройки размров canvas. Получить размер canvas и разрешение css. На их основе вычислить отношение. Использовать это отношение для расчета координат мыши и тача.

После этого все будет выглядеть красиво на HiDPI мониторах. Но есть одна “особенность” – увеличенный (в зависимости от отношения размеров css и canvas) в несколько раз фреймбуфер. При отношении равном 2, получаем размер фреймбуфера в четыре раза больший, со всеми вытекающими.

Немного кода

CSS

canvas { width: 100vw; height: 100vh; display: block; }

JavaScript

window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { var realToCSSPixels = window.devicePixelRatio; var displayWidth = Math.floor(canvas.clientWidth * realToCSSPixels); var displayHeight = Math.floor(canvas.clientHeight * realToCSSPixels); if (canvas.width !== displayWidth || canvas.height !== displayHeight) { canvas.width = displayWidth; canvas.height = displayHeight; } } resizeCanvas();

C++

int width, height; emscripten_get_canvas_element_size(nullptr, &width, &height); double cssWidth, cssHeight; emscripten_get_element_css_size(nullptr, &cssWidth, &cssHeight); const auto ratiox = (float)(width / cssWidth); const auto ration = (float)(height / cssHeight);

Можно сделать настройку, доступную пользователю – пусть он сам решает, что ему лучше – производительность или качество рендеринга.

Некоторые пользователи моего вьювера жаловались на медленное проигрывание GIF -анимации во вьювере. И чем больше по размеру GIF -файл, тем медленнее происходит загрузка следующего фрейма. И проблема была явно не в медленном декодировании фрейма и его загрузке в GL -текстуру. Все оказалось проще. Каждый раз, когда вьювер запрашивал следующий фрейм, он заново инициализировал giflib , скармливал ему заново путь к файлу, выбирал нужный фрейм и только потом загружал его GL -текстуру.

Фикс получился прост как валенок. Хотя нет, из шерсти делать войлок я не умею, а вот исправить способ работы с GIF -анимацией удалось за пару минут. Теперь и большие анимации проигрываются без тормозов.

А еще я добавил экспериментальную поддержку JPEG 2000 , основанную на библиотеке OpenJPEG . А так же написал загрузчик Apple Icon Image . Заодно сделал небольшой рефакторинг PNG , дабы унифицировать код загрузки, т.к. он используется и для загрузки PNG , и для ICO , а теперь и для ICNS .

Подробнее о Simpel Viewer GL .

Довольно много времени потратил на поиск “плавающего” бага. За это время успел отрефакторить кучу кода, до которого руки не доходили ранее. Но баг не ловился. И в его поимке не смогли помочь ни Xcode Instruments, ни Xcode Analyzer (фронтэнд к статическому анализатору llvm).

Баг проявлялся редко и далеко не на всех девайсах. Я никак не мог понять условия его проявления. Пробовал записывать направление и температуру ветра, положение звезд на небе и длительность соседского ора. Но это никак не помогало в поиске проблемы.

Падения игры под отладчиком и backtrace давали BAD EXC, что как бы намекало на испорченную где-то ранее память. Но где именно? Статический анализатор, по идее, должен на раз находить access out of bounds. Но анализатор молчал, типа вообще все пучком.

От безысходности и обиды на самого себя, решил синхронизировать линуксовую версию с main branch, т.к. в процессе поиска бага был сделан серьезный рефакторинг кода. Ну и очевидно, что погонять движок под valgrind никогда лишним не будет.

И valgrind сразу же нашел memory corruption (тот самый “плавающий” баг, на поиски которого я убил много времени. И мелкий ничего не значащий memory leak.

Linux и valgrind рулят!

Столкнулся с проблемой на itch.io , когда приложение запущенной внутри iframe не получает события клавиатуры. Придумал вот такой workaround:

postRun: (function() { window.addEventListener('mousedown', function(evt) { window.focus(); evt.preventDefault(); evt.stopPropagation(); evt.target.style.cursor = 'default'; }, false); })(),

К событию postRun добавляем установку листенера на событие mousedown. Теперь при клике мышью на канавасе с игрой события от клавиатуры будут передаваться в наше приложение.

Давно использую декодер, состоящий из кучи бранчей и логических операций. Вот вариант без бренча (тернарный оператор в данном случае брачнем не является), двух логических операций и таблицы – Flexible and Economical UTF-8 Decode

Texture Packer для Linux и macOS – утилита, которая упаковывает набор входных изображений в один большой атлас. Утилита консольная, что удобно для автоматизации.

Из возможностей:

Достаточно шустрая. Сравнивал с “обычным платным” (с) пакером. Умеет создавать Power of Two атлас. Можно ограничить максимальный размер атласа. Умеет отрезать “лишние” пиксели (trim) у входных изображений. Может добавить бордюр нужного размера вокруг изображений при размещении в атласе.

Утилита делалась для себя, а теперь доступна на Bitbucket – Texture Packer .

Наверняка многие используют макрос, подобный нижеприведенному:

#define countof(array) (sizeof(array)/sizeof(array[0]))

Он хорош до тех пор, пока в качестве array в него не будет передан указатель на array. Компилятор проглотит и ничего не скажет, а результат будет совсем не тот, которого ожидает разработчик.

Благодаря constexpr появившемуся в C++11 есть возможность сделать безопасный countof.

template <class T, size_t N> constexpr size_t countof(const T (&)[N]) noexcept { return N; }

Теперь на этапе компиляции произойдет ошибка:

const int values[] = { 42, 76, 16, 11, 31 }; void foo(const int v[]) { for (size_t i = 0; i < countof(v); ++i) // <-- compilation error! { bar(v[i]); } }

Версия для C++98 может быть такой:

template <typename T, size_t N> char (&CountOfHelper(T(&)[N]))[N]; #define countof(x) sizeof(CountOfHelper(x))

Emscripten is an LLVM-based project that compiles C and C++ into highly-optimizable JavaScript in asm.js format. This lets you run C and C++ on the web at near-native speed, without plugins.

Решил еще раз установить Emscripten с помощью brew, на сей раз все оказалось гораздо проще. Возможно это работало и раньше, но я только сегодня обратил на это внимание.

Правильный способ установки Emscripten с помощью brew:

# устанавливаем emscripten как обычно: $ brew install emscripten # запускаем emcc, что бы он создал файл ~/.emscripten $ emcc # исправляем LLVM_ROOT: $ vim ~/.emscripten

Должно получиться как-то так:

LLVM_ROOT = '/usr/local/opt/emscripten/libexec/llvm/bin'

К сожалению с помощью brew правильно установить emscripten под OS X El Capitan мне не удалось.

Я не смог найти какую-либо информацию по правильной установке emscripten с помощью brew, поэтому получилась вот такая магическая инструкция.

Список шагов для установки emscripten из-под OS X :

С официального сайта качаем портабельную версию emscripten – http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html#sdk-download-and-install Распаковываем и запускаем ./emsdk update . С помощью команды ./emsdk list можно посмотреть список доступных пакетов, утилит и sdk. С помощью комады ./emsdk install latest устанавливаем самые последние версии. Командой ./emsdk activate активируем переменные окружения emscripten. Теперь при необходимости сборки проекта инициализируем переменные окружения с помощью команды source ./emsdk_env.sh . По желанию можно прописать путь к директории с emsdk.
rss