Как загрузить текстуры с SFML для OpenGL?

Ответы:

16

Добро пожаловать в OpenGL, где быстрые вещи бесплатны, а простые - трудными.

Если вы думали, что этот образец длинный и сложный, «только для загрузки текстуры», то вы еще ничего не видели. Дождитесь загрузки текстур DDS, обработки текстур HDR, поддержки кубических карт, рендеринга в текстуру и т. Д.

Загрузка текстуры в OpenGL состоит из двух компонентов:

  • Получение данных из вашего формата изображения. Вы можете загрузить текстуру из файла или сгенерировать ее процедурно. Это не имеет значения, до тех пор, пока вы получите хороший набор цветовой информации.

  • Положить данные на видеокарту. Данные должны идти из системной памяти в видео-память.

Первая часть должна быть простой, потому что SFML поставляется со стандартным загрузчиком изображений.

sf::Image img_data;
if (!img_data.LoadFromFile("images/avatar.png"))
{
    LOG_ERROR("Could not load '%s'.", "images/avatar.png");
    return false;
}

Далее нам нужно сгенерировать объект текстуры OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Существует несколько вариантов связывания текстуры. Существует три основных типа: 1D, 2D и 3D, и у вас есть поддержка кубических карт (+ X, -X, + Y, -Y, + Z, -Z). Однако в 99% случаев вам понадобится 2D-текстура.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Теперь перейдем к интересной части. Давайте загрузим наши данные на видеокарту.

glTexImage2D(
    GL_TEXTURE_2D, 0, GL_RGBA,
    img_data.GetWidth(), img_data.GetHeight(),
    0,
    GL_RGBA, GL_UNSIGNED_BYTE, img_data.GetPixelsPtr()
);

Наконец, мы можем установить ряд параметров текстуры. Они отвечают на такие вопросы, как: что если мы используем текстурную координату, которая находится за пределами диапазона (0,0, 1,0)? Мы оборачиваемся ( GL_REPEAT) или ничего не делаем ( GL_CLAMP)? Их также можно использовать для объяснения видеокарте, что мы хотим использовать линейную интерполяцию для наших текстур.

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

И теперь вы должны быть в состоянии связать свою текстуру, используя glBindTextureи использовать ее для рисования текстурированных сеток.

knight666
источник
ммм, я попытался сделать это, и все, что я получаю, это белый куб: pastebin.com/nVQFAMRJ
Darestium
Попробуйте ввести glEnable(GL_TEXTURE2D);функцию init.
knight666
Круто, работает! Спасибо! Кстати, что делает эта функция? Включить текстурирование?
Darestium
Да, он включает 2D-объект текстуры, чтобы он мог получать данные текстуры. Вы должны включить его только один раз при инициализации, но об этом часто забывают при копировании кода в новый проект. Я в том числе. ;)
knight666
Очень хорошее объяснение. Вы могли бы написать учебники!
Данияр
2

SFML 2.0+ облегчает загрузку текстуры;

sf::Texture texLid;
std::string image2="images/top.jpg";
if (!texLid.loadFromFile(image2))
{
    std::cout << "Could not load" << image2;
    char c;
    std::cin>>c;
    return false;
}


glEnable(GL_TEXTURE_2D);//tell OpenGL to use textures when drawing

sf::Texture::bind(&texLid);//select this texture for OpenGL rendering
кругозор
источник