Я использую OpenGL для рисования большого массива 2D-точек с их цветами. Каждая точка (вершина) также определила альфа-канал в массиве MX.c
Я хотел бы иметь возможность увеличить или уменьшить значение альфа целого массива (каждой отображаемой вершины). Есть ли разумный способ сделать это, используя функции OpenGL? Здесь мой метод рисования:
void PointsMX::drawMX()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, MX.c);
glVertexPointer(2, GL_DOUBLE, 0, MX.p);
glPushMatrix();
glTranslated(position[X], position[Y], 0.0);
glScaled(scale, scale, 1.0);
glDrawArrays(GL_POINTS, 0, MX.size);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
Как отмечает datenwolf в своих комментариях, вы можете сделать это довольно просто, используя шейдер, но не используя конвейер фиксированной функции (это то, что вы используете, если вы никогда не вызываете glUseProgram()
.
Если вы не используете освещение, воспроизведение фиксированных функций шейдеров не очень сложно, и небольшой поиск в Google поможет вам подойти к этому моменту.
Ключевым моментом здесь является то, что вы хотите изменить что-то, что обычно является атрибутом вершины (альфа-канал цвета), до настраиваемого значения для всей операции рисования. В шейдерных терминах это означает переопределение attribute
вершины в uniform
. uniform
- это просто значение, которое вы передаете в программу OpenGL, которая затем имеет то же значение для каждой обработанной вершины или фрагмента (в зависимости от того, помещена ли она в вершину или фрагментарный шейдер).
Вот пример очень простого вершинного шейдера:
#version 330
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
layout(location = 0) in vec3 Position;
layout(location = 3) in vec4 Color;
out vec4 vColor;
void main() {
gl_Position = Projection * ModelView * vec4(Position, 1);
vColor = Color;
}
И соответствующий фрагментарный шейдер
#version 330
in vec4 vColor;
out vec4 FragColor;
void main()
{
FragColor = vColor;
}
Чтобы выполнить то, что вы пытаетесь сделать, вы хотите изменить вершинный шейдер, чтобы добавить дополнительную форму, представляющую альфа-переопределение:
#version 330
uniform mat4 Projection = mat4(1);
uniform mat4 ModelView = mat4(1);
uniform float AlphaOverride = -1.0;
layout(location = 0) in vec3 Position;
layout(location = 3) in vec4 Color;
out vec4 vColor;
void main() {
gl_Position = Projection * ModelView * vec4(Position, 1);
vColor = Color;
if (AlphaOverride > 0.0) {
vColor.a = AlphaOverride;
}
}
Если вам не удалось установить равномерность AlphaOverride
это будет -1 и поэтому будет игнорироваться вершинным шейдером. Но если вы установите его значение от 0 до 1, оно будет применено к альфа-каналу вашей вершины.