2015-03-15 2 views
1

Я передаю строку в геометрический шейдер и выводя кубоид. Я создаю 4 новых точки на каждом конце строки, которые были переданы путем добавления постоянной «толщины» в направлении x или y. Если я задаю толщину в геометрическом шейдере, он отлично работает, но когда я попытался передать его шейдерам в качестве части данных вершин, я не могу получить доступ к нему в геометрическом шейдере. Когда я устанавливаю thickness = vThickness[0] в геометрический шейдер, тогда ничего не рисуется.Geometry shader, похоже, не принимает входной атрибут

Я могу получить данные о толщине в вершинном шейдере, и он кажется действительным (я задал выходной цвет по толщине, а кубоид был нарисован белым, что отлично, так как оно должно быть целым числом> = 1). Проблема, похоже, связана с интерфейсом между вершинным шейдером и геометрическим шейдером.

Vertex шейдеров:

#version 150 core 

uniform vec3 uColor; 

in vec3 position; 
in int thickness; 

out vec4 vColor; 
out int vThickness; 

void main() { 

    vColor = vec4(uColor, 1.0); 
    vThickness = thickness; 
    gl_Position = vec4(position, 1.0); 
} 

Геометрия шейдер:

#version 150 core 

uniform mat4 uProjection; 
uniform mat4 uModel; 

in vec4 vColor[]; 
in int vThickness[]; 
out vec4 gColor; 
out vec3 normalV; 
out vec3 points; 

layout (lines) in; 
layout (triangle_strip, max_vertices = 20) out; 

void main() { 
    gColor = vColor[0]; 

    vec3 z = (gl_in[1].gl_Position - gl_in[0].gl_Position).xyz; 
    vec3 x = cross(vec3(0.0, 1.0, 0.0), z); 

    float thickness = vColor[0]; 
    // float thickness = 0.5; // This worked 

    x = thickness * normalize(x); 
    vec3 y = cross(z, x); 
    y = thickness * normalize(y); 

    vec4 endTL = uProjection * uModel * (gl_in[1].gl_Position - vec4(x, 0.0) + vec4(y, 0.0)); 
    vec4 endTR = uProjection * uModel * (gl_in[1].gl_Position + vec4(x, 0.0) + vec4(y, 0.0)); 
    vec4 endBL = uProjection * uModel * (gl_in[1].gl_Position - vec4(x, 0.0) - vec4(y, 0.0)); 
    vec4 endBR = uProjection * uModel * (gl_in[1].gl_Position + vec4(x, 0.0) - vec4(y, 0.0)); 

    vec4 begTL = uProjection * uModel * (gl_in[0].gl_Position - vec4(x, 0.0) + vec4(y, 0.0)); 
    vec4 begTR = uProjection * uModel * (gl_in[0].gl_Position + vec4(x, 0.0) + vec4(y, 0.0)); 
    vec4 begBL = uProjection * uModel * (gl_in[0].gl_Position - vec4(x, 0.0) - vec4(y, 0.0)); 
    vec4 begBR = uProjection * uModel * (gl_in[0].gl_Position + vec4(x, 0.0) - vec4(y, 0.0)); 

    gl_Position = begTL; // 0 
    points = begTL.xyz; 
    normalV = normalize(-x + y); 
    EmitVertex(); 

    gl_Position = endTL; // 1 
    points = endTL.xyz; 
    normalV = normalize(-x + y); 
    EmitVertex(); 

    gl_Position = begTR; // 2 
    points = begTR.xyz; 
    normalV = normalize(x + y); 
    EmitVertex(); 

    gl_Position = endTR; // 3 
    points = endTR.xyz; 
    normalV = normalize(x + y); 
    EmitVertex(); 

    gl_Position = begBR; // 4 
    points = begBR.xyz; 
    normalV = normalize(-x + y); 
    EmitVertex(); 

    gl_Position = endBR; // 5 
    points = endBR.xyz; 
    normalV = normalize(x - y); 
    EmitVertex(); 

    gl_Position = begBL; // 6 
    points = begBL.xyz; 
    normalV = normalize(x - y); 
    EmitVertex();  

    gl_Position = endBL; // 7 
    points = endBL.xyz; 
    normalV = normalize(-x - y); 
    EmitVertex(); 

    gl_Position = begTL; // 8 
    points = begTL.xyz; 
    normalV = normalize(-x + y); 
    EmitVertex(); 

    gl_Position = endTL; // 9 
    points = endTL.xyz; 
    normalV = normalize(-x + y); 
    EmitVertex(); 
} 

Фрагмент Shader:

#version 150 core 

vec3 intensities = vec3(0.2f,0.2f,0.2f); 
in vec4 gColor; 
in vec3 normalV; 
in vec3 points; 
out vec4 fColor; 

void main() { 

    vec3 surfaceToLight = normalize(vec3(1,1,0)); 

    float brightness = dot(normalV, surfaceToLight); 
    brightness = clamp(brightness, 0, 1); 
    vec4 surfaceColor = gColor; 
    fColor = vec4(brightness * intensities + surfaceColor.rgb * 0.5f, surfaceColor.a); 

} 

Данные Я передаю:

struct Vertex 
{ 
    Vector3 position; 
    uint32 thickness; 
}; 

GLint positionAttribLocation = glGetAttribLocation(renderContext->branchesContext.program, "position"); 
glEnableVertexAttribArray(positionAttribLocation); 
glVertexAttribPointer(positionAttribLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); 

GLint thicknessAttribLocation = glGetAttribLocation(renderContext->branchesContext.program, "thickness"); 
glEnableVertexAttribArray(thicknessAttribLocation); 
glVertexAttribPointer(thicknessAttribLocation, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(Vertex), (void*)(3 * sizeof(float))); 
+2

Я не думаю, что это вообще связано, но вам нужно установить значение 'gColor' после каждого' EmitVertex (...) '. Каждая переменная 'out' становится неопределенной после вызова' EmitVertex', вы можете уйти с настройкой только один раз на одном графическом процессоре, а с другой - вести себя совершенно иначе. –

+0

Спасибо, я не знал об этом. – pseudomarvin

ответ

2

Вы используете неправильную функцию для установки указателя атрибута вершины для thickness.

glVertexAttribPointer(thicknessAttribLocation, 1, GL_UNSIGNED_INT, GL_FALSE, sizeof(Vertex), (void*)(3 * sizeof(float))); 

Толщина имеет тип int, и вы используете glVertexAttribPointer (...). Эта функция предназначена для преобразования данных вершин в плавающую точку и подходит только для float, vec<N> и типов матричных данных.

Чтобы правильно присвоить атрибуту вершин указатель данных, вам необходимо использовать glVertexAttribIPointer (...). Это оставит только целые данные и передаст их непосредственно в ваш шейдер, он подходит для атрибутов {u}int и [i|u]vec<N>.

glVertexAttribIPointer(thicknessAttribLocation, 1, GL_UNSIGNED_INT, sizeof(Vertex), (void*)(3 * sizeof(float))); 

Вы заметите, есть один меньше параметра в этом вызове функции, и это потому, что с плавающей точкой нормализация не является вариантом для атрибутов целой вершины.

+0

Спасибо, ты действительно помог мне. Я бы поднял ваш ответ, если бы мог :). – pseudomarvin

Смежные вопросы