Я только что столкнулся с этой же проблемой; здесь для возможного использования в будущем есть ответ, который я могу придумать сейчас, когда я решил это для себя:
Такой подход copy_pixels хорош. Единственная проблема - тип назначения. Если вам известно, что rgb8_pixel_t отформатирован в памяти, как если бы это было три последовательных uint8_t, то все, что вам нужно сделать, это примерно так:
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);
Это скопировано из моего проекта, более или менее; Я использую 32-битное изображение, но оно должно работать одинаково для любого другого, жестко закодированного типа изображения. (Я не научился использовать «any_» из GIL, поэтому не могу комментировать динамически определенные типы изображений.)
В приведенном выше коде я несколько грубо подтверждаю, что rgba8_pixel_t - это то, что OpenGL будет видеть как "INT_8_8_8_8" или что-то подобное, выполняя этот static_assert. Я думаю, что, вероятно, лучше взять эту информацию из документации GIL, чем делать предположения и пытаться подтвердить ее утверждением, но я не могу найти там четкого утверждения (я тоже новичок в GIL, так что может я просто скучаю) Но кажется довольно ясным, что это является частью замысла дизайна типов пикселей GIL. Например, руководство по дизайну GIL в какой-то момент говорит: «Наиболее часто используемый пиксель - это однородный пиксель, значения которого находятся вместе в памяти». «Вместе в памяти», кажется, именно то, что я ищу. Сразу после этого руководство рассказывает о «плоских» типах пикселей, в которых значения цветовых каналов для одного пикселя НЕ хранятся вместе в памяти. Было бы странно, если бы все заботы поддерживали это различие так же тщательно, как они это делают, а затем даже не удосужились бы заставить чередующийся тип пикселя плотно объединить свои значения цвета в памяти.
В любом случае, я продемонстрировал в своем собственном проекте, что этот подход работает по крайней мере с версией Boost, которую я использую (1.57), и я утверждаю, что если будущая версия изменит это, то мой static_assert почти наверняка будет поймай это.
(Другой подход к потенциальному отступлению заключается в том, чтобы фактически пойти дальше и использовать планарный пиксель для сопоставления между вашим массивом uint_8_t и rgb8_pixel_t, который for_each_pixel дает вам:
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;
// if data were an array of rgba8_pixel_t's, then we could just do this and be done with it:
// *cursor++ = pixel;
// (but in that case we might as well use copy_pixels!)
}));
gl->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
Но это не совсем лучше стратегии at_c. Думаю, это просто хороший пример. * _planar_ptr_t удивительно умен!)
Также обратите внимание, что в сегодняшнем C ++ вам не нужно создавать отдельный тип для захвата тела вашего цикла «для каждого»; Вы можете использовать анонимную функцию, как указано выше. (Я оборачиваю свой в std :: function, потому что я предполагаю, что GIL выполняет некоторое внутреннее копирование-назначение объекта функции, или что-то в этом роде, и компилятор злится, если передается голая анонимная функция. Я предполагаю, что std :: function Обмотка может немного снизить эффективность, в моем случае это не кажется важным.)