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

El siguiente código carga un archivo .ASC, es un archivo de texto que contiene
vertices, caras, luces, camaras, materiales, de un modelo 3D, creado por programas de animacion y modelado 3D, ejemplo 3DStudioMAX, 3D Studio R4, mi código solo carga los vertices y las caras de una escena formada por un solo objeto, ignorando las luces, camaras, y materiales, el propio programa crea la fuente de luz y una camara. El calculo de las normales de iluminacion es realizada por el programa, utilizando la informacion de los vertices y caras que forman el objeto.
cualquier comentario o sugerencia a valcoey@hotmail.com, en estos momentos estoy
viendo como poder cargar multiples objetos, incluyendo sus materiales y texturas
si alguien tiene algunas ideas? :-).
La siguiente imagen es la representacion del archivo face.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 |
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
//email = valcoey@hotmail.com
//www = www.oocities.org/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