Крім того, у нас є заздалегідь визначений gl_FragColor.
Почнемо з цього. Ні, у вас немає попередньо визначеного gl_FragColor
. Це було видалено з ядра OpenGL 3.1 і вище. Якщо ви не використовуєте сумісність (у цьому випадку ваші шейдери 3,30 повинні писати #version 330 compatibility
вгорі), ви ніколи не повинні використовувати це.
Тепер повернемося до визначених користувачем виходів шейдерів фрагментів. Але спочатку швидка аналогія.
Пам'ятайте, як у вершинних шейдерах ви маєте вхідні дані? І ці входи є вершину індексів атрибутів, число Проходьте glVertexAttribPointer
і glEnableVertexAttribArray
так далі? Ви встановлюєте, який вхід витягує з якого атрибута. У GLSL 3.30 ви використовуєте такий синтаксис:
layout(location = 2) in color;
Це встановлює введення color
вершинного шейдера з місця розташування атрибутів 2. До 3.30 (або без ARB_explicit_attrib_location) вам доведеться або налаштувати це явно, glBindAttrbLocation
перед зв’язуванням, або запитати програму для індексу атрибутів glGetAttribLocation
. Якщо ви явно не вказали розташування атрибута, GLSL призначить місце довільно (тобто: визначеним реалізацією способом).
Встановлення його в шейдері майже завжди є кращим варіантом.
У будь-якому випадку виходи фрагментних шейдерів працюють майже точно так само. Шейдери фрагментів можуть писати на кілька вихідних кольорів , які самі потрапляють у кілька буферів в буфері кадрів . Отже, вам потрібно вказати, який вихід надходить на який фрагмент виводить колір.
Цей процес починається зі значення розташування вихідного фрагмента. Він встановлений дуже подібно до місць введення вершинного шейдера:
layout(location = 1) out secColor;
Є також функції API glBindFragDataLocation
та glGetFragDataLocation
, які є аналогами glBindAttribLocation
та glGetAttribLocation
.
Якщо ви не виконуєте жодних явних присвоєнь, реалізації зазвичай призначають одну з ваших вихідних змінних розташуванню 0. Однак стандарт OpenGL не вимагає такої поведінки, тому ви також не повинні залежати від неї.
Тепер , щоб бути справедливим, ваша програма повинна не вдалося в зв'язку , коли ви використовували два виходи, які не отримують в різних місцях виходу. Напевно, сталося так, що ваш компілятор оптимізував той, який ви не записали, тому він начебто забув про нього, коли прийшов час перевірити помилки компонувальника.