Programación Específica > Programación de Videojuegos

 Que Formato Utilizar?bmp,jpg...para Sprites

<< < (4/4)

Geo:
Por lo pronto pongo el archivo de cabecera de las funciones para manipular el bitmap (de 24 bits):

--- Código: Text --- #ifndef MYBMP_H#define MYBMP_H // El tipo de bitmap como entero#define BM 19778 // Valores de compresión del mapa de bits#define BI_RGB 0#define BI_RLE4 1#define BI_RLE8 2#define BI_BITFIELDS 3 // Constantes para el retorno de// int loadMyBmp(char *fileName, MYBMP *myBmp);#define SUCCESS 1#define E_FILENOTOPENED 2#define E_FILENOTVALID 3#define E_FILECOMPRESSED 4#define E_COLDEPTHNOTSUPPORTED 5#define E_MEMORYFAILURE 6#define E_FILENOTLOADED 7#define E_COULDNOTCREATEFILE 8 // Tipos de datos empleados en el programa,// no es necesario declararlos si incluímos// la cabecera &#60;windows.h&#62; (o &#60;winalleg.h&#62;// en el caso de emplear Allegro).typedef unsigned char BYTE;typedef unsigned short WORD;typedef unsigned long DWORD;typedef long LONG; // Cabecera de información del archivo de mapa de bits.typedef struct MYBMPFILEHEADER {  WORD  type;  DWORD fileSize;  WORD  reserved1;  WORD  reserved2;  DWORD dataOffset;} MYBMPFILEHEADER; // Cabecera del archivo de mapa de bits con información// sobre la imagen.typedef struct MYBMPINFOHEADER {  DWORD headerSize;  LONG  width;  LONG  height;  WORD  planes;  WORD  bitsPerPixel;  DWORD compression;  DWORD dataSize;  DWORD hRes;  DWORD vRes;  DWORD colors;  DWORD importantColors;} MYBMPINFOHEADER; // Tipo de dato para cada elemento de la// paleta de colores en caso de necesitarse.// Por el momento no se hace uso de ella porque// estamos trabajando con una imagen de 24 bits.typedef struct MYPALENTRY {  BYTE b;  BYTE g;  BYTE r;  BYTE reserved;} MYPALENTRY; // La estructura a usar por cada mapa de bits// que se emplee en el programa.typedef struct MYBMP {  MYBMPFILEHEADER fileHeader;  MYBMPINFOHEADER infoHeader;  MYPALENTRY *palette;  BYTE *data;} MYBMP; int loadMyBmp(char *fileName, MYBMP *myBmp);int saveMyBmp(char *fileName, MYBMP *myBmp);void printMyBmpInfo(const MYBMP *myBmp);void clearMyBmp(MYBMP *myBmp);void copyMyBmpHeaders(const MYBMP *source, MYBMP *output); #endif /* MYBMP_H */  Al principio hay muchos defines, no son necesarios, es simplemente que yo implementé la función de la carga del bitmap de tipo int, así puedo reconocer más fácilmente el error que se presente simplemente devolviendo la constante (macro) adecuada. Otra forma que se me ocurrió más tarde es usar la función de la carga del bitmap de la siguiente manera:

--- Código: Text --- MYBMP *loadMyBmp(char *fileName);  y así la usaría de esta forma:

--- Código: Text --- MYBMP *miBitmap = loadMyBmp(&#34;archivo.bmp&#34;);  (Así es como la implementó JuanK :P). Yo preferí la otra manera para poder encontrar más fácilmente los errores, sin embargo, también podría hacerlo creando una variable global en la que se guardara el último error corregido (al estilo de varias librerías :smartass:)

Con este código hice un programa que recibe como parámetro una imagen mapa de bits de 24 bits y la convierte a escala de grises, lo adjunto al mensaje por si quieren echarle un vistazo (sólo Blag lo probó, me comentó que no se podía ejecutar en WindowsXP.
Nota: este programa (creo) si funciona en WindowsXP, pero tiene un problema con la liberación de memoria: al checar para encontrar la causa del error que me mencionó Blag sólo me di cuenta de que daba error al tratar de liberar memoria usando free() en un par de instrucciones, entonces lo único que hice fué eliminar esas dos llamadas, o sea, el programa NO funciona como debiera (en cuanto a liberar la memoria), cuando chequé esto ya no quise corregir completamente el error (yo trabajo bajo Windows98 y tendría que conseguir una PC con WinXP para trabajar y pues la verdad me dió flojera :P). Eso si, pronto espero hacerme de una PC nueva y entonces corregiré este programa :kicking:.

Por cierto, ya nos desviamos bastante de la pregunta del título del post :P, no tengo mucha experiencia, pero en realidad el formato de imagen a utilizar para tus sprites dependerá de lo que prefieras manejar: menos espacio, mayor flexibilidad, etc. Por ejemplo, cargar un mapa de bits no es muy difícil, puedes crear tus propias funciones, para cargar una imagen JPG es un poco más complicado, lo mejor sería buscar una librería que se encargue de manejar estas imágenes (de hecho, sería lo mejor buscar una librería que se encargue de cargar las imágenes, es más cómodo y te enfocas rápidamente a lo que deseas en lugar de estar investigando sobre formatos gráficos). Una buena alternativa son las imágenes PNG, son un estándar abierto y según comentarios que he leído tienen buena calidad en poco espacio (en muchas ocasiones prefiero manejar PNG en lugar de GIF para imágenes para alguna página web, ya que si tratas de obtener imágenes de la misma calidad entre estos formatos la de formato PNG tiene menor tamaño, aunque claro, depende de varios parámetros :P).

Saludos,
José Jorge (Geo).

JuanK:
hola geo..
ya lo habia visto antes, pero no habia dicho nada.  :hola:

yo_aprendiz:
Juank si te ha sentado mal mi comentario, espero que me perdones, pero es desesperante intentar hacer algo que no tienes mucha idea y sin ayuda de ningún tipo, por eso quise pedir algo de código para irme orientando.  Por ejemplo, esto de quedarse unos dias sin avanzar nada y sin que te ofrezcan un poco de ayuda de lo que pides, ¿no crees que es para tirarse de los pelos?
  Desde mi modesta opinión, no cuesta ningún trabajo mostrar un poco de código fuente.

  Aquí dejo la carga del BMP 8bits que he encontrado por la red. Tambien se como cargar un TGA de 24 ó 32 bits sin comprimir, comprimido lo he conseguido sacar de una carga de textura de 3d pero las dimensiones tienen que ser de NxN y no me pregunteis el ¿por que?--> si quereis os lo paso, a ver si podemos cargarlo MxN.

  Espero que el que este en mi situación le ayude.

class CBmpFileReader
{
protected:
    BITMAPFILEHEADER m_BMPFileHead ; // guarda la cabezera de archivo
    BITMAPINFOHEADER m_BMPFileInfo ; // guarda la informacion del fichero
    RGBQUAD m_rgbPalette[COLORS] ; // guada la paleta
    BYTE* m_cImage ; // guarda la imagen

public:
    CBmpFileReader() ; // constructor
    ~CBmpFileReader() ; // destructor
    BOOL load(char *filename) ; // carga la imagen    
} ;

BOOL CBmpFileReader::load(char *filename){ //carga BMP de fichero
  HANDLE hfile; //manejador de fichero de entrada
  DWORD actualRead; //numero de bits actualmente leidos
  int image_size; //dimensión de la imagen(width*height)
  BOOL OK=TRUE; //no ha ocurrido ningún error todavia
  //abre el archivo de entrada para lectura
  hfile=CreateFile(filename,GENERIC_READ,FILE_SHARE_READ,
    (LPSECURITY_ATTRIBUTES)NULL,OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
  //comprueba si el archivo no puede abrirse
  if(hfile==INVALID_HANDLE_VALUE)return FALSE;
  //lee el titulo y la información de la estructura
  OK=ReadFile(hfile,&m_BMPFileHead,sizeof(m_BMPFileHead),
    &actualRead,NULL);
  if(OK)OK=ReadFile(hfile,&m_BMPFileInfo,
    sizeof(m_BMPFileInfo),&actualRead,NULL);
  //se asegura de que el BMP es de 8 bits
  if(OK)OK=m_BMPFileInfo.biBitCount==8;
  //coge la paleta del BMP
  if(OK)OK=ReadFile(hfile,m_rgbPalette,sizeof(m_rgbPalette),
    &actualRead,NULL);
  //sale fuera si algo salio mal
  if(!OK){CloseHandle(hfile); return FALSE;}
  //asignación de memoria para los datos de la imagen
  image_size=m_BMPFileInfo.biWidth*m_BMPFileInfo.biHeight;
  if(m_cImage)delete[]m_cImage; //borra cualquier espacio antiguo
  m_cImage=new BYTE[image_size]; //asigna nuevo espacio
  if(!m_cImage){ //comprueba si ha fallado la asignación de memoria
    CloseHandle(hfile); return FALSE;
  }
  //redondea a la anchura de la linea a un multiplo proximo a 4
  int width=(m_BMPFileInfo.biWidth+3)&~3;
  //lectura de la imagen BMP
  int i=0; //contador
  BYTE trash[4]; //para sostener la basura al final de cada línea
  int remainder=width-m_BMPFileInfo.biWidth; //anchura de basura
  while(OK&&i<m_BMPFileInfo.biHeight){
    //lee los datos
    OK=OK&&ReadFile(hfile,
      (BYTE*)(m_cImage+i*m_BMPFileInfo.biWidth),
      m_BMPFileInfo.biWidth,&actualRead,NULL);
    //lea basura al extremo de línea
    OK=OK&&ReadFile(hfile,trash,remainder,&actualRead,NULL);
    i++; //siguiente linea
  }
  if(!OK)delete[]m_cImage; //limpia si fallo
  //cierre y salida
  CloseHandle(hfile);
  return OK;
} //load

JuanK:

--- Citar ---Por ejemplo, esto de quedarse unos dias sin avanzar nada y sin que te ofrezcan un poco de ayuda de lo que pides, ¿no crees que es para tirarse de los pelos?

--- Fin de la cita ---
No.

--- Citar ---Desde mi modesta opinión, no cuesta ningún trabajo mostrar un poco de código fuente.
--- Fin de la cita ---
En efecto no es ningun trabajo pasarlo hecho, pero si es trabajo hacerlo y aun mas trabajo hacerlo con la suficiente voluntad e interes antes de pedir fuentes.

En todo caso adelante con tu ejercicio, y si tienes duas puedes preguntar.

Navegación

[0] Índice de Mensajes

[*] Página Anterior

Ir a la versión completa