| PRINCIPAL | GRAFICOS 3D | GRAFICOS 2D | MATEMATICAS | TUTORIALES | FRACTALES | FUENTES | LINKS |

Mapeado de Texturas en OpenGL y carga de un archivo 3DS

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.

face_tex.jpg

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

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.

El cuerpo principal del programa, main.cpp

/*
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;
}

Modulo para el manejo de la textura, textures.h y textures.cpp

/****** 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;
}

Modulo para cargar el 3DS, 3ds.h y 3ds.cpp

Todo el codigo esta en el link de arriba, es muy largoooooo.


| PRINCIPAL | GRAFICOS 3D | GRAFICOS 2D | MATEMATICAS | TUTORIALES | FRACTALES | FUENTES | LINKS |

Copyright© 2002, Ramiro, Argentina
valcoey@hotmail.com