如何使用 OpenGL 加载 8 位 bmp

How can I load 8 bit bmp with OpenGL?

本文关键字:bmp 加载 何使用 OpenGL      更新时间:2023-10-16

这是我的情况:我需要预加载 2000 张图像并按顺序显示它们以 60 fps 的速度制作动画。目前,我正在使用OpenGL加载bmp文件,但由于内存限制,我最多只能预加载500+图像。如何解决这个问题?到目前为止,我可以提出两个方向的解决方案:首先,也许我可以加载 8 位 bmp 图像以节省内存。但是我在使用glDrawPixels时遇到困难。 其次,如果可能的话,我可以直接加载jpeg吗?感谢您的任何建议!

不使用视频的原因是我需要通过跳过一个或多个图像来更改为动画速度,如您在代码中看到的那样(imgCount+=stp;//stp 表示要转义的图像数量。 它可以使视频更快)。在我的动画中,帧速率很重要,低于 50 的 FPS 显示闪烁。

这是代码:

void Frame::LoadBMP(void){
 FILE *in;

 in=fopen(file,"rb");//open file 
 if(in==NULL){
     exit(0);
 }
 fread(&(this->bmfh),sizeof(BITMAPFILEHEADER),1,in);//read bmp file header
 fread(&(this->bmih),sizeof(BITMAPINFOHEADER),1,in);//read bmp infomation header
 colours=new RGBQUAD[bmih.biBitCount];
 fread(colours,sizeof(RGBQUAD),bmih.biBitCount,in);//read bmp colour table
 size=bmfh.bfSize-bmfh.bfOffBits;
 tempPixelData=new GLubyte[size];
 if(tempPixelData==NULL) {
     fclose(in);
 }
 fread(tempPixelData,sizeof(GLubyte),size,in);//read bmp image data
 fclose(in);
}

我将显示图像序列,显示代码:

void display(void){
static clock_t start=clock();
static clock_t end=clock();
CurrtempPixelData=msFrame[offset]->tempPixelData;
glEnable(GL_ALPHA_TEST);
glEnable(GL_BLEND);
glDrawPixels(frWidth, frHeight, GL_RGBA, GL_UNSIGNED_BYTE, msFrame[offset]->tempPixelData);
for(int i=0;i<m;i++){
    clock_t c=clock();
}
glutSwapBuffers();
imgCount+=stp; // stp means how many images to escape. it can make video faster.
offset=imgCount%numFrame;
glutPostRedisplay();
}

你不应该使用glDrawPixels,它是不推荐使用的功能。最好的方法可能是绘制一个屏幕大小的四边形(-1,-1 => 1,1,1,没有任何矩阵变换),您可以使用这些图像进行纹理处理。

对于纹理,您可以在glTexImage2D和类似函数中指定几种内部格式。例如,您可以使用 GL_R3_G3_B2​ 格式来获取 8 位大小,但也可以使用 S3TC 等压缩格式。例如,您可以传递 COMPRESSED_SRGB_S3TC_DXT1_EXT ,这应该将您的图像大小减小到每像素 4 位,可能比 8 位格式的质量更好。您不能在OpenGL中使用JPEG作为压缩格式(它太复杂了)。

最后,为什么要通过OpenGL来做到这一点?将图像传送到常规窗口可能会给你带来足够的性能。然后,您甚至可以将图像序列存储为视频,并仅对解码的帧进行比拼。在这种情况下,您不太可能遇到内存问题。

也许您根本不需要拥有 2000 张图像并以 60fps 显示它们?稳定的 25fps 对于任何电影来说都足够了。

我鼓励你重新思考你原来的问题,并提出一个更合适的解决方案(视频、动画、矢量,也许还有其他东西)

至于最初的问题:

如果您只需要一次图像 - 在需要时将它们放入内存,并在显示后立即丢弃它们。

使用 DXT 打包映像。随着质量的轻微下降,您将获得恒定的x4/x8压缩比。

OpenGL现在不太擅长处理调色板纹理(许多供应商的实现很差)。但是您可以使用着色器实现这一点。