Новости
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 получаются с помощью указателей функций. Общая процедура:
- Как-то получить типы указателей функций (по существу, прототипы функций)
- Объявите каждую функцию, которую мы хотели бы использовать (с ее указателем на функцию)
- Получить фактическую функцию
Например, рассмотрим 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, и ее содержимое будет выглядеть следующим образом:
Загрузите и установите CMake для сборки GLFW. Перейти на www.cmake.org/download/ , загрузить CMake и установить для MAC OS X
Если Xcode не установлен. Загрузите и установите Xcode из Mac App Store.
Создание новой папки Создание внутри папки GLFW
Откройте CMake, нажмите кнопку « Обзор источника» , чтобы выбрать папку GLFW (убедитесь, что CMakeLists.txt) находится внутри этой папки. После этого нажмите кнопку « Обзор сборки» и выберите новую созданную папку « Создать » на предыдущем шаге.
Теперь нажмите кнопку « Настроить» и выберите «Генератор Xcode как генератор» с параметром « Использовать стандартные компиляторы» и нажмите « Готово» .
Отметьте опцию BUILD_SHARED_LIBS, а затем снова нажмите кнопку « Настроить» и, наконец, нажмите кнопку « Создать» .
После поколения CMake должно выглядеть так
Теперь Open Finder и goto / usr , создайте локальное имя папки, если оно еще не существует. Откройте локальную папку и создать две папки включают в себя и Lib , если уже не там.
Теперь откройте папку GLFW и goto Build (где CMake создал файлы). Откройте файл GLFW.xcodeproj в Xcode.
Выберите « Установить»> «Мой Mac», а затем нажмите « Запустить» (кнопка «Форма игры»).
Теперь он успешно установлен (игнорируйте предупреждения).
Чтобы убедиться, что Open Finder и папка goto / usr / local / lib и три библиотеки библиотеки GLFW уже присутствуют там (если нет, то откройте папку « Сборка » внутри папки GLFW и перейдите в src / Debug, скопируйте все файлы в / usr / local / lib )
Open Finder и goto / usr / local / include и папка GLFW будут присутствовать там с двумя файлами заголовков внутри него по имени glfw3.h и glfw3native.h
2. Установите GLEW
GLEW — это кросс-платформенная библиотека, которая помогает в поиске и загрузке расширений OpenGL. Он предоставляет механизмы времени выполнения для определения, какие расширения OpenGL поддерживаются на целевой платформе. Это только для современного OpenGL (OpenGL версии 3.2 и выше, который требует определения функций во время выполнения). Чтобы установить первую загрузку своих файлов с glew.sourceforge.net
Извлеките папку GLFW, и ее содержимое будет выглядеть так.
Теперь откройте терминал, перейдите в папку GLEW и введите следующие команды
make
sudo make install
make clean
Теперь GLEW успешно установлен. Чтобы убедиться, что его установленный, Open Finder, перейдите в каталог / usr / local / include, и в нем будет присутствовать папка GL с тремя файлами заголовков внутри нее по имени glew.h , glxew.h и wglew.h
Откройте Finder и перейдите в / usr / local / lib, и файлы библиотеки GLEW будут уже присутствовать там
3. Тестирование и запуск
Теперь мы успешно установили GLFW и GLEW. Его время кодировать. Откройте Xcode и создайте новый проект Xcode. Выберите « Инструмент командной строки», затем выполните следующие действия и выберите язык C ++ .
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 с Java и LWJGL 3.0
В этом примере кода мы создадим пустое окно Opengl с использованием LWJGL 3.0+, это не содержит шагов для создания проекта в вашей среде IDE
- Создайте имя класса 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);
}
}
- Затем создайте класс, содержащий основной цикл рендеринга, который вызовет все указанные выше функции
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;
}