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);
}

 

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

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

Понравилась статья? Поделиться с друзьями: