Подтвердить что ты не робот

Изучение OpenGL при тренировке TDD (модульное тестирование)

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

Ответ 4

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

Ответ 5

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

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

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

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

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

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

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

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

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

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

Ответ 6

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