Buenas a todos. Estoy ya dando mis primeros pasos en cuanto a la programación con DirectX y me he puesto a pensar en cargar modelos 3D con animaciones. En páginas como gamedev.net o gametutorials.com he podido ojear artículos de cómo cargar modelos del quake 2 y quake 3. De hecho esta tarde cogí el código del primer ejemplo de gametutorials de cómo cargar un archivo del quake 2y lo pasé de opengl a directx, eso sí, teniendo algún que otro problemilla, aunque por ahora no viene al caso.
En definitiva, os pido ayuda para saber los pros y contras de los diferentes formatos. He oído que el formato smd, para los modelos de half life es bueno, ya que va por bones y puedes girar la cabeza independientemente de otras partes del cuerpo, por ejemplo, y que se le pueden añadir todas las texturas que quieras en un sólo modelo. Luego, también oí que el formato de quake 3 tb va por bones, etc... En fin, que estoy hecho un lío y, por primera vez, os pido que ayudéis a un novatillo en busca de cierta sabiduría.
El formato de Half-Life parece una buena elección. También podrías mirarte el de milkshape que es ASCII y soporta bones...despúes podrías convertir dicho formato al tuyo propio (que podría ser binario). Los MD3...no soportan exactamente bones (aunque como con el del HL, puedes mover las partes del cuerpo independientemente)...y el modelo no está de una pieza sino que está dividido en 3 trozos (cabeza, torso y piernas) y ciertamente no parece demasiado cómodo a la hora de trabajar con ellos (aunque eso lo tendría que decir un grafista).
También tienes el formato del Doom3 que por ahora es ASCII por lo que podrías ver la estructura que tiene pero ciertamente ahora mismo no está extendido (cuando salga, entonces lo estará :D)...
Saludos
Entonces estaba en lo cierto, half life es una buena opción, aunque tambien hablas del Milkshape. Lo malo es que he visto poca información de cual es la estructura de los modelos del HL, he buscado x ej en wosit.org y nada :P, sin embargo en una página llamada 'Chumbalosoft' o algo así viene un visor, hecho en directx, donde viene el código así que ya podría hacer algo.
El formato de milkshape parece una buena idea, pq junto con la herramienta milkshape en sí misma, se puede convertir fácilmente de un formato a otro, y creo que en la web de Nexe viene un tutorial sobre ello.
links:
http://www.swissquake.ch/chumbalum-soft/hlmv/http://nexe.gamedev.net/Tutorials/ViewTuto...Tutorial7.myxml
si te fijas, chumbalum-soft son lo tambien los autores de milkshape. Con este programa podrás importar/exportar a muchos formatos asi que el formato propio (binario o ascii) de milkshape puede ser una buena opcion.
Buenas de nuevo, me he decidido a usar el formato del Milkshape. Pero viendo el ejemplo de la web Nexe, veo que está llamando a ProcessVertices() cada frame, cosa nada recomendable para las targetas gráficas actuales. Creo que si quiero conseguir un framerate más optimizado debería de sobreescribir ese código por una función que utilize el hardware gráfico. ¿Qué me recomendáis?
PD: Si no véis los ProcessVertices() en el tutorial de
http://nexe.gamedev.net/Tutorials/ViewTuto...Tutorial7.myxml , descargaos el código fuente en
http://nexe.gamedev.net/Tutorials/Files/Tutorial7.zip. La función está al final del archivo 'VertexBuffer.cpp', que por lo que he podido ver en las funciones 'CGroup::ReprocessVertices' y 'CModel::ReprocessVertices' (en Model.cpp) y luego en el bucle de la ventana, es utilizada varias veces cada frame.
PD2: Menudo Post Data que me he marcado :jaja:
Huye de NeXe como de la lepra , en serio
jajajaja
Mirate el ejemplo ese que hay en la otra web, que es un visor de animaciones en .MS3D. Creo que es de los creadores, y será mejor que el de NeXe seguro :P:P
el formato .x lo he usado para poner algunos modelo y ami me gusto, pero no se los pros/contras de este formato, podria alguien hacer una minitabla con los pros/contras de los clasicos md2 smdl x md3 etc?
asias
Oks, parece que por voto popular, la web de Nexe no es muy buen ejemplo. Entonces veré el código del
MilkShape viewer, que aunque es del año 2000, pues viene el código y seguramente el formato del milkshape no habrá cambiado... :loco:
Perdonad la intrusión de un grafista.
¿Pq no se usa más el directx8 y sus bones con pesos? Graficamente, es la manera más perfecta que he visto para personajes animados..
Supongo que porque es más complejo para el programador, o más dificil de optimizar, no?
Leo cosas contradictorias al respecto.
Los bones y pesos también son soportados por el formato mds (no sé si lo he dicho ya en algún thread) del juego RTCW, que tb usaba mdc y md3. pero estos dos últimos, son fragmentados (y si, eso a mi como grafista me fastidia, pero puede que sea sólo cosa mía) Son como dice berseker, o eso he leído siempre.
El mds, cierto pajarito me ha dicho que tpoco es sencillo, pero me da a mí que se no se lo llegó a mirar realmente...Últimamente estoy más con el Gmax. Aquí hay un importador a mds (y otros) para max y gmax, junto con las especificaciones del formato (van en el mismo zip y me pareció muy clarito) Es un formato con pesos y bones, no sé si se usó mucho en RTCW, de todos modos. Pero como grafista, estoy interesado en formatos que soporten las dos features esas.
http://mojo.gmaxsupport.com/Por cierto, en esa page hay tb importadores a gmax de md2, halflife, etc.
Una preguntilla, ya que estamos. ¿De veras es más heavy en rendimiento -o más complejo de programar- lo del dx8 con bones y pesos, que lo que usa Gamestudio y algun otro chisme de esos, lo de usar una malla (en plan keyframe) y luego otra malla (otra pose) y que el código interpole (he oído hablar de spline interpolation y linear interpolation.Character FX soporta las dos) los frames interemdios ?
Si así fuera, podrías plantearte hacer algo como eso cargando OBJs (un formato extendidísimo y que soporta muchas cosas de cara al grafista)
Imagino que tiene sus pegas. Dudo mucho que llegue al realismo de bones y pesos, porque al interpolar, supongo que lo hará un poco como le dé la gana... Aunque tiene la ventaja de que puedes meter cambios de expresión en la cara, respiración, etc, más fácilmente que con pequeños bones. Supongo que esto de las "istantáneas interpoladas" es idóneo para animaciones tipo toon. Y ahí tengo cierto lío. Parece que con bones y pesos en directx 8 tb se da interpolación; es un setting que yo puedo activar o desactivar cuando exporto en directx8 desde Character FX (te da una cantidad de opciones de exportado enorme, con ese formato)
La putadilla es que aunque se está extendiendo (truespace6 ya importa y exporta dx8 con pesos, deep exploration, ultimate unwrap...porque exportado ya tenían desde antes todos los paquetes) aún parece que no del todo, y la peña con dx engines, de un modo u otro no importa dx con pesos y bones. Aquí hay un tipo que tiene un engine dx8 que sí lo soporta, se llama jtgame, y por el momento es free.
Tiene un modelador/animador (free, luego será de 20$) pal formato dx8 peroooo...como que me quedaré con el Character FX y Ultimate Unwrap, hasta que no le pegue "3 o 4" cambios.
http://www.jtgame.com/Ya está, que para ser una intrusión es demasiado.
se me olvidaba. El Neoengine parece soportar el md5, que creo que es el formato de doom III, ¿no?
http://neoengine.sourceforge.net Soporta md3 y un montonazo de cosas más, además de tener ya plugins para maya y Max. No sé, quien quiera que lo compruebe, que hablo de memoria.
Y el nebula, creo que también hace este bending suave, pero no estoy seguro. Es completamente libre. El character FX exporta a código de nébula directamente.
http://radonlabs.de/ y
http://nebuladevice.sourceforge.net/ (yo me aclaré más por la primera)
Parece que se maneja con tcl scirpt, y son unas librerías de c++. Que pueden funcionar con directx u opengl. Bueno, la definición se la dejo a alguien que sepa algo más que html ;)
Supongo que las cal3d tpoco es una opción...
es gpl o lgpl .Están por tanto los sources, ahí.
edit--
En cuanto a pros y contras de formatos. Como siempre, sólo puedo hablar desde el punto de vista de un grafista.
el md2, que te hace ese baile de vértices raro. (hay otro thread sobre eso ahora mismo en stratos) El md3, lo de la segmentación. Y que por lo que sea, hay menos softwares que exporten a md3 que a md2. Aunque la enorme base de usuarios de max, milkshape y gmax diría lo contrario ;). El del halflife, que tiene bones, (lo cual es ventajos para los engines, creo...por lo de las colisiones y porque manejais los bones por código, y porque se ahorra memoria frente a un md2 o md3 ¿no?) pero no pesos. Por tanto la animación orgánica es bien jodidilla. Tienes que poner bones dobles en los hombro, trucar bastante la geometría, y en mi opinión, nunca queda bien del todo y te limita mucho.
Y por pedir q no haga falta... :
Cuales son los pros y contras que tú ves del formato .x (directx), del md5 (doom III) y .ms3d (milkshape 3d) ?
Parece ser que el formato de directx te gusta bastante, ya que soporta bones con pesos. La verdad esque por lo que he visto, es fácil de utilizar...
Por cierto que vaya pedazo de respuesta que te has marcado, gracias :D
Me suelo marcar pedazos de respuestas... ;)
Me lo preguntas a mí? Soy el que menos sabe. Pero bueno, de mi parte de grafista, algo sé.
De directx, pues muchos si se usa directx7 para personajes (que no soporta pesos, y que me da marrones al exportar en ciertos casos) y casi ninguno con directx 8. Para objetos y demás, pues casi igual...
el md5 no lo conozco. Pero vamos, nada en absoluto. Alguien me ha dicho que los formatos de ID son un tanto crípticos, y muy optimizados/especializados para su código. Pero esto es lo que me cuentan. Digo yo que soportará el tema de los mapas de normales, pero yo como que me olvidaría de muchas complejidades al principio.
Igual puedes usar uno de estos fomatos en su manejo más básico y no meter otras features más avanzadas, al principio.
Milkshape3d...Soporta pesos de 1.0. O sea, no permite que un vértice sea influenciado en un 20% por un bone y en un 80% por otro, por ponerte un ejemplo. La mayoría de gente que dice que esto de los pesos (dtos de 1.0) no son necesarios, o no son grafistas, o lo son , pero gente de halflife. No pasa nada, pero creo que la diferencia en calidad que se consigue es enorme. Si es tanto lo que se mejora, sólo me cabe pensar que se trata de un auténtico cuello de botella, o que no hay mucha o buena información aportada, por parte de los grafistas.
Tb he leído en muchos otros sitios que el formato ms3d es sencillo pal coder.
Milkshape internamente no soporta pesos. O sea, el exportado desde character fx perderá los pesos una vez abierta la anim en Ms3d. (no obstante, los tendrá en la versión 2...va lentamente por la 1.65. Aun así, es utilísimo.)
El hacerlo para directx8 con bones y pesos abre las puertas de animaciones con bones y pesos para: character FX, Ultimate Unwrap, 3d Canvas, Truespace 6 (y no sé si 5), Max y Maya (mediante plugin), Lighwave (idem), y probablemente, mucho más.
Salvo que haya grandes problemas a nivel de programación, yo no veo mejor formato.
Pero cuidado, que es la opinión de un grafista.
Por eso, no sé si este tutorial es el adecuado :
http://www.gamedev.net/reference/programmi...tures/skinmesh/Cualquiera de aquí sabrá mil tutos mejores que éste. Y como no soy coder, no sé qué tal es.
Sólo he leído el párrafo de la última página, y dice que es un ejemplo muy simple pa empezar. y que el sample que viene con el sdk de dx8 es más complejo y contempla no se qué cosas.
si usas .x qe sean apartir de directx8, porqe los x anteriores dan bastante pena..
Hola de nuevo a todos. He tardado unos días ya que he estado ocupado con varios exámenes. Ya me puse a portar el código del cargador de ficheros del milkshape en formato ASCII y parece que va bien.
Sin embargo, aunque tengo los vértices uen un buffer de vértices y creo que se corresponden con lo que debería de ser, sólo veo un polígono :o . No me va bien. Esto creo que es ya cosa de cómo utilizo el DirectX. Así que os pido ayuda desde mi humildad :-? y os dejo revisar mi código. Lo he hecho un poco aprisa este fin de semana y no sé en qué fallo. Ahora explico más detalles:
lo que he hecho es coger el código de
http://www.swissquake.ch/chumbalum-soft/ms...d/download.html y pasarlo a directx, cosa que parece fácil. Ésto lo he hecho cogiendo como 'modelo' los tutoriales de
http://www.lessman.net/planetiso/. Básicamente lo que he hecho es coger el 4º tutorial de esa web, quitarle el cubo y añadirle mi propia clase modificada de Cmodel a partir del código del cargador de milkshape (y le he añadido funciones de loggeo y render en directx).
Así, tengo todos los vértices en un vb, tb los tengo en el log.txt y puedo comprobar que se asemejan al archivo blend.txt, que es dnd está el modelo inicial en formato milkshape. Digo que se asemejan pq en el archivo inicial no se repite ningún vértice y en el log.txt 'imprimo' cada vértice de cada triángulo, sin utilizar index buffers.
Todo por supuesto lo he intentado comentar lo que he podido para que sea más fácil de comprender. Creo que el error puede estar en las funciones 'fillbufferwith' y 'renderbuffer'.
Para descargar mi código pinchar en
http://tumundoweb.com/findeton/cargador.zipGracias de nuevo por sus respuestas.
En la función fillbufferwith estás copiando sólo un vértice al buffer, en vez de todos, prueba a cambiar:
memcpy(pVertices, cvVertices, sizeof(cvVertices) );
por algo así como:
memcpy(pVertices, cvVertices, range*sizeof(VERTCUBO) );
Además, no estás liberando la memoria que reservas para cvVertices. En los dos puntos de salida de la función, añade:
delete [] cvVertices;
Se ve el perfil de una especie de "bestia" azul girando, aunque he tenido que alejar al observador un poco más, estaba muy cerca.
Quedan otros problemas por resolver, ya que de pronto aparece un montón de poligonos de todos los colores.
Venga, un saludo.
Deja el LSD, Juan... ;)
(Jo, me prometí a mí mismo que me autocensuraría estos posts... pero es que es tan grande la tentación...)
Gracias Juan Mellado. Todabía no he probado el código pero lo haré en cuanto pueda, ya que mi hermano está instalando linux gentoo en el PC dnd programo.
Por cierto, suena mal eso de los polígonos de todos los colores :llorando: . Tendré que hacer pruebas, aunque todos estáis invitados ;) . Y es raro ya que a todos los vértices les pongo el mismo color....
Tu codigo tiene un leak o solo a mi me pasa q me gasta solo 400 megas de ram ? xD
:o pues si, parece que va comiendo memoria a mogollón :P, tendré que revisar el código de nuevo ya que seguro que es un fallo tonto de nuevo... :oops:
PD: ya coseguí ver mi león/diablo ;)
Bien, el fallo era que estaba utilizando el operador new para un doble puntero sin antes utilizar el delete. la corrección es poner en el constructor:
vertices=NULL;
y al principio de Draw2(), después de:
if (!m_pModel)
return;
poner:
if(vertices!=NULL)
{
for (int i = 0; i < nmeshes; i++)
{
delete[] vertices[i];
}
}
if (pntris!=NULL)
delete[] pntris;
Buenas, después de un cierto tiempo de inactividad (más exámenes.. :-? )he podido volver al desarrollo de mi programa. Y de nuevo, os pido ayuda desde mi hulmildad. Después de crear dos post larguísimos y que parece que a nadie han interesado, he hayado el problema, una cosa mucho más reducida y que contaré en otro nuevo post...
Bien, creo un nuevo post simplemente para que apareza como respondido, como algo 'nuevo' :X9: .
La cosa es que tengo un buffer de vértices lleno, donde cada 3 vértices forma un triángulo, totalmente diferente y que me es indiferente que esté unido o no a otros vértices. Mientras que cuando renderizo triángulo a triángulo (cada 3 vértices) mediante TRIANGLELIST el modelo se ve perfecto. Sin embargo, cuando renderizo el buffer entero de una sola pasada, con TRIANGLELIST tb, se ven cosas 'extrañas'.
De esta forma rendeo los triángulos uno a uno:
for (int i = 0; i < nmeshes; i++)
{
if(FAILED(BufferVert->Lock(0, 3*pntris[i]*sizeof(VERTCUBO), (BYTE**)&pVertices, 0 )))
{
return 0;
}
// copiamos los vértices en los que hemos especificado el modelo
// a la zona de memoria a la que apunta nuestro buffer de vértices.
memcpy(pVertices, vert3, 3*pntris[i]*sizeof(VERTCUBO) ); //pntris[i] es el nº de polígonos de la malla
// ¡Nunca olvidar desbloquear el buffer cuando se halla terminado de rellenarlo!
BufferVert->Unlock();
for (j = 0; j < 3*pntris[i]; j++)
{
D3DDisp->DrawPrimitive(D3DPT_TRIANGLELIST, j, 3);
}
}
Dando como resultado:
(http://www.iespana.es/flixre/trompeta.JPG)
y de esta otra, todos a la vez:
for (int i = 0; i < nmeshes; i++)
{
if(FAILED(BufferVert->Lock(0, 3*pntris[i]*sizeof(VERTCUBO), (BYTE**)&pVertices, 0 )))
{
return 0;
}
// copiamos los vértices en los que hemos especificado el modelo
// a la zona de memoria a la que apunta nuestro buffer de vértices.
memcpy(pVertices, vert3, 3*pntris[i]*sizeof(VERTCUBO) ); //pntris[i] es el nº de polígonos de la malla
// ¡Nunca olvidar desbloquear el buffer cuando se halla terminado de rellenarlo!
BufferVert->Unlock();
D3DDisp->DrawPrimitive(D3DPT_D3DPT_TRIANGLELIST, 0, 3*pntris[i]);
}
Dando como resultado:
(http://www.iespana.es/flixre/trompetam.JPG)
Realmente, en la imagen donde se ve la trompeta, de vez en cuando se ven fallos, y tb en la imagen donde no se ve la trompeta, de vez en cuando se ve, lo que pasa es que está tapada por tantos triángulos de colores (aunque el buffer lo he rellenado sólo con vértices de un mismo color! La cosa es que cuando rendeo triángulo a triángulo, rellenando cada vez el buffer (esta vez de sólo 1 triángulo, 3 vértices) y representando un triángulo, se ve sin ningún fallo :!:
Imprímelo en un lienzo y llévalo a algún museo de arte contemporáneo como una pieza valiosísima. Ganarás millones (eso sí, quita lo de Nvidia).
El tercer parámetro del método DrawPrimitive es el número de primitivas que se van a procesar (en tu caso una lista de triángulos). En el primer caso que pones, le pasas un valor de 3 (entiendo que te refieres a vértices) cuando el valor correcto sería 1 (1 triángulo). En el segundo caso le pasas (3 * pntris) cuando supongo que debería ser pntris a secas...
Como supongo ya sabrás, mejor utiliza el segundo método
"IDirect3DDevice9::DrawPrimitive should not be called with a single triangle at a time"
:ojo:
Saludos
Uhm, grave error el mío. Y sí, ya sé que es mejor renderizar todos los vértices de una sola llamada que de una por triángulo o primitiva, cuando pueda probaré el código, gracias.
PD: De todas formas la segunda imagen me va a hacer famoso, una vez desactive el logo de Nvidia de las propiedades de mi Geforce 4 :P .