Я пытаюсь загрузить следующее изображение:
В качестве текстуры для Стэнфордского дракона. Однако результат выглядит следующим образом:
Я читал, что у других людей были проблемы с этим из-за неправильной привязки текстур или использования неправильного количества компонентов при загрузке текстуры. Я думаю, что у меня нет ни одной из этих проблем, поскольку я проверяю формат изображения и привязываю текстуру. Мне удалось правильно загрузить другие изображения, поэтому похоже, что есть проблема, специфичная для этого изображения (я не говорю, что изображение повреждено, скорее, что-то в этом изображении немного отличается от других изображений, которые я пробовал) .
Код, который я использую для инициализации текстуры, выглядит следующим образом:
//Main constructor
Texture::Texture(string file_path, GLuint t_target)
{
//Change the coordinate system of the image
stbi_set_flip_vertically_on_load(true);
int numComponents;
//Load the pixel data of the image
void *data = stbi_load(file_path.c_str(), &width, &height, &numComponents, 0);
if (data == nullptr)//Error check
{
cerr << "Error when loading texture from file: " + file_path << endl;
Log::record_log(
string(80, '!') +
"\nError when loading texture from file: " + file_path + "\n" +
string(80, '!')
);
exit(EXIT_FAILURE);
}
//Create the texture OpenGL object
target = t_target;
glGenTextures(1, &textureID);
glBindTexture(target, textureID);
//Name the texture
glObjectLabel(GL_TEXTURE, textureID, -1,
("\"" + extract_name(file_path) +"\"").c_str());
//Set the color format
color_format = numComponents == 3 ? GL_RGB : GL_RGBA;
glTexImage2D(target, 0, color_format, width, height, 0,
color_format, GL_UNSIGNED_BYTE, data);
//Set the texture parameters of the image
glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//free the memory
stbi_image_free(data);
//Create a debug notification event
char name[100];
glGetObjectLabel(GL_TEXTURE, textureID, 100, NULL, name);
string message = "Succesfully created texture: " + string(name) +
". Bound to target: " + textureTargetEnumToString(target);
glDebugMessageInsert(GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0,
GL_DEBUG_SEVERITY_NOTIFICATION, message.size(), message.c_str());
}
JPEG а? Наверное, тогда нет альфа-канала. А ширина 894 пикселя не делится довольно на 4 без остатка.
Дважды проверьте, попадаете ли вы в корпус numComponents == 3
, и если это так, убедитесь, что для GL_UNPACK_ALIGNMENT
установлено значение 1
(по умолчанию 4
) с glPixelStorei()
перед вызовом glTexImage2D()
.
Вы, сэр, были правы. Как мне поступить так, чтобы мой код управлял этой ситуацией самостоятельно? Иными словами, что мне следует проверить и что делать, чтобы изображения загружались правильно?
@Makogan: Всегда устанавливайте GL_UNPACK_ALIGNMENT
на 1
, и вы должны быть готовы использовать как 3-, так и 4-компонентные изображения, независимо от делимости ширины на 4.
@Makogan: в качестве альтернативы вы можете указать stbi_load()
, чтобы он всегда возвращал вам 3/4-компонентные изображения независимо от входа и иметь только один путь кода.
Вы пробовали не переворачивать изображение по вертикали? Удалите этот вызов и посмотрите, не изменится ли что-нибудь.