Como carrego texturas com SFML para OpenGL?

Respostas:

16

Bem-vindo ao OpenGL, onde as coisas rápidas são gratuitas e as coisas fáceis são dificultadas.

Se você pensou que a amostra era longa e complicada, "apenas para carregar uma textura", não viu nada ainda. Aguarde até ter de carregar texturas DDS, processar texturas HDR, suportar mapas de cubos, renderizar em uma textura etc.

O carregamento de uma textura no OpenGL consiste em dois componentes:

  • Obtendo os dados do seu formato de imagem. Você pode carregar uma textura de um arquivo ou gerá-la proceduralmente. Não importa, desde que você tenha uma boa variedade de informações sobre cores.

  • Colocando os dados na placa de vídeo. Os dados precisam ir da RAM do sistema para a RAM de vídeo.

A primeira parte deve ser fácil, porque o SFML vem com um carregador de imagens padrão.

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

Em seguida, teremos que gerar um objeto de textura OpenGL.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

Existem várias opções para vincular uma textura. Existem três tipos principais: 1D, 2D e 3D e você tem suporte para mapas de cubos (+ X, -X, + Y, -Y, + Z, -Z). No entanto, em 99% dos casos, você desejará uma textura 2D.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Agora chegamos à parte interessante. Vamos enviar nossos dados para a placa de vídeo.

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

Por fim, podemos definir vários parâmetros de textura. Eles respondem a perguntas como: e se usarmos uma coordenada de textura que está fora do intervalo (0,0, 1,0)? Nós envolvemos ( GL_REPEAT) ou não fazemos nada ( GL_CLAMP)? Eles também podem ser usados ​​para explicar ao videocard que queremos usar interpolação linear em nossas texturas.

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

E agora você deve conseguir vincular sua textura usando-a glBindTexturee desenhando malhas texturizadas.

knight666
fonte
mmm, eu tentei fazê-lo e tudo que eu vejo é um cubo branco: pastebin.com/nVQFAMRJ
Darestium
Tente colocar glEnable(GL_TEXTURE2D);a função init.
8282 Knight666
Incrível, funciona! Obrigado! BTW, o que essa função faz? Ativar texturização?
Darestium
Sim, ele ativa o objeto de textura 2D para receber dados de textura. Você só precisa habilitá-lo uma vez na inicialização, mas geralmente é esquecido ao copiar o código para um novo projeto. Eu mesmo incluído. ;)
knight666
Explicação muito boa. Você pode escrever tutoriais!
procurando
2

O SFML 2.0+ facilita ainda mais o carregamento de uma textura;

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
Ken
fonte