Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
fw:lib3ds [2008/07/09 08:34] alfred |
fw:lib3ds [2020/05/09 09:25] (actual) |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== Lib3ds ====== | ====== Lib3ds ====== | ||
| - | Librería para la lectura de archivos 3D Studio con extensión .3ds. | + | Librería para la lectura de archivos 3D Studio con extensión .3ds en C\C++. |
| * {{fw:lib3ds:lib3ds-1.3.0.zip|Lib3ds}} | * {{fw:lib3ds:lib3ds-1.3.0.zip|Lib3ds}} | ||
| + | * [[http://lib3ds.sourceforge.net/index.html|Website y documentación de Lib3ds]] | ||
| * {{fw:lib3ds:3ds.rtf|Especificación del formato 3ds}} | * {{fw:lib3ds:3ds.rtf|Especificación del formato 3ds}} | ||
| + | Como cualquier librería de C necesitarás linkarla e incluir los .h necesarios. Cada clase (más bien estructura, lib3ds está escrito en ANSI C) tiene su definición en su .h correspondiente. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| ===== Utilización ===== | ===== Utilización ===== | ||
| + | El tipo básico sobre el que se trabaja es ''Lib3dsFile'', para crear una variable de este sólo debemos pasarle el nombre del archivo a la función ''lib3ds_file_load'' la cual devolverá su correspondiente ''Lib3dsFile''. Este estará estructurado como un archivo .3ds, como un árbol, con ramas correspondientes a los objetos, las luces, etc. En definitiva, tenemos la escena separada por bloques. Un ejemplo tonto, el de contar las meshes en el archivo: | ||
| + | <code c> | ||
| + | #include "lib3ds\file.h" | ||
| + | #include "lib3ds\mesh.h" | ||
| + | |||
| + | int getNumMeshes (Lib3dsFile* f) { | ||
| + | int tmp = 0; | ||
| + | Lib3dsMesh* mesh = f->meshes; | ||
| + | while (mesh != NULL) { | ||
| + | tmp++; | ||
| + | mesh = mesh->next; | ||
| + | } | ||
| + | return tmp; | ||
| + | } | ||
| + | void main () { | ||
| + | Lib3dsFile* file = lib3ds_file_load("caja.3DS"); | ||
| + | int i = getNumMeshes(file); | ||
| + | lib3ds_file_free(file); | ||
| + | } | ||
| + | </code> | ||
| + | ''lib3ds_file_free'' libera de memoria el ''Lib3dsFile'' pasado por parámetro. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ==== Dibujar un modelo de la escena ==== | ||
| + | Los modelos están guardados como una linked list en la variable ''meshes'' del ''Lib3dsFile'' del tipo ''Lib3dsMesh''enlazadas por la variable //next//, que corresponde a la siguiente dentro del fichero. \\ | ||
| + | Una mesh tiene un nombre\id (//name//) y un número de caras (//faces//). Una cara es un triangulo de tres vértices (o puntostodos los vértices de la mesh se encuentran en su variable //pointL//, que es un array de ''Lib3dsPoint''. Para dibujar una cara debemos acceder al array de caras de la mesh (en //faceL//), escoger la cara deseada (tipo ''Lib3dsFace'') y acceder a sus tres vertices que están en //points//, un array de tres integers correspondientes a los índices del array de vertices de la mesh. Cada ''Lib3dsPoint'' contiene una variable //pos// que es un array con tres números que son las tres coordenadas xyz de un vértice. | ||
| + | <code c> | ||
| + | Lib3dsMesh* mesh = file->meshes; | ||
| + | Lib3dsPoint ptmp; | ||
| + | |||
| + | glBegin(GL_TRIANGLES); | ||
| + | for (int i=0; i<mesh->faces; i++) { | ||
| + | Lib3dsFace face = mesh->faceL[i]; | ||
| + | for (int i=0; i<3; i++) { | ||
| + | ptmp = mesh->pointL[face.points[i]]; | ||
| + | glVertex3f(ptmp.pos[0], ptmp.pos[1], ptmp.pos[2]); | ||
| + | } | ||
| + | } | ||
| + | glEnd(); | ||
| + | </code> | ||
| + | |||
| + | ==== Cálculo de normales ==== | ||
| + | Lib3ds dispone de una función llamada ''lib3ds_mesh_calculate_normals'' que calcula las normales para una mesh, se le pasa la mesh de la cual queremos calcular las normales y tantos arrays de 3 floats como normales tenga esta mesh (número de caras multiplicado por 3, que son los vértices). Para más comodidad podemos utilizar la estructura ''Lib3dsVector''. | ||
| + | <code c> | ||
| + | Lib3dsVector* normals = new Lib3dsVector[mesh->faces * 3]; | ||
| + | lib3ds_mesh_calculate_normals(mesh, normals); | ||
| + | </code> | ||
| + | Ahora dentro del vector de normales tendremos las normales por cada vértice. | ||
| + | |||
| + | |||
| + | ==== Cargar las coordenadas de textura ==== | ||
| + | Las coordenadas de textura las tratamos desde la instancia a ''Lib3dsMesh''. Esta contiene dos variables: | ||
| + | * //texels// que contiene el número de coordenadas almacenadas. | ||
| + | * //texelL// que contiene las coordenadas en un array de arrays de dos números (x e y) de la coordenada. Para saber que coordenada que le toca a cada vértice iremos a la cara con la que estemos trabajando y en su variable //points// encontraremos los tres indices del array de vértices correspondientes a sus tres vértices, ese índice también coincide con el vértice para las coordenadas de textura. | ||
| + | <code c> | ||
| + | for (int i=0; i<mesh->faces; i++) { | ||
| + | Lib3dsFace face = mesh->faceL[i]; | ||
| + | for (int i=0; i<3; i++) { | ||
| + | glTexCoord2f (mesh->texelL[face.points[i]][0], mesh->texelL[face.points[i]][1]); | ||
| + | ... | ||
| + | </code> | ||
| + | Para saber qué textura tiene aplicada una cara accederemos a su variable //material//, esta contiene un string con el identificador. | ||