Opengl шейдери
Блоговая публікація користувача: Flashhell Ця публікація була перенесена з особистого блога користувача в загальні розділи уровок сайту.
OpenGL шейдери. Простий шейдер на GLSL
Йтиметься про GLSL шейдерах, хоча GLSL не єдиний шейдерний мову, який може працювати з OpenGL. З OpenGL можна також використовувати шейдери на Cg (C for Graphics).
Примітка: для їх використання потрібна додаткова бібліотека Cg (від NVidia).
GLSL (OpenGL Shading Language) - мова високого рівня для програмування шейдеров. Синтаксис мови базується на мові програмування ANSI C. однак, через його специфічної спрямованості з нього були виключені багато можливостей. Це було зроблено для спрощення мови і підвищення продуктивності. У мову включені додаткові функції і типи даних, наприклад, для роботи з векторами і матрицями. GLSL повністю став частиною OpenGL в версії 2.0.
- Верховий шейдер - замінює частину графічного конвеєра, що виконує перетворення, пов'язані з даними вершин. Такі як множення вершин і нормалей на матрицю проекції і моделювання, установка квітів вершин, установка матеріалів освітлення. Він працює для кожної відмалювати вершини. Обов'язковою роботою для вершинного шейдера є запис позиції вершини, в вбудовану змінну gl_Position.
- Геометричний шейдер - шейдер, здатний обробити не тільки одну вершину, а й цілий примітив. Він може або відкинути (від обробки) примітиви, або створити нові, тобто геометричний шейдер здатний генерувати примітиви. А також здатний змінювати тип вхідних примітивів (геометричний шейдер повністю увійшов в OpenGL в версії 3.2).
- Фрагментний шейдер - замінює частину графічного ковейера (ГК), обробляючи кожен отриманий на попередніх стадіях ГК фрагмент (НЕ піксель). Обробка може включати такі стадії, як отримання даних з текстури, прорахунок освітлення, прорахунок змішування. Обов'язковою роботою для фрагментного шейдера є запис кольору фрагмента у вбудовану змінну gl_FragColor або його відкидання спеціальної командою discard. У разі відкидання фрагмента, ніякі розрахунки далі з ним проводитися не будуть, і фрагмент вже не потрапить в буфер кадру.
Завантаження і компіляція
GLSL -шейдери прийнято зберігати в вигляді вихідних кодів (хоча в OpenGL 4.1 і з'явилася можливість завантажувати шейдери у вигляді бінарних даних). Такий підхід був використаний для кращої переносимості шейдеров на різні апаратні і програмні платформи. Тексти програм компілюються драйвером. Вони можуть бути скомпільовані лише після створення діючого контексту OpenGL. Драйвер сам генерує всередині себе оптимальний двійковий код, який розуміє дане устаткування. Це гарантує, що один і той же шейдер буде правильно і ефективно працювати на різних платформах.
Вихідний код може бути представлений у вигляді ANSI -строк, що завершуються перенесенням рядка ( '\ n') або без нього. У випадку якщо перенесення немає, потрібно передати масив довжин кожного рядка.
- Спочатку виділяються ідентифікатори у вигляді GLuint. під шейдери - glCreateShader. а під шейдерну програму - glCreateProgram.
- На ідентифікатор шейдера завантажується вихідний код, який передається драйверу glShaderSource.
- Після цього шейдер компілюється glCompileShader.
- Кілька шейдеров різних типів прикріплюються до програми glAttachShader
- Останній крок - лінкування прикріплених шейдеров в одну шейдерну програму glLinkProgram.
Ми будемо використовувати верховий і Фрагментний шейдери, так як без них в сучасних версіях OpenGL нічого не намалюєш. Решта типів шейдеров поки розглядати не будемо, так їх немає в OpenGL 2.0, і вони не є обов'язковими в OpenGL 3.3 і вище.