CImg не чередует свои цвета. То есть 3 красных, зеленых и синих пикселя будут храниться линейно как:
R1, R2, R3, ..., G1, G2, G3, ..., B1, B2, B3, ...
Однако в OpenGL glReadPixel и glDrawPixel ожидаются чередующиеся компоненты цвета, такие как:
R1, G1, B1, R2, G2, B2, ...
Кроме того, OpenGL помещает начало координат (0,0) в левый нижний угол изображения. CImg использует больше подходов, где источник находится в верхнем левом углу изображения.
Вот процедура, которую я написал для преобразования чередующихся цветов в канально-ориентированный формат CImg.
void convertToNonInterleaved(int w, int h, unsigned char* tangled, unsigned char* untangled) {
//Take string in format R1 G1 B1 R2 G2 B2... and re-write it
//in the format format R1 R2 G1 G2 B1 B2...
//Assume 8 bit values for red, green and blue color channels.
//Assume there are no other channels
//tangled is a pointer to the input string and untangled
//is a pointer to the output string. This method assumes that
//memory has already been allocated for the output string.
int numPixels = w*h;
int numColors = 3;
for(int i=0; i<numPixels; ++i) {
int indexIntoInterleavedTuple = numColors*i;
//Red
untangled[i] = tangled[indexIntoInterleavedTuple];
//Green
untangled[numPixels+i] = tangled[indexIntoInterleavedTuple+1];
//Blue
untangled[2*numPixels+i] = tangled[indexIntoInterleavedTuple+2];
}
}
Мне следовало бы добавить код, чтобы учесть изменения в происхождении, но я чувствовал себя ленивым и решил использовать CImg для этого. После запуска этой программы этот код создает объект изображения:
unsigned char* p = (unsigned char *)malloc(bytes);
convertToNonInterleaved(width, height, buffer, p);
CImg<unsigned char> img(p, width, height,1,3);
free(p);
img.mirror('y');
CImgDisplay main_disp(img,"Snapshot");
while (!main_disp.is_closed() ) {
main_disp.wait();
}
И, насколько я могу судить, мне не нужно устанавливать какие-либо параметры упаковки. Вот код, который я использую для захвата пикселей из цели рендеринга OpenGL:
bytes = width*height*3; //Color space is RGB
if(buffer)
free(buffer);
buffer = (GLubyte *)malloc(bytes);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer);