Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
калачева перевод.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
237.97 Кб
Скачать

Блоки In/Out

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

Например, вершинный шейдер выводит данные:

out Lighting {

vec3 normal;

vec2 bumpCoord;

};

Эти данные совпадают с данными ввода фрагментарного шейдера:

in Lighting {

vec3 normal;

vec2 bumpCoord;

};

Данные вывода вершинного шейдера, помеченные material и lighting, каждые сгруппированы в свой блок. Интерфейсы, встроенные в OpenGL Shading Language, также представлены в виде блоков, как например, gl_PerVertex, в котором есть встроенная переменная gl_Positions, помимо прочих. Полный список этих блоков находится в Appendix C

Компилирование шейдеров

Написание шейдеров для OpenGL схоже с использованием языка “С”, основанного на компиляции. Вы задаете компилятору анализировать ваше программу, проверить на ошибки, а потом перевести ее в код объектов. Далее, вы объединяете набор объектов вместе в фазе привязки, для создания выполняемой программы. Использование GLSL шейдеров в вашей программе - схожий процесс, за тем лишь исключением, что компилятор и компоновщик оба являются частью API OpenGL.

Диаграмма 2.1 показывает шаги по созданию объекта шейдера GLSL и привязки его к исполняемой программе шейдера.

[картинка]

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

Для каждого объекта:

  1. Создать объект шейдера.

  2. Компилировать код вашего шейдера в объект.

  3. Проверить, успешно ли компилируется ваш шейдер.

Затем, для привязки нескольких объектов шейдера в программу, нужно:

  1. Создать программу шейдера.

  2. Прикрепить соответствующий объект шейдреа к программе шейдера.

  3. Привязать программу шейдера.

  4. Убедиться, что стадия привязки прошла успешно.

  5. Использовать шейдер для обработки вершин или фрагментов.

Зачем создавать несоклько объектов шейдера? Точно так же, как можно повторно использовать функцию и другой программе, можно поступить и с программой GLSL. Общие процедуры, которые вы пишете, могут быть использованы в других шейдерах. Вместо того, чтобы писать несколько тяжелых программ шейдинга, использующих отрывки общего кода, вам понадобится лишь отослать шейдер к соответствующему объекту шейдера.

Для создания объекта шейдера запросите glCreateShader().

GLuint glCreateShader(GLenum type);

Allocates a shader object. type must be one of GL_VERTEX_SHADER,

GL_FRAGMENT_SHADER, GL_TESS_CONTROL_SHADER,

GL_TESS_EVALUATION_SHADER, or GL_GEOMETRY_SHADER. The

return value is either a nonzero integer or zero if an error occurred.

Когда вы закончите создание объекта шейдера, вам нужно будет ассоциировать исходный код шейдера с этим объектом, созданным glCreateShader(). Это делается вызовом glSHaderSource().

glShaderSource(GLuint shader, GLsizei count,

const GLchar **string, const GLint *length);

Associates the source of a shader with a shader object shader. string is an

array of count GLchar strings that compose the shader’s source. The

character strings in string may be optionally null-terminated. length can

be one of three values. If length is NULL, then it’s assumed that each

string provided in string is null-terminated. Otherwise, length has count

elements, each of which specifies the length of the corresponding entry

in string. If the value of an element in the array length is a positive

integer, the value represents the number of characters in the

corresponding string element. If the value is negative for particular

elements, then that entry in string is assumed to be null-terminated

Для компиляции кода объекта шейдера используйте glCompileshader().

void glCompileShader(GLuint shader);

Compiles the source code for shader. The results of the compilation can

be queried by calling glGetShaderiv() with an argument of

GL_COMPILE_STATUS.

По тому же принципу, что и компиляция программы на “С”, вам нужно убедиться, что компиляция пойдет успешно. Запрос к glGetShaderiv() с поправкой GL_COMPILE_STATUS возвращает статус фазы компиляции. Если приходит GL_TRUE, значит компиляция удалась, и объект можно привязать к программе. Если компиляция не удалась, вы можете определить, какая ошибка тому помешала, запросив лог компиляции. glGetSharedInfoLog() выдаст сообщения по использованию с записью ошибок компиляции. Текущий размер лога ошибок может быть запрошен вызовом glGetShaderiv() с поправкой GL_INFO_LOG_LENGTH.

"> void glGetShaderInfoLog(GLuint shader, GLsizei bufSize,

GLsizei *length, char *infoLog);

Returns the log associated with the last compilation of shader. The log is

returned as a null-terminated character string of length characters in the

buffer infoLog. The maximum return size of the log is specified in bufSize.

If length is NULL, infoLog’s length is not returned.

Когда вы создали и скомпилировали все необходимые объекты шейдеров, вам нужно будет привязать их для создания выполняемой программы шейдера. Это процесс схожий с созданием самих объектов ешйдера. Сначала вам нужно создать программу шейдера, к которой вы можете прикрепить объекты. Используя glCreateProgramm(), вы получите программу для дальнейшей с ней работы.

GLuint glCreateProgram(void);

Creates an empty shader program. The return value is either a n

integer, or zero if an error occurred.

Когда вы получите свою программу шейдера, вам нужно будет заполнить её необходимыми объектами шейдера, для создания исполняемой программы. Это сопровождается прикреплением объектов шейдера к программе посредством вызова glAttachShader()

void glAttachShader(GLuint program, GLuint shader);

Associates the shader object, shader, with the shader program, program. A

shader object can be attached to a shader program at any time, although

its functionality will only be available after a successful link of the shader

program. A shader object can be attached to multiple shader programs

simultaneously

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

void glDetachShader(GLuint program, GLuint shader);

Removes the association of a shader object, shader, from the shader

program, program. If shader is detached from program and had been

previously marked for deletion (by calling glDeleteShader()), it is deleted

at that time.

После того, как все необходимые объекты шейдера были прикреплены к программе, вам привязать их к исполняемой программе. Это делается вызовом glLinkProgram().

void glLinkProgram(GLuint program);

Processes all shader objects attached to program to generate a completed

shader program. The result of the linking operation can be queried by

calling glGetProgramiv() with GL_LINK_STATUS. GL_TRUE is returned

for a successful link; GL_FALSE is returned otherwise.

Также как с объектами шейдеров, есть вероятность, что эта фаза не пройдет успешно из-за ошибок в привязанных объектах. Вы можете запросить результат операции привязки вызовом glGetProgramiv() с поправкой GET_LINK_STATUS. Если ответ будет в форме GL_TRUE, то операция прошла успешно, и вы можете определить шейдер для обработки вершин и фрагментов. Если привзяка не была успешной, придет ответ GL_FALSE. Вы можете определить причину ошибки запросом glGetProgramInfoLog()

void glGetProgramInfoLog(GLuint program, GLsizei bufSize,

GLsizei *length, char *infoLog);

Returns the log associated with the last compilation of program. The log

is returned as a null-terminated character string of length characters in

the buffer infoLog. The maximum return size of the log is specified in

bufSize. If length is NULL, infoLog’s length is not returned.

После успешной привязки программы, вы можете запустить вершинный или фрагментарный шейдер вызовом glUseProgram() с дескриптором программы.

void glUseProgram(GLuint program);

Use the linked shader program program. If program is zero, any shaders

currently in use are unbound. OpenGL’s operation is undefined if no

shader is bound, but no error is generated.

While a program is in use, it can have new shader objects attached to it,

or detach previously attached objects. It may also be relinked. If the link

phase is successful, the newly linked shader program replaces the

previously active program. If the link fails, the currently bound shader

program remains active and is not replaced until either a new program is

specified with glUseProgram() or the program is successfully relinked.

Когда вы закончите работу с объектом шейдера,вы можете удалить его командой glDeleteShader(), даже если он прикреплен к активной программе. Также как с привязкой программы в “С”, когда у вас готово исполняемое приложение, вам больше не нужны объекты до тех пор, пока вы не повторите компиляцию.

void glDeleteShader(GLuint shader);

Deletes shader. If shader is currently linked to one or more active shader

programs, the object is tagged for deletion and deleted once the shader

program is no longer being used by any shader program.

Также, когда вы закончите с программой шейдера, вы можете её удалить через glDeleteProgram()

void glDeleteProgram(GLuint program);

Deletes program immediately if not currently in use in any context, or

schedules program for deletion when the program is no longer in use by

any contexts.

Наконец, для полного завершения вы также можете запросить, использыется ли имя файла каким-нибудь объектом шейдера, запросив glIsShader(), или для программы шейдера glIsProgram():

GLboolean glIsShader(GLuint shader);

Returns GL_TRUE if shader is the name of a shader object that was

previously generated with glCreateShader(), but has not been

subsequently deleted. Returns GL_FALSE if shader is zero or a nonzero

value that is not the name of a shader object.

GLboolean glIsProgram(GLuint program);

Returns GL_TRUE if program is the name of a program object that was

previously generated with glCreateProgram(), but has not been

subsequently deleted. Returns GL_FALSE if program is zero or a nonzero

value that is not the name of a program object.