I ran into this problem; here for a possible future reference - this is the answer that I can come up with now that I have decided this for myself:
This copy_pixels method is good. The only problem is the type of destination. If you know that rgb8_pixel_t is formatted in memory, as if it were three consecutive uint8_t, then all you have to do is something like this:
boost::gil::rgba8_image_t image; boost::gil::png_read_image(filePath, image); auto view = boost::gil::view(image); typedef decltype(view)::value_type pixel; static_assert(sizeof(pixel) == 4, "the glTexImage2D call below assumes this"); pixel imageData[view.width() * view.height()]; boost::gil::copy_pixels(view, boost::gil::interleaved_view(view.width(), view.height(), imageData, view.width() * sizeof(pixel))); gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, imageData);
This is copied from my project, more or less; I use a 32-bit image, but it should work the same for any other type of hard coded image. (I have not learned how to use the "any_" material from the GIL, so I cannot comment on dynamically defined types of images.)
In the above code, I am somewhat crudely confirming that rgba8_pixel_t is what OpenGL sees as "INT_8_8_8_8" or something else by doing this static_assert. I think it is probably better to take this information from the GIL documentation than to guess and try to confirm it with a statement, but I cannot find a clear statement about it (I am also new to GIL, so maybe I just skipped this) . But it seems pretty obvious that this is part of the design intent of the GIL pixel types. For example, the GIL design guide says at one point: “The most commonly used pixel is a uniform pixel whose values are in memory.” “Together in memory” seems to be exactly what I'm looking for. Immediately after this, the manual talks about “flat” types of pixels in which the color channel values for one pixel are NOT stored together in memory. It would be strange to go into all the problems in order to maintain this difference as carefully as they do, and then not actually worry about alternating pixel types packing its color values together in memory.
In any case, I demonstrated in my own project that this approach works with at least the version of Boost that I use (1.57), and argue that if a future version changes this value, then my static_assert will almost certainly catch it.
(Another approach to potential return is actually to switch to using a planar pixel to match between your uint_8_t and rgb8_pixel_t array, which for_each_pixel gives you:
boost::gil::rgba8_image_t image; boost::gil::png_read_image(filePath, image); auto view = boost::gil::view(image); uint8_t data[view.width() * view.height() * view.num_channels()]; using boost::gil::rgba8_pixel_t; uint8_t* cursor = data; boost::gil::for_each_pixel(view, std::function<void(rgba8_pixel_t)>( [&cursor](rgba8_pixel_t pixel) { boost::gil::rgba8_planar_ptr_t pixelInData(cursor++, cursor++, cursor++, cursor++); *pixelInData = pixel;
But this is not much better than the at_c strategy. I think this is just a great example. * _planar_ptr_t amazingly smart!)
Also note that in today's C ++ you do not need to make a separate type to capture the body of your loop "for each"; you can use anonymous function as above. (I end mine in std :: function because I assume that the GIL does the internal assignment of a copy of the function object or something like that, and the compiler goes crazy if a naked anonymous function is passed. I assume that std :: function packaging may slightly decrease efficiency, in my case this does not seem important.)