c++ - para - manual de programacion android pdf
¿Cómo puedo cargar 8 bit bmp con OpenGL? (2)
No debe usar glDrawPixels
, es una funcionalidad obsoleta. La mejor manera de hacerlo sería dibujar un cuadrante del tamaño de una pantalla (-1, -1 => 1,1 sin ninguna transformación de matriz) que pueda texturizar con estas imágenes.
Para las texturas, puede especificar varios formatos internos en glTexImage2D y funciones similares. Por ejemplo, puede usar el formato GL_R3_G3_B2
para obtener su tamaño de 8 bits, pero también podría usar los formatos comprimidos como S3TC . Podría, por ejemplo, pasar COMPRESSED_SRGB_S3TC_DXT1_EXT
, lo que debería reducir el tamaño de su imagen a 4 bits por píxel, probablemente en una calidad mejor que el formato de 8 bits. No puede usar JPEG como formato de compresión en OpenGL (es demasiado complejo).
Finalmente, ¿por qué quieres hacer esto a través de OpenGL? cambiar una imagen a una ventana normal probablemente le dará un rendimiento lo suficientemente bueno. Entonces, incluso podría almacenar su secuencia de imágenes como video y simplemente ajustar los marcos decodificados. Es muy poco probable que alguna vez tenga problemas de memoria en este caso.
Aquí está mi situación: necesito precargar 2000 imágenes y mostrarlas en secuencia para que sean una animación a 60 fps. Actualmente, estoy usando OpenGL para cargar archivos bmp, pero debido al límite de memoria, solo puedo precargar hasta 500+ imágenes. ¿Como puedó resolver esté problema? Hasta ahora puedo encontrar dos direcciones de soluciones: primero, tal vez pueda cargar imágenes de 8 bits en bmp para ahorrar memoria. Pero tengo dificultades para usar glDrawPixels . En segundo lugar, si es posible, ¿puedo cargar jpeg directamente? Gracias por cualquier consejo!
La razón para no usar video es que necesito cambiar a la velocidad de la animación omitiendo una o más imágenes como se puede ver en el código (imgCount + = stp; // stp significa cuántas imágenes se escapan, puede hacer que el video sea más rápido). Y en mi animación, la velocidad de fotogramas es importante, FPS inferior a 50 muestra parpadeo.
Aquí está el código:
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);
}
y mostraré la secuencia de imágenes, el código de visualización:
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();
}
Tal vez no necesita tener 2000 imágenes y mostrarlas a 60 fps en absoluto? La estabilidad de 25 fps es suficiente para cualquier película.
Te animo a que reconsideres tu problema original y propongas una solución más adecuada (video, animación, vectores, tal vez alguna otra cosa)
En cuanto a la pregunta original:
Si necesita imágenes solo una vez, póngalas en la memoria cuando las necesite y deséchelas justo después de mostrarlas.
Use imágenes empaquetadas DXT. Con una ligera degradación en la calidad, obtienes una relación de compresión constante x4 / x8.
OpenGL no es muy bueno para trabajar con texturas con paleta en la actualidad (muchos proveedores tienen implementaciones deficientes). Pero puedes implementar eso con sombreadores.