Если вы хотите нарисовать треугольник с цветом, связанным с каждой координатой вершины, то вам нужен вершинный шейдер с 2 атрибутами.Один для координаты вершины и один для цвета.Атрибут цвета должен быть передан из Вершинный шейдер в Фрагментный шейдер с помощью переменной varying
.
Примечание, attribute
и varying
устарели, нодолжны быть использованы в GLSL версии 1.10, которая соответствует OpenGL версии 2.0.В «модере» OpenGL используются классификаторы типа (GLSL) in
и out
:
Вершинный шейдер
#version 110
attribute vec2 in_pos;
attribute vec3 in_col;
varying vec3 v_volor;
void main()
{
v_color = in_col;
gl_Position = vec4(in_pos.xy, 0.0, 1.0);
}
Фрагмент шейдера
varying vec3 v_color;
void main()
{
gl_FragColor = vec4(v_color.rgb, 1.0);
}
После того, как программа связана, вы должны получить индексы атрибутов in_pos
и in_col
по glGetAttribLocation
:
int attr_pos = glGetAttribLocation(program, "in_pos");
int attr_col = glGetAttribLocation(program, "in_col");
Если вы хотите установить индексы атрибутов на glBindAttribLocation
, то это должно быть сделано до того, как программа будет связана с glLinkProgram
, потому чтоэто информация, которая обрабатывается в процессе связывания.
Цветовые каналы в OpenGL Shading Language (GLSL) должны находиться в диапазоне [0,0, 1,0], где RGB(0,0, 0,0, 0,0) полностью черный, а RGB (1,0, 1,0, 1,0) белый.Таким образом, атрибуты цвета должны быть значениями с плавающей запятой:
float[] vertices = { -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f };
float[] color = { 0, 0.5f, 0.5f, 0.5f, 0, 0.5f, 0.5f, 0.5f, 0 };
int[] indices = { 0, 1, 2 };
FloatBuffer vb = this.toBuffer(vertices);
FloatBuffer cb = this.toBuffer(color);
IntBuffer ib = this.toBuffer(indices);
Создать буферы массива и буфер индекса:
int vbo = glGenBuffers();
int cbo = glGenBuffers();
int ibo = glGenBuffers();
// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, vb, GL_STATIC_DRAW);
// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glBufferData(GL_ARRAY_BUFFER, cb, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ib, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
Указать массивы данных общих атрибутов вершины:
// Position
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glEnableVertexAttribArray(attr_pos);
glVertexAttribPointer(attr_pos, 2, GL_FLOAT, false, 0, 0);
// Color
glBindBuffer(GL_ARRAY_BUFFER, cbo);
glEnableVertexAttribArray(attr_col);
glVertexAttribPointer(attr_col, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Для рисования объекта программный объект должен быть установлен по glUseProgram
, а буфер элемента должен быть привязан:
glUseProgram(program);
while (glfwWindowShouldClose(this.window) == false) {
// ....
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0L);
// .....
}
Примечание, исправленоатрибуты -функции (glVertexPointer
, ...), возможности клиента (glEnableClientState
/ glDisableClientState
) и стек с фиксированной матрицей функций (glMatrixMode
, glLoadIdentity
, ...) не действуют, когда шейдериспользуется такая программа.
Если вы хотите использовать матричные преобразования, то вы должны использовать Унифицированные переменные типа mat4
и установить собственные матрицы проекции, вида и модели -например, Matrix4f библиотека.