Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Junxcosio

Iniciado por JunXCosio, 08 de Marzo de 2004, 02:48:46 PM

« anterior - próximo »

JunXCosio

 Ante todo agradecer a este foro la ayuda que me estais dando, ya que sino estaria muy trabao... (ole)

Y ahora comentaros una situación que yo creo que es muy curiosa y no tengo ni P..a idea de solucionar...

En la clase que tengo para las texturas llamada CTextura con la cual carga BMP y TGA sin ningun problema... he decidido pos meter JPG y ya que builder c++ tiene una libreria para ello (jpeg.hpp) pues la he usado...

y me he creado una funcion llamada CargarJPG y me lo carga sin problemas, pero me lo visualiza con los colores cambiados es decir el ROJO me lo pone como AZUL y la verdad por mas prueba que realizo no me sale... (nooo)

QUe es lo que me pasa????

el codigo de la funcion CargarJPG es este:


bool CTextura::CargarJPG (char *szNombreFichero)
{
   TJPEGImage *jpg;
   Graphics::TBitmap* Imagen;
   FILE *hFichero;
bool bResultado=false;

       if (szNombreFichero) //Comprobamos que el nombre de fichero sea correcto
      {
hFichero=fopen(szNombreFichero,"r"); //Cpmprueba si el fichero existe
if (hFichero) //Existe???
{
                  fclose(hFichero); //Cerramos el handle al fichero
                  Crear();             //Establece los parámetros GL para cargar
                  jpg = new TJPEGImage();
                    Imagen = new Graphics::TBitmap();

                        jpg->LoadFromFile(szNombreFichero);
                       Imagen->Assign(jpg);

                        m_nAncho=jpg->Width;
         
                        m_nAlto=jpg->Height;
                       gluBuild2DMipmaps(GL_TEXTURE_2D, 3, m_nAncho, m_nAlto, GL_RGB, GL_UNSIGNED_BYTE, Imagen->ScanLine [m_nAncho-1]);

                      glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
                     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);

                      bResultado=true;

                      //Borramos los Punteros iniciados
                        Imagen->ReleaseHandle();
                       delete Imagen;
                        delete jpg;
}
         }
          return bResultado;
}


Muchas gracias de antemano... (ole)  
a televisión es muy educativa, cuando alguien la enciende en casa, yo me marcho a la habitación a leer un libro. Groucho Marx

Lord Trancos 2

 Es obvio, no?

Debe de ser que los BMPs y TGAs tienen formato BGR y los JPEG deben de tenerlo RGB (o al reves).

Lo unico que tienes que hacer es despues de cargar el jpeg recorrertelo pixel a pixel e invertirle el orden de los canales.

No se si habra una forma mas facil y rapida  :rolleyes:  pero esa es la que se me ocurre asi a bote pronto.
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

JunXCosio

Cita de: "Lord Trancos 2"Lo unico que tienes que hacer es despues de cargar el jpeg recorrertelo pixel a pixel e invertirle el orden de los canales.
Muy bien, pero solo por curiosidad como lo hago???  (nooo)

Por que me has dejado de piedra.... :huh:  
a televisión es muy educativa, cuando alguien la enciende en casa, yo me marcho a la habitación a leer un libro. Groucho Marx

Lord Trancos 2

 Te pongo un ejemplo hecho en delphi, con un boton y un control TImage que tiene una imagen .BMP de 24 bits (ojo; que si no tiene esa profundidad de color no rulara). Con un jpeg deberia de ser mas o menos igual.


procedure TForm1.Button1Click(Sender: TObject);

var
 x,y,z : integer;
 P : PByteArray;
 b : byte;

begin
 with image1.Picture do
 begin
   for y := 0 to BitMap.height -1 do
   begin
     P := BitMap.ScanLine[y];
     for x := 0 to BitMap.width - 1 do
     begin
       z := x*3;
       // intercambiamos rojo y azul
       b := P[z];
       P[z] := P[z+2];
       P[z+2] := b;
     end;
   end;
 end;
 image1.Refresh;
end;


No te limites a implementarlo; intenta entenderlo.
Si no lo comprendes me lo dices y me explayo explicandotelo ;)
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

JunXCosio

 Correcto... lo he entendido mas o menos, lo unico que no tengo ni idea que coño es es la sentencia "with xxxx.xxxx do" pero me imagino que sea del delphi...

Tampoco se que tipo es PByteArray, por la pinta sera un puntero pero a donde???

y por ultimo porque multiplicas por 3 " z := x*3;"????

Muchas gracias

a televisión es muy educativa, cuando alguien la enciende en casa, yo me marcho a la habitación a leer un libro. Groucho Marx

Zaelsius

 La manera más fácil es que detectes la extensión .tga y utilices GL_BGR_EXT como formato al cargar la textura. Especificando ese flag puedes hacer la carga directamente en el caso de los .TGA.

Aunque pone _EXT, es un formato compatible con todas las tarjetas que existen. En el Red Book que tengo yo he mirado y no aparece, pero sí sale en la MSDN, asi que supongo que será parte del estándar OpenGL 1.2 (¿?).

Edit: me he fijado que quieres cargar JPG(dices q los TGA ya los carga el builder) bueno si son BGR lo de arriba te sirve igualmente : )

Lord Trancos 2

 
Cita de: "JunXCosio"Correcto... lo he entendido mas o menos, lo unico que no tengo ni idea que coño es es la sentencia "with xxxx.xxxx do" pero me imagino que sea del delphi...

Tampoco se que tipo es PByteArray, por la pinta sera un puntero pero a donde???

y por ultimo porque multiplicas por 3 " z := x*3;"????

Muchas gracias
Aunque veo que ZaelSiuS ha dado una respuesta mejor y mas facil, te respondo las dudas.

Lo de with xxxx.xxxx do es para evitar escribir varias veces lo mismo. Ejemplo.


Boton1.Caption := 'Pulsame si tienes huevos';
Boton1.Enabled := false;


es lo mismo que


with Boton1 do
begin
 Caption := 'Pulsame si tienes huevos';
 Enabled := false;
end;


con lo que si tienes que acceder muchas veces a propiedades o metodos de un objeto te ahorras de escribir el Boton1. delante de cada llamada. (aunque en este ejemplo he terminado escribiendo mas codigo). El with (o algo parecido) tambien deberia de estar en C Builder.

PByteArray es un puntero a un array de bytes (1 byte = 1 unsigned char).

Respecto a la tercera pregunta;
 - Cada scanline es un puntero que apunta a cada linea horizontal de la imagen.
 - Cada linea horizontal de la imagen esta formada por el numero de pixels de ancho * 3 bytes (uno para cada color; rojo, verde y azul RGB)
  - Por lo que Z es la posicion de cada pixel dentro del array de bytes de la linea.

Ejemplo visual:


                012345678901234  
 LINEA1 : RGBRGBRGBRGBRGB
 LINEA2 : RGBRGBRGBRGBRGB
 LINEA3 : RGBRGBRGBRGBRGB

(imaginate que los numeros son los indices de las columnas; por culpa de la fuente no me ha quedao bien)


Aqui tenemos una imagen con 3 lineas (scanlines), y 5 pixels de ancho (cada RGB es 1 pixel formado por 3 bytes). Cada scanline apunta al primer byte (la columna 0). Cada pixel esta formado por tres bytes (uno para el color rojo [R] otro para el verde [G] y otro para el azul ). Asi que si quiero leer el 3er pixel (indice 2) tengo que ir a la posicion 6 (osea multiplicar 2 * 3; el indice por el numero de canales). Y ese es el valor de Z.

Z es la posicion del primer byte de un pixel. Que en este ejemplo siempre es el color rojo.
 Pixel 0 = 0 x 3 = 0
 Pixel 1 = 1 x 3 = 3
 Pixel 2 = 2 x 3 = 6
 etc...

Si te fijas en el "ejemplo visual" de arriba veras que debajo de las columnas 0, 3, 6... pone siempre una R (Red).

Asi, para un determinado pixel;
Z = Rojo
Z+1 = Verde
Z+2 = Azul
Z+3 = Rojo del siguiente pixel.

Y como queriamos intercambiar el rojo por el azul pues habia que intercambiar Z por Z+2.

Las imagenes se suelen guardar en varios formatos. Unas veces veras... RGB,  RGBA, BGR, BGRA,.... otras veces veras A1R5G5B5, A8R8G8B8

En el primer caso indican solo el orden de los colores, y en el segundo caso indican el color y cuantos bits ocupan.

R = Red
G = Green
B = Blue
A = Alpha

Ejemplos;
 RGB - Rojo, verde y azul (3 canales)
 BGR - Azul, verde y rojo  (3 canales)
 RGBA - Rojo, verde, azul y alpha (4 canales)
 A1R5G5B5 - 1 bit para el canal Alpha, 5 para rojo, 5 para verde y 5 para azul (16 bits; 4 canales)
 A8R8G8B8 - 8bits (1 byte) para cada canal .

--------
Arf, arf.... espero haberte despejado mas dudas que interrogantes te hayan podido surgir,
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

JunXCosio

 Muchas gracias a todos, Implemente el codigo de intercambio y chapo... funciona...

Pero despues vi el mensaje de ZaelSiuS y puse GL_BGR_EXT y correcto...

Bueno muchas gracias y hasta proto que os aseguro que no tardare  :D  :D

Sois la hostia  (ole)  
a televisión es muy educativa, cuando alguien la enciende en casa, yo me marcho a la habitación a leer un libro. Groucho Marx






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.