Изучение OpenGL во время практики TDD (модульное тестирование) - PullRequest
19 голосов
/ 11 июля 2010

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

Однако я думаю, что мое отсутствие знаний может сбить меня с толку, и я продолжаю врезаться в стену, пытаясь написать свои модульные тесты для «рендеринга» частей кодовой базы. Я надеюсь, что кто-то может дать мне некоторое представление о том, как продолжить.

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

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

Где середина? Как научиться использовать OpenGL, в то же время заранее проводя правильное модульное тестирование?

Ответы [ 6 ]

9 голосов
/ 11 июля 2010

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

Вот отличная статья о TDD, играх и OpenGL.

3 голосов
/ 12 июля 2010

Относитесь к OpenGL так же, как к базе данных.Я бы изначально начал с одного интерфейса.Со временем, когда вы добавляете больше методов, вы можете начать разбивать один интерфейс на несколько интерфейсов.

Как уже упоминалось, вы не можете использовать стандартную библиотеку TDD для проверки рендеринга.Но это возможно.Думайте об этом как о тестировании рендеринга HTML в веб-клиенте.При написании своего HTML я не использую TDD Firefox или Internet Explorer.

3 голосов
/ 11 июля 2010

Вы не можете автоматически проверить деталь рендеринга.Для этого вам понадобится разумное существо, способное видеть и распознавать изображения.Компьютер не подходит.

Вы можете автоматически тестировать на успешное создание ресурса - VBO, текстуры, шейдеры, списки отображения - вы можете тестировать шейдеры на наличие ошибок компиляции, тестировать математическую библиотеку, вы можете обнаружить ошибки OpenGL,но вы не можете проверить часть рендеринга.Лучшее, что вы можете сделать, - это создать какую-нибудь процедуру тестирования, которая будет отображать изображение (возможно, анимированное и интерактивное) и спрашивать, выглядит ли оно правильно.Тест не будет на 100% надежным - может работать на одном оборудовании, а не на другом, человек может пропустить ошибку и т. Д.

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

Нет, оно того не стоит.

или сгруппировать их в функции более высокого уровня в зависимости от выполняемых задач?

Это делаетесть смысл написать несколько вызовов / классов для создания «текстуры», «сетки», «шейдерной программы», создать какой-то автоматический способ получения унифицированного местоположения (если вы используете шейдеры), возможно, несколько классов для автоматического выпуска OpenGLресурсы (то есть те, что с glDelete *** или с такими функциями, как glIsTexture), но это все.Как правило, вы не должны вводить дополнительные абстракции / классы, если в них нет необходимости - потому что это будет дополнительная работа без выгоды.

2 голосов
/ 24 ноября 2013

Многие люди думают, что графика невосприимчива к традиционным тестам TDD / unittesting.Это не так.

Проблемы, связанные с TDD, заключаются в том, что изображения не всегда будут точно одинаковыми.Такие вещи, как настройки сглаживания (которые могут быть переопределены настройками драйвера).Различия между тем, как разные графические процессоры отображают одно и то же изображение (порядок раскрутки полигонов и т. Д.).Кроме того, по мере того, как ваша игра проходит через разработку, такие вещи, как сетки и текстуры, могут быть изменены или изменены.

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

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

Что я бы порекомендовал сделать, так это отделить результаты рендеринга от вашей оконной системы.Под этим я подразумеваю 'Render to Texture' или использование объектов FrameBuffer.Это также помогает делать такие вещи, как видовые окна и оверлеи UI / HUD.

Создание объекта 'Window'.Что-то, что открывает настоящее окно рабочего стола с использованием Qt, SDL, SFML, GLUT или чего-либо еще.И передать ему какой-нибудь рендерер.Вы можете сделать такие вещи, как разрешить несколько рендеров и указать координаты прямоугольника (вы можете визуализировать другой вид в углу экрана).Или, может быть, сделать один мастер рендеринга, но унаследовать версию, которая позволяет ему иметь subrenderers.Объект Window также может обрабатывать ввод, это обеспечивает хороший способ ввести ложный / фиктивный объект ввода, вы можете проверить, движется ли игрок вперед, как ожидалось.

Этот модульный подход - это то, что падаетвне TDD он также может позволить вашему рендереру иметь свои собственные рендереры (возможно, вы хотите сделать скайбокс отдельно или изображение на мониторе безопасности в игре, отражения, карты теней и т. д.).Вы также можете легко выполнить рендеринг с другим разрешением для собственного рабочего стола (что полезно для установки фиксированного разрешения в TDD и может быть чем-то вроде 32x32 для простых операций, но также полезно для устройств, таких как Android, где фиксированные разрешения иГрафические процессоры имеют различные возможности. Nexus 10 недостаточно мощен, чтобы визуализировать вашу игру с ее XDPI? Уменьшите ее. Также помогает с Linux / Xorg, который не всегда позволяет вам устанавливать все разрешения, которые делает GPU, хотя сейчас это не проблема).

Как только у вас будет FBO, сделайте несколько функций для запроса цвета пикселей.Затем вы можете запросить все ваши основные операции.Правильно ли отображаются ваши сетки?Попробуй это.Создайте сетку с одним белым треугольником и спросите, какие позиции вы ожидаете увидеть белым, а какие должны оставаться черными при рисовании этого треугольника.Треугольник 1x1 в окне 1x1 должен охватывать% 50 по диагонали, поэтому тестируйте пиксели около края и обеих сторон середины, границ окна и заостренных битов.Далее объединяем два треугольника в прямоугольник и он должен заполнить экран, теперь все пиксели должны быть белыми.Теперь попробуйте отодвинуть его от камеры и проверить, что границы черные, но центр белый, с прямоугольником 1,0x1,0 в окне 1,0x1,0 на расстоянии 1,0, вы можете применить простую геометрию, чтобы увидеть приблизительно, где границыдолжен закончиться. Тест с другим цветом .Сделайте более сложную сетку с разноцветным кубом и проверьте вращение.Сделайте тестовую карту нормалей.

Возможно, вы сможете проверить источники света, отрисовав сферу и проверив, что с левой стороны она ярче правой, и если вы добавите другой источник света с другой стороны, они будут примерно одинаковыми (просто добавьте все пиксели слева и все пиксели справа и сравнить с допустимой погрешностью). Увеличьте яркость света и посмотрите, увеличивается ли сумма пикселей. Вы можете проверить алгоритмы освещения, разработав ожидаемый цвет в определенной точке на плоской плоскости. Вы могли видеть, что спектральная подсветка является самой яркой в ​​ожидаемой области. Для нормального / рельефного отображения сделайте тестовую текстуру .

Просто избегайте чего-то особенного, например, не тестируйте точно на грани. Они могут быть сглажены или просто немного отключены. Если вы делаете что-то вроде тестирования яркости влево / вправо для освещения, не ожидайте, что количество пикселей будет одинаковым в разных системах или даже в обеих сторонах (в симметричной сцене), используйте погрешность. Не используйте реальные данные, убедитесь, что вы используете базовые «тестовые» текстуры и сетки, которые не изменятся.

2 голосов
/ 11 июля 2010

Я бы предложил сделать небольшой прототип или какой-нибудь другой небольшой побочный проект и поиграть с opengl. Это даст вам некоторое представление об этом. Как только это будет сделано, сборка приложения с использованием tdd станет намного проще. И вы точно понимаете, что вам нужно издеваться над opengl, а не тестировать opengl.

0 голосов
/ 11 июля 2010

Взгляните на Как лучше всего отлаживать OpenGL? ; инструменты, упомянутые в ответах на этот вопрос, сделают возможной некоторую форму тестирования, особенно GLIntercept (перехватчик вызова функции OpenGL) звучит как очень интересная опция / отправная точка для дальнейших исследований.

...