Я подключил шейдер, но не могу найти никакой информации о том, как использовать glDrawElements с шейдером goemetry, присоединенным к программе шейдеров.
Программа выведет на экран четырехугольник без геометрического шейдера, теперь я пытаюсь сделать то же самое, но с подключенным геометрическим шейдером.
//In my .cpp file
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);// Vertex shader
#version 440
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;
uniform mat4 world_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
out vec3 color;
void main() {
color = vertex_color;
gl_Position = projection_matrix*view_matrix* world_matrix *
vec4(vertex_position, 1.0);
}
// Geometry shader
#version 440 core
layout (triangle_strip) in;
layout (triangle_strip, max_vertices = 6) out;
layout(location = 1) in vec3 vertex_color;
out vec3 color;
void main()
{
for(int i = 0; i < gl_in.length(); i++)
{
// copy attributes
gl_Position = gl_in[i].gl_Position;
color=vertex_color;
// done with the vertex
EmitVertex();
}
EndPrimitive();
}
//Fragment shader
#version 440
in vec3 color;
out vec4 fragment_color;
void main () {
fragment_color = vec4 (color, 1.0);
}
Смотрите удобный вики-сайт OpenGL Khronos Group для Входы и выходы шейдерного каскада:
Глобальные переменные объявлены с
in
квалификатором являются входные переменные этапа шейдера. Этим переменным присваиваются значения на предыдущем этапе (возможно, посредством интерполяции значений, выводимых из нескольких исполнений шейдеров).Глобальные переменные объявлены с
out
квалификатором являются выходные переменные стадии шейдера. Эти значения передаются на следующую стадию конвейера (возможно, путем интерполяции значений, выводимых из нескольких исполнений шейдеров).Входные данные Geometry Shader объединяются в массивы, по одному на вершину в примитиве. Длина массива зависит от типа входного примитива, используемого GS. Каждый индекс массива представляет одну вершину во входном примитиве.
У вас есть вершинный шейдер, геометрический шейдер и фрагментный шейдер. В этом случае вершинный шейдер является первым этапом шейдера, за которым следует геометрический шейдер, а последним этапом шейдера является фрагментный шейдер.
Таким образом, входные переменные геометрического шейдера должны матч к выходным переменным вершинного шейдера. Входные переменные фрагмента шейдера должны матч к выходным переменным геометрического шейдера.
Также отметим, что возможный входной спецификатор примитива points
, lines
, lines_adjacency
, triangles
а также triangles_adjacency
,
Смотрите также Geometry Shader — спецификация примитива входа / выхода.
Это означает, что ваш код должен выглядеть примерно так:
Вершинный шейдер:
#version 440
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_color;
uniform mat4 world_matrix;
uniform mat4 view_matrix;
uniform mat4 projection_matrix;
out vec3 vert_stage_color;
void main()
{
vert_out_color = vertex_color;
gl_Position = projection_matrix*view_matrix* world_matrix * vec4(vertex_position, 1.0);
}
Геометрия шейдера:
#version 440 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 6) out;
layout(location = 1) in vec3 vertex_color;
in vec3 vert_stage_color[];
out vec3 geo_stage_color;
void main()
{
for(int i = 0; i < gl_in.length(); i++)
{
// copy attributes
gl_Position = gl_in[i].gl_Position;
geo_stage_color = vert_stage_color[i];
// done with the vertex
EmitVertex();
}
EndPrimitive();
}
Фрагмент шейдера:
#version 440
in vec3 geo_stage_color;
out vec4 fragment_color;
void main ()
{
fragment_color = vec4(geo_stage_color, 1.0);
}
Других решений пока нет …