Як завантажувати текстури в SFML для OpenGL?


9

Я переглядаю навчальний посібник зі створення текстури NeHe . Це виглядає надмірно складним для просто завантаження текстури.

Чи є можливість завантажити текстуру в SFML і потім використовувати її у Open GL? Я використовую SFML для мого вікна.

Відповіді:


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% випадків вам потрібна двовимірна текстура.

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використовуючи її для малювання текстурованих сіток.


ммм, я спробував це зробити, і все, що я отримую - це білий куб: pastebin.com/nVQFAMRJ
Darestium

Спробуйте ввести glEnable(GL_TEXTURE2D);функцію init.
knight666

Дивовижно, працює! Дякую! До речі, що ця функція робить? Увімкнути текстурування?
Дарестіум

Так, він вмикається на 2D текстурний об'єкт, тому він може отримувати дані текстури. Увімкнути його потрібно лише один раз при ініціалізації, але це часто забувається при копіюванні коду в новий проект. Я сам включений. ;)
лицар666

Дуже приємне пояснення. Ви можете писати підручники!
danijar

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.