Как изменить настройки opengl

Авторы: Станислав Васильев, Кузин Андрей Intro Софтверная группа nVidia, под управлением Ника Триантоса в nVidia работает не покладая рук над исправлением ошибок, введением новых возможностей и другими модификациями своего объединенного драйвера.

логотип 3DNews

Новости


3DNews Detonator 3.56. Настройка


Самое интересное в новостях

Настройки OpenGL

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

  • Enable buffer region extension (разрешить расширение GL_KTX_buffer_extension) — включает специальное расширение OpenGL, которое можно отключить для совместимости. Не вдаваясь в технические детали скажем, что приложения 3D моделирования, поддерживающие это расширение будут работать быстрее.
  • Allow dual planes extension to use local video memory — функция, так же критичная для 3D CAD приложений, работающих через OpenGL. Позволяет использовать локальную память акселератора для специальной аппаратной функции. Работает только, если включить первую опцию. Иногда использование двух этих функций ведёт к неправильному рендерингу окна в
    программе моделирования.
  • Use fast linear-mipmap-linear filtering — включение этой опции заставляет акселератор использовать более быстрый метод трилинейной филтрации. Зависимость скорость-качество остаётся в силе.
  • Enable anisotropic filtering — включает расширение OpenGL для анизотропной филтрации, что позволяет приложением использовать её. Приложение, не использующее это GL расширение не будет выглядеть лучше.
  • Enable alternate depth buffering technique — по мнению nVidia включение этой опции разрешает включение альтернативного метода буферирования, что может помочь рисовать картинку в 16-бит более качественно. Мы не заметили сколько-нибудь серьёзного отличия в качестве, зато при включении опции скорость немного возросла.
  • Disable support for enchanced CPU instruction sets — отключить поддержку расширенных комманд процессоров, к которым можно отнести MMX, SSE и 3DNow! Включение этой опции может для отключить поддержку в драйвере оптимизации под современные процессоры, что в определённых случаях необходимо для стабильности. Мы не рекомендуем включать эту опцию
    во избежание потерь производительности.

Далее идут три выпадающих списка, параметры которых серьёзно влияют на производительность.

Default color depth for textures задаёт глубину цветности текстур по умолчанию. Если приложение задаёт глубину цвета текстуры само, то изменение параметра никак не скажется на его внешнем виде и скорости. В обратном случае текстуры
могут быть принудительно конвертированы в 16 бит или в 32 бита. Имеет смысл поставить 16 бит, так как современные приложения задают формат текстур сами, а тратить память и ресурсы акселератора в старых 16-ти битных играх, конвертируя их текстуры, лишено смысла.

Buffer flipping mode — режим работы с буфером кадра. Возможно два режима — page flipping или block transfer, возможна установка режима авто-определения. По нашим замерам установка block transfer замедляет Quake 2 в 1280×960/32 бит с 81 fps до 55. Очень серьёзное падение производительности. Если установить на автоматическое определение, то как правило работает page flipping. Проблем с принудительно установленным page flipping не наблюдалось, поэтому мы рекомендуем
использовать это значение параметра.

Vertical sync задаёт режим работы с вертикальной синхронизацией. Если вы хотите получить супер качество картинки
без разрывов при резких рывках, то не отключайте синхронизацию с VSYNC. Но хотя картинка будет более качественной,
количество FPS, выводимых акселератором будет лимитировано развёрткой монитора, кроме того это съест немного производительности. В сумме вы получите существенное падение производительности. Есть одна деталь — параметр задаёт значение по умолчанию, а значит если само приложение (к примеру Quake 3) отключает синхронизацию с VSYNC, то
значение параметра никак не влияет на производительность.

Use up to X MB of system memory for textures in PCI mode — задаёт обьём памяти, выделяемый для
хранения текстур PCI версии GeForce 256 или AGP плате, работающей в PCI-совместимом режиме. Если вы уверены, что ваша плата
не работает в PCI-совместимом режиме, то имеет смысл установить число на 0, чтобы не резервировать оперативную память.

Остальные кнопки в этой панели полностью идентичны кнопкам в панели Direct3D Settings.

Следующая страница →

← Предыдущая страница

Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.

Самые обсуждаемые публикации

#include <GL/glut.h>

#include<iostream>

using namespace std;

int rx = 100, ry = 125;

int xCenter = 250, yCenter = 250;

void myinit(void)

{

    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluOrtho2D(0.0, 640.0, 0.0, 480.0);

}

void setPixel(GLint x, GLint y)

{

    glBegin(GL_POINTS);

    glVertex2i(x, y);

    glEnd();

}

void ellipseMidPoint()

{

    float x = 0;

    float y = ry;

    float p1 = ry * ry - (rx * rx) * ry + (rx * rx) * (0.25);

    float dx = 2 * (ry * ry) * x;

    float dy = 2 * (rx * rx) * y;

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (dx < dy)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p1 < 0)

        {

            x = x + 1;

            dx = 2 * (ry * ry) * x;

            p1 = p1 + dx + (ry * ry);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dx = 2 * (ry * ry) * x;

            dy = 2 * (rx * rx) * y;

            p1 = p1 + dx - dy + (ry * ry);

        }

    }

    glFlush();

    float p2 = (ry * ry) * (x + 0.5) * (x + 0.5) + (rx * rx) * (y

        - 1) * (y - 1) - (rx * rx) * (ry * ry);

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (y > 0)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p2 > 0)

        {

            x = x;

            y = y - 1;

            dy = 2 * (rx * rx) * y;

            p2 = p2 - dy + (rx * rx);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dy = dy - 2 * (rx * rx);

            dx = dx + 2 * (ry * ry);

            p2 = p2 + dx -

                dy + (rx * rx);

        }

    }

    glFlush();

}

void display()

{

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 0.0, 0.0);

    glPointSize(2.0);

    ellipseMidPoint();

    glFlush();

}

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitWindowSize(640, 480);

    glutInitWindowPosition(10, 10);

    glutCreateWindow("User_Name");

    myinit();

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;

}

#include <GL/glut.h>

#include<iostream>

using namespace std;

int rx = 100, ry = 125;

int xCenter = 250, yCenter = 250;

void myinit(void)

{

    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluOrtho2D(0.0, 640.0, 0.0, 480.0);

}

void setPixel(GLint x, GLint y)

{

    glBegin(GL_POINTS);

    glVertex2i(x, y);

    glEnd();

}

void ellipseMidPoint()

{

    float x = 0;

    float y = ry;

    float p1 = ry * ry - (rx * rx) * ry + (rx * rx) * (0.25);

    float dx = 2 * (ry * ry) * x;

    float dy = 2 * (rx * rx) * y;

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (dx < dy)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p1 < 0)

        {

            x = x + 1;

            dx = 2 * (ry * ry) * x;

            p1 = p1 + dx + (ry * ry);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dx = 2 * (ry * ry) * x;

            dy = 2 * (rx * rx) * y;

            p1 = p1 + dx - dy + (ry * ry);

        }

    }

    glFlush();

    float p2 = (ry * ry) * (x + 0.5) * (x + 0.5) + (rx * rx) * (y

        - 1) * (y - 1) - (rx * rx) * (ry * ry);

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (y > 0)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p2 > 0)

        {

            x = x;

            y = y - 1;

            dy = 2 * (rx * rx) * y;

            p2 = p2 - dy + (rx * rx);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dy = dy - 2 * (rx * rx);

            dx = dx + 2 * (ry * ry);

            p2 = p2 + dx -

                dy + (rx * rx);

        }

    }

    glFlush();

}

void display()

{

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 0.0, 0.0);

    glPointSize(2.0);

    ellipseMidPoint();

    glFlush();

}

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitWindowSize(640, 480);

    glutInitWindowPosition(10, 10);

    glutCreateWindow("User_Name");

    myinit();

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;

}

Обзор

Note


Команда mhwd все еще находится в стадии разработки и в настоящее время способна устанавливать драйверы только для видеокарт, подключенных по протоколу pci.

При установке полной версии Manjaro (т.е. с предустановленным окружением рабочего стола, кодеками и программами) команда mhwd будет автоматически выполняться программой установки GUI и CLI для автоматического определения вашей видеокарты и установки наиболее подходящего для нее драйвера. Будут ли установлены свободные или проприетарные драйверы, будет зависеть от вашего первоначального выбора использования свободных или несвободных видеодрайверов при загрузке.
В противном случае, необходимо будет выполнить команду mhwd вручную как часть процесса после установки минималистичного NET-издания Manjaro.

Для новичков рекомендуется использовать «Обнаружение оборудования» в Менеджере настроек Manjaro для изменения или установки новых графических драйверов
.
Для средних и опытных пользователей также можно использовать команду mhwd для установки, переустановки и удаления установленных видеодрайверов в любое время, как показано ниже.

Автоматическое распознавание и установка

Это рекомендуемый метод обнаружения и установки видеодрайверов. Синтаксис метода автоматической установки следующий:

user $ sudo mhwd -a [pci или usb подключение] [free или nonfree драйверы] 0300 COPY TO CLIPBOARD

Ниже приводится описание команд, используемых для автоматизированного метода:

  • -a: автоматическое обнаружение и установка соответствующего драйвера
  • [pci или usb]: установка соответствующего драйвера для устройств, подключенных к компьютеру через pci или через usb (опять же, на данном этапе разработки mhwd поддерживает только pci)
  • [free или nonfree]: установка либо бесплатных драйверов (например, предоставленных сообществом Linux), либо несвободных драйверов (например, предоставленных производителями оборудования)
  • 0300: определить, что драйвер должен быть установлен для видеокарты (0300 — это идентификатор для видеокарт. По мере развития команды mhwd будут использоваться новые идентификаторы для других аппаратных устройств).

Например, следующая команда приведет к автоматическому обнаружению и установке наилучшего доступного проприетарного драйвера для видеокарты, подключенной через pci-соединение:

user $ sudo mhwd -a pci nonfree 0300 COPY TO CLIPBOARD

В противном случае следующая команда приведет к автоматическому обнаружению и установке лучшего из доступных бесплатных драйверов для видеокарты, подключенной к pci-порту:

user $ sudo mhwd -a pci free 0300 COPY TO CLIPBOARD

Ручное распознавание и установка

Сам по себе подход «сделай сам» является относительно простым и понятным с помощью команды mhwd. Его следует применять в два этапа:

1. Определить соответствующий драйвер для установки, а затем

2. Установить его

Tip


Просто убедитесь, что вы определили и действительно собираетесь установить правильный драйвер для вашей конкретной видеокарты!

Определение доступных драйверов

Прежде чем вручную устанавливать видеодрайвер, необходимо определить, какие драйверы доступны для вашей системы. Чтобы перечислить доступные драйверы, используйте следующий синтаксис:

user $ mhwd -l [дополнительно: подробный просмотр] [дополнительно: —pci или —usb подключение] COPY TO CLIPBOARD

Использование этой команды без дополнительных опций выведет список базовой информации для всех доступных драйверов устройств, подключенных к вашей системе. Все драйверы видеокарт будут иметь префикс (video-) в своем названии. Основная информация, предоставленная для всех перечисленных драйверов, будет следующей:

  • Название
  • Версия
  • Свободная или проприетарная, и
  • PCI или USB соединение

Более подробный список установленных драйверов можно получить, введя:

user $ mhwd -l -d COPY TO CLIPBOARD

Подробный список предоставит следующую информацию:

  • Название
  • Версия
  • PCI или USB соединение
  • Описание
  • Приоритет
  • Свободная или проприетарная
  • Зависимости
  • Конфликты
  • Идентификатор класса (например, ‘0300’ для драйверов видеокарт), и
  • Идентификатор поставщика

Кроме того, использование фильтра —pci в следующем примере выведет список подробной информации только для драйверов, доступных для устройств (например, видеокарт), использующих внутреннее PCI-соединение:

user $ mhwd -l -d —pci COPY TO CLIPBOARD

Установка драйвера

Для установки драйвера видеокарты используйте следующий синтаксис:

user $ sudo mhwd -i pci [название драйвера] COPY TO CLIPBOARD

Ниже приведено описание команд, используемых для ручной установки драйвера:

  • -i: Установить драйвер
  • [pci]: Установка драйвера для устройства, подключенного к компьютеру через pci (например, видеокарты).
  • [название драйвера]: Название устанавливаемого драйвера

Например, для установки проприетарного драйвера видеокарты nvidia используется следующая команда:

user $ sudo mhwd -i pci video-nvidia COPY TO CLIPBOARD

Принудительная переустановка драйвера

Warning


используйте эту команду с осторожностью!

Чтобы принудительно переустановить существующий драйвер без его предварительного удаления, используйте следующий синтаксис:

user $ sudo mhwd -f -i pci [название драйвера] COPY TO CLIPBOARD

Например, чтобы принудительно переустановить ранее установленный драйвер видеокарты nvidia можно использовать следующую команду:

user $ sudo mhwd -f -i pci video-nvidia COPY TO CLIPBOARD

Удаление установленного драйвера

В некоторых случаях может потребоваться удалить установленный драйвер видеокарты. Аналогично ручной установке драйвера видеокарты, для его удаления необходимо выполнить два шага:

1. Распознать установленный драйвер

2. Удалить распознанный драйвер

В конце концов, будет трудновато удалить установленный драйвер, если вы не знаете как он называется!

Распознавание установленных драйверов

Чтобы определить и перечислить установленные в Manjaro драйверы, включая видеодрайвер, который нужно удалить, используйте следующий синтаксис:

user $ mhwd -li [дополнительно: подробный просмотр] [дополнительно: только pci или usb устройства] COPY TO CLIPBOARD

При использовании этой команды без дополнительных опций будет выведена основная информация обо всех драйверах, установленных в вашей системе. Опять же, все драйверы для видеокарт будут иметь префикс (video-) в своем названии. Как и в случае со списком драйверов, доступных для вашей системы, опция -d, используемая в следующей команде, выведет подробную информацию:

user $ mhwd -li -d COPY TO CLIPBOARD

Эта информация может оказаться полезной для определения любых непредвиденных последствий или проблем после удаления драйвера. И опять же, можно отфильтровать список установленных драйверов по тому, используются ли они на оборудовании, подключенном через pci или usb. В этом случае подробный список будет сформирован только для установленных драйверов, используемых на оборудовании с подключением PCI:

user $ mhwd -li -d —pci COPY TO CLIPBOARD

Еще один способ сообщить об установленных и используемых драйверах — использовать инструмент inxi.

user $ inxi -G COPY TO CLIPBOARD

Note


Профиль mhwd ‘video-linux’ соответствует последнему драйверу с открытым исходным кодом, доступному для вашего оборудования.

Note


Профиль mhwd ‘video-vesa’ является общим резервным драйвером, который не следует использовать в подавляющем большинстве случаев.

Удаление установленных драйверов

Warning


используйте эту команду с осторожностью!

Для удаления установленного драйвера используйте следующий синтаксис:

user $ sudo mhwd -r [pci или usb] [название драйвера] COPY TO CLIPBOARD

Например, чтобы удалить установленный драйвер для видеокарты nvidia (подключенной через pci) необходимо выполнить следующую команду:

user $ sudo mhwd -r pci video-nvidia COPY TO CLIPBOARD

Проверка конфигурации

Вы можете проверить конфигурацию с помощью:

user $ sudo mhwd-gpu —check COPY TO CLIPBOARD

user $ mhwd-gpu —status COPY TO CLIPBOARD

И при необходимости устранить проблемы:

user $ sudo mhwd-gpu —setmod COPY TO CLIPBOARD

user $ sudo mhwd-gpu —setxorg [ПУТЬ] COPY TO CLIPBOARD

Убедитесь, что путь к файлу конфигурации xorg является действительным.

Примечание по поводу ati, файла xorg и артефактов при входе в систему или kicad: если вы получаете артефакты при входе в систему или если рендеринг и масштабирование kicad происходит медленно — попробуйте добавить [Option «EXAPixmaps» «off»] в раздел «Device» файла конфигурации xorg. Смотрите здесь.

Двойной GPU

Разгрузка PRIME GPU

Если ваше оборудование включает более одной карты GPU — вы можете воспользоваться разгрузкой PRIME. PRIME — это технология, используемая для управления гибридной графикой, встречающейся в последних настольных компьютерах и ноутбуках (Optimus для NVIDIA, AMD Dynamic Switchable Graphics для Radeon). PRIME обнаруживает обе карты и автоматически выбирает карту Intel по умолчанию; более мощная дискретная видеокарта используется для более требовательных приложений.

В Manjaro это будет автоматически доступно для гибридных графических систем, использующих intel/modesetting для интегрированной карты и бесплатные драйверы (AMDGPU или Nouveau) для dGPU.

Вы можете запустить программу с определенным GPU, добавив к команде приложения DRI_PRIME=x, где x — номер приоритета карты.

Например, для запуска приложения с помощью второй карты добавьте в команду запуска приложения DRI_PRIME=1.

user $ DRI_PRIME=1 glxspheres64 COPY TO CLIPBOARD

Для использования 1-й карты (обычно, когда процессор имеет встроенный GPU, используется именно она)

user $ DRI_PRIME=0 glxspheres64 COPY TO CLIPBOARD

Если вы хотите всегда запускать какое-то приложение с дискретным процессором, то можете скопировать файл .desktop этого приложения в ~/.local/share/applications/ и отредактировать свойство «Exec».

user $ Exec=DRI_PRIME=1 inkscape COPY TO CLIPBOARD

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

Например, в Steam выберите игру, которую вы хотите запустить с помощью дискретной карты Nvidia, на странице библиотеки клиента Steam, щелкните правой кнопкой мыши и выберите пункт «Свойства».
Нажмите кнопку SET LAUNCH OPTIONS… и укажите параметры командной строки, за которыми следует стандартный ключ запуска %command%.

DRI_PRIME=1 %command%

Чтобы использовать dGPU по умолчанию, смотрите Reverse Prime.

Проприетарные (несвободные) драйвера NVIDIA

Если у Вас карта Nvidia — у Вас есть возможность использовать проприетарные (с закрытым исходным кодом = несвободные) драйверы вместо открытого (свободного) драйвера nouveau.

Для устаревших карт nvidia Manjaro поддерживает старые драйверы для совместимости. В этих случаях имя драйвера отличается, вместо nvidia это nvidia-390xx или nvidia340xx, будь то в конфигурации драйвера nvidia-only или bumblebee mhwd.

Когда Вы устанавливаете несвободный драйвер, mhwd включает утилиту от Nvidia «Nvidia Settings Utility», которая может помочь вам настроить несколько параметров. Вы можете найти эту утилиту в графическом меню приложений или запустить из терминала

user $ sudo nvidia-settings COPY TO CLIPBOARD

Если вы используете bumblebee — утилита nvidia нуждается в специальной команде

user $ sudo optirun -b none nvidia-settings -c :8 COPY TO CLIPBOARD

Nvidia Optimus

Для ноутбуков Optimus или оборудования с двумя GPU — intel и nvidia — у Вас есть три варианта использования драйвера карты в соответствии с вашими предпочтениями или возможностями вашего оборудования.

PRIME (по-умолчанию в mhwd)

Bumblebee

При установке Manjaro с опцией non-free, выбранной в меню Grub, или при использовании автоматической установки драйверов, по умолчанию устанавливается PRIME или bumblebee, в зависимости от поддержки вашего GPU, причем PRIME предпочтительнее. В этих случаях драйвер mhwd называется «video-hybrid-intel-nvidia-***xx-prime» или «video-hybrid-intel-nvidia-***xx-bumblebee».

Настройка разрешения/частоты обновления

Warning


Приведенный метод в настоящее время не работает для редакции Cinnamon. Как только решение будет найдено — эта статья будет обновлена.

1. Запустите утилиту nvidia-settings

2. Измените разрешение и частоту обновления на вкладке ‘X Server Display Configuration’.

3. Нажмите кнопку ‘Save to X Configuration File’ и сохраните в /etc/X11/mhwd.d/nvidia.conf.

4. Теперь запустите терминал и введите следующую команду для завершения процесса:

user $ sudo mhwd-gpu —setmod nvidia —setxorg /etc/X11/mhwd.d/nvidia.conf COPY TO CLIPBOARD

Настройка параметров X Screen (настройки OpenGL, сглаживание, X Server XVideo)

1. Запустите утилиту nvidia-settings

2. Измените настройки в X Server XVideo Settings, OpenGL и Antialiasing на вкладке ‘X Screen’.

3. Перейдите на вкладку ‘nvidia-settings configuration’ и нажмите на кнопку ‘Save Current Configuration’.

4. Сохраните .nvidia-settings-rc в указанном по умолчанию месте (/home/[имя вашей учетной записи]).

5. Отредактируйте файл .xinitrc с помощью предпочитаемого текстового редактора. Например, если вы используете gedit, запустите это в терминале:

user $ gedit ~/.xinitrc COPY TO CLIPBOARD

6. После открытия добавьте следующую строку в файл конфигурации:

user $ exec nvidia-settings —load-config-only COPY TO CLIPBOARD

7. Сохраните и выйдите.

Настройки Nvidia для особых случаев

Если ваш монитор не входит в режим энергосбережения (DPMS), попробуйте добавить `Option «HardDPMS» «true»` в разделе монитора Xorg. Например:

  Section "Monitor"
    # HorizSync source: edid, VertRefresh source: edid
    Identifier     "Monitor0"
    VendorName     "Unknown"
    ModelName      "BenQ ZOWIE XL LCD"
    HorizSync       30.0 - 160.0
    VertRefresh     56.0 - 144.0
    Option         "DPMS"
    Option         "HardDPMS" "true"
  EndSection

После вопроса на форуме

nvidia-prime

Manjaro также предлагает простой способ использования PRIME с проприетарными драйверами Nvidia.
.
Просто выберите и установите профиль ‘nvidia-prime’ через MSM или mhwd (например, video-hybrid-intel-nvidia-440xx-prime) и убедитесь, что пакет nvidia-prime установлен.

Затем для использования дискретной карты Nvidia это работает так же, как и Разгрузка PRIME выше, но использует другую команду. Добавьте к команде приложения prime-run. Например:

user $ prime-run glxspheres64 COPY TO CLIPBOARD

Bumblebee

Конфигурация Bumblebee в основном разработана для того, чтобы помочь минимизировать расход батареи ноутбука, поскольку Nvidia обычно потребляет значительное количество энергии, в то время как карты Intel более энергоэффективны. Таким образом, bumblebee обнаруживает обе карты и автоматически выбирает карту Intel по умолчанию, а для более требовательных приложений может использовать Nvidia.
Чтобы приложение использовало карту Nvidia, добавьте к команде приложения optirun или primusrun. Например:

user $ optirun glxspheres64 COPY TO CLIPBOARD

user $ primusrun inkscape COPY TO CLIPBOARD

Если вы хотите специально запустить какое-то приложение с драйвером nvidia, то можете изменить свойство «Exec» файла .desktop этого приложения или запустить его в терминале следующим образом

 Exec=primusrun chromium

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

Например, в Steam выберите игру, которую вы хотите запустить с помощью дискретной карты Nvidia, на странице библиотеки клиента Steam, щелкните правой кнопкой мыши и выберите пункт «Свойства».
Нажмите кнопку SET LAUNCH OPTIONS… и укажите параметры командной строки, за которыми следует стандартный ключ запуска %command%.

primusrun %command%

Смотрите также

  • Обзор обнаружения оборудования в Manjaro

Более легкий путь

Вы можете использовать GUI-версию mhwd в Конфигурации оборудования

С помощью этого инструмента вы можете:
— установить графический драйвер
— переключить графический драйвер

Как проверить драйвер

user $ glxinfo | grep OpenGL COPY TO CLIPBOARD

Пример вывода команды:

драйвер Nvidia driver ( проприетарный )

$ glxinfo | grep OpenGL

OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GTX 660/PCIe/SSE2
OpenGL core profile version string: 4.3.0 NVIDIA 331.49
OpenGL core profile shading language version string: 4.30 NVIDIA via Cg compiler
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.4.0 NVIDIA 331.49
OpenGL shading language version string: 4.40 NVIDIA via Cg compiler
OpenGL context flags: (none)
OpenGL profile mask: (none)
OpenGL extensions:

Nouveau , Gallium для Mesa ( свободный драйвер )

$ glxinfo | grep OpenGL

OpenGL vendor string: nouveau
OpenGL renderer string: Gallium 0.4 on NVE6
OpenGL core profile version string: 3.1 (Core Profile) Mesa 9.2.5
OpenGL core profile shading language version string: 1.40
OpenGL core profile context flags: (none)
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 9.2.5
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:

драйвер Intel для Mesa ( открытый драйвер )

$ glxinfo | grep OpenGL

OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Desktop
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.0.6
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 11.0.6
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 11.0.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:

замечания

OpenGL — это открытый стандарт для рендеринга 2D и 3D-графики с использованием графического оборудования. OpenGL реализован в потрясающем массиве платформ, позволяющих приложениям, нацеленным на OpenGL, быть чрезвычайно гибкими.

Версии

Версия Дата выхода
1,1 1997-03-04
1.2 1998-03-16
1.2.1 1998-10-14
1,3 2001-08-14
1.4 2002-07-24
1,5 2003-07-29
2,0 2004-09-07
2,1 2006-07-02
3.0 2008-08-11
3,1 2009-03-24
3,2 2009-08-03
3,3 2010-03-11
4,0 2010-03-11
4,1 2010-07-26
4,2 2011-08-08
4,3 2012-08-06
4,4 2013-07-22
4.5 2014-08-11

Одно из самых распространенных заблуждений относительно OpenGL заключается в том, что это была библиотека, которую можно было установить из сторонних источников. Это заблуждение приводит ко многим вопросам в форме «Как установить OpenGL» или «Где скачать OpenGL SDK».

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

Когда OpenGL был впервые выпущен, API как-то нашел свой путь в контракте ABI (Application Binary Interface) Windows, Solaris и Linux (LSB-4 Desktop) в дополнение к его происхождению Sun Irix. Apple следовала и фактически интегрировала OpenGL так глубоко в MacOS X, что доступная версия OpenGL тесно связана с установленной версией MacOS X. Это имеет заметный эффект, что среды системного программирования для этих операционных систем (т.е. компилятор и компоновщик ссылок, которые ориентированы на эти системы) должны также предоставлять определения API OpenGL. Такого нет необходимости фактически устанавливать SDK для OpenGL. Технически возможно программировать OpenGL в этих операционных системах без необходимости установки выделенного SDK, предполагая, что установлена ​​среда сборки после целевого ABI.

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

Linux

В Linux довольно распространено разделение пакетов разработки для различных аспектов системы, чтобы их можно было обновлять индивидуально. В большинстве дистрибутивов Linux файлы разработки для OpenGL содержатся в выделенном пакете, который обычно зависит от мета-пакета разработки приложений для настольных приложений. Поэтому для установки файлов разработки OpenGL для Linux, как правило, позаботятся об установке мета-пакета /

Майкрософт Виндоус

Библиотека привязки API opengl32.dll (названная так для 32-разрядных и 64-разрядных версий Windows) поставляется по умолчанию с каждой версией Windows с Windows NT-4 и Windows 95B (оба около 1997 года). Однако эта DLL не обеспечивает фактическую реализацию OpenGL (кроме программной резервной копии, единственной целью которой является обеспечение безопасности программ, если другая реализация OpenGL не установлена). Эта DLL принадлежит Windows и не может быть изменена или перемещена! Современные версии OpenGL поставляются как часть так называемого Installable Client Driver (ICD) и доступны через opengl32.dll по умолчанию, который поставляется с предустановленной версией каждой версии Windows. Однако корпорация Microsoft решила, что графические драйверы, установленные с помощью Центра обновления Windows , не будут устанавливать / обновлять OpenGL ICD. Поскольку в таких новых установках Windows с установленными драйверами автоматически отсутствует поддержка современных функций OpenGL. Чтобы получить OpenGL ICD с современными функциями, графические драйверы должны быть загружены непосредственно с веб-сайта поставщика графического процессора и установлены вручную.

Что касается разработки, никаких дополнительных шагов не следует предпринимать. Все компиляторы C / C ++, следующие спецификациям Windows ABI, поставляются с заголовками и заглушкой компоновщика (opengl32.lib), необходимыми для сборки и связывания исполняемых файлов, которые используют OpenGL.

Ручная настройка OpenGL в Windows

Полный код примера, включенный в конце

Компоненты Windows для OpenGL

WGL

WGL (может быть выражен wiggle ) означает «Windows-GL», как в «интерфейсе между Windows и OpenGL» — набор функций из Windows API для связи с OpenGL. Функции WGL имеют префикс wgl, а его маркеры имеют префикс WGL_ .

Версия OpenGL по умолчанию, поддерживаемая в системах Microsoft, составляет 1,1. Это очень старая версия (последняя — 4.5). Способ получения последних версий — обновить графические драйверы, но ваша видеокарта должна поддерживать эти новые версии.

Полный список функций WGL можно найти здесь .

Интерфейс графического устройства (GDI)

GDI (сегодня обновленный до GDI +) — это 2D-интерфейс рисования, который позволяет рисовать окно в Windows. Вам нужно, чтобы GDI инициализировал OpenGL и разрешил ему взаимодействовать с ним (но фактически не использует GDI).

В GDI каждое окно имеет контекст устройства (DC), который используется для идентификации цели рисования при вызове функций (вы передаете его как параметр). Однако OpenGL использует свой собственный контекст рендеринга (RC) . Таким образом, DC будет использоваться для создания RC.


Основные настройки

Создание окна

Итак, для того, чтобы делать вещи в OpenGL, нам нужен RC, и чтобы получить RC, нам нужен DC, и для получения DC нам нужно окно. Создание окна с использованием Windows API требует нескольких шагов. Это базовая процедура, поэтому для более подробного объяснения вам следует проконсультироваться с другой документацией, потому что речь идет не об использовании Windows API.

Это настройка Windows, поэтому необходимо включить Windows.h , а точкой входа программы должна быть процедура WinMain с ее параметрами. Программа также должна быть связана с opengl32.dll и с gdi32.dll (независимо от того, находитесь ли вы в 64 или 32-битной системе).

Сначала нам нужно описать наше окно, используя структуру WNDCLASS . Он содержит информацию о окне, которое мы хотим создать:

/* REGISTER WINDOW */
WNDCLASS window_class;

// Clear all structure fields to zero first
ZeroMemory(&window_class, sizeof(window_class));

// Define fields we need (others will be zero)
window_class.style = CS_OWNDC;
window_class.lpfnWndProc = window_procedure; // To be introduced later
window_class.hInstance = instance_handle;
window_class.lpszClassName = TEXT("OPENGL_WINDOW");

// Give our class to Windows
RegisterClass(&window_class);
/* *************** */

Для точного объяснения значения каждого поля (и для полного списка полей) обратитесь к документации MSDN.

Затем мы можем создать окно с помощью CreateWindowEx . После создания окна мы можем получить DC:

/* CREATE WINDOW */
HWND window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                                    TEXT("OPENGL_WINDOW"),
                                    TEXT("OpenGL window"),
                                    WS_OVERLAPPEDWINDOW,
                                    0, 0,
                                    800, 600,
                                    NULL,
                                    NULL,
                                    instance_handle,
                                    NULL);

HDC dc = GetDC(window_handle);

ShowWindow(window_handle, SW_SHOW);
/* ************* */

Наконец, нам нужно создать цикл сообщений, который принимает события окна из ОС:

/* EVENT PUMP */
MSG msg;

while (true) {
    if (PeekMessage(&msg, window_handle, 0, 0, PM_REMOVE)) {
        if (msg.message == WM_QUIT)
            break;
        
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    
    // draw(); <- there goes your drawing

    SwapBuffers(dc); // To be mentioned later
}
/* ********** */

Формат пикселей

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

/* PIXEL FORMAT */
PIXELFORMATDESCRIPTOR descriptor;

// Clear all structure fields to zero first
ZeroMemory(&descriptor, sizeof(descriptor));

// Describe our pixel format
descriptor.nSize = sizeof(descriptor);
descriptor.nVersion = 1;
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER | PFD_SWAP_LAYER_BUFFERS;
descriptor.iPixelType = PFD_TYPE_RGBA;
descriptor.cColorBits = 32;
descriptor.cRedBits = 8;
descriptor.cGreenBits = 8;
descriptor.cBlueBits = 8;
descriptor.cAlphaBits = 8;
descriptor.cDepthBits = 32;
descriptor.cStencilBits = 8;

// Ask for a similar supported format and set it
int pixel_format = ChoosePixelFormat(dc, &descriptor);
SetPixelFormat(dc, pixel_format, &descriptor);
/* *********************** */

Мы включили двойную буферизацию в поле dwFlags , поэтому мы должны вызвать SwapBuffers , чтобы видеть вещи после рисования.

Рендеринг контекста

После этого мы можем просто создать наш контекст рендеринга:

/* RENDERING CONTEXT */
HGLRC rc = wglCreateContext(dc);
wglMakeCurrent(dc, rc);
/* ***************** */

Обратите внимание, что только один поток может использовать RC за раз. Если вы хотите использовать его из другого потока позже, вы должны вызвать wglMakeCurrent чтобы снова активировать его (это отключит его в текущем потоке и так далее).

Получение функций OpenGL

Функции OpenGL получаются с помощью указателей функций. Общая процедура:

  1. Как-то получить типы указателей функций (по существу, прототипы функций)
  2. Объявите каждую функцию, которую мы хотели бы использовать (с ее указателем на функцию)
  3. Получить фактическую функцию

Например, рассмотрим glBegin:

// We need to somehow find something that contains something like this,
// as we can't know all the OpenGL function prototypes
typedef void (APIENTRY *PFNGLBEGINPROC)(GLenum);

// After that, we need to declare the function in order to use it
PFNGLBEGINPROC glBegin;

// And finally, we need to somehow make it an actual function

(«PFN» означает «указатель на функцию», затем следует имя функции OpenGL и «PROC» в конце — это обычное имя типа указателя функции OpenGL.)

Вот как это делается в Windows. Как упоминалось ранее, Microsoft только отправляет OpenGL 1.1. Во-первых, типы указателей функций для этой версии можно найти, включив GL/gl.h После этого мы объявляем все функции, которые мы намерены использовать, как показано выше (выполнение этого в файле заголовка и объявление их «extern» позволит нам использовать их все после их загрузки один раз, просто включив его). Наконец, загрузка функций OpenGL 1.1 выполняется путем открытия библиотеки DLL:

HMODULE gl_module = LoadLibrary(TEXT("opengl32.dll"));

/* Load all the functions here */
glBegin = (PFNGLBEGINPROC)GetProcAddress("glBegin");
// ...
/* *************************** */

FreeLibrary(gl_module);

Однако мы, вероятно, хотим немного больше, чем OpenGL 1.1. Но Windows не дает нам прототипов функций или экспортированных функций для чего-либо выше этого. Прототипы должны быть приобретены из реестра OpenGL . Есть три интересующих нас файла: GL/glext.h , GL/glcorearb.h и GL/wglext.h .

Чтобы завершить GL/gl.h предоставленный Windows, нам нужен GL/glext.h . Он содержит (как описано в реестре) «OpenGL 1.2 и выше профили совместимости и интерфейсы расширений» (подробнее о профилях и расширениях позже, где мы увидим, что на самом деле не рекомендуется использовать эти два файла ).

Фактические функции должны быть получены с помощью wglGetProcAddress (нет необходимости открывать DLL для этого парня, их там нет, просто используйте функцию). С его помощью мы можем получить все функции из OpenGL 1.2 и выше (но не 1.1). Обратите внимание, что для правильной работы контекста рендеринга OpenGL необходимо создать и сделать текущим . Так, например, glClear :

// Include the header from the OpenGL registry for function pointer types

// Declare the functions, just like before
PFNGLCLEARPROC glClear;
// ...

// Get the function
glClear = (PFNGLCLEARPROC)wglGetProcAddress("glClear");

Мы можем создать процедуру get_proc для обёртки, которая использует как wglGetProcAddress и GetProcAddress :

// Get function pointer
void* get_proc(const char *proc_name)
{
    void *proc = (void*)wglGetProcAddress(proc_name);
    if (!proc) proc = (void*)GetProcAddress(gl_module, proc_name); // gl_module must be somewhere in reach

    return proc;
}

Итак, чтобы завершить, мы создали бы заголовочный файл с объявлениями указателей функций следующим образом:

extern PFNGLCLEARCOLORPROC glClearColor;
extern PFNGLCLEARDEPTHPROC glClearDepth;
extern PFNGLCLEARPROC glClear;
extern PFNGLCLEARBUFFERIVPROC glClearBufferiv;
extern PFNGLCLEARBUFFERFVPROC glClearBufferfv;
// And so on...

Затем мы можем создать такую ​​процедуру, как load_gl_functions которую мы вызываем только один раз, и работает так:

glClearColor = (PFNGLCLEARCOLORPROC)get_proc("glClearColor");
glClearDepth = (PFNGLCLEARDEPTHPROC)get_proc("glClearDepth");
glClear = (PFNGLCLEARPROC)get_proc("glClear");
glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)get_proc("glClearBufferiv");
glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)get_proc("glClearBufferfv");

И ты все настроен! Просто включите заголовок с указателями функций и GL.


Лучшая настройка

Профили OpenGL

OpenGL находится в разработке более 20 лет, и разработчики всегда были строгими относительно обратной совместимости (BC) . Из-за этого очень сложно добавить новую функцию. Таким образом, в 2008 году он был разделен на два «профиля». Ядро и совместимость . Основной профиль ломает BC в пользу улучшения производительности и некоторых новых функций. Он даже полностью удаляет некоторые устаревшие функции. Профиль совместимости поддерживает BC со всеми версиями до 1.0, а некоторые новые функции недоступны на нем. Он предназначен только для старых, устаревших систем, все новые приложения должны использовать основной профиль.

Из-за этого возникает проблема с нашей базовой настройкой — она ​​предоставляет только контекст, который обратно совместим с OpenGL 1.0. Формат пикселей также ограничен. Существует лучший подход, используя расширения.

Расширения OpenGL

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

Существуют три основные группы расширений: поставщик, EXT и ARB. Расширения поставщиков исходят от конкретного поставщика, и у них есть определенная производителем марка, например AMD или NV. Расширения EXT производятся несколькими поставщиками, работающими вместе. Через некоторое время они могут стать расширениями ARB, которые являются официально поддерживаемыми и одобрены ARB.

Чтобы получить типы указателей функций и прототипы функций всех расширений и, как упоминалось ранее, все типы указателей функций из OpenGL 1.2 и выше , необходимо загрузить файлы заголовков из реестра OpenGL . Как обсуждалось, для новых приложений лучше использовать основной профиль, поэтому было бы GL/glcorearb.h включить GL/glcorearb.h вместо GL/gl.h и GL/glext.h (если вы используете GL/glcorearb.h тогда GL/glcorearb.h Включить GL/gl.h ).

Существуют также расширения для WGL, в GL/wglext.h . Например, функция для получения списка всех поддерживаемых расширений фактически является самим расширением wglGetExtensionsStringARB (она возвращает большую строку с разделенным пробелом списком всех поддерживаемых расширений).

Получение расширений также осуществляется через wglGetProcAddress , поэтому мы можем просто использовать наш обертку, как раньше.

Расширенный формат пикселей и создание контекста

Расширение WGL_ARB_pixel_format позволяет нам создавать расширенные форматы пикселей. В отличие от ранее, мы не используем struct. Вместо этого мы передаем список желаемых атрибутов.

int pixel_format_arb;
UINT pixel_formats_found;

int pixel_attributes[] = {
    WGL_SUPPORT_OPENGL_ARB, 1,
    WGL_DRAW_TO_WINDOW_ARB, 1,
    WGL_DRAW_TO_BITMAP_ARB, 1,
    WGL_DOUBLE_BUFFER_ARB, 1,
    WGL_SWAP_LAYER_BUFFERS_ARB, 1,
    WGL_COLOR_BITS_ARB, 32,
    WGL_RED_BITS_ARB, 8,
    WGL_GREEN_BITS_ARB, 8,
    WGL_BLUE_BITS_ARB, 8,
    WGL_ALPHA_BITS_ARB, 8,
    WGL_DEPTH_BITS_ARB, 32,
    WGL_STENCIL_BITS_ARB, 8,
    WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
    WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
    0
};

BOOL result = wglChoosePixelFormatARB(dc, pixel_attributes, NULL, 1, &pixel_format_arb, &pixel_formats_found);

Аналогично, расширение WGL_ARB_create_context позволяет нам создавать расширенные контексты:

GLint context_attributes[] = {
    WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
    WGL_CONTEXT_MINOR_VERSION_ARB, 3,
    WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
    0
};

HGLRC new_rc = wglCreateContextAttribsARB(dc, 0, context_attributes);

Для точного объяснения параметров и функций обратитесь к спецификации OpenGL.

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

Однако Windows не позволяет устанавливать формат пикселя окна более одного раза. Из-за этого окно необходимо уничтожить и воссоздать, чтобы применить новые вещи:

wglMakeCurrent(dc, NULL);
wglDeleteContext(rc);
ReleaseDC(window_handle, dc);
DestroyWindow(window_handle);

// Recreate the window...

Полный пример кода:

/* We want the core profile, so we include GL/glcorearb.h. When including that, then
   GL/gl.h should not be included.

   If using compatibility profile, the GL/gl.h and GL/glext.h need to be included.

   GL/wglext.h gives WGL extensions.

   Note that Windows.h needs to be included before them. */

#include <cstdio>
#include <Windows.h>
#include <GL/glcorearb.h>
#include <GL/wglext.h>

LRESULT CALLBACK window_procedure(HWND, UINT, WPARAM, LPARAM);
void* get_proc(const char*);

/* gl_module is for opening the DLL, and the quit flag is here to prevent
   quitting when recreating the window (see the window_procedure function) */

HMODULE gl_module;
bool quit = false;

/* OpenGL function declarations. In practice, we would put these in a
   separate header file and add "extern" in front, so that we can use them
   anywhere after loading them only once. */

PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB;
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
PFNGLGETSTRINGPROC glGetString;

int WINAPI WinMain(HINSTANCE instance_handle, HINSTANCE prev_instance_handle, PSTR cmd_line, int cmd_show) {
    /* REGISTER WINDOW */
    WNDCLASS window_class;

    // Clear all structure fields to zero first
    ZeroMemory(&window_class, sizeof(window_class));

    // Define fields we need (others will be zero)
    window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
    window_class.lpfnWndProc = window_procedure;
    window_class.hInstance = instance_handle;
    window_class.lpszClassName = TEXT("OPENGL_WINDOW");

    // Give our class to Windows
    RegisterClass(&window_class);
    /* *************** */
        
    /* CREATE WINDOW */
    HWND window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                                        TEXT("OPENGL_WINDOW"),
                                        TEXT("OpenGL window"),
                                        WS_OVERLAPPEDWINDOW,
                                        0, 0,
                                        800, 600,
                                        NULL,
                                        NULL,
                                        instance_handle,
                                        NULL);
        
    HDC dc = GetDC(window_handle);
        
    ShowWindow(window_handle, SW_SHOW);
    /* ************* */
        
    /* PIXEL FORMAT */
    PIXELFORMATDESCRIPTOR descriptor;
        
    // Clear all structure fields to zero first
    ZeroMemory(&descriptor, sizeof(descriptor));
        
    // Describe our pixel format
    descriptor.nSize = sizeof(descriptor);
    descriptor.nVersion = 1;
    descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER | PFD_SWAP_LAYER_BUFFERS;
    descriptor.iPixelType = PFD_TYPE_RGBA;
    descriptor.cColorBits = 32;
    descriptor.cRedBits = 8;
    descriptor.cGreenBits = 8;
    descriptor.cBlueBits = 8;
    descriptor.cAlphaBits = 8;
    descriptor.cDepthBits = 32;
    descriptor.cStencilBits = 8;
        
    // Ask for a similar supported format and set it
    int pixel_format = ChoosePixelFormat(dc, &descriptor);
    SetPixelFormat(dc, pixel_format, &descriptor);
    /* *********************** */
        
    /* RENDERING CONTEXT */
    HGLRC rc = wglCreateContext(dc);
    wglMakeCurrent(dc, rc);
    /* ***************** */

    /* LOAD FUNCTIONS (should probably be put in a separate procedure) */
    gl_module = LoadLibrary(TEXT("opengl32.dll"));

    wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)get_proc("wglGetExtensionsStringARB");
    wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)get_proc("wglChoosePixelFormatARB");
    wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)get_proc("wglCreateContextAttribsARB");
    glGetString = (PFNGLGETSTRINGPROC)get_proc("glGetString");
    
    FreeLibrary(gl_module);
    /* ************** */

    /* PRINT VERSION */
    const GLubyte *version = glGetString(GL_VERSION);
    printf("%sn", version);
    fflush(stdout);
    /* ******* */

    /* NEW PIXEL FORMAT*/
    int pixel_format_arb;
    UINT pixel_formats_found;
    
    int pixel_attributes[] = {
        WGL_SUPPORT_OPENGL_ARB, 1,
        WGL_DRAW_TO_WINDOW_ARB, 1,
        WGL_DRAW_TO_BITMAP_ARB, 1,
        WGL_DOUBLE_BUFFER_ARB, 1,
        WGL_SWAP_LAYER_BUFFERS_ARB, 1,
        WGL_COLOR_BITS_ARB, 32,
        WGL_RED_BITS_ARB, 8,
        WGL_GREEN_BITS_ARB, 8,
        WGL_BLUE_BITS_ARB, 8,
        WGL_ALPHA_BITS_ARB, 8,
        WGL_DEPTH_BITS_ARB, 32,
        WGL_STENCIL_BITS_ARB, 8,
        WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
        WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
        0
    };

    BOOL result = wglChoosePixelFormatARB(dc, pixel_attributes, NULL, 1, &pixel_format_arb, &pixel_formats_found);

    if (!result) {
        printf("Could not find pixel formatn");
        fflush(stdout);
        return 0;
    }
    /* **************** */

    /* RECREATE WINDOW */
    wglMakeCurrent(dc, NULL);
    wglDeleteContext(rc);
    ReleaseDC(window_handle, dc);
    DestroyWindow(window_handle);
    
    window_handle = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                                        TEXT("OPENGL_WINDOW"),
                                        TEXT("OpenGL window"),
                                        WS_OVERLAPPEDWINDOW,
                                        0, 0,
                                        800, 600,
                                        NULL,
                                        NULL,
                                        instance_handle,
                                        NULL);
        
    dc = GetDC(window_handle);
        
    ShowWindow(window_handle, SW_SHOW);
    /* *************** */

    /* NEW CONTEXT */
    GLint context_attributes[] = {
        WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
        WGL_CONTEXT_MINOR_VERSION_ARB, 3,
        WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
        0
    };

    rc = wglCreateContextAttribsARB(dc, 0, context_attributes);
    wglMakeCurrent(dc, rc);
    /* *********** */
        
    /* EVENT PUMP */
    MSG msg;
        
    while (true) {
        if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
            if (msg.message == WM_QUIT) 
                break;
                
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
            
        // draw(); <- there goes your drawing
            
        SwapBuffers(dc);
    }
    /* ********** */
        
    return 0;
}

// Procedure that processes window events
LRESULT CALLBACK window_procedure(HWND window_handle, UINT message, WPARAM param_w, LPARAM param_l)
{
    /* When destroying the dummy window, WM_DESTROY message is going to be sent,
       but we don't want to quit the application then, and that is controlled by
       the quit flag. */

    switch(message) {
    case WM_DESTROY:
        if (!quit) quit = true;
        else PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(window_handle, message, param_w, param_l);
}

/* A procedure for getting OpenGL functions and OpenGL or WGL extensions.
   When looking for OpenGL 1.2 and above, or extensions, it uses wglGetProcAddress,
   otherwise it falls back to GetProcAddress. */
void* get_proc(const char *proc_name)
{
    void *proc = (void*)wglGetProcAddress(proc_name);
    if (!proc) proc = (void*)GetProcAddress(gl_module, proc_name);

    return proc;
}

Скомпилирован с g++ GLExample.cpp -lopengl32 -lgdi32 с MinGW / Cygwin или cl GLExample.cpp opengl32.lib gdi32.lib user32.lib с компилятором MSVC. Убедитесь, однако, что заголовки из реестра OpenGL находятся в пути include. Если нет, используйте флаг -I для g++ или /I для cl , чтобы сообщить компилятору, где они находятся.

Создание OpenGL 4.1 с C ++ и Cocoa

Примечание. В этом примере будет некоторый Objective-c. В этом примере мы создадим оболочку для C ++. Поэтому не беспокойтесь об этом.

Сначала запустите Xcode и создайте проект.

введите описание изображения здесь

И выберите приложение Cocoa введите описание изображения здесь

Удалите все источники, кроме файла Info.plist (ваше приложение не будет работать без него)

Создайте 4 новых исходных файла: файл и заголовок Objective-c ++ (я назвал мой MacApp). Класс C ++ (я назвал my (Application)

В левом верхнем углу (с именем проекта) щелкните по нему и добавьте связанные фреймворки и библиотеки. Добавить: OpenGL.Framework AppKit.Framework GLKit.Framework

Вероятно, ваш проект будет выглядеть следующим образом:

введите описание изображения здесь

NSApplication — основной класс, который вы используете при создании приложения MacOS. Это позволяет вам регистрировать окна и захватывать события.

Мы хотим зарегистрировать (наше) окно в NSApplication. Сначала создайте в своем объектно-c ++-заголовке объект-c-класс, который наследует NSWindow и реализует NSApplicationDelegate. NSWindow нуждается в указателе на приложение C ++, OpenGL View и таймер для цикла рисования

//Mac_App_H
#import <Cocoa/Cocoa.h>
#import "Application.hpp"
#import <memory>
NSApplication* application;

@interface MacApp : NSWindow <NSApplicationDelegate>{
    std::shared_ptr<Application> appInstance;
}
@property (nonatomic, retain) NSOpenGLView* glView;
-(void) drawLoop:(NSTimer*) timer;
@end

Мы называем это основным

int main(int argc, const char * argv[]) {
    MacApp* app;
    application = [NSApplication sharedApplication];
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 
    //create a window with the size of 600 by 600   
    app = [[MacApp alloc] initWithContentRect:NSMakeRect(0, 0, 600, 600)              styleMask:NSTitledWindowMask | NSClosableWindowMask |  NSMiniaturizableWindowMask   backing:NSBackingStoreBuffered defer:YES];    
    [application setDelegate:app];
    [application run];
}

Реализация нашего окна на самом деле довольно просто. Сначала мы объявляем с синтезом нашего glview и добавляем глобальную цель-c булевым, когда окно должно закрываться.

#import "MacApp.h"

@implementation MacApp

@synthesize glView;

BOOL shouldStop = NO;

Теперь для конструктора. Я предпочитаю использовать initWithContentRect.

-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag{
if(self = [super initWithContentRect:contentRect styleMask:aStyle backing:bufferingType defer:flag]){
    //sets the title of the window (Declared in Plist)
    [self setTitle:[[NSProcessInfo processInfo] processName]];
 
    //This is pretty important.. OS X starts always with a context that only supports openGL 2.1
    //This will ditch the classic OpenGL and initialises openGL 4.1
    NSOpenGLPixelFormatAttribute pixelFormatAttributes[] ={
        NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
            NSOpenGLPFAColorSize    , 24                           ,
            NSOpenGLPFAAlphaSize    , 8                            ,
            NSOpenGLPFADoubleBuffer ,
            NSOpenGLPFAAccelerated  ,
            NSOpenGLPFANoRecovery   ,
            0
    };

    NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc]initWithAttributes:pixelFormatAttributes];
    //Initialize the view 
    glView = [[NSOpenGLView alloc]initWithFrame:contentRect pixelFormat:format];
    
    //Set context and attach it to the window
    [[glView openGLContext]makeCurrentContext];
  
    //finishing off
    [self setContentView:glView];
    [glView prepareOpenGL];
    [self makeKeyAndOrderFront:self];
    [self setAcceptsMouseMovedEvents:YES];
    [self makeKeyWindow];
    [self setOpaque:YES];

    //Start the c++ code
    appInstance = std::shared_ptr<Application>(new Application());

}
return self;
}

Хорошо … теперь у нас действительно запущенное приложение. Возможно, вы видите черный экран или мерцание.

Давайте начнем рисовать удивительный треугольник. (В c ++)

Мой заголовок приложения

#ifndef Application_hpp
#define Application_hpp
#include <iostream>
#include <OpenGL/gl3.h>
class Application{
private:
    GLuint          program;
    GLuint          vao;
public:
    Application();
    void update();
    ~Application();

};

#endif /* Application_hpp */

Реализация:

Application::Application(){
 static const char * vs_source[] =
    {
        "#version 410 core                                                 n"
        "                                                                  n"
        "void main(void)                                                   n"
        "{                                                                 n"
        "    const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),  n"
        "                                   vec4(-0.25, -0.25, 0.5, 1.0),  n"
        "                                   vec4( 0.25,  0.25, 0.5, 1.0)); n"
        "                                                                  n"
        "    gl_Position = vertices[gl_VertexID];                          n"
        "}                                                                 n"
    };

    static const char * fs_source[] =
    {
        "#version 410 core                                                 n"
        "                                                                  n"
        "out vec4 color;                                                   n"
        "                                                                  n"
        "void main(void)                                                   n"
        "{                                                                 n"
        "    color = vec4(0.0, 0.8, 1.0, 1.0);                             n"
        "}                                                                 n"
    };

    program = glCreateProgram();
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, fs_source, NULL);
    glCompileShader(fs);

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, vs_source, NULL);
    glCompileShader(vs);

    glAttachShader(program, vs);
    glAttachShader(program, fs);

    glLinkProgram(program);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
}

void Application::update(){
    static const GLfloat green[] = { 0.0f, 0.25f, 0.0f, 1.0f };
    glClearBufferfv(GL_COLOR, 0, green);

    glUseProgram(program);
    glDrawArrays(GL_TRIANGLES, 0, 3);
}


Application::~Application(){
    glDeleteVertexArrays(1, &vao);
    glDeleteProgram(program);
}

Теперь нам нужно снова и снова вызывать обновление (если вы хотите что-то переместить). Внедрите в свой класс object-c

-(void) drawLoop:(NSTimer*) timer{

if(shouldStop){
    [self close];
    return;
}
if([self isVisible]){
  
       appInstance->update();
    [glView update];
    [[glView openGLContext] flushBuffer];
}

}

И добавьте этот метод в реализацию вашего класса object-c:

- (void)applicationDidFinishLaunching:(NSNotification *)notification {
    [NSTimer scheduledTimerWithTimeInterval:0.000001 target:self selector:@selector(drawLoop:) userInfo:nil repeats:YES];
}

это вызовет функцию обновления вашего класса c ++ снова и снова (каждые 0,000001 секунд, чтобы быть точным)

Чтобы закончить, мы закрываем окно при нажатии кнопки закрытия:

- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication     *)theApplication{
    return YES;
}

- (void)applicationWillTerminate:(NSNotification *)aNotification{
    shouldStop = YES;
}

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

Создание контекста OpenGL в Cross Platform (с использованием SDL2)

Создание окна с контекстом OpenGL (добавление нагрузки через GLEW ):

#define GLEW_STATIC

#include <GL/glew.h>
#include <SDL2/SDL.h>

int main(int argc, char* argv[])
{
    SDL_Init(SDL_INIT_VIDEO); /* Initialises Video Subsystem in SDL */

    /* Setting up OpenGL version and profile details for context creation */
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
    
    /* A 800x600 window. Pretty! */
    SDL_Window* window = SDL_CreateWindow
        (
        "SDL Context",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        800, 600,
        SDL_WINDOW_OPENGL
        );
    
    /* Creating OpenGL Context */
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);

    /* Loading Extensions */
    glewExperimental = GL_TRUE;
    glewInit();

    /* The following code is for error checking. 
    *  If OpenGL has initialised properly, this should print 1.
    *  Remove it in production code.
    */
    GLuint vertex_buffer;
    glGenBuffers(1, &vertex_buffer);
    printf("%un", vertex_buffer);
    /* Error checking ends here */

    /* Main Loop */
    SDL_Event window_event;
    while(1) {
        if (SDL_PollEvent(&window_event)) {
            if (window_event.type == SDL_QUIT) {
                /* If user is exiting the application */
                break;
            }
        }
        /* Swap the front and back buffer for flicker-free rendering */
        SDL_GL_SwapWindow(window);
    }
    
    /* Freeing Memory */
    glDeleteBuffers(1, &vertex_buffer);
    SDL_GL_DeleteContext(gl_context);
    SDL_Quit();

    return 0;
}

Настройка современного OpenGL 4.1 на macOS (Xcode, GLFW и GLEW)

1. Установите GLFW

Первый шаг — создать окно OpenGL. GLFW — это библиотека с открытым исходным кодом, многоплатформенная библиотека для создания окон с OpenGL, для установки GLFW сначала загружайте свои файлы с сайта www.glfw.org

Веб-страница GLFW

Извлеките папку GLFW, и ее содержимое будет выглядеть следующим образом:

Содержимое папки GLFW

Загрузите и установите CMake для сборки GLFW. Перейти на www.cmake.org/download/ , загрузить CMake и установить для MAC OS X

Веб-страница загрузки

Если Xcode не установлен. Загрузите и установите Xcode из Mac App Store.

Xcode из Mac App Store

Создание новой папки Создание внутри папки GLFW

Папка GLFW после создания папки «Build»

Откройте CMake, нажмите кнопку « Обзор источника» , чтобы выбрать папку GLFW (убедитесь, что CMakeLists.txt) находится внутри этой папки. После этого нажмите кнопку « Обзор сборки» и выберите новую созданную папку « Создать » на предыдущем шаге.

Пути CMake

Теперь нажмите кнопку « Настроить» и выберите «Генератор Xcode как генератор» с параметром « Использовать стандартные компиляторы» и нажмите « Готово» .

Makefile для Xcode

Отметьте опцию BUILD_SHARED_LIBS, а затем снова нажмите кнопку « Настроить» и, наконец, нажмите кнопку « Создать» .

Выберите BUILD_SHARED_LIBS

После поколения CMake должно выглядеть так

Заключительный CMake

Теперь Open Finder и goto / usr , создайте локальное имя папки, если оно еще не существует. Откройте локальную папку и создать две папки включают в себя и Lib , если уже не там.

Теперь откройте папку GLFW и goto Build (где CMake создал файлы). Откройте файл GLFW.xcodeproj в Xcode.

Файл проекта Xcode

Выберите « Установить»> «Мой Mac», а затем нажмите « Запустить» (кнопка «Форма игры»).

Установка GLFW

Теперь он успешно установлен (игнорируйте предупреждения).

Чтобы убедиться, что Open Finder и папка goto / usr / local / lib и три библиотеки библиотеки GLFW уже присутствуют там (если нет, то откройте папку « Сборка » внутри папки GLFW и перейдите в src / Debug, скопируйте все файлы в / usr / local / lib )

Файлы GLFW Lib

Open Finder и goto / usr / local / include и папка GLFW будут присутствовать там с двумя файлами заголовков внутри него по имени glfw3.h и glfw3native.h

Файлы заголовков GLFW

2. Установите GLEW

GLEW — это кросс-платформенная библиотека, которая помогает в поиске и загрузке расширений OpenGL. Он предоставляет механизмы времени выполнения для определения, какие расширения OpenGL поддерживаются на целевой платформе. Это только для современного OpenGL (OpenGL версии 3.2 и выше, который требует определения функций во время выполнения). Чтобы установить первую загрузку своих файлов с glew.sourceforge.net

Веб-страница GLEW

Извлеките папку GLFW, и ее содержимое будет выглядеть так.

Содержимое папки GLEW

Теперь откройте терминал, перейдите в папку GLEW и введите следующие команды

make
sudo make install 
make clean

Теперь GLEW успешно установлен. Чтобы убедиться, что его установленный, Open Finder, перейдите в каталог / usr / local / include, и в нем будет присутствовать папка GL с тремя файлами заголовков внутри нее по имени glew.h , glxew.h и wglew.h

Файлы заголовков GLEW

Откройте Finder и перейдите в / usr / local / lib, и файлы библиотеки GLEW будут уже присутствовать там

Файлы библиотеки GLEW

3. Тестирование и запуск

Теперь мы успешно установили GLFW и GLEW. Его время кодировать. Откройте Xcode и создайте новый проект Xcode. Выберите « Инструмент командной строки», затем выполните следующие действия и выберите язык C ++ .

Проект Xcode

Xcode создаст новый проект командной строки.

Нажмите на название проекта, а на вкладке « Параметры сборки» выберите « Базовый для всех» в разделе « Пути поиска », добавьте / usr / local / include в пути поиска заголовков и добавьте / usr / local / lib в пути поиска библиотеки

Пути поиска

Нажмите на название проекта, а на вкладке « Сборка фаз » и в разделе « Связывание с бинарными библиотеками» добавьте OpenGL.framework, а также добавьте недавно созданные библиотеки GLFW и GLEW из / usr / local / lib

Связать бинарники

Теперь мы готовы кодировать в Modern Open GL 4.1 на macOS, используя C ++ и Xcode. Следующий код создаст окно OpenGL, используя GLFW с выводом пустого экрана.

#include <GL/glew.h> 
#include <GLFW/glfw3.h>

// Define main function
int main() 
{
    // Initialize GLFW
    glfwInit();

    // Define version and compatibility settings
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 
    glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

    // Create OpenGL window and context
    GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
    glfwMakeContextCurrent(window);

    // Check for window creation failure
    if (!window) 
    {
        // Terminate GLFW
        glfwTerminate();
        return 0; 
    }

    // Initialize GLEW
    glewExperimental = GL_TRUE; glewInit();

    // Event loop
    while(!glfwWindowShouldClose(window)) 
    {
        // Clear the screen to black
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);
        glfwPollEvents(); 
    }

    // Terminate GLFW
    glfwTerminate(); return 0;
}

Пустое окно OpenGL

Создать контекст Opengl с Java и LWJGL 3.0

В этом примере кода мы создадим пустое окно Opengl с использованием LWJGL 3.0+, это не содержит шагов для создания проекта в вашей среде IDE

введите описание изображения здесь

  1. Создайте имя класса WindowManager, который будет содержать весь код плиты котла для создания окна контекста opengl на экране

WindowManager.java

import org.lwjgl.glfw.*;
import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;

/**
 * Class Containing code related to inflating Opengl Window
 */
public class Displaymanager {

    private static long window;

    public static void createDisplay(){
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialize GLFW. Most GLFW functions will not work before doing this.
        if ( !glfwInit() )
            throw new IllegalStateException("Unable to initialize GLFW");

        // Configure our window
        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

        int WIDTH = 300;
        int HEIGHT = 300;

        // Create the window
        window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("Failed to create the GLFW window");

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                glfwSetWindowShouldClose(window, true); // We will detect this in our rendering loop
        });

        // Get the resolution of the primary monitor
        GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        // Center our window
        glfwSetWindowPos(
                window,
                (vidmode.width() - WIDTH) / 2,
                (vidmode.height() - HEIGHT) / 2
        );

        // Make the OpenGL context current
        glfwMakeContextCurrent(window);
        // Enable v-sync
        glfwSwapInterval(1);

        // Make the window visible
        glfwShowWindow(window);
    }

    public static boolean isCloseRequested(){
        return glfwWindowShouldClose(window);
    }

    public static void updateDisplay(){
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer

        glfwSwapBuffers(window); // swap the color buffers

        // Poll for window events. The key callback above will only be
        // invoked during this call.
        glfwPollEvents();
    }

    public static void destroyDisplay(){
        // Terminate GLFW and free the error callback
        cleanUp();
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private static void cleanUp() {
        // Free the window callbacks and destroy the window
        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);
    }
}
  1. Затем создайте класс, содержащий основной цикл рендеринга, который вызовет все указанные выше функции

OpenGlMain.java

import org.lwjgl.opengl.GL;
import renderEngine.Displaymanager;
import static org.lwjgl.opengl.GL11.glClearColor;


/**
 * Class to test the opengl Window
 */
public class OpenGlMain {

    public static void main(String[] args) {

        Displaymanager.createDisplay();

        // This line is critical for LWJGL's interoperation with GLFW's
        // OpenGL context, or any context that is managed externally.
        // LWJGL detects the context that is current in the current thread,
        // creates the GLCapabilities instance and makes the OpenGL
        // bindings available for use.
        GL.createCapabilities();

        while (!Displaymanager.isCloseRequested()){

            // Set the clear color
            glClearColor(1.0f, 0.0f, 0.0f, 0.0f);

            Displaymanager.updateDisplay();
        }

        Displaymanager.destroyDisplay();
    }
}

Для получения дополнительной информации официальный представитель LWJGL Guide

#include <GL/glut.h>

#include<iostream>

using namespace std;

int rx = 100, ry = 125;

int xCenter = 250, yCenter = 250;

void myinit(void)

{

    glClearColor(1.0, 1.0, 1.0, 0.0);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    gluOrtho2D(0.0, 640.0, 0.0, 480.0);

}

void setPixel(GLint x, GLint y)

{

    glBegin(GL_POINTS);

    glVertex2i(x, y);

    glEnd();

}

void ellipseMidPoint()

{

    float x = 0;

    float y = ry;

    float p1 = ry * ry - (rx * rx) * ry + (rx * rx) * (0.25);

    float dx = 2 * (ry * ry) * x;

    float dy = 2 * (rx * rx) * y;

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (dx < dy)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p1 < 0)

        {

            x = x + 1;

            dx = 2 * (ry * ry) * x;

            p1 = p1 + dx + (ry * ry);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dx = 2 * (ry * ry) * x;

            dy = 2 * (rx * rx) * y;

            p1 = p1 + dx - dy + (ry * ry);

        }

    }

    glFlush();

    float p2 = (ry * ry) * (x + 0.5) * (x + 0.5) + (rx * rx) * (y

        - 1) * (y - 1) - (rx * rx) * (ry * ry);

    glColor3ub(rand() % 255, rand() % 255, rand() % 255);

    while (y > 0)

    {

        setPixel(xCenter + x, yCenter + y);

        setPixel(xCenter - x, yCenter + y);

        setPixel(xCenter + x, yCenter - y);

        setPixel(xCenter - x, yCenter - y);

        if (p2 > 0)

        {

            x = x;

            y = y - 1;

            dy = 2 * (rx * rx) * y;

            p2 = p2 - dy + (rx * rx);

        }

        else

        {

            x = x + 1;

            y = y - 1;

            dy = dy - 2 * (rx * rx);

            dx = dx + 2 * (ry * ry);

            p2 = p2 + dx -

                dy + (rx * rx);

        }

    }

    glFlush();

}

void display()

{

    glClear(GL_COLOR_BUFFER_BIT);

    glColor3f(1.0, 0.0, 0.0);

    glPointSize(2.0);

    ellipseMidPoint();

    glFlush();

}

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitWindowSize(640, 480);

    glutInitWindowPosition(10, 10);

    glutCreateWindow("User_Name");

    myinit();

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;

}

Понравилась статья? Поделить с друзьями:
  • Как изменить настройки nfs heat
  • Как изменить настройки nat тип nat на открытый
  • Как изменить настройки nat на windows 10
  • Как изменить настройки mysql
  • Как изменить настройки media player