如何在win32可执行文件中嵌入任何* .jpg图像并在运行时使用它

时间:2015-05-07 12:48:13

标签: c++ image opengl resources soil

我正在使用名为Space Voyager的纯OpenGL和FREEGLUT进行项目。问题是在运行期间,当程序调用一个函数加载所有图像时,播放器必须在加载屏幕上等待大约2分钟!一些图像类似于16 MB文件,否则平均为1 MB。总共有20张图片。我需要在启动关卡之前加载所有图像。

现在我正在使用SOIL来加载游戏中的图像。 SOIL具有从内存加载图像的功能SOIL_load_OGL_texture_load_from_memory(unsigned char * image_in_RAM,...)。

我的解决方案是将所有图像嵌入游戏的* .exe文件中并在运行时使用它,以节省加载游戏中所有图像的时间。

我几乎迷失了如何将jpg图像完全嵌入可执行文件和中 在运行时使用它作为unsigned char * imagePointer ?????

1 个答案:

答案 0 :(得分:1)

  

我的解决方案是将所有图像嵌入到游戏的* .exe文件中,并在运行时使用它,以节省加载游戏中所有图像的时间。

你觉得这会怎么做?存储设备上的数据标签与其无关。计算机系统的努力是不变的。如果将资源放在一个单独的文件中与计算机无关,那就没有任何意义了。

  

某些图像类似于16 MB文件,否则平均为1 MB。总共有20张图片。我需要在启动关卡之前加载所有图像。

这不是很多数据。平均1MiB的20张图像,平均为20MiB。即使是旋转生锈的慢速HDD盘也可以轻松提供10MiB / s。如今,对于廉价的硬盘驱动器来说,更常见的数字是50MiB到80MiB / s。无论你的瓶颈在哪里,都不是I / O.

另外请记住,如果您将文件RAW嵌入到可执行文件中,则会迫使系统通过I / O推送更多数据;在可执行文件中压缩图像仍然需要您解压缩。鉴于大多数情况下你的I / O绑定而不是CPU绑定存储中的压缩图像是可取的。

更新

你的问题是:

SOIL_FLAG_POWER_OF_TWO

你要求土壤将每个图像重新缩放到下一个更大的尺寸,这是2的幂。在OpenGL-2之前必须完成这个,因为OpenGL-1只能接受2的2倍幂图像。纹理。自从OpenGL-2问世以来(你现在很难找到一台不支持OpenGL-2的GPU),这种约束已被解除。

另一个耗时的操作是生成mipmap(SOIL_FLAG_MIPMAPS),因为这需要为每个图像生成整个图像金字塔。现在mipmapping是你通常想要的东西。如果你有一个上下文> = OpenGL-3,你可以使用内置mipmap生成器的OpenGL。您还要求SOIL为您生成纹理ID,但您也可以自己生成ID。使用其中任何一个,但不要同时使用它们。

这会导致您的代码中出现以下建议的更改:

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);
}