Mapeo de Texturas - sis2430.files.wordpress.com · Tipos de filtrado void glTexParameteri...
Transcript of Mapeo de Texturas - sis2430.files.wordpress.com · Tipos de filtrado void glTexParameteri...
Mapeo de Texturas
Mapeo de texturas
Texturas 1D
• Para definir la textura:void glTexImage1D (GLenum objetivo, GLint nivel,
GLint componentes, GLsizei ancho, GLint borde, GLenum formato, GLenum tipo, const GLvoid *pixels)
donde:– objetivo vale siempre GL_TEXTURE_1D
– nivel indica el nivel de detalle (0 para texturas individuales)
– componentes vale 1 (modo índice), 3 (RGB) ó 4 (RGBA)
– ancho indica el ancho en pixel del mapa de textura (debe ser potencia de 2)
– borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
– formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
– tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
– pixels es un puntero a los pixels de la textura
Ejemplo
• Para activar el mapeo de texturas 1D:void glEnable (GL_TEXTURE_1D)
unsigned char ArcoIris[8][3] = {{ 0x3f, 0x00, 0x3f }, // Violeta oscuro{ 0x7f, 0x00, 0x7f }, // Violeta { 0xbf, 0x00, 0xbf }, // Malva { 0x00, 0x00, 0xff }, // Azul { 0x00, 0xff, 0x00 }, // Verde { 0xff, 0xff, 0x00 }, // Amarillo { 0xff, 0x7f, 0x00 }, // Naranja{ 0xff, 0x00, 0x00 } // Rojo
};
glTexImage1D (GL_TEXTURE_1D, 0, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, ArcoIris);
Coordenadas de la textura
• Para hacer corresponder las coordenadas de la textura con las de la superficie:void glTexCoord1f (GLfloat s)
S=0.0 S=1.0
glBegin(GL_QUADS);glTexCoord1f (0.0);glVertex3f (0, 0, 0);
glTexCoord1f (1.0);glVertex3f (8, 0, 0);
// glTexCoord1f (1.0);glVertex3f (8, 8, 0);
glTexCoord1f (0.0);glVertex3f (0, 8, 0);
glEnd();
(0,8) s=0.0
(8,0) s=1.0
(8,8) s=1.0
(0,0) s=0.0
Variando las coordenadas
• Virtualmente la textura se extiende para cualquier valor de s
S=0.0 S=1.0 S=2.0 S=3.0S=-1.0
• Podemos asignar a un vértice cualquier valor de s
s=0.0 s=1.0
s=1.0 s=1.0
s=0.0 s=2.0
s=0.0 s=2.0
s=0.0 s=1.0
s=-1.0 s=2.0
Filtrado• Al mapear la imagen de textura sobre una superficie, los texels no se
van a corresponder exactamente con los pixels– Si la superficie es mayor que la textura, cada pixel se corresponderá con
un trozo pequeño de texel ---> Magnificación– Si la superficie es menor que la textura, cada pixel se corresponderá con
una conjunto de texels contiguos ---> Minificación
Texels
PixelsPixels
Tipos de filtrado
void glTexParameteri (GL_TEXTURE_1D, GLenum filtro, GLint valor)
GL_LINEAR
GL_NEARESTGL_TEXTURE_MAG_FILTER
GL_TEXTURE_MIN_FILTER
TexturaGL_NEAREST GL_LINEAR
unsigned char Arco[8][3] = {...}
// Habilitamos el mapeo de texturasglEnable(GL_TEXTURE_1D);
// Indicamos el tipo de filtradoglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// Creamos la texturaglTexImage1D(GL_TEXTURE_1D,0,3,8,0,GL_RGB,GL_UNSIGNED_BYTE,Arco);
// Indicamos el modo de mapeo //(volcar el valor de los texels directamente sobre los pixels)glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// dibujamos el objetoglBegin(...);
glTexCoord1f (..);glVertex3f (...);...
glEnd();
Ejemplo final con texturas 1D
Modos de mapeo• Para establecer el modo de mapeo:
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GLint valor)
donde valor puede tomar 3 valores:
– GL_DECAL: el valor del texel se copia directamente al pixel
– GL_MODULATE: el valor del texel se escala por el color del objeto
– GL_BLEND: el valor del texel se usa para interpolar entre el color del objeto y un color constante definido para la textura, mediante la función
glTexEnvfv(GL_TEXTURE_ENV,GL_TEXTURE_ENV_COLOR,GLfloat color[4])
ENV_COLOR
Texturas 2D
• Para definir la textura:void glTexImage2D (GLenum objetivo, GLint nivel,
GLint componentes, GLsizei ancho, GLsizei alto, GLint borde, GLenum formato, GLenum tipo, const GLvoid *pixels)
donde:– objetivo vale siempre GL_TEXTURE_2D
– nivel indica el nivel de detalle (0 para texturas individuales)
– componentes vale 1 (modo índice o luminancia), 3 (RGB) ó 4 (RGBA)
– ancho indica el ancho en pixels del mapa de textura (debe ser potencia de 2)
– alto indica el alto en pixels del mapa de textura (debe ser potencia de 2)
– borde indica el número de pixels que forman el borde de la textura (0, 1 ó 2)
– formato indica el formato de los pixels: GL_RED, GL_RGB, GL_LUMINANCE
– tipo indica el tipo de dato de los pixels: GL_UNSIGNED_INT, GL_FLOAT
– pixels es un puntero a los pixels de la textura
Ejemplo
• Para activar el mapeo de texturas 2D:void glEnable (GL_TEXTURE_2D)
unsigned char Colores[4][4][3] = {{{64,0,0}, {128,0,0}, {192,0,0}, {255,0,0}}, // Rojos{{0,64,0}, {0,128,0}, {0,192,0}, {0,255,0}}, // Verdes{{0,0,64}, {0,0,128}, {0,0,192}, {0,0,255}}, // Azules{{64,64,0}, {128,128,0}, {192,192,0}, {255,255,0}} // Amarillos
};
glTexImage2D (GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, Colores);
Coordenadas de la textura
• Para hacer corresponder las coordenadas de la textura con las de la superficie:void glTexCoord2f (GLfloat s, GLfloat t)
glBegin(GL_QUADS);glTexCoord2f (0.0, 0.0);glVertex3f (0, 0, 0);
glTexCoord2f (1.0, 1.0);glVertex3f (4, 0, 0);
glTexCoord2f (1.0, 0.0);glVertex3f (4, 4, 0);
glTexCoord2f (0.0, 0.0);glVertex3f (0, 4, 0);
glEnd();
(s,t)=(1,0)(s,t)=(0,0)
(s,t)=(0,1) (s,t)=(1,1)
(0,4) (s,t)=(0,0) (4,4) (s,t)=(1,0)
(0,0) (s,t)=(0,1) (4,0) (s,t)=(1,1)
Variando las coordenadas
• Virtualmente la textura se extiende para cualquier valor de s y de t
(s,t)=(0,1)
(s,t)=(0,0) (s,t)=(1,0)
(s,t)=(1,1)
(s,t)=(1,-1)(s,t)=(-1,-1)
(s,t)=(0.5,2)
• Podemos asignar a un vértice cualquier valor de s y de t
Leyendo la textura de un fichero (C++ Builder)
Graphics::Tbitmap *bitmap; // objeto donde leeremos la imagenunsigned char *textura; // vector donde se leerá la texturaTColor tcolor; // variable donde se lee cada pixelunsigned char *color = (unsigned char *) &tcolor;int dimx, dimy, n=0;
bitmap = new Graphics::TBitmap; // creamos el objeto bitmapbitmap->LoadFromFile(”textura.bmp"); // volcamos la imagen en éldimx = bitmap->Width; dimy = bitmap->Height; // potencias de 2textura = (unsigned char *) malloc (dimx*dimy*3);
for (int j=0; j<dimy; j++) for (int i=0; i<dimx; i++) { // leemos el color pixel
tcolor = bitmap->Canvas->Pixels[i][j];textura[n++] = color[0]; // leemos la componente rojatextura[n++] = color[1]; // leemos la componente verdetextura[n++] = color[2]; // leemos la componente azul
}delete bitmap; // borramos el objeto bitmap
glTexImage2D (GL_TEXTURE_2D, 0, 3, dimx, dimy, 0, GL_RGB, GL_UNSIGNED_BYTE, textura);
Texturas sobre una malla de vértices
• Al texturar un objeto hay que especificar la coordenada de textura para cada vértice
glTexCoord2f (.., ..);glVertex3f (.., .., ..);
glTexCoord2f (.., ..);glVertex3f (.., .., ..);
glTexCoord2f (.., ..);glVertex3f (.., .., ..);
glTexCoord2f (.., ..);glVertex3f (.., .., ..);
Generación automática de coordenadas
• Podemos decirle a OpenGL que genere automáticamente las coordenadas de textura para cada vértice del objetovoid glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GLint param)
GL_SPHERE_MAP
GL_EYE_LINEAR
GL_OBJECT_LINEAR
• Para cada vértice, la coordenada de textura vendrá dada por:
s = x*plano_s[0] + y*plano_s[1] + z*plano_s[2] + w*plano_s[3]
– donde (x,y,z,w) son las coordenadas homogéneas del vértice,
– y plano_s viene definido por la llamada a la función:
void glTexGenfv (GL_S, GL_OBJECT_PLANE, GLfloat plano_s[4])
Ejemplo con texturas 1D
GLfloat plano_s[4] = {1, 0, 0, 0}; // s=xglTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);glTexGenfv (GL_S, GL_OBJECT_PLANE, plano_s);glEnable (GL_TEXTURE_GEN_S);
x
y
z
GL_DECAL
GL_BLEND
Ejemplo con texturas 2D
GLfloat plano_s[4] = {1, 0, 0, 0}; // s=xGLfloat plano_t[4] = {0, 1, 0, 0}; // t=yglTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);glTexGenfv (GL_S, GL_OBJECT_PLANE, plano_s);glEnable (GL_TEXTURE_GEN_S);glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);glTexGenfv (GL_T, GL_OBJECT_PLANE, plano_t);glEnable (GL_TEXTURE_GEN_T);
xy
z
GL_BLEND GL_DECAL
textura
Matrices de textura
• Las coordenadas de textura también se pueden transformar a través de la matriz de textura.
glMatrixMode (GL_TEXTURE)
• Las coordenadas de textura se pueden trasladar, escalar y rotar.
• Ejemplo: para simular la ondulación del agua podemos trasladar la textura con un timer
Problemas con las texturas individuales
• Cuando la proyección del objeto con textura ocupa pocos pixels en la pantalla, no tiene sentido trabajar con un mapa de textura grande
xz
y
256
64
8256
256
Texturas multimapa (Mipmaps)
• Se generan varias imágenes de la textura con distinta resolución– las resoluciones son siempre potencias de dos– hay que acabar en las imágenes 1x1
glTexImage2D (GL_TEXTURE_2D,0,3,2n,2n,0,GL_RGB,..,imagen_0);glTexImage2D (GL_TEXTURE_2D,1,3,2n-1,2n-1,0,GL_RGB,..,imagen_1); ....glTexImage2D (GL_TEXTURE_2D,n,3,1,1,0,GL_RGB,..,imagen_n);
2n 2n-12n-2
2n-3
2 1
• OpenGL decide qué imagen usar automáticamente, en función del tamaño de la proyección del objeto
Filtrado con mipmaps
GL_LINEAR_MIPMAP_LINEAR
• Para decidir qué texels deben usarse para calcular el color de cada pixel:glTexParameteri(GL_TEXTURE_1D,GL_TEXTURE_MIN_FILTER, GLint valor)
GL_LINEAR_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_NEAREST_MIPMAP_NEAREST
Texels deimagen i
Texels deimagen i+1
PixelsFiltrado
Generación automática de mipmaps
• Si queremos que OpenGL calcule automáticamente las imágenes de textura de menor resolución, a partir de la imagen original:
void gluBuild2DMipmaps(GL_TEXTURE_2D, GLint componentes, GLsizei ancho, GLsizei alto, GLenum formato, GLenum tipo, const GLvoid *pixels)
• La anterior llamada es equivalente a
unsigned char imagen_0 [256][256][3] = {....}unsigned char imagen_1 [128][128][3] = {....}....unsigned char imagen_8 [1][1][3] = {....}
glTexImage2D (GL_TEXTURE_2D, 0, 3, 256, 256, GL_RGB, GL_UNSIGNED_BYTE, imagen_0)
glTexImage2D (GL_TEXTURE_2D, 1, 3, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, imagen_1)
....glTexImage2D (GL_TEXTURE_2D, 8, 3, 1, 1, GL_RGB,
GL_UNSIGNED_BYTE, imagen_8)
Objetos de textura
• Se usan para acelerar la carga de texturas en memoria.
• Para reservar un número de objetos de textura:void glGenTextures (GLsizei num, Gluint *nombres)
• Para asociar una textura a cada índice reservado:void glBindTexture (GLenum num, Gluint nombre)
– La primera vez que se llama a esta función, se carga la textura en memoria.
– Las demás veces, sólo selecciona la textura, por lo que no hace falta cargarla de nuevo
• Para liberar memoria, en caso de que dejemos de usar la textura:void glDeleteTextures (GLsizei num, const Gluint *nombres)
EjemploGLuint texturas[3];
void Init(){
glGenTextures (3, texturas);
// textura del sueloglBindTexture (GL_TEXTURE_2D, textura[0]);glTexParameteri (…);glTexImage2D (GL_TEXTURE_2D, …);
// textura de la paredglBindTexture (GL_TEXTURE_2D, textura[1]);glTexParameteri (…);glTexImage2D (GL_TEXTURE_2D, …);…
}
void Paint(){
// pinto el sueloglBindTexture (GL_TEXTURE_2D, textura[0]);glBegin (…);
…glEnd();
// pinto la paredglBindTexture (GL_TEXTURE_2D, textura[1]);glBegin (…);
…glEnd();
}