Jak ładować tekstury za pomocą SFML dla OpenGL?


Odpowiedzi:


16

Witamy w OpenGL, gdzie szybkie rzeczy są dostępne za darmo, a te łatwe stają się trudne.

Jeśli uważasz, że próbka jest długa i skomplikowana, „tylko do załadowania tekstury”, to jeszcze nic nie widziałeś. Poczekaj, aż będziesz musiał załadować tekstury DDS, przetworzyć tekstury HDR, wesprzeć mapy kubaturowe, renderować do tekstury itp.

Ładowanie tekstury w OpenGL składa się z dwóch komponentów:

  • Pobieranie danych z formatu obrazu. Możesz załadować teksturę z pliku lub wygenerować ją proceduralnie. To nie ma znaczenia, o ile uzyskasz niezłą gamę informacji o kolorze.

  • Umieszczanie danych na karcie wideo. Dane muszą przejść z RAM systemowej do RAM wideo.

Pierwsza część powinna być łatwa, ponieważ SFML jest wyposażony w standardowy moduł ładujący obrazy.

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

Następnie będziemy musieli wygenerować obiekt tekstury OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Istnieje wiele opcji wiązania tekstury. Istnieją trzy główne typy: 1D, 2D i 3D i masz wsparcie dla map sześciennych (+ X, -X, + Y, -Y, + Z, -Z). Jednak w 99% przypadków będziesz potrzebować tekstury 2D.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Teraz dochodzimy do interesującej części. Prześlijmy nasze dane na kartę wideo.

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

Wreszcie możemy ustawić szereg parametrów tekstury. Odpowiadają na takie pytania, jak: co zrobić, jeśli użyjemy współrzędnej tekstury, która jest poza zakresem (0,0, 1,0)? Czy owijamy się wokół ( GL_REPEAT), czy nic nie robimy ( GL_CLAMP)? Można ich również użyć do wyjaśnienia na karcie wideo, że chcemy zastosować interpolację liniową w naszych teksturach.

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);

A teraz powinieneś być w stanie związać teksturę za pomocą glBindTexturei użyć jej do rysowania teksturowanych siatek.


mmm, próbowałem to zrobić, a dostaję tylko biały sześcian: pastebin.com/nVQFAMRJ
Darestium

Spróbuj wprowadzić glEnable(GL_TEXTURE2D);funkcję init.
knight666

Wspaniale, działa! Dzięki! BTW, co robi ta funkcja? Włączyć teksturowanie?
Darestium

Tak, włącza obiekt tekstury 2D, aby mógł odbierać dane tekstury. Musisz włączyć go tylko raz podczas inicjalizacji, ale często jest to zapominane podczas kopiowania kodu do nowego projektu. Ja wliczony w cenę. ;)
knight666

Bardzo miłe wytłumaczenie. Możesz pisać tutoriale!
danijar

2

SFML 2.0+ jeszcze bardziej ułatwia ładowanie tekstury;

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.