Как процессор и графический процессор взаимодействуют для визуализации компьютерной графики?
Центральный процессор (CPU) и графический процессор (GPU) вашего компьютера взаимодействуют каждый раз, когда вы используете компьютер, чтобы предоставить вам четкий и отзывчивый визуальный интерфейс. Читайте дальше, чтобы лучше понять, как они работают вместе.
фото sskennel.
Сегодняшняя сессия Вопросов и Ответов приходит к нам благодаря SuperUser - подразделению Stack Exchange, групповой группе веб-сайтов вопросов и ответов..
Вопрос
Читатель SuperUser Сатья задал вопрос:
Здесь вы можете увидеть скриншот небольшой программы на C ++ под названием Triangle.exe с вращающимся треугольником на основе OpenGL API..
По общему признанию очень простой пример, но я думаю, что это применимо к другим операциям с графическими картами.
Мне было просто любопытно, и я хотел узнать весь процесс от двойного щелчка по Triangle.exe под Windows XP, пока не смогу увидеть вращающийся треугольник на мониторе. Что происходит, как взаимодействуют процессор (который сначала обрабатывает .exe) и графический процессор (который, наконец, выводит треугольник на экран)?
Я предполагаю, что для отображения этого вращающегося треугольника в первую очередь используется следующее аппаратное / программное обеспечение:
аппаратные средства
- жесткий диск
- Системная память (RAM)
- ЦПУ
- Видеопамять
- GPU
- ЖК дисплей
Программного обеспечения
- Операционная система
- DirectX / OpenGL API
- Nvidia Driver
Может кто-нибудь объяснить процесс, может быть, с какой-то блок-схем для иллюстрации?
Это не должно быть сложное объяснение, которое охватывает каждый шаг (думаю, что это выходит за рамки), но объяснение, за которым может следовать специалист по ИТ.
Я уверен, что многие люди, которые бы назвали себя ИТ-специалистами, не могли правильно описать этот процесс.
Ответ
Хотя несколько членов сообщества ответили на вопрос, Оливер Зальцбург прошел лишнюю милю и ответил на нее не только подробным ответом, но и превосходной сопроводительной графикой..
Изображение JasonC, доступно в качестве обоев здесь.
Он пишет:
Я решил написать немного о программном аспекте и о том, как компоненты взаимодействуют друг с другом. Может быть, это будет пролить свет на некоторые области.
Презентация
Что нужно, чтобы нарисовать на экране то единственное изображение, которое вы разместили в своем вопросе??
Есть много способов нарисовать треугольник на экране. Для простоты предположим, что буферы вершин не использовались. (A буфер вершинэто область памяти, где вы храните координаты.) Предположим, что программа просто сообщила конвейеру графической обработки о каждой отдельной вершине (вершина - это просто координата в пространстве) в строке.
Но, прежде чем мы сможем что-то нарисовать, мы должны сначала запустить некоторые леса. Посмотрим Зачем потом:
// Очистить экран и буфер глубины glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Сбросить текущую матрицу просмотра модели glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Рисование с использованием треугольников glBegin (GL_TRIANGLES); // Red glColor3f (1.0f, 0.0f, 0.0f); // Вершина треугольника (передняя часть) glVertex3f (0.0f, 1.0f, 0.0f); // Зеленый glColor3f (0.0f, 1.0f, 0.0f); // слева от треугольника (спереди) glVertex3f (-1.0f, -1.0f, 1.0f); // Blue glColor3f (0.0f, 0.0f, 1.0f); // справа от треугольника (спереди) glVertex3f (1.0f, -1.0f, 1.0f); // Завершено рисование glEnd ();
Так, что это сделало?
Когда вы пишете программу, которая хочет использовать видеокарту, вы обычно выбираете какой-то интерфейс для драйвера. Некоторые хорошо известные интерфейсы для драйвера:
- OpenGL
- Direct3D
- CUDA
Для этого примера мы будем использовать OpenGL. Теперь ваш интерфейс к водителю это то, что дает вам все инструменты, необходимые для создания вашей программы говорить на видеокарту (или драйвер, который затем переговоры на карту).
Этот интерфейс должен дать вам определенные инструменты. Эти инструменты принимают форму API, который вы можете вызывать из вашей программы..
Этот API - это то, что мы видим в примере выше. Давайте внимательнее посмотрим.
Леса
Прежде чем вы действительно сможете сделать какой-либо фактический рисунок, вы должны выполнить настроить. Вы должны определить ваш видовой экран (область, которая будет фактически визуализироваться), вашу перспективу ( камера в ваш мир), какое сглаживание вы будете использовать (чтобы сгладить края вашего треугольника) ...
Но мы не будем на это смотреть. Мы просто взглянем на то, что вам нужно сделать каждый кадр. Подобно:
Очистка экрана
Графический конвейер не собирается очищать экран для каждого кадра. Вы должны будете сказать это. Зачем? Вот почему:
Если вы не очистите экран, вы просто перебирать это каждый кадр. Вот почему мы называем glClear
сGL_COLOR_BUFFER_BIT
задавать. Другой бит (GL_DEPTH_BUFFER_BIT
) говорит OpenGL очистить глубинабуфер. Этот буфер используется для определения того, какие пиксели находятся перед (или позади) другими пикселями.
преобразование
Источник изображения
Преобразование - это та часть, где мы берем все входные координаты (вершины нашего треугольника) и применяем нашу матрицу ModelView. Это матрица, которая объясняет как наш модель (вершины) вращаются, масштабируются и переводятся (перемещаются).
Далее мы применяем нашу матрицу проекции. Это перемещает все координаты, чтобы они правильно смотрели на нашу камеру.
Теперь мы снова преобразуем нашу матрицу Viewport. Мы делаем это, чтобы масштабировать наши модель к размеру нашего монитора. Теперь у нас есть набор вершин, которые готовы к визуализации!
Мы вернемся к преобразованию чуть позже.
Рисование
Чтобы нарисовать треугольник, мы можем просто сказать OpenGL начать новый список треугольников позвонив glBegin
с GL_TRIANGLES
постоянная.
Есть и другие формы, которые вы можете нарисовать. Как треугольная полоса или треугольный веер. Это в первую очередь оптимизация, так как они требуют меньше связи между процессором и графическим процессором, чтобы нарисовать одинаковое количество треугольников.
После этого мы можем предоставить список наборов из 3 вершин, которые должны составлять каждый треугольник. Каждый треугольник использует 3 координаты (как в 3D-пространстве). Кроме того, я также предоставляю цвет для каждой вершины, вызываяglColor3f
до призвание glVertex3f
.
Тень между 3 вершинами (3 углами треугольника) рассчитывается OpenGLавтоматически. Он будет интерполировать цвет по всей поверхности многоугольника.
взаимодействие
Теперь, когда вы нажимаете на окно. Приложение должно только захватить сообщение окна, которое сигнализирует о щелчке. Затем вы можете запустить любое действие в вашей программе, которое вы хотите.
Это получает много сложнее, когда вы хотите начать взаимодействовать с 3D-сценой.
Сначала вы должны четко знать, в каком пикселе пользователь щелкнул окно. Затем, принимая ваш перспективыво внимание, вы можете рассчитать направление луча, от точки мыши в вашей сцене. Затем вы можете рассчитать, если какой-либо объект в вашей сцене пересекается с этим лучом. Теперь вы знаете, нажал ли пользователь на объект.
Итак, как вы делаете это вращаться?
преобразование
Мне известны два типа преобразований, которые обычно применяются:
- Матричное преобразование
- Костная трансформация
Разница в том, что скелет влияет на одного вершины. Матрицы всегда влияют на все нарисованные вершины одинаково. Давайте посмотрим на пример.
пример
Ранее мы загрузили наш единичная матрица прежде чем рисовать наш треугольник. Тождественная матрица - это та, которая просто обеспечивает без преобразования совсем. Таким образом, все, что я рисую, зависит только от моей точки зрения. Таким образом, треугольник не будет вращаться вообще.
Если я хочу повернуть его сейчас, я мог бы сам сделать математику (на процессоре) и просто вызвать glVertex3f
сДругой координаты (которые вращаются). Или я мог бы позволить GPU делать всю работу, позвонив glRotatef
перед нанесением:
// Поворот треугольника по оси Y glRotatef (amount, 0.0f, 1.0f, 0.0f);
количество
это, конечно, просто фиксированное значение. Если хотите оживлять, вам придется следить за количество
и увеличивать его каждый кадр.
Итак, подождите, что случилось со всеми матричными разговорами ранее?
В этом простом примере нам не нужно заботиться о матрицах. Мы просто звоним glRotatef
и это заботится обо всем этом для нас.
glRotate
производит вращениеугол
градусов вокруг вектора x y z. Текущая матрица (seeglMatrixMode) умножается на матрицу вращения с продуктом, заменяющим текущую матрицу, так как ifglMultMatrix вызывается со следующей матрицей в качестве аргумента:x 2 1 - c + cx y z 1 - c - z sx z 1 - c + y s 0 y x 1 - c + z sy 2 1 - c + cy z 1 - c - x s 0 x z 1 - c - y sy z 1 - c + x sz 2 1 - c + c 0 0 0 0 1
Ну спасибо за это!
Заключение
Что становится очевидным, так это много разговоров в OpenGL. Но это не говорит нас что-нибудь. Где связь?
Единственное, что OpenGL говорит нам в этом примере, это когда это будет сделано. Каждая операция займет определенное количество времени. Некоторые операции занимают невероятно много времени, другие невероятно быстро.
Отправка вершины к GPU будет так быстро, я даже не знаю, как это выразить. Отправка тысяч вершин из ЦП в ГП, каждый кадр, скорее всего, не проблема.
Очистка экрана может занять миллисекунду или хуже (имейте в виду, у вас обычно есть только приблизительно 16 миллисекунд времени, чтобы нарисовать каждый кадр), в зависимости от того, насколько велика ваша область просмотра. Чтобы очистить его, OpenGL должен нарисовать каждый пиксель в цвет, который вы хотите очистить, это может быть миллионы пикселей.
Кроме этого, мы можем только спросить у OpenGL о возможностях нашего графического адаптера (максимальное разрешение, максимальное сглаживание, максимальная глубина цвета,…).
Но мы также можем заполнить текстуру пикселями, каждый из которых имеет определенный цвет. Таким образом, каждый пиксель содержит значение, а текстура представляет собой гигантский «файл», заполненный данными. Мы можем загрузить это в видеокарту (создав текстурный буфер), затем загрузить шейдер, сказать этому шейдеру использовать нашу текстуру в качестве входных данных и выполнить некоторые чрезвычайно тяжелые вычисления для нашего «файла».
Затем мы можем «визуализировать» результат нашего вычисления (в виде новых цветов) в новую текстуру.
Вот как вы можете заставить работать графический процессор другими способами. Я предполагаю, что CUDA работает аналогично этому аспекту, но у меня никогда не было возможности работать с ним.
Мы действительно лишь слегка коснулись всей темы. Программирование 3D-графики - адское чудовище.
Источник изображения
Есть что добавить к объяснению? Звук выключен в комментариях. Хотите узнать больше ответов от других технически подкованных пользователей Stack Exchange? Ознакомьтесь с полным обсуждением здесь.