En este ejemplo voy a seguir con la carga de texturas, pero ahora el modelo
lo tengo en un archivo 3DS, lo que me facilita mucho las cosas, ya que
es un formato que se puede considerar como standar en el mundo 3D, ya que no
hay software que no lo soporte, Lightwave, Maya, 3D Studio
MAX, Truespace, la lista es interminable para decir los mas conocidos.
No voy a explicar como leer un archivo 3DS, solo les digo que es un binario,
algo complicado, pero el codigo para su lectura es relativamente simple, se
puede encontrar mucha informacion en la red sobre su estructura, en el ejemplo
que tengo aqui solo cargo la definicion de la malla, las normales y las coordenadas
de mapeado UV.
Una de las ventajas, bueno ademas del tamaño del archivo, de ser un formato
conocido, es que ya tengo las normales!!!, calculadas, esto me permite que la
representacion de la malla sea suave y no faceteada, es decir que no se pueden
ver los bordes de los poligonos, por lo tanto el codigo es mas corto.
La imagenes de abajo son una serie de capturas del programa, la malla tiene
un mapeado del tipo UV, como se puede verno hay estiramiento de la textura.
La imagen que utilice como textura es un mapa de bits (.BMP) de 512x512 pixels.
Utilice 3D Studio MAX 3.0, para aplicar la textura , escalar y orientar el modelo para luego exportarlo como un archivo .3DS, el procedimiento es el siguiente :
El código fuente, con el proyecto para VisualC++ 6.0 lo podes
bajar de aquí., y el archivo
.3DS es el siguiente modelo.zip
(321 kb), en cuanto a la imagen utilizada como textura sirve cualquier .BMP
de 512x512 pixels, pero podes usar la que tengo mas arriba, previo paso a formato
.BMP y modificar su tamaño.
Espero que me sepan disculpar en el proyecto anterior me habia olvidado incluir las librerias
opengl32.lib, glu32.lib y glut32.lib es las opciones del compilador, eso me producia una serie de
errores cuando se tratab de compilar, eso ya esta arreglado en el nuevo proyecto utilice la version
6.0 del VisualC++.
Descarga del fuente y proyecto para el VisualC++
6.0
Descarga del archivo
.3ds y la textura
Aclaracion la textura esta en formato .jpg, la tenes que pasar a formato .bmp
con cualquier programa de edicion de imagenes para poder ser utilizada por el
programa, las dimensiones son las correctas 512x512 pixels.
/* Este codigo te abre y visualiza un archivo 3DS en OpenGL, la textura tiene que ser de 512x512 pixels.. Compilado con VisualC++ 6.0, OpenGL y librerias GLUT Ramiro, bastante sencillo, mmmm libere la memoria??? :-p */ #include <stdlib.h> #include <stdio.h> #include <gl/glut.h> #include <gl/glaux.h> #include "textures.h" #include "3ds.h" float LightPos[] = { 0.25f, 0.4f, 1.0f, 0.0f}; float LightAmb[] = { 0.0f, 0.0f, 0.0f, 1.0f}; float LightDif[] = { 1.0f, 1.0f, 1.0f, 1.0f}; float LightSpc[] = { 1.0f, 1.0f, 1.0f, 1.0f}; char *archivo_3ds="SARA.3DS"; COGLTexture MyTextura; L3DS scene; GLfloat anguloY=0.0f; void InitTextures(void) { MyTextura.LoadFromFile("SARA.BMP"); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); } void init(void) { if (!scene.LoadFile(archivo_3ds)) { fprintf(stderr, "No puedo abrir el archivo: %s\n", archivo_3ds); exit(1); } glClearColor(0.0, 0.0, 0.0, 0.0); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 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); InitTextures(); } void Dibujar3DS(void) { LFace face; int i,k; for (i=0; i<scene.GetMeshCount(); i++) { for (k=0; k<scene.GetMesh(i)->GetFaceCount(); k++) { face = scene.GetMesh(i)->GetFace(k); glBegin(GL_TRIANGLES); glTexCoord2f(face.uv[0].u,face.uv[0].v); glNormal3f(face.normals[0].x, face.normals[0].y, face.normals[0].z); glVertex3f(face.vertices[0].x, face.vertices[0].y, face.vertices[0].z); glTexCoord2f(face.uv[1].u,face.uv[1].v); glNormal3f(face.normals[1].x, face.normals[1].y, face.normals[1].z); glVertex3f(face.vertices[1].x, face.vertices[1].y, face.vertices[1].z); glTexCoord2f(face.uv[2].u,face.uv[2].v); glNormal3f(face.normals[2].x, face.normals[2].y, face.normals[2].z); glVertex3f(face.vertices[2].x, face.vertices[2].y, face.vertices[2].z); glEnd(); } } } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glEnable(GL_TEXTURE_2D); MyTextura.SetActive(); gluLookAt (0.0, 0.0, 4.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotatef(anguloY, 0.0f, 1.0f, 0.0f); Dibujar3DS(); glutSwapBuffers(); } 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 keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } void Idle(void) { anguloY += 1.0; display(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(400, 400); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutCreateWindow("3DS con Texturas en OpenGL"); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutIdleFunc(Idle); glutMainLoop(); return 0; } |
/****** textures.h ******/ #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; }; /***** textures.cpp ******/ #include "textures.h" void COGLTexture::LoadFromFile(char *filename) { Image = auxDIBImageLoadA( (const char*) filename ); if (Image==NULL) exit(0); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1,&ID); glBindTexture( GL_TEXTURE_2D, ID); 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; } |
Todo el codigo esta en el link de arriba, es muy largoooooo.
Copyright© 2002, Ramiro, Argentina
valcoey@hotmail.com