В частности, DirectX и OpenGL работают, вызывая операционную систему и / или драйвер видеооборудования.Драйвер, в свою очередь, выполняет фактическое рисование, взаимодействуя с графическим устройством.Точные детали взаимодействия варьируются от одной видеокарты к другой.
Еще в дни DOS программисты на C ++ могли напрямую работать с оборудованием.Это было достигнуто двумя способами.Во-первых, путем записи в / чтения из специального блока памяти («кадровый буфер»), где были сохранены пиксели или текст.Это был промежуток памяти по известному адресу, поэтому для работы с ним необходимо было привести целочисленную константу к указателю и работать с этим указателем.Чисто C ++ механизм.Другим способом взаимодействия было чтение / запись в порты ввода / вывода.Теперь это механизм, который напрямую не поддерживается C, если вы не хотите считать встроенную сборку или встроенные функции компилятора.Существовали две библиотечные функции, которые обернули бы эти две операции (буквально, обертки вокруг двух команд процессора - INP и OUTP), но большинство программистов просто использовали бы однострочный встроенный фрагмент сборки вместо этого.
Даже сейчас большинствовзаимодействие видеооборудования сводится к этим двум путям - кадровому буферу и портам ввода / вывода (DMA и прерывания обычно не используются для графики).Но мы, программисты прикладного уровня, не видим их.Это штучка водителя.
Одно современное предупреждение касается защищенного режима;в защищенном режиме указатели C не совпадают с базовыми физическими адресами.Простое приведение 0xA0000 к указателю не приведет к кадровому буферу даже в режиме ядра.Однако код уровня ядра (т. Е. Драйвер) может запросить у менеджера памяти указатель, соответствующий конкретному физическому адресу.