HI,
this code below loads a tga file and tries to texturized with it a square.
The problem is the texture doesnt fit the square.
The down-left corner of the texture sets the center of the square…
#include "stdafx.h"
#include "GL/glut.h"
#include "GL/glaux.h"
#include "GL/glu.h"
#include "stdio.h"
typedef struct // Utilizamos esta estructura
{
GLubyte *imageData;
GLuint bpp;
GLuint width;
GLuint height;
GLuint texID;
} Imagen;
/*
---------------------
Carga_TGA
Carga un TGA en memoria. El TGA debe cumplir las siguientes caracterÃsticas:
Ser de 24 bits + Canal ALPHA. (32 bits) y SIN COMPRIMIR
El tamaño debe ser cuadrado (x=y) y 32x32 o 64x64 o 128x128 o 256x256
Devuleve un puntero a la imagen y el tamaño (variable tam) de la imagen
-----------------------
*/
GLubyte *CargaTGA(char *filename,int *tam)
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
GLubyte TGAcompare[12];
GLubyte header[6];
GLuint bytesPerPixel;
GLuint imageSize;
GLuint temp,i;
GLuint type=GL_RGBA;
Imagen texture;
GLubyte *aux;
FILE *file = fopen(filename, "rb");
if (file == NULL)
printf("Error1");
/* Esto abre y comprueba que es un TGA */
fread(TGAcompare,1,sizeof(TGAcompare),file);
if (memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0)
printf("Its a TGA file");
/* Leemos la cabecera*/
fread(header,1,sizeof(header),file);
/* Determinamos el tamaño */
texture.width = header[1] * 256 + header[0];
texture.height = header[3] * 256 + header[2];
/* Vemos las caracterÃsticas y comprobamos si son correctas*/
if( texture.width <=0 ||texture.height <=0 ||texture.width >256 ||texture.height !=texture.width ||( header[4]!=32))
{
fclose(file);
printf("Error - > Las caracteristicas de la imagen no son las correctas.");
}
/* Calculamos la memoria que será necesaria */
texture.bpp = header[4];
bytesPerPixel = texture.bpp/8;
imageSize = texture.width*texture.height*bytesPerPixel;
/* Reservamos memoria */
texture.imageData=(GLubyte *)malloc(imageSize);
/* Cargamos y hacemos alguna comprobaciones */
if( texture.imageData==NULL ||
fread(texture.imageData, 1, imageSize, file)!=imageSize)
{
if(texture.imageData!=NULL)
free(texture.imageData);
fclose(file);
printf("Error6");
}
/* El TGA viene en formato BGR con, lo pasamos a RGB */
for(i=0; i<(GLuint)(imageSize); i+=bytesPerPixel)
{
temp=texture.imageData[i];
texture.imageData[i] = texture.imageData[i + 2];
texture.imageData[i + 2] = temp;
}
fclose (file);
/* Ahora, cambiamos el orden de las lÃneas, como si hiciesemosun flip vertical. */
aux=(GLubyte *)malloc(imageSize);
for(i=0; i<texture.height; i++)
memcpy(&aux[imageSize-((i+1)*texture.width*4)],&texture.imageData[i*texture.width*4],texture.width*4);
/* tam devolverá el tamaño */
*tam=texture.width;
/* Liberamos memoria */
free(texture.imageData);
/* Todo fue bien!*/
return aux;
}
void RenderScene (void)
{
GLubyte *pImage = NULL;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Establecemos el color del cuadrado que queremos dibujar.
glColor3f(1.0f, 0.0f, 0.0f);
//glRectf(-1.0f, 1.0f, 1.0f, -1.0f);
glBegin (GL_QUADS);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-10.0f, -10.0f, 0.0f);
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 10.0f, -10.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 10.0f, 10.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-10.0f, 10.0f, 0.0f);
glEnd();
// Targa's are 1 byte aligned
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Load the TGA file, get width, height, and component/format information
pImage = CargaTGA("tga con alfa.tga", &iWidth);
// Use Window coordinates to set raster position
glRasterPos2i(0, 0);
// Escribe un bloque de pixels en el "frame buffer"
if(pImage != NULL)
glDrawPixels(iWidth, iWidth, GL_RGBA, GL_UNSIGNED_BYTE, pImage);
//Vinculamos la imagen a GL_TEXTURE_2D
glTexImage2D(GL_TEXTURE_2D,
0, // Nivel de detalle de la imagen. Generalmente el 0
3, // Especifica el numero de componentes de color de la textura sin contar con el alpha?
iWidth, // Anchura de la imagen. SIEMPRE POTENCIA DE 2
iWidth, // Altura
0, // Numero de pixels que debe tener el borde la textura. Toma 0,1 o 2
GL_RGBA, // Formato de la imagen.
GL_UNSIGNED_BYTE, // el tipo de datos en que va a ser pasada la informacion de la imagen cargada
pImage // Puntero que apunta a la imagen.
);
// Don't need the image data anymore
free(pImage);
////TEXTURE FILTERS
////Cuando la imagen de la textura no se adecua con el tamaño de la superficie
////que se quiere cubrir.
////MIN_FILTER: cuando la superficie sea mayor que la imagen.
////MAX_FILTER: cuando la superficie sea menor que la imagen.
////GL_LINEAR: en escaso se ha optado por una interpolacion lineal. Hay 6 mas.
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR
);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR
);
////WRAP FILTERS
////Cuando se pega la textura a una superficie debe indicarse la correspondecia
////entre las coordenadas de la textura y los vertices de dicha superficie.
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_S, // Se repite o se estira hacia el lado s? de la textura.
GL_CLAMP //La textura se puede estirar (GL_CLAMP) o se puede repetir (GL_REPEAT).
);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_WRAP_T, // Se repite o se estira hacia el lado s? de la textura.
GL_CLAMP //La textura se puede estirar (GL_CLAMP) o se puede repetir (GL_REPEAT).
);
////Una textura es un poster que adherimos al poligono, este poster lo podemos combinar con
////el color del poligono. Podemos elegir 4 modos de combinar el color del poligono con el
////color de la textura.
glTexEnvi(GL_TEXTURE_ENV, //Obligatorio siempre.
GL_TEXTURE_ENV_MODE, //Al poner aqui GL_TEXTURE_ENV_MODE, la siguiente linea puede valer GL_DECAL, GL_REPLACE (usan el color de la textura, ignoran el del poligono), GL_MODULATE o GL_BLEND.
GL_REPLACE //
);
glEnable(GL_TEXTURE_2D);
// Do the buffer Swap
glutSwapBuffers();
}
void SetupRC(void)
{
//Establece el color azul como color para borrar la ventana.
glClearColor(0.0f,0.0f,1.0f,1.0f);
}
///////////////////////////////////////////////////////////
// Called by GLUT library when the window has chanaged size
void ChangeSize(int w, int h)
{
GLfloat aspectRatio;
// Prevent a divide by zero
if(h == 0)
h = 1;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
glOrtho (-100.0, 100.0, -100 / aspectRatio, 100.0 / aspectRatio, 1.0, -1.0);
else
glOrtho (-100.0 * aspectRatio, 100.0 * aspectRatio, -100.0, 100.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main (void)
{
/*
InitDisplayMode: el modo de presentacion (display) que se usará al crear la ventana.
GLUT_SINGLE: usaremos una ventana de un solo buffer, pero en la mayoria del resto de
los casos (siempre que se requiera animacion) usaremos el doble buffer.
GLUT_RGB: modo de color que usaremos. (RGBA=RGB)
*/
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Simple");
//OJO: RenderScene aparece arriba como funcion
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
//OJO: RenderScene esta empalmada con otra funcion (mirar arriba)
//Establece el color de borrado de la pantalla pero no la borra.
SetupRC();
//Inicia la estructura principal de GLUT
glutMainLoop();
}