Ya basta de aplicar texturas planas a los típicos cubitos 3D, en este
ejemplo voy a hacer lo mismo :-) pero a un objeto mas complicado, en este caso
una malla 3D que la tengo definida en un archivo de texto head.dat, que
tiene todos sus datos, vértices, caras, coordenadas de textura definidas
en ese archivo.
La imagen que utilizo como textura esta en formato BMP de 512x512 pixels, al
aplicarse la textura esta es filtrada para que se produzca un ajuste exacto
entre los pixels de la textura y los pixels de la pantalla también tengo
una fuente de luz, y utilizo smoothing (suavizado de caras) para que se vea
mejor. Gran parte del código es similar al de mis ejemplos anteriores.
La imagen de abajo es una captura del programa, si observan hacia los costados
hay un estiramiento de la textura, por eso mismo puse la grilla para tener esa
referencia, eso se debe a que el mapeo de textura es del tipo plano, la idea
es que la textura envuelva al modelo, eso se logra aplicando un mapeo UV, cosa
que voy a hacer en el próximo ejemplo de texturas.
El formato es el siguiente, primero indico el numero total de vértice
de la malla, después en cada linea las coordenadas de los vértice
y textura.
Al finalizar de listar todos los vértice, indico el numero de caras que
tiene , la siguientes lineas me indica que vértice forman esa cara, un
flag que me identifica el material y finalmente el grupo de suavizado.
El archivo con los datos de la malla están aquí.
Vertices: 1469 -1.688360 -4.163916 2.318413 0.413706 0..288504 -1.713966 -4.156930 2.296686 0.412293 0..288905 -1.675014 -4.160190 2.301188 0.414442 0..288718 ...... ...... ...... 1.456195 0.323630 1.695802 0.587216 0.546147 1.869924 0.433806 1.828177 0.610045 0.552473 2.244856 0.414572 1.811106 0.630733 0.551368 Faces: 2849 0 1 2 MaterialID: 0 Smoothing: 1 3 4 5 MaterialID: 0 Smoothing: 1 ...... ...... ...... 1135 1332 743 MaterialID: 0 Smoothing: 1 |
La imagen de abajo es la que utilizo como textura, aquí la tengo en 360x360 pixels y en formato JPG, para poder usarla desde el programa la tienes que redimensionar a 512x512 pixel y grabarla como BMP, con cualquier programa de adición de imágenes, ejemplo Photoshop.
El programa tiene los siguientes archivos.
El código fuente, con el proyecto para VisualC++ 6.0 lo podes bajar de aquí.
#include <GL/glaux.h> #include <GL/glut.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "textures.h" struct Point3f { float x, y, z; float u, v; }; struct Face { int material; int vertexIndices[3]; int smoothingGroup; Point3f normal[3]; Point3f faceNormal; }; struct Object3D { int nVertices; Point3f *pVertices; int nFaces; Face *pFaces; }; //parametros y ubicacion de la fuente de luz float LightPos[] = { 0.25f, 0.2f, 1.0f, 0.0f}; float LightAmb[] = { 0.1f, 0.1f, 0.1f, 1.0f}; float LightDif[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float LightSpc[] = { 1.0f, 1.0f, 1.0f, 1.0f}; Object3D obj; COGLTexture MyTextura; GLfloat angulo=0.0f; void CargarModelo(char *filename, Object3D &object) { ......... ......... } void CalcularNormales(Object3D &object) { ......... ......... } void applySmoothingGroups(Object3D &object) { ......... ......... } void killObject(Object3D &object) { delete[] object.pFaces; object.pFaces = NULL; object.nFaces = 0; delete[] object.pVertices; object.pVertices = NULL; object.nVertices = 0; } void InitTextures(void) { MyTextura.LoadFromFile("textura.bmp"); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } void reshape(int w, int h) { if (!h) return; glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, (GLfloat) w/(GLfloat) h, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void display(void) { int a, b, c; int i; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glEnable(GL_TEXTURE_2D); MyTextura.SetActive(); gluLookAt (0.0, 0.0, 20.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(angulo,0.0f,1.0f,0.0f); glBegin(GL_TRIANGLES); for (i=0; i<obj.nFaces; i++) { const Face& face = obj.pFaces[i]; a=face.vertexIndices[0]; b=face.vertexIndices[1]; c=face.vertexIndices[2]; glNormal3f(face.normal[0].x, face.normal[0].y, face.normal[0].z); glTexCoord2f(obj.pVertices[a].u, obj.pVertices[a].v); glVertex3f(obj.pVertices[a].x, obj.pVertices[a].y, obj.pVertices[a].z); glNormal3f(face.normal[1].x, face.normal[1].y, face.normal[1].z); glTexCoord2f(obj.pVertices[b].u, obj.pVertices[b].v); glVertex3f(obj.pVertices[b].x, obj.pVertices[b].y, obj.pVertices[b].z); glNormal3f(face.normal[2].x, face.normal[2].y, face.normal[2].z); glTexCoord2f(obj.pVertices[c].u, obj.pVertices[c].v); glVertex3f(obj.pVertices[c].x, obj.pVertices[c].y, obj.pVertices[c].z); } glEnd(); glutSwapBuffers(); } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glLightfv(GL_LIGHT0, GL_POSITION, LightPos); glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb); glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif); glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpc); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); CargarModelo("head.dat", obj); CalcularNormales(obj); applySmoothingGroups(obj); InitTextures(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } void Idle(void) { angulo += 1.0; display(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(400, 400); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("Texturas en OpenGL"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutIdleFunc(Idle); glutMainLoop(); killObject(obj); return 0; } |
#include <GL\glaux.h> class COGLTexture { public: _AUX_RGBImageRec *Image; unsigned int GetID(); void LoadFromFile(char *filename); void SetActive(); int GetWidth(); int GetHeight(); private: int Width, Height; unsigned int ID; }; |
#include "textures.h" void COGLTexture::LoadFromFile(char *filename) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1,&ID); glBindTexture( GL_TEXTURE_2D, ID); Image = auxDIBImageLoadA( (const char*) filename ); Width = Image->sizeX; Height = Image->sizeY; gluBuild2DMipmaps( GL_TEXTURE_2D, 3, Image->sizeX, Image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, Image->data); delete Image; } void COGLTexture::SetActive() { glBindTexture( GL_TEXTURE_2D, ID); } unsigned int COGLTexture::GetID() { return ID; } |
Copyright© 2002, Ramiro, Argentina
valcoey@hotmail.com