Как встроить любое изображение *.jpg в исполняемый файл win32 и использовать его во время выполнения

Я делаю проект на чистом OpenGL и FREEGLUT под названием Space Voyager. Проблема в том, что во время выполнения, когда программа вызывает функцию для загрузки всех изображений, игроку приходится ждать около 2 минут на экране загрузки!!!! Некоторые изображения имеют размер 16 МБ, в то время как в среднем 1 МБ. Всего около 20 изображений. Мне нужно загрузить все изображения, прежде чем смотреть уровень.

Теперь я использую SOIL для загрузки изображений в игру. В SOIL есть функция загрузки изображений из памяти SOIL_load_OGL_texture_load_from_memory(unsigned char *image_in_RAM,...).

Мое решение состоит в том, чтобы встроить все изображения в *.exe файл игры и использовать его во время выполнения, чтобы сэкономить время на загрузку всех изображений в игре.

Я почти не понимаю, как точно вставлять изображения jpg в исполняемый файл и
использовать его во время выполнения как unsigned char* imagePointer ?????


person sohail_chd    schedule 07.05.2015    source источник
comment
Вы профилировали свой код, чтобы убедиться, что загрузка является узким местом в вашем приложении?   -  person EdChum    schedule 07.05.2015
comment
Вы можете использовать файлы .tga вместо .jpg? Это формат, предназначенный для текстур. Он тяжелее на вашем диске, потому что файлы обычно больше, чем .jpg, но загружается немного быстрее.   -  person Aracthor    schedule 07.05.2015
comment
Логика кажется шаткой, что одни и те же данные будут загружаться с диска в память быстрее, если они находятся в exe-файле.   -  person Drew Dormann    schedule 07.05.2015
comment
См. LoadResource и связанные с ним материалы. msdn.microsoft.com/ en-us/library/windows/desktop/   -  person deviantfan    schedule 07.05.2015
comment
Я не вижу, как это будет быстрее. Данные по-прежнему необходимо загружать с диска, а JPG (или любой другой формат) по-прежнему необходимо декодировать. Он просто из другого места на диске...   -  person Steve    schedule 07.05.2015
comment
Я предполагаю, что встраивание jpg в исполняемый файл не является правильным решением проблемы. Я понял суть. Мне нужно создать многопоточный загрузчик ресурсов, чтобы сэкономить время на экране загрузки. БЛАГОДАРНОСТЬ!!!!!   -  person sohail_chd    schedule 07.05.2015


Ответы (1)


Мое решение состоит в том, чтобы встроить все изображения в *.exe файл игры и использовать его во время выполнения, чтобы сэкономить время на загрузку всех изображений в игре.

Как вы полагаете, это поможет? Неважно, какая метка имеет данные на устройстве хранения. Усилия для компьютерной системы неизменны. Не имеет значения, размещаете ли вы ресурсы в отдельном файле, для компьютера это не имеет никакого значения.

Некоторые изображения имеют размер 16 МБ, в то время как в среднем 1 МБ. Всего около 20 изображений. Мне нужно загрузить все изображения, прежде чем смотреть уровень.

Это не так много данных. 20 изображений со средним размером 1 МБ, это в среднем 20 МБ. Даже медленные жесткие диски с вращающейся ржавчиной могут легко обеспечить скорость 10 МБ/с. Гораздо более распространенная цифра составляет от 50 МБ до 80 МБ / с для дешевых жестких дисков в наши дни. Где бы ни было ваше узкое место, это не ввод-вывод.

Также имейте в виду, что если вы встроили файлы RAW в исполняемый файл, вы вынуждаете систему передавать больше данных через ввод-вывод; сжатие изображений в исполняемом файле по-прежнему требует распаковки. Учитывая тот факт, что большую часть времени вы привязаны к вводу-выводу, а не к процессору, сжатые изображения в хранилище желательны.

ОБНОВИТЬ

Ваша проблема заключается в следующем:

SOIL_FLAG_POWER_OF_TWO

Вы просите почву изменить масштаб каждого изображения до следующего большего размера, который является степенью 2. До OpenGL-2 это нужно было сделать, поскольку OpenGL-1 принимал только изображения размера степени 2 для текстур. С тех пор, как вышел OpenGL-2 (а в наши дни вам будет трудно найти GPU, который не поддерживает OpenGL-2), это ограничение было снято.

Еще одна трудоемкая операция — генерация мип-карт (SOIL_FLAG_MIPMAPS), поскольку для этого требовалось генерировать целую пирамиду изображений для каждого изображения. Теперь мипмаппинг — это то, что вы обычно хотите иметь. Если у вас есть контекст ›=OpenGL-3, вы можете использовать встроенный в OpenGL генератор mipmap. Кроме того, вы просите SOIL сгенерировать для вас идентификаторы текстур, но сами создаете идентификаторы. Используйте любой из них, но не используйте оба.

Это приводит к следующим предлагаемым изменениям в вашем коде:

while( GL_NO_ERROR != glGetError() ); // flush OpenGL errors;
GLint gl_version;
glGetIntegerv(GL_MAJOR_VERSION, &gl_version);
if( GL_NO_ERROR != glGetError() ) {
    // GL_MAJOR_VERSION enum supported only since OpenGL-3
    gl_version = 1;
    while( GL_NO_ERROR != glGetError() ); // flush OpenGL errors;
}
bool const gl3_or_later = 3 <= gl_version;

tex_id = SOIL_load_OGL_texture(
        fileNameConstant,
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        gl3_or_later ? 0 : SOIL_FLAG_MIPMAPS );
if( gl3_or_later ) {
    glBindTexture(GL_TEXTURE_2D, tex_id);
    glGenerateTextureMipmap(GL_TEXTURE_2D);
    glTexParameteri(
        GL_TEXTURE_2D,
        GL_TEXTURE_MIN_FILTER,
        GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(
        GL_TEXTURE_2D,
        GL_TEXTURE_MAX_LEVEL,
        1000);
}
person datenwolf    schedule 07.05.2015
comment
На самом деле идут все необходимые образы, объем которых составляет ровно 167 МБ. Я пытаюсь загрузить их до начала игрового уровня. Мне нужно использовать другой поток для загрузки ресурсов. Надеюсь, мне удастся сэкономить часть времени, затрачиваемого на экран загрузки. !!!! Спасибо. - person sohail_chd; 07.05.2015
comment
Могу ли я спросить вас, есть ли способ загрузить и связать любой предварительно скомпилированный объектный код во время выполнения. Что-то близкое к этому или что-то в этом роде?? - person sohail_chd; 07.05.2015
comment
@Sohail_CHD: Какая разница, что это объектный код? Да, вы можете поместить данные изображения в объектный код, но для чего это нужно. Все, что вы получаете, это файл с немного другой структурой, но нагрузка на передачу изображения на GPU не меняется! Для компьютера это не имеет абсолютно никакого значения! Глубоко внутри себя вы должны понимать: Нет разницы между кодом и данными! Данные есть код, а код есть данные. Да, вы можете засунуть изображения в PE и бросить на него LoadLibrary / dlopen, но за кулисами все сводится к открытию и чтению файла. - person datenwolf; 07.05.2015
comment
@Sohail_CHD: 167 МБ - это не так уж много данных. Даже с медленным жестким диском это будет загружаться менее чем за 4 секунды. Проблема, с которой вы столкнулись, заключается в том, что SOIL, вероятно, не самый эффективный загрузчик изображений. Кроме того, создание MIP-карт в Интернете стоит дорого. Вы бы выиграли гораздо больше, если бы предварительно вычислили MIP-карты. НЕ ПЫТАЙТЕСЬ УПАКОВАТЬ ИЗОБРАЖЕНИЯ ПО-ДРУГОМУ! это не даст ничего хорошего. Вместо этого обратите внимание на более эффективные загрузчики JPEG (TurboJPEG, libjpeg-turbo). Также может помочь отображение памяти, но если вам все равно нужно хранить файл while в памяти для декодирования, простое чтение работает так же хорошо. - person datenwolf; 07.05.2015
comment
Никогда так быстро не учись. Отличные советы. Я покончу с ПОЧВОЙ и попробую что-нибудь, как вы предложили. Вилен Данк !!! - person sohail_chd; 07.05.2015
comment
@Sohail_CHD: В случае, если вопрос касается не использования объектного кода для изображений, а динамической загрузки логики программы. Что ж, скомпилируйте его в DLL/так и используйте LoadLibrary/dlopen. Хотя для игры обычно требуется что-то вроде встраиваемого языка сценариев, который выполняет JIT-компиляцию. Я предлагаю вам взглянуть на Lua (lua.org) или Squirrel (squirrel-lang.org). - person datenwolf; 07.05.2015
comment
@Sohail_CHD: Просто чтобы дать вам представление о том, что возможно: программное обеспечение, которое я пишу для жизни, имеет дело с данными изображения размером в несколько гигабайт (гигабайт), и я могу удобно загружать и просматривать набор данных 35 гигабайт практически мгновенно (избегая загрузки все это полностью и вместо этого читать необходимые части по запросу). - person datenwolf; 07.05.2015