Array ( )
Вход:




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

GLSL: Практика: цветовой шейдер






У GLSL есть доступ к части функционала OpenGL. В этом уроке я покажу, как получить доступ
к переменным цвета, установленным в OpenGL с помощью glColor.

В GLSL есть attribute-переменная, предназначенная для хранения текущего цвета. Кроме того GLSL
предоставляет varying-переменные для получения цвета пикселным шейдером от вершинного шейдера.

attribute vec4 gl_Color;

varying vec4 gl_FrontColor; // перезаписываемо вершинным шейдером
varying vec4 gl_BackColor; // перезаписываемо вершинным шейдером

varying vec4 gl_Color; // читаемо пикселным шейдером

Смысл в следующем:

1. Приложение OpenGL посылает цвет, использую glColor.
2. Вершинный шейдер получает его в attribute-переменную gl_Color
3. Вершинный шейдер рассчитывает передние и задние цвета полигонов
и записывает их в gl_FrontColor и gl_BackColor соответственно.
4. Пикселный шейдер получает интерполированные значения в varying-переменную
glColor в зависимости от ориентации текущего примитива.
5. Пикселный шейдер устанавливает gl_FragColor, основываясь на значении gl_Color

Это исключение из правила, в котором varying-переменная должна быть обьявлена в обоих шейдерах
с одинаковым именем. Смысл в том, что у вершинного шейдера есть 2 переменные цвета, gl_FrontColor
и gl_BackColor, и они используются для автоматического рассчета gl_Color в зависимости от
ориентации полигона. Заметьте, что конфликт между attribute-переменной gl_Color и varying-переменной
gl_Color не возникает, так как первая видна только в вершинном шейдере, а вторая - в пикселном.





Итак, код вершинного шейдера, в котором вычисляется только цвет передней стороны полигона:
void main()
{
    gl_FrontColor = gl_Color;

    gl_Position = ftransform();
}


Пикселный шейдер тоже очень прост:
void main()
{  
    gl_FragColor = gl_Color;
}




Создайте два файла: color.vert и color.frag и занесите в них этот код соответственно.

Остальной код возьмите из [a=http://masandilov.ru/glsl/glsl-practic-helloworld:a]предыдущего урока, будем
его модифицировать.
Файл main.cpp:
////////////////////////////////////////////////////////////////
//
// Изменим обьявление переменных; одну уберём, одну добавим:

GLuint v,f,f2,p;
GLint loc;
float a = 0;


////////////////////////////////////////////////////////////
//
//   Новая функция: создаёт куб
//
////////////////////////////////////////////////////////////
void drawCube() {

    float hd = 1.0;

    glColor3f(1,0,0);
    glBegin(GL_QUADS);
        glVertex3f(-hd,-hd,-hd);
        glVertex3f(-hd,hd,-hd);
        glVertex3f(hd,hd,-hd);
        glVertex3f(hd,-hd,-hd);
    glEnd();

    glColor3f(1,1,0);
    glBegin(GL_QUADS);
        glVertex3f(-hd,-hd,-hd);
        glVertex3f(hd,-hd,-hd);
        glVertex3f(hd,-hd,hd);
        glVertex3f(-hd,-hd,hd);
    glEnd();

    glColor3f(1,0,1);
    glBegin(GL_QUADS);
        glVertex3f(-hd,-hd,-hd);
        glVertex3f(-hd,-hd,hd);
        glVertex3f(-hd,hd,hd);
        glVertex3f(-hd,hd,-hd);
    glEnd();

    glColor3f(0,1,0);
    glBegin(GL_QUADS);
        glVertex3f(-hd,-hd,hd);
        glVertex3f(hd,-hd,hd);
        glVertex3f(hd,hd,hd);
        glVertex3f(-hd,hd,hd);
    glEnd();

    glColor3f(0,0,1);
    glBegin(GL_QUADS);
        glVertex3f(-hd,hd,-hd);
        glVertex3f(-hd,hd,hd);
        glVertex3f(hd,hd,hd);
        glVertex3f(hd,hd,-hd);
    glEnd();

    glColor3f(0,1,1);
    glBegin(GL_QUADS);
        glVertex3f(hd,-hd,-hd);
        glVertex3f(hd,hd,-hd);
        glVertex3f(hd,hd,hd);
        glVertex3f(hd,-hd,hd);
    glEnd();
}

////////////////////////////////////////////////////////////
//
// Немного изменим функцию SetShaders():

// Изменим имена файлов с кодом шейдеров на новые:
    vs = textFileRead("minimal.vert");
    fs = textFileRead("minimal.frag");

// И в самый конец добавим:
    loc = glGetUniformLocation(p,"time");


////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////
//
// И наконец, изменим функцию RenderScene():

void RenderScene()
{
 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
 
    glLoadIdentity();
    gluLookAt(0.0,5.0,5.0,
              0.0,0.0,0.0,
              0.0f,1.0f,0.0f);

    glRotatef(a,0,1,0);

    drawCube();;
    a+=0.1;
 
    SwapBuffers(g_hDC);
}

 



Вот и всё. Теперь, запустив программу, вы увидите вращающийся раскрашенный кубик.
Но если, например, уберёте код из пикселного шейдера - куб не будет окрашен и вы ничего не увидите.






Исходные коды к уроку




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

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












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