В настоящее время я пытаюсь сделать небольшую игру в OpenGL как попытку научиться использовать API. Я подошел к моменту, когда я могу перемещать камеру по простой сцене, и я могу рендерить модели и затенять их с помощью простого шейдерного макета.
Сейчас я работаю над текстурированием моделей в сцене, поэтому я получил копию Maya и сделал (с некоторыми трудностями) квадрат с текстурой с UV-отображением, созданным в Maya.
Когда я рендеринг сцены, текстура применяется, но далеко не правильно. Я читаю модели как файлы .obj с парсером, который я написал сам, а текстуры читаются с помощью функции, которую я нашел в Интернете некоторое время назад.
Я не уверен, как описать проблему достаточно подробно, и что искать в коде, но вот некоторые фрагменты кода, которые, как я подозреваю, содержали проблему.
Чтение текстуры
GLuint loadTexture(Image* image){
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGB,
image->width, image->height,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
image->pixels);
return textureId;
}
Установка текстуры перед рендерингом меша
// set texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, this->body_texture);
current_shader->setUniformint(0, "Difuse_texture");
Вершинный шейдер
#version 410
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 1) in vec2 TextureCoord;out vec3 Position;
out vec3 Normal;
out vec2 TexCoord;
uniform mat4 ModelMatrix;
uniform mat4 VeiwMatrix;
uniform mat4 ProjectionMatrix;
uniform mat3 NormalMatrix;void main(){
mat4 ModelVeiwMatrix = VeiwMatrix * ModelMatrix;
mat4 MVP = ProjectionMatrix * ModelVeiwMatrix;
TexCoord = TextureCoord;
Normal = normalize( NormalMatrix * VertexNormal );
Position = vec3(ModelVeiwMatrix * vec4(VertexPosition, 1.0));
gl_Position = MVP * vec4(VertexPosition, 1.0);
}
Фрагмент шейдера
#version 410
in vec3 Position;
in vec3 Normal;
in vec2 TexCoord;
uniform vec4 LightPosition;
uniform vec3 LightIntensity;
uniform vec3 Kd;
uniform vec3 Ka;
uniform vec3 Ks;
uniform float Shininess;
uniform sampler2D Difuse_texture;
layout(location = 0) out vec4 FragColor;
vec4 ads(){
vec3 n = normalize( Normal );
vec3 s = normalize( vec3(LightPosition) - Position );
vec3 v = normalize( vec3(-Position) );
vec3 r = reflect( -s, n );
vec3 specular_light = Ks * pow(max(dot(r, v), 0.0), Shininess);
vec3 ad_light = Ka + Kd * max(dot(s, n), 0.0);
vec4 TexColor = texture2D(Difuse_texture, TexCoord);
return TexColor; // (vec4(LightIntensity, 1.0) * (vec4(ad_light, 1.0) * TexColor + vec4(specular_light, 1.0)));
}void main() {
FragColor = ads();
}
Я знаю, что некоторые вещи написаны странно, но в этот момент я начинаю просто пробовать что-нибудь, чтобы это работало.
У кого-нибудь есть предложения по решению этого странного УФ-картирования?
РЕДАКТИРОВАТЬ:
OBJ ЗАГРУЗКА
Я заставил загрузчик obj распечатать все атрибуты вершин и сравнил их с индексированием в файле .obj. Похоже, что графики, нормали и ультрафиолеты отображаются в правильном порядке.
Скриншот
Сцена выглядит следующим образом, используя простой градиент зеленого цвета в качестве изображения текстуры.
(Насколько я понимаю, квадрат должен показывать градиент от текстуры, а не только один цвет)
Выравнивание звучит как возможный недостаток, как я могу это исправить?
http://imageshack.com/a/img674/9927/y0bJ51.png
РЕШЕНИЕ
Я сделал очень простую и легко упускаемую ошибку. В вершине вершинного шейдера я написал
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 1) in vec2 TextureCoord;
Поэтому я предполагаю, что когда я отправил нормальные данные в местоположение 1, я установил координаты текстуры на нормальные данные, чтобы координаты UV никогда не достигали фрагментного шейдера.
Переход на следующую страницу решил проблему без дальнейших изменений.
layout(location = 0) in vec3 VertexPosition;
layout(location = 1) in vec3 VertexNormal;
layout(location = 2) in vec2 TextureCoord;
Задача ещё не решена.