Karlovsky120
Karlovsky120

Reputation: 6352

How to load texture into openGl using png++?

This line will read the texture into memory and store it in an image:

png::image<png::rgba_pixel> image("texture.png");

This line should then load it into openGL memory:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.get_width(), image.get_height(), 0, GL_ABGR, GL_UNSIGNED_BYTE, image.get_pixbuf());

However, the last argument should be const void*, but image.get_pixbuf() returns pixbuf. How do I get the pixel data from image into openGL?

Ignore any other arguments I specified wrongly, I'll fix it later, this is the one that doesn't work at all.

Upvotes: 2

Views: 2615

Answers (1)

gavinb
gavinb

Reputation: 20018

OpenGL can't know ahead of time what types anyone might want to pass in (since it can work with virtually any library), so it takes a generic const void* pointer to your raw buffer, and relies on you to describe it accurately with the supplied metadata.

In the case of the png++ library, you need to dig a few layers down in the abstraction, as it wraps images, rows and pixels for you.

Since you have a png::image instance, get_pixbuf() will return you a png::pixbuf instance, from which you can get a reference to the first row with get_row(0), which returns a png::row_traits specialisation for your pixel type. This gives you access to the first row of the buffer, at which point you can finally request the raw buffer pointer with the get_data() method. (This is the first byte of the first row, thus pointing to the start of the contiguous buffer.)

So something like this should do the trick:

const void* buffer = image.get_pixbuf().get_row(0).get_data();

glTexImage2D(GL_TEXTURE_2D,
             0,
             GL_RGBA,
             image.get_width(),
             image.get_height(),
             0,
             GL_ABGR,
             GL_UNSIGNED_BYTE,
             buffer);

assuming your image data is 8-bit RGBA, with no row padding.

Upvotes: 2

Related Questions