Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links

Carga de un archivo .asc del 3D Studio MAX 4.0

Podemos utilizar el 3D Studio MAX para modelar y texturar un objeto 3D, para que una ves exportado, lo podamos leer desde nuestro programa en OpenGL.
La idea es exportarlo desde el MAX como un archivo .asc, este es un archivo de texto, podes utilizar el Block de Notas de Windows, o cualquiere editor de texto para ver su contendido alli, tenes los vertices, caras y coordenadas de textura del modelo.
Ventajas: Facil de leer.
Desventajas:

face.jpg

Modelo de un archivo (.ASC)

Ejemplo de una archivo (.ASC), cubo.zip

Named Object: "Box01"
Tri-mesh, Vertices: 8     Faces: 12
Vertex list:
Vertex 0: X: 5.051399     Y: 5.003852     Z: -4.986376
Vertex 1: X: 15.051399     Y: 5.003852     Z: -4.986376
Vertex 2: X: 5.051399     Y: 15.003852     Z: -4.986376
Vertex 3: X: 15.051399     Y: 15.003852     Z: -4.986376
Vertex 4: X: 5.051399     Y: 5.003852     Z: 5.013624
Vertex 5: X: 15.051399     Y: 5.003852     Z: 5.013624
Vertex 6: X: 5.051399     Y: 15.003852     Z: 5.013624
Vertex 7: X: 15.051399     Y: 15.003852     Z: 5.013624
Face list:
Face 0:    A:0 B:2 C:3 AB:1 BC:1 CA:0
Smoothing: 2 
Face 1:    A:3 B:1 C:0 AB:1 BC:1 CA:0
Smoothing: 2 
Face 2:    A:4 B:5 C:7 AB:1 BC:1 CA:0
Smoothing: 3 
Face 3:    A:7 B:6 C:4 AB:1 BC:1 CA:0
Smoothing: 3 
Face 4:    A:0 B:1 C:5 AB:1 BC:1 CA:0
Smoothing: 6 
Face 5:    A:5 B:4 C:0 AB:1 BC:1 CA:0
Smoothing: 6 
Face 6:    A:1 B:3 C:7 AB:1 BC:1 CA:0
Smoothing: 5 
Face 7:    A:7 B:5 C:1 AB:1 BC:1 CA:0
Smoothing: 5 
Face 8:    A:3 B:2 C:6 AB:1 BC:1 CA:0
Smoothing: 6 
Face 9:    A:6 B:7 C:3 AB:1 BC:1 CA:0
Smoothing: 6 
Face 10:    A:2 B:0 C:4 AB:1 BC:1 CA:0
Smoothing: 7 
Face 11:    A:4 B:6 C:2 AB:1 BC:1 CA:0
Smoothing: 7 

Código Fuente

El codigo fuente se encuentra dividido en varios archivos main.cpp, asc.cpp, y asc.h

Desacarga del Codigo Fuente, proyecto en VisualC++.
Descarga de los archivo de prueba (.ASC), todos fueron creados con 3DStudio MAX 2.0
knot.asc
jet.asc
face.asc
Desacarga del Ejecutable

main.cpp

//main.cpp
//email = valcoey@hotmail.com
//www   = www.geocities.com/valcoey/index.html
#include <windows.h>	
#include <math.h>
#include <gl\gl.h>		
#include <gl\glu.h>		
#include <gl\glaux.h>		
#include "asc.h"

#define PI 3.1419592654

Object3D	obj;
Point3f		*vnormales=0;

float LightPos[] = { 0.0f, 0.0f, 1.0f, 0.0f};   
float LightAmb[] = { 0.15f, 0.15f, 0.15f, 1.0f};   
float LightDif[] = { 1.0f, 1.0f, 1.0f, 1.0f};   
float LightSpc[] = { 1.0f, 1.0f, 1.0f, 1.0f};   

HDC g_HDC;						
bool fullScreen = false;		
bool keyPressed[256];		
int mouseX, mouseY;				
float cameraX, cameraY, cameraZ;	
float lookX, lookY, lookZ;			
float alfa=0.0f, rho=0.0f;				

float Modulo(float x, float y, float z)
{
 float len;

 len = x*x + y*y + z*z;
 return ((float) sqrt(len));
}


void Normalizar(float *x, float *y, float *z)
{
 float len;

 len = Modulo(*x, *y, *z);
 len = (float) 1.0/len;
 (*x) *= len;
 (*y) *= len;
 (*z) *= len;
}


void VectorNormal(Object3D& object, int i)
{
 Face& face = object.pFaces[i];
 const Point3f& v1 = object.pVertices[face.vertexIndices[0]];
 const Point3f& v2 = object.pVertices[face.vertexIndices[1]];
 const Point3f& v3 = object.pVertices[face.vertexIndices[2]];
 float tempx, tempy, tempz;
 
 tempx=(v2.y-v1.y)*(v3.z-v1.z) - (v2.z-v1.z)*(v3.y-v1.y); 
 tempy=(v2.z-v1.z)*(v3.x-v1.x) - (v2.x-v1.x)*(v3.z-v1.z);
 tempz=(v2.x-v1.x)*(v3.y-v1.y) - (v2.y-v1.y)*(v3.x-v1.x);
 Normalizar(&tempx, &tempy, &tempz);
 face.normals.x=tempx;
 face.normals.y=tempy;
 face.normals.z=tempz;
}

void CalcularNormales(void)
{
 Point3f sum;
 int shared = 0;
 int i,j;

 vnormales = new Point3f[obj.nVertices];
 for (i=0;i<obj.nFaces;i++)						
		VectorNormal(obj,i);

 for (i=0; i<obj.nVertices; i++)
	{
	for (j=0; j<obj.nFaces; j++)
      {
	  const Face& face = obj.pFaces[j];
	  if (face.vertexIndices[0]==i || 
		  face.vertexIndices[1]==i || 
		  face.vertexIndices[2]==i)
         {
         sum.x += face.normals.x;
         sum.y += face.normals.y;
         sum.z += face.normals.z;
		 shared++;
         }
      }      
	vnormales[i].x = (sum.x / (float) shared);
	vnormales[i].y = (sum.y / (float) shared);
	vnormales[i].z = (sum.z / (float) shared);
    Normalizar(&vnormales[i].x, &vnormales[i].y, &vnormales[i].z);
    sum.x=0.0;
	sum.y=0.0;
	sum.z=0.0;
    shared = 0;
   }

}


void killObject(Object3D& object)
{
	delete[] object.pFaces;
	object.pFaces = NULL;
	object.nFaces = 0;
	delete[] object.pVertices;
	object.pVertices = NULL;
	object.nVertices = 0;
	delete [] vnormales;
    vnormales = 0;
}


GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		
{
if (!height)
	return;
 glViewport(0, 0,  (GLsizei) width, (GLsizei) height);
 glMatrixMode(GL_PROJECTION);
 glLoadIdentity();
 gluPerspective(60.0, (GLfloat)width/(GLfloat)height, 1.0, 500.0);
 glMatrixMode(GL_MODELVIEW);
 glLoadIdentity();									
}

void Initialize(void)
{
 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);		
 glClearDepth(1.0f);
 glEnable(GL_DEPTH_TEST);

 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);
 LoadScene("face.asc", obj);
 CalcularNormales();
}


void Render(void)								
{
 GLfloat mat_ambient[] = { 0.0f, 0.4648f, 0.7929f, 1.0f };
 GLfloat mat_diffuse[] = { 0.1f, 0.5742f, 0.6172f, 1.0f };
 GLfloat mat_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
 GLfloat mat_shininess[] = { 100.0f };
 double rad_alfa=0.0, rad_rho=0.0;
 int count, i;

 rad_alfa = PI*alfa/180.0;
 rad_rho = PI*rho/180.0;
 cameraX = (float) (50*sin(rad_rho)*cos(rad_alfa));
 cameraZ = (float) (50*sin(rad_rho)*sin(rad_alfa));  
 cameraY = (float) (50*cos(rad_rho));
 lookX = 0.0f;
 lookY = 0.0f;
 lookZ = 0.0f;

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		
 glLoadIdentity();
 gluLookAt(cameraX, cameraY, cameraZ, lookX, lookY, lookZ, 0.0, 1.0, 0.0);
 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
 glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

 glBegin(GL_TRIANGLES);
 for (count=0; count<obj.nFaces; count++)
	{
	const Face& face = obj.pFaces[count];
	for (i=0; i<3; i++)
		{
		const Point3f& vertex = obj.pVertices[face.vertexIndices[i]]; 
	    glNormal3f(vnormales[face.vertexIndices[i]].x, 
			       vnormales[face.vertexIndices[i]].y, 
				   vnormales[face.vertexIndices[i]].z);
		glVertex3f(vertex.x, vertex.y, vertex.z);
		}
	}
 glEnd();	
 glFlush();
 SwapBuffers(g_HDC);	
}

void SetupPixelFormat(HDC hDC)
{
 int nPixelFormat;					
 static PIXELFORMATDESCRIPTOR pfd = {
		sizeof(PIXELFORMATDESCRIPTOR),	
		1,								
		PFD_DRAW_TO_WINDOW |			
		PFD_SUPPORT_OPENGL |			
		PFD_DOUBLEBUFFER,				
		PFD_TYPE_RGBA,					
		32,								
		0, 0, 0, 0, 0, 0,				
		0,								
		0,								
		0,								
		0, 0, 0, 0,						
		16,								
		0,								
		0,								
		PFD_MAIN_PLANE,					
		0,								
		0, 0, 0 };						
 nPixelFormat = ChoosePixelFormat(hDC, &pfd);	
 SetPixelFormat(hDC, nPixelFormat, &pfd);	
}


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 static HGLRC hRC;					
 static HDC hDC;						
 int width, height;					
 int oldMouseX, oldMouseY;

 switch(message)
	{
	case WM_CREATE:					
	hDC = GetDC(hwnd);			
	g_HDC = hDC;
	SetupPixelFormat(hDC);		
	hRC = wglCreateContext(hDC);
	wglMakeCurrent(hDC, hRC);
	return 0;
	break;

	case WM_CLOSE:				
	wglMakeCurrent(hDC, NULL);
	wglDeleteContext(hRC);
	PostQuitMessage(0);
	return 0;
	break;

	case WM_SIZE:
	height = HIWORD(lParam);		
	width = LOWORD(lParam);
	if (height==0)					
		{
		height=1;					
		}

	glViewport(0, 0, width, height);	
	glMatrixMode(GL_PROJECTION);		
	glLoadIdentity();					
	gluPerspective(60.0f,(GLfloat)width/(GLfloat)height,1.0f,500.0f);
	glMatrixMode(GL_MODELVIEW);			
	glLoadIdentity();					
	return 0;
	break;

	case WM_KEYDOWN:				
	keyPressed[wParam] = true;
	return 0;
	break;

	case WM_KEYUP:
	keyPressed[wParam] = false;
	return 0;
	break;

	case WM_MOUSEMOVE:
	oldMouseX = mouseX;
	oldMouseY = mouseY;
	mouseX = LOWORD(lParam);
	mouseY = HIWORD(lParam);
	if ((mouseY - oldMouseY)>0)
		rho +=5.1f;
	else if ((mouseY - oldMouseY)<0)
		rho -=5.1f;
	if ((mouseX - oldMouseX)>0)	
		alfa += 5.1f;
	else if ((mouseX - oldMouseX)<0)	
		alfa -= 5.1f;
	return 0;
	break;

	default:
	break;
	}
 return (DefWindowProc(hwnd, message, wParam, lParam));
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
 WNDCLASSEX windowClass;	
 HWND		hwnd;			
 MSG		msg;		
 bool		done;
 DWORD		dwExStyle;	
 DWORD		dwStyle;			
 RECT		windowRect;
 int		width = 550;
 int		height = 400;
 int		bits = 32;

 windowRect.left=(long)0;					
 windowRect.right=(long)width;					
 windowRect.top=(long)0;							
 windowRect.bottom=(long)height;					
 windowClass.cbSize			= sizeof(WNDCLASSEX);
 windowClass.style			= CS_HREDRAW | CS_VREDRAW;
 windowClass.lpfnWndProc		= WndProc;
 windowClass.cbClsExtra		= 0;
 windowClass.cbWndExtra		= 0;
 windowClass.hInstance		= hInstance;
 windowClass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);	
 windowClass.hCursor		= LoadCursor(NULL, IDC_ARROW);		
 windowClass.hbrBackground	= NULL;								
 windowClass.lpszMenuName	= NULL;								
 windowClass.lpszClassName	= "MyClass";
 windowClass.hIconSm		= LoadIcon(NULL, IDI_WINLOGO);		

 if (!RegisterClassEx(&windowClass))
	return 0;

 if (fullScreen)							
	{
	 DEVMODE dmScreenSettings;				
	 memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
	 dmScreenSettings.dmSize = sizeof(dmScreenSettings);	
	 dmScreenSettings.dmPelsWidth = width;		
	 dmScreenSettings.dmPelsHeight = height;	
	 dmScreenSettings.dmBitsPerPel = bits;	
	 dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
     if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
		MessageBox(NULL, "Display mode failed", NULL, MB_OK);
		fullScreen=FALSE;	
		}
	}

 if (fullScreen)						
	{
	dwExStyle=WS_EX_APPWINDOW;			
	dwStyle=WS_POPUP;				
	ShowCursor(FALSE);						
	}
 else
	{
	dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
	dwStyle=WS_OVERLAPPEDWINDOW;					
	}
 AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);	
 hwnd = CreateWindowEx(NULL,									
		"MyClass",							
		"Demo OpenGL (.asc)",		
		dwStyle | WS_CLIPCHILDREN |
		WS_CLIPSIBLINGS,
		0, 0,								
		windowRect.right - windowRect.left,
		windowRect.bottom - windowRect.top,	
		NULL,									
		NULL,								
		hInstance,							
		NULL);								
 if (!hwnd)
		return 0;
 ShowWindow(hwnd, SW_SHOW);			
 UpdateWindow(hwnd);				
 done = false;						
 Initialize();						
 while (!done)
	{
	PeekMessage(&msg, hwnd, NULL, NULL, PM_REMOVE);
	if (msg.message == WM_QUIT)		
		{
		done = true;			
		}
	else
		{
		if (keyPressed[VK_ESCAPE])
			done = true;
		else
			{
			Render();
			TranslateMessage(&msg);		
			DispatchMessage(&msg);
			}
		}
	}
 killObject(obj);
 if (fullScreen)
	{
	ChangeDisplaySettings(NULL,0);		
	ShowCursor(TRUE);				
	}
 return msg.wParam;
}

valcoey@hotmail.com

Ramiro Alcocer, 2001

Principal | Gráficos 3D | Gráficos 2D | Fractales | Math | Códigos | Tutoriales | Links