2014-01-17 4 views
0

Я пытаюсь преобразовать старый код OpenGL для использования шейдеров, и у меня возникла проблема с получением шейдера фрагмента для рисования текстуры на кубе. Однако все, что я вижу, это серый куб. Я отлаживал мой код загрузчика .obj, и я знаю, что UV-объекты загружаются правильно, и я знаю, что текстура загружается с диска и правильно устанавливается на графический процессор. После довольно много испытаний я узнал, что мои значения UV не интерполируются по всему треугольнику. То есть, похоже, что каждый фрагмент получает значение uv 0.0,0.0 (это первое значение uv в моем буфере). Любые идеи, почему?OpenGL: значения UV не интерполируются в шейдере фрагмента

Вот мой пиксельный шейдер:

#version 430 core 

in vec3 color; 
in vec2 uv; 
uniform sampler2D tex; 
out vec3 frag_color; 

void main() 
{ 
    //frag_color = color; 
    frag_color = texture(tex,uv).rgb; 
} 

И моя вершинный шейдер:

#version 430 core 

layout(location = 0) in vec3 pos; 
layout(location = 1) in vec3 normal; 
layout(location = 2) in vec2 uv; 
uniform mat4 mvMatrix; 
uniform mat4 mvpMatrix; 
attribute vec3 lightPos; 
out vec3 color; 
out vec2 uv_out; 

void main() 
{ 
uv_out = uv; 

vec3 modelViewVertex = vec3(mvMatrix * vec4(pos,1.0)); 
vec3 modelViewNormal = vec3(mvMatrix * vec4(normal,0.0)); 
vec3 modelViewLightPos = vec3(mvMatrix * vec4(lightPos,1.0)); 

vec3 lightVector = normalize(lightPos - pos); 
float diffuse = clamp(dot(normal,lightVector),0,1); 

gl_Position = mvpMatrix * vec4(pos,1.0); 
color = vec3(diffuse,0.0,0.0); 

} 

Вот где я настраивал буферы:

glGenVertexArrays(1, &vertexBufferObjectID); 
glBindVertexArray(vertexBufferObjectID); 
glGenBuffers(1, &vertexBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), &vertices[0], GL_STATIC_DRAW); 
glGenBuffers(1, &normalBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); 
glBufferData(GL_ARRAY_BUFFER, normals.size()*sizeof(vec3), &normals[0], GL_STATIC_DRAW); 
glGenBuffers(1, &UVBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer); 
glBufferData(GL_ARRAY_BUFFER, uvs.size()*sizeof(vec2), &uvs[0], GL_STATIC_DRAW); 

Наконец, вот мой петля визуализации:

glUseProgram(shaderProgram); 
glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, texture); 
glUniform1i(textureID, 0); 
glEnableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 
glEnableVertexAttribArray(1); 
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); 
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 
glEnableVertexAttribArray(2); 
glBindBuffer(GL_ARRAY_BUFFER, UVBuffer); 
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); 

mvpMatrix = projectionMatrix * viewMatrix * modelMatrix; 
glUniformMatrix4fv(mvpMatrixID, 1, GL_FALSE, &mvpMatrix[0][0]); 
mvMatrix = viewMatrix * modelMatrix; 
glUniformMatrix4fv(mvMatrixID, 1, GL_FALSE, &mvMatrix[0][0]); 
glVertexAttrib3fv(lightposID, &lightpos[0]); 
glDrawArrays(GL_TRIANGLES, 0, vertices.size()); 

glDisableVertexAttribArray(0); 
glDisableVertexAttribArray(1); 
glDisableVertexAttribArray(2); 

Снова все выглядит правильно, основываясь на том, что я читал. Все выглядит неправильно?

+0

Вы получаете что-либо из 'glGetError()'? – zero298

+1

Это не должно даже компилироваться, у вас есть некорректные пробелы в середине вашей директивы '# version', что делает ее« # version ». Вы также должны использовать 'texture (...)' вместо 'texture2D (...)' (устаревший) в базовом шейдере GLSL 3.30. –

+0

@zero: glGetError() возвращал ошибку, когда я вызывал glVertexAttrib3fv (lightposID, & lightpos [0]); Однако, когда я снова включил освещение вершин, это исчезло. Ошибка заключалась в том, что «lightposID» не был правильно инициализирован (я думаю, шейдер оптимизировал его, поскольку я не использовал его). Кроме этого, ничего. – redsoxfantom

ответ

3

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

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

in vec2 uv_out 

Конечно имя uv_out затем немного вводит в заблуждение.

+0

Это сработало отлично, я не могу поверить, что забыл об этом :) Спасибо! – redsoxfantom