Я начал смотреть поток Handmade Hero , где Кейси Муратори создает игровой движок без использования фреймворков или чего-то подобного. Вчера я попал в ту часть, где он показал, как изображение выводится на экран. Насколько я понял, он просто выделил немного памяти размером с экран, на котором он хочет нарисовать. А затем он создал растровое изображение, которое он передал в буферную память, которую он выделил, и нарисовал его на экране, используя специальную функцию ОС.
Это кажется довольно прямым. Я использовал GameMaker, сменил на Love2D, немного поработал со Sprite Kit, но мне всегда было интересно, что же на самом деле происходит под этими иногда запутанными слоями.
Учитывая это, зачем вообще беспокоиться об использовании графических библиотек (OpenGL, SFML, SDL,…), когда все, что вам нужно сделать, это просто выделить некоторый буфер, передать растровое изображение и вывести его на экран?
Если вы затем хотите нарисовать на экране разные вещи, вы просто записываете их в растровое изображение, которое затем передается в буфер. Я довольно новичок в программировании, но мне это кажется довольно простым. Пожалуйста, поправьте меня, если я ошибаюсь.
источник
Ответы:
Речь идет не только о скорости выполнения, но и о простоте. Хотя программный рендеринг, используемый в этом примере, будет намного медленнее, чем использование аппаратного ускорения (например, графического процессора), рисование нескольких растровых изображений на экране является такой тривиальной задачей, что вы не заметите падения производительности.
Тем не менее, низкоуровневая активность, такая как растеризация треугольника, сортировка по глубине и тому подобное, являются хорошо понятными концепциями, которые GPU может обрабатывать неявно с помощью нескольких команд. Реализация тех, кто работает в программном режиме, по сути, заново изобретает колесо. Это хорошо, если вы хотите получить низкоуровневое понимание того, как выполняется рендеринг, я сам написал 3D-рендеринг программного обеспечения, просто чтобы немного его изучить, но в большинстве случаев это пустая трата времени, когда OpenGL может сделать это быстрее из коробка.
Пример, который вы привели, звучит очень просто, просто рисуете одно изображение на экране, поэтому его реализация проста. Однако, как только вы начнете разделять по уровням сложности, становится все сложнее правильно отобразить все. Вещи, которые люди должны были делать в дни Quake 3D-рендеринга программного обеспечения, были безумными, хотя я ценю, что вы не продвинетесь так далеко (пока).
источник
Коротко: потому что это быстро (OpenGL, DirectX).
Длинная:
Вы можете думать, что можете сделать все это самостоятельно. Нарисуйте пиксели на экране. Вы можете написать небольшую библиотеку для рисования фигур, таких как квадраты или треугольники. Это будет работать, конечно. Есть много библиотек, чтобы сделать именно это. Некоторые из них даже реализуют OpenGL-спецификацию (так что они похожи на программную часть opengl), которая будет делать именно то, что делает Кейси Муратори. Они вычисляют все на стороне программного обеспечения, устанавливают пиксели на стороне программного обеспечения и записывают результат на экран.
Однако это медленно . Процессор, который в конечном итоге выполнит все эти вещи, не был создан для этого сценария. Вот для чего нужны графические процессоры. Что делает OpenGL (если, конечно, это не программная реализация), так это берет все, что вы ему скажете, и помещает все данные, все вызовы на отрисовку, почти все на видеокарту и приказывает GPU выполнить эту работу. Графический процессор сделан специально для такой работы. Умножение чисел с плавающей точкой (То , что вы делаете много при рисовании 3D-сцены) и выполнения шейдеров. И это параллельно. Просто для того, чтобы понять, насколько быстрым является GPU, подумайте о простой трехмерной сцене в полноэкранном режиме с разрешением 1920x1080 пикселей. Это умноженные 2 073 600 пикселей для рисования. Для каждогопиксель, графический процессор будет запускать фрагмент-шейдер по крайней мере один раз , в большинстве случаев более одного раза. Теперь, допустим, мы работаем со скоростью 60 кадров в секунду. Это означает, что графический процессор запускает фрагмент-шейдер 2073 600 * 60 = 124 416 000 раз в секунду . Как вы думаете, вы можете сделать что-то подобное на своем процессоре? (Это довольно упрощенное объяснение, есть еще много вещей, которые нужно учитывать, например, сколько пикселей вы перерисовываете с помощью более близких объектов, сколько MSAA вы используете и т. Д., Однако, 124 416 000 раз в секунду , вероятно, самые низкие, которые вы можете получить, и вы легко получится намного больше, чем 60fps с простой сценой)
Вот что делают OpenGL и Direct3D, для каких движков смотрите ответ @Uri Popovs.
источник
То, что он делает, называется программным рендерингом , то, что делает OpenGL, называется графическим рендерингом.
Какая разница между ними? Скорость и память.
Растеризация (заполнение треугольников на экране) занимает некоторое время. Если вы делаете это на процессоре, вы, по сути, отводите это время от игровой логики, особенно если она не оптимизирована хорошо.
И не имеет значения, насколько маленьким является изображение, ему нужно выделить для него определенное количество памяти. Для этого у видеокарт есть видеопамять.
источник
Хотя ответы других людей являются более правильными, чем любые ответы, которые я мог бы дать, я хочу указать на фундаментальное недоразумение о том, как работает разработка программного обеспечения, которое, как мне кажется, лежит в основе вашего вопроса. Несмотря на то, что всегда можно сделать что-то «без посторонней помощи», и зачастую это дает большую образовательную выгоду, но реальность заключается не в том, как создается современное программное обеспечение.
Кто-то создал аппаратное обеспечение и машинные языки, которые на нем работают. Кто-то еще создает языки и компиляторы более высокого уровня, драйверы и операционные системы, графические библиотеки и так далее. Каждый из нас опирается на работу наших предшественников. Это не только «хорошо», это требование.
Вы рисуете линию того, что «приемлемо» или нет в произвольной точке в наборе инструментов. Вы также можете легко сказать «зачем использовать C ++, если вы можете сделать то же самое в сборке?», Или «зачем полагаться на драйверы клавиатуры, когда вы можете так же легко считывать напряжения с проводов и рассчитывать сами?» Не хватает часов в день или лет в жизни, чтобы каждый мог делать все сам.
Это относится не только к разработке программного обеспечения, но и к современной жизни в целом. Вы когда-нибудь слышали о парне, который сам построил тостер с нуля? http://www.thomasthwaites.com/the-toaster-project/ . Это заняло очень много времени и усилий. Для тостера. Попробуйте собрать все, что требуется для реализации видеоигры из эфира, самостоятельно!
источник
Двигатели делают гораздо больше, чем просто рисуют картинку на экране. Они управляют освещением, тенями, входом, обнаружением столкновений. Даже просто часть рендеринга намного сложнее, чем просто поместить буфер на экран. Особенно для трехмерных сцен вам нужно сделать много вычислений на гораздо более сложных данных, чем на растровом изображении. Позвольте мне привести вам аналогию с автомобилем. То, что вы описываете как простой, - это выхлоп автомобиля. Вы просто делаете трубу нужного размера, а затем проталкиваете газ от одного конца к другому. Однако это далеко не единственное, что происходит в механизме автомобиля.
источник
Приведенные выше ответы превосходны, но ни один из них не идет по поводу самой важной причины, почему OpenGL и тому подобное являются предпочтительными. Основная причина заключается в том, чтобы использовать специализированное оборудование, специально предназначенное для работы с такими вещами, как рендеринг миллионов пикселей на экране, графическом процессоре .
При программном рендеринге с использованием ЦП рендерер будет циклично, один за другим, проходить по всем пикселям на растровом изображении и отдавать приказы для отображения каждого на экране. Так что, если вы рендерите изображение размером 1000x1000, то этот цикл увеличится до 1000000 для вашего процессора. Они разработаны с учетом контроля в конце концов; множество условий, переход от одного набора инструкций к другому и строгое направление потока управления. Тем не менее, графический процессор разработан с учетом того, что он будет выполнять много подобных циклов по пикселям на экране.Графический процессор будет использовать цикл for с 1000000 итерациями и разделять работу на огромное количество ядер, чтобы каждое работало ** параллельно и независимо друг от друга **. Таким образом, в отличие от ЦП, каждый раз, когда графический процессор сталкивается с условием if-else, он будет обрабатывать обе ветви кода до двух своих ядер И, ТОГДА, в самом конце, он будет смотреть на то, что условие оценивает, и отбрасывает результат ненужного перехода (вот почему многие условия if-else в шейдерах GPU не одобряются; они всегда несут ответственность за потери).
Так что да, графические процессоры построены вокруг параллелизма . Это делает работу с пикселями для них намного быстрее по сравнению с процессорами.
источник
См. Мне действительно нужно использовать графический API?
Конечно, вы можете запросить буфер, установить в нем несколько битов и записать его на экран. По сути, это был единственный способ программирования графики на ПК до появления графических ускорителей в середине 90-х от 3DFX. Даже в Windows DirectX был разработан для предоставления прямого доступа к видеопамяти.
Но на оборудовании, отличном от ПК, на специализированных игровых автоматах всегда были методы ускорения графики за счет разгрузки работы с процессора. Даже у Atari 2600 были «аппаратные спрайты», отчасти потому, что у него не было достаточно оперативной памяти для кадрового буфера.
Позднее (середина 80-х) игровые приставки были оптимизированы для платформенных игр. Опять же, нет кадрового буфера; вместо этого программист может указать сетки плиток :
источник
Современные процессоры достаточно быстры, чтобы делать любую 2-мерную игру в программном обеспечении, поэтому для 2-мерной графики OpenGL / DirectX не даст никаких преимуществ, кроме добавления еще одной зависимости и уровня сложности для вашего проекта, таких как установка матрицы 3D-проекции для рисования связки. спрайтов и загрузка данных в GPU.
OpenGL также заставит вас упаковать все ваши спрайты в текстуры 512x512 (артефакт старых консолей, таких как PSX, упаковывать графику в страницы видеопамяти), требуя от вас написания довольно сложного кода упаковки спрайтов.
С другой стороны, если вы делаете 3d, отрисовывая миллионы треугольников со сложным затенением, то использование графического процессора неизбежно. Давным-давно существовала более простая версия Direct3d, предназначенная только для 2d, называемая DirectDraw, которая ускоряла рисование спрайтов с помощью графического процессора, но теперь Microsoft ее больше не поддерживает, возможно, потому что процессоры достаточно быстры, чтобы выполнять 2D без ускорения, если вам не нужно экономить энергию ,
источник