9
\$\begingroup\$

I'm looking at NeHe's texture mapping tutorial. It looks overly complicated for just loading a texture.

Is there a way to load a texture in SFML and then use it in Open GL? I use SFML for my windowing.

\$\endgroup\$
0

2 Answers 2

16
\$\begingroup\$

Welcome to OpenGL, where the fast things come for free and the easy things are made hard.

If you thought that sample was long and complicated, "just for loading a texture", then you've seen nothing yet. Wait until you have to load DDS textures, process HDR textures, support cubemaps, render to a texture, etc.

Loading a texture in OpenGL consists of two components:

  • Getting the data from your image format. You could load a texture from a file or generate it procedurally. It doesn't matter, as long as you end up with a nice array of color information.

  • Putting the data on the videocard. The data needs to go from system RAM to video RAM.

The first part should be easy, because SFML comes with a standard image loader.

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

Next, we'll have to generate an OpenGL texture object.

GLuint texture_handle;
glGenTextures(1, &texture_handle);

There are a number of choices for binding a texture. There are the three main types: 1D, 2D and 3D and you have support for cubemaps (+X, -X, +Y, -Y, +Z, -Z). However, in 99% of the cases, you will want a 2D texture.

glBindTexture(GL_TEXTURE_2D, texture_handle);

Now we get to the interesting part. Let's upload our data to the video card.

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

Finally, we can set a number of texture parameters. These answer questions like: what if we use a texture coordinate that is outside of the range (0.0, 1.0)? Do we wrap around (GL_REPEAT) or do we do nothing (GL_CLAMP)? They can also be used to explain to the videocard that we want to use linear interpolation on our textures.

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

And now you should be able to bind your texture using glBindTexture and use it to draw textured meshes.

\$\endgroup\$
6
  • \$\begingroup\$ mmm, I tried doing so and all I get is a white cube: pastebin.com/nVQFAMRJ \$\endgroup\$
    – Darestium
    Jul 8, 2012 at 4:40
  • \$\begingroup\$ Try putting glEnable(GL_TEXTURE2D); in the init function. \$\endgroup\$
    – knight666
    Jul 8, 2012 at 5:17
  • \$\begingroup\$ Awesome, works! Thanks! BTW, what does that function do? Enable texturing? \$\endgroup\$
    – Darestium
    Jul 8, 2012 at 5:42
  • \$\begingroup\$ Yes, it turns on the 2D texture object, so it can receive texture data. You only have to enable it once on initialization, but it is often forgotten when copying code to a new project. Myself included. ;) \$\endgroup\$
    – knight666
    Jul 8, 2012 at 8:38
  • \$\begingroup\$ Very nice explanation. You could write tutorials! \$\endgroup\$
    – danijar
    Nov 9, 2012 at 21:44
2
\$\begingroup\$

SFML 2.0+ makes it even easier to load a texture;

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
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .