Простой код для создания кубической карты OpenGL из файла изображения "кросс-макет"

Я ищу простой C подпрограмма (в Linux), которая принимает параметр имени файла и делает 6 вызовов glTexImage2D определить текстуру "кубическая карта" (GL_TEXTURE_CUBE_MAP).

Я хотел бы иметь возможность читать файл "кросс-макет" (горизонтальный или вертикальный) или "горизонтальная полоса", поэтому для этого требуются различные операции обрезки (и, возможно, некоторые повороты, чтобы соответствовать ориентации, которую ожидает OpenGL).

Я уверен, что этот код существует, но я погуглил и нашел только фрагменты.

Я наткнулся на GEGL / BABL библиотеки. Это выглядит хорошо. Немного перебор, но он может читать из файла ("gegl:load"), кадрирование, поворот и BABL могут выполнять различные операции в формате пикселей (в соответствии с OpenGL GL_RGB или же GL_RGBA формат).

Также может быть полезно прочитать "прямолинейный" файл текстуры и преобразовать его в проекции gnomic (сейчас я использую MMPS для этого).

Я нашел этот код Python "gimpfu" ( http://registry.gimp.org/files/cubemap-to-dds-v0.3.py.txt), который преобразуется из "кросс-макета" в файл DDS с несколькими изображениями., так что это похоже на то, что я хочу, но я бы предпочел не иметь кода Python в моем приложении. GIMP использует GEGL внутри, поэтому я и использую это.

1 ответ

Ну... я написал очень простую программу для чтения кубических карт с вертикальной полосой, используя библиотеку Freeimage. Вот суть:

FIBITMAP *bitmap = FreeImage_Load(FreeImage_GetFileType(name0, 0), name0, BMP_DEFAULT);
FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap);
FreeImage_Unload(bitmap);

int width0=FreeImage_GetWidth(pImage);
int height0=FreeImage_GetHeight(pImage);
void *pixels0 = FreeImage_GetBits(pImage);

// "v-strip" (for simplicity, assume OpenGL order and orientation)
height0 /= 6;
for(int idx0=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; idx0 >= GL_TEXTURE_CUBE_MAP_POSITIVE_X ; idx0--) { // NB : index goes backwards because image files start at the bottom
    glTexImage2D(idx0, 0, GL_RGB, width0, height0,
            0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, pixels0);
    pixels0 += width0 * height0 * 4; // "4" : sizeof(RGBA pixel) ?
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
FreeImage_Unload(pImage);

Это заставляет меня начать. У меня есть сценарий MMPS, который преобразует прямолинейный в V-полосу, но я все еще играю с ориентациями. Как говорится в одной книге, "ориентация текстурных координат каждой грани нелогична". Я мог бы преобразовать скрипт в "nona" / PTstitcher (часть PanoTools).

К вашему сведению, существует много форматов файлов изображений кубических карт. V-стрип легче всего читать. "Горизонтальный крест", кажется, популярен. В общем, есть {горизонтальный, вертикальный} х {крест, полоса, тройник} (и, вероятно, больше).

У меня есть некоторый код, который читает крестики, h-полосы (он использует glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, width0)), но он по-прежнему не имеет отношения к ориентации. Мне придется использовать что-то вроде GEGL или libpano13. Или, возможно, взломать промежуточный шаг, который использует execl для запуска MMPS / nona / ImageMagick. Возможно, libpano13 - это то, что нужно: я могу генерировать кубические карты на лету из прямолинейных файлов.

Ура!

Обновление: вот сценарий MMPS bash для преобразования из прямолинейного изображения в v-strip (в порядке и ориентации OpenGL):

## NB : yum install ImageMagick # for convert & montage

infile0=$1

MMPS0=~/mmps-0-1-36
tmp0=/tmp/cube$$
convert $infile0 $tmp0.ppm

ARGS0="gnomonic -grid -gridcolor 255:255:255 -scale 2 -w 512 -h 512"
ARGS0="gnomonic -scale 2 -w 512 -h 512"
#
$MMPS0/project $ARGS0 -lat   0 -long   0 -f $tmp0.ppm -rotate -90 > $tmp0-xp.ppm &    ## africa
$MMPS0/project $ARGS0 -lat   0 -long 180 -f $tmp0.ppm -rotate  90 > $tmp0-xn.ppm &    ## pacific ocean
$MMPS0/project $ARGS0 -lat   0 -long  90 -f $tmp0.ppm -rotate 180 > $tmp0-yp.ppm &    ## indian ocean
$MMPS0/project $ARGS0 -lat   0 -long 270 -f $tmp0.ppm -rotate   0 > $tmp0-yn.ppm &    ## americas
$MMPS0/project $ARGS0 -lat  90 -long   0 -f $tmp0.ppm -rotate -90 > $tmp0-zp.ppm &    ## north pole
$MMPS0/project $ARGS0 -lat -90 -long   0 -f $tmp0.ppm -rotate -90 > $tmp0-zn.ppm &    ## south pole
wait
montage $tmp0-xp.ppm $tmp0-xn.ppm \
    $tmp0-yn.ppm $tmp0-yp.ppm \
    $tmp0-zp.ppm $tmp0-zn.ppm \
    -mode Concatenate -tile 1x6 cube-vstrip-ogl.jpg
    ##$tmp0-yp.ppm $tmp0-yn.ppm \   ##### swap 'em ??? had to reverse
    # also, for textures viewed from the "outside" (eg : earth texture on sphere, swap y in frag shader:
    # gl_FragColor = textureCube(cubemap2, vec3(texCoord0.x, -texCoord0.y, texCoord0.z));

rm $tmp0-*

К вашему сведению, я нашел несколько тестовых изображений ( https://www.terathon.com/wiki/index.php/Importing_a_Texture), и v-полоса находится в порядке и ориентации OpenGL, так что, возможно, это типично.

Другие вопросы по тегам