Array ( )
Вход:




Главная | OpenGL | GLSL | AI | Сеть | Примеры | Библиотека

GLSL: Коммуникация OGL-GLSL: Attribute-переменные






Как указано в предыдущем разделе, Uniform-переменные не могут использоватся в блоках glBegin/glEnd.

Если необходимо присваивать переменные каждой вершине, должны использоватся Attribute-переменные.
Фактически эти переменные могут быть обновлены в любое время. Attribute-переменные могут быть
прочитаны (не перезаписаны) только вершинным шейдером, так как содержат данные вершин. Как и с
Uniform-переменными, сначала необходимо получить адрес переменной в памяти. Учтите, что программа должна
быть предварительно слинкована, и некоторые драйверы могут потребовать, чтобы программа уже использовалась.

В OpenGL 2.0 используйте следующие функции:
GLint glGetAttribLocation(GLuint program,char *name);

// Параметры:

//    program - Дескриптор программы
//    name - Имя переменной



Синтаксис шейдерных расширений ARB:
GLint glGetAttribLocationARB(GLhandleARB program,char *name);

// Параметры:

//    program - Дескриптор программы
//    name - Имя переменной



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

Синтаксис OpenGL 2.0:
void glVertexAttrib1f(GLint location, GLfloat v0);
void glVertexAttrib2f(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3f(GLint location, GLfloat v0, GLfloat v1,GLfloat v2);
void glVertexAttrib4f(GLint location, GLfloat v0, GLfloat v1,,GLfloat v2, GLfloat v3);

or

GLint glVertexAttrib{1,2,3,4}fv(GLint location, GLfloat *v);

// Параметры

//    location - Вычисленный до этого адрес в памяти
//    v0,v1,v2,v3 - float-значения.
//    v - массив float-ов.



Синтаксис расширений ARB:
void glVertexAttrib1fARB(GLint location, GLfloat v0);
void glVertexAttrib2fARB(GLint location, GLfloat v0, GLfloat v1);
void glVertexAttrib3fARB(GLint location, GLfloat v0, GLfloat v1,GLfloat v2);
void glVertexAttrib4fARB(GLint location, GLfloat v0, GLfloat v1,,GLfloat v2, GLfloat v3);

or

GLint glVertexAttrib{1,2,3,4}fvARB(GLint location, GLfloat *v);

// Параметры

//    location - Вычисленный до этого адрес в памяти
//    v0,v1,v2,v3 - float-значения.
//    v - массив float-ов.




Такое же семейство функций назначено для типа данных int и других.


Теперь маленький пример. Вершинный шейдер обьявляет переменную float под названием "height".
Фаза установки после линковки программы:
loc = glGetAttribLocation(p,"height");


В функции рендеринга код должен быть примерно таким:
    glBegin(GL_TRIANGLE_STRIP);

        glVertexAttrib1f(loc,2.0);
        glVertex2f(-1,1);

        glVertexAttrib1f(loc,2.0);
        glVertex2f(1,1);

        glVertexAttrib1f(loc,-2.0);
        glVertex2f(-1,-1);

        glVertexAttrib1f(loc,-2.0);
        glVertex2f(1,-1);

    glEnd();


Маленький рабочий пример:
[a=http://masandilov.ru/coding/sources/glutglsl3.zip:a]Синтаксис расширений ARB
[a=http://masandilov.ru/coding/sources/glutglsl3_2.0.zip:a]Синтексис OpenGL 2.0



Также возможно использовать Attribute-переменные с массивами вершин. Первое, что надо делать
- включить массивы.
Синтаксис OpenGL 2.0:
void glEnableVertexAttribArray(GLint loc);

// Параметр:

//    loc - адрес переменной


Синтаксис ARB:
void glEnableVertexAttribArrayARB(GLint loc);

// Параметр:

//    loc - адрес переменной


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

OpenGL 2.0:
void glVertexAttribPointer(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);

// Параметры:

//    loc - Адрес переменной
//    size - число компонентов на один элемент. Напр.: 1 для float, 2 для vector2, 3 для vector2 и т.п.
//    type - ассоциированный тип данных: GL_FLOAT например.
//    normalized - При установке в 1 данные будут нормализованы, преобразованы в от -1 до 1 для signed и
//                 от 0 до 1 - для unsigned
//    stride - Шаг между элементами
//    pointer - Указатель на массив данных



Синтаксис расширений ARB:
void glVertexAttribPointerARB(GLint loc, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);

//    loc - Адрес переменной
//    size - число компонентов на один элемент. Напр.: 1 для float, 2 для vector2, 3 для vector2 и т.п.
//    type - ассоциированный тип данных: GL_FLOAT например.
//    normalized - При установке в 1 данные будут нормализованы, преобразованы в от -1 до 1 для signed и
//                 от 0 до 1 - для unsigned
//    stride - Шаг между элементами
//    pointer - Указатель на массив данных





А теперь немного кода. Сначала - инициализация. Представлено два массива, вершин и аттрибутов. Переменная
heights обьявлена в глобальном пространстве, так что доступна и в этом куске кода, и в момент рендера.

    float vertices[8] = {-1,1, 1,1, -1,-1, 1,-1};
    float heights[4] = {2,2,-2,-2};
   
    ...
   
    loc = glGetAttribLocationARB(p,"height");

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableVertexAttribArrayARB(loc);

    glVertexPointer(2,GL_FLOAT,0,vertices);
    glVertexAttribPointerARB(loc,1,GL_FLOAT,0,0,heights);



Процесс рендера - точно такой же, как и без шейдеров: просто вызывайте, например, glDrawArrays().
Маленький демонстрационный исходный код:
[a=http://masandilov.ru/coding/sources/glutglsl4.zip:a]Расширения ARB
[a=http://masandilov.ru/coding/sources/glutglsl4_2.0.zip:a]OpenGL 2.0










Комментарии:

Войдите, чтобы оставить комментарий:












Яндекс.Метрика
 Яндекс цитирования.