Friday, July 03, 2009

Hoy, snippets cortos de código

Viendo como OpenGL va a deprecar parte del API (cosa que me parece bien, a ver si conseguimos mejores drivers!), y la costumbre de programar cosas de mas que tenemos algunos, he creído que alguien le seria útil. Funcionan 100% igual que las funciones de la API (misma matriz, etc). Empezaré por el mas trivial (la implementación es directa respecto a la documentación), crear una matriz de proyección ortográfica, con los mismos parámetros que gluOrtho:

   1:  CMatrix4x4 CreateOrtographicProj (float left,   float right, 
   2:                                    float bottom, float top, 
   3:                                    float Near,   float zFar)
   4:  {
   5:   CMatrix4x4 result;
   6:
   7:   float  tx = -(right+left)/(right-left),
   8:          ty = -(top+bottom)/(top-bottom),
   9:          tz = -(zFar+zNear)/(zFar-zNear);
  10:
  11:   result.Set (2.f/(right-left), 0.f,              0.f,               tx,
  12:               0.f,              2.f/(top-bottom), 0.f,               ty,
  13:               0.f,              0.f,             -2.f/(zFar-zNear),  tz,
  14:               0.f,              0.f,              0.f,               1.f);
  15:
  16:   return result;
  17:  }

Como apunte, en todos los snippets de codigo usan ciertas clases matemáticas sencillas que uso, en esta la clase matriz cuadrada de 4 elementos. Si hay alguna duda sobre esto, comentadlo y expando los detalles sobre ellas. A efectos prácticos, podéis suponer que CMatrix4x4::Set (...) es equivalente a ir asignando a un array de floats de 16 elementos: el primer parámetro seria el primer elemento del array, el segundo parámetro el segundo elemento, etc.

En segundo lugar, proyección en perspectiva, equivalente a gluPerspective:

   1:  CMatrix4x4 CreatePerspectiveProj (float fovy,  float aspect, 
   2:                                    float zNear, float zFar)
   3:  {
   4:   float f    = tanf (((fovy/180.f)*(float)M_PI) / 2.0f);
   5:   float div  = (zNear-zFar);
   6:
   7:   f   = IsFloatEqual(f, 0.f) ? FLT_MAX : 1.f / f;
   8:   div = IsFloatEqual(div, 0.f) ? FLT_MAX : 1.f / div;
9:
  10:   CMatrix4x4 result;
  11:
  12:   result.Set (f / aspect, 0.f,   0.f,              0.f,
  13:               0.f,          f,   0.f,              0.f,
  14:               0.f,        0.f,   (zFar+zNear)*div, (2.f*zFar*zNear)*div,
  15:               0.f,        0.f,  -1.f,              0.f);
  16:
  17:   return result;
  18:  }

A comentar, la macro IsFloatEqual solo compara dos números en coma flotante: el método normalmente mas recomendado (pero menos rápido, obviamente), es restarlos, coger el valor absoluto, y comparar si es menor que cierto epsilon. Esto se hace así debido a que por precisión de los numeros en coma flotante, comparar con numeros exactos (por ejemplo, haciendo float == 0.0) es desaconsejable.

Finalmente, el que tiene mas curro, el gluLookAt (sobretodo, porque la documentación obvia ciertos detalles):

   1:  CMatrix4x4 CreateLookAt (const CVector3 &eye,
   2:                           const CVector3 &center, 
   3:                           const CVector3 &up)
   4:  {
   5:   CVector3 f      (center-eye);
   6:   CVector3 upLocal(up);
   7:
   8:   f.Normalize();
   9:   upLocal.Normalize();
  10:
  11:   CVector3 s = f ^ upLocal;
  12:   CVector3 u = s ^ f;
  13:
  14:   s.Normalize();
  15:   u.Normalize();
  16:
  17:   CMatrix4x4 result, translate;
  18:
  19:   result.Set ( s.x,  s.y,  s.z, 0.f,
  20:                u.x,  u.y,  u.z, 0.f,
  21:               -f.x, -f.y, -f.z, 0.f,
  22:                0.f,  0.f,  0.f, 1.f);
  23:
  24:   translate.SetTranslation (eye*-1.f);
  25:
  26:   return result*translate;
  27:  }

A ver, destacar de este snippet, que el operador^ de la clase CVector3 equivale a hacer un producto vectorial (cross product), que el método Normalize hace lo inferible del nombre (es decir, normaliza el vector usando su modulo), y que el método SetTranslation de la clase CMatrix4x4, simplemente asigna a una traslación a la matriz (en este caso, al ser una matriz identidad, simplemente creamos una matriz de traslación).

No he explicado a fondo que hace cada parte, para eso tenéis los links a la documentación de OpenGL, y si hay mas preguntas mejor dejad comentarios.

La licencia de este código es la obvia y clásica haced lo que os dé la gana con él. Si encontrais algun bug, comentarlo y aprendemos todos de ello :)

Tuesday, June 16, 2009

Como se creó la Extasik / Collapse & Necrostudios

Iba a hacer un post técnico sobre mi demo-engine, comentando tonterías que estoy haciendo, y las mil paridas que estoy aprendiendo a base de leer más libros de C++ (y darme cuenta que soy un pardillo de C++), pero como no estoy en casa, he preferido contar como surgió la que es, posiblemente, la producción de la que estoy mas orgulloso: la extasik.

Primero empecemos con el contexto de la producción en si:

katedra July 2006
e-fill April 2006
extasik March 2006
ifparty invitation'06 February 2006
xmo06 January 2006
siahtu December 2005

(Ripeado vilmente de pouet)

Como veis, fue una época realmente muy productiva, prácticamente a producción por mes, de las cuales la única que considero flojilla es la siahtu (a pesar que tenia mucho trabajo detrás, no quedo demasiado bien). En medio de todas estas producciones, esta la extasik.

En febrero de 2006, la gente de Bixo me invitaron a la Plugparty. Por ser demoscener no tenia que pagar entrada, pero insistieron que tenía que producir. La Plugparty era una party pequeña, con un publico mayoritariamente gamer, que se hacia en un pueblo tranquilo cerca de Lleida. Como al mes siguiente había la, también ahora, desaparecida ifparty, que organizaba, entre otros, slack, decidí matar dos pájaros de un tiro y hacer una invitación para tal party (diría, si mal no recuerdo, que fue slack quien me instó a hacerlo). Al final la prod dio la temática de la party, y quedó muy resultona. Lo importante es que fue posiblemente la primera colaboración seria con slack (no tendré en cuenta la grevox, ejem), aprendiendo a usar el sinte para sincronizar, tener en cuenta cuanto ocupa y que podía hacer.

Al mes siguiente había la ifparty, a la cual bajaba con los Bixo, y también tenia que llevar prod. Para cambiar mi sistema habitual de rellenar hasta llegar a 4k, esta vez decidí programar todo lo que quería en la prod, y luego sufrir bajándola hasta los 4k. Las inspiraciones principales para la prod fueron The S (que es la obvia) y la menos obvia, VHS. Quería una prod usando mucha sincro, rápida, y con 4 partes diferentes mínimo. Además quería postprods y algo de decoración a parte de lo mostrado en pantalla: evitar fondos negros y/o efectos "limpios", etc.

La prod la empecé hacia el día 6 de marzo, es decir, 2 semanas antes de la deadline. Durante la primera semana y media, se hizo toda la parte grafica, sin optimizar nada (a parte de ciertas obviedades), y sin música ni sincronismo. De hecho, como curiosidad, la prod la probaba con la música de la invitación de la ifparty, y no fue hasta la misma ifparty cuando slack hizo el track para la 4k. Entonces, el martes antes de la party, decidí que ya tenia todo el contenido que deseaba, y que era el momento de empezar a optimizar. Probé de comprimirla con crinkler, para saber cuanto me había pasado de 4k: la prod ocupaba algo menos de 6kb, si no recuerdo mal.

Bajar el primer kilobyte y medio fue un trabajo bastante lineal y divertido: eliminar redundancias, añadir secciones, quitar burradas, etc. Estuve 3 días casi sin dormir optimizando la producción, de hecho, la noche antes de ir hacia la party (diría que fuimos para allá el sábado por la mañana) no dormí nada. Justo cuando me venían a recoger en coche, la prod bajaba hasta los 4096 bytes (recuerdo estar bastante contento de tener la prod sin sincro ni música, pero cerca de algo presentable).

Acabar la producción en la party fue posiblemente la parte más divertida. Por una parte, me había comprometido con slack a dar una charla sobre las 4k que había/habíamos hecho hasta ese día (que funcionó bastante bien para ser una charla orientada a explicar tonterías internas de cada prod), y aun tenia que conseguir una canción de slack, sincronizar y pulir la prod: todo eso en unas 12 horas. Estuve optimizando mas cosas de la prod hasta el medio día, entonces me fui a comer con bastante gente de la party a un chino, mientras el pobre slack se quedaba en la party haciendo la música de la prod (igualmente se tenia que quedar, al ser organizador).

Cuando volvimos del chino, slack tenia un esbozo bastante final de la música, así que podía empezar a sincronizar y optimizar. Gran parte de la tarde se basó en hacer la sincro con la música y optimizar alguna cosa, aunque no salirse de 4k en este punto fue gracias a slack, pues le dejé muy poco espacio para la música. A media tarde dí la charla (explicar cosas sobre la charla es una historia para otro día), para después seguir con la prod.

Quizás la parte mas remarcable fue terminar la prod en si mismo. Como muchas veces pasa, cuando teníamos la prod terminada y por debajo de 4k, la probamos en la compo machine (que traía una ATI, como no) y el texto se veía mal. Corregí el bug, pero al corregirlo la prod volvió a subir: estábamos al límite de los 4kb, y al hacer cualquier cambio, la compresión de la prod no era tan eficiente y subía bastante (10 bytes, aproximadamente). El principal problema a esas horas es que la deadline era inminente. Por suerte, slack estaba muy liado montando las compos, y yo estaba al final de la sala de la ifparty. Lo que hice fue ir dándole largas (nos pasamos mucho rato pegando gritos de punta a punta), porque sabía que no se levantaría para recorrer los 20 metros, estando hasta arriba de responsabilidades. Así conseguí casi una hora más para terminar la prod, escribir el nfo, el diz, hacer screenshots, etc. Truquillos de party-coding que no viene mal saber :P

Finalmente, unas cuantas curiosidades:

- La llamamos extasik por la canción de Chimo Bayo. Luego le siguió la extanok.
- La escena final fue en principio una sala con columnas y un objeto central (hay un screenshot al final del post). Al final se cambió. La escena que sé usó al final, se referenciaba entre slack y yo como la escena de las tetas. Esto es una referencia oscura a la invitación de la ifparty06, donde la primera se referenciaba como la escena de las p*****.
- El texto que sale en las dos partes finales eran, en principio, el nombre completo de los dos grupos. Por motivos de tamaño se recortó.
- La mayoría de la prod la monté a 320x240, porque mi pobre portátil se moría con los postprods.
- Todos los objetos en la prod son cilindros. El sistema para pintarlo hereda de la grevox, la siahtu y una prod que nunca terminé.
- El fondo de las dos primeras escenas se reutilizó para la e-fill, pero sin rotarlo como hace en esta.
- Gran parte del código gráfico de la extasik se reutilizó para la extanok, por ejemplo la sala y el sistema de dibujado de cilindros.
- Unos meses más tarde, descubrimos el truquillo de truncar floats. La optimización en la extasik es principalmente refactorización de código.

Y unos screenshots de la prod a medio montar. Las imágenes no están desaturadas, el esquema de color lo metí cuando acababa la parte gráfica:







Saturday, June 06, 2009

Cronica de la captura de una demo

Hace tiempo, en un ataque de los que nos da a algunos coders, porté varias demos de MS-DOS a Windows:

- Un pack que llamé internamente "hat-trick" de Anaconda (Eunectex, Requiem y fix de la Insane Elements)
- La Fulcrum/Matrix (esta la porte en una noche non-stop) y la G-Cube
- La Mayhem/Incognita (sobre esta hasta hay un pseudo-diario de desarrollo, parte 1 y parte 2)

Y dejando de lado al capitán obvio comentado lo que todos sabéis, siempre me quedó cierta espina clavada por no haber podido portar la ultima demo de Anaconda para MS-DOS, la Myth Of Orion: pedí el código algunos coders de Anaconda, pero no lo pudieron localizar. Tenia muchas ganas de portarla, en parte, porque así habría portado todas sus demos a Windows, permitiéndome verlas en cuanto me apeteciera. Pero el motivo mas importante es algo más largo de explicar.

Hacia 1997 mi padre compró un Pentium MMX a 200Mhz. Al cabo de aproximadamente 4 años ese PC pasó a ser mio, y le metí una Voodoo Banshee. Aunque la mayoría de demos que quería ver iban bien, habia una en particular que iba a framerates bajos (menos de 10fps): la Myth Of Orion. Aunque la vi muchas veces, habia ciertas partes que se arrastraban sobremanera, y siempre quise poder verla a una velocidad decente.

Hacia 2002, me compré un portatil nuevo, pero traía instalado WindowsXP, y el soporte de MS-DOS de este deja bastante que desear. Asi pues, aparqué el tema de verla bien, y seguí viendola en mi viejo equipo.

Unos dos años mas tarde, Dosbox empezó a tener soporte para VESA. Probé los primeros parches que lo traían (diría que a través de un nighty build), y por fin pude ver la demo. Y digo ver, porque la velocidad no era muy aceptable. Ademas, se colgaba hacia el segundo minuto (sigue haciéndolo hoy en día). He ido probando cada nueva versión que sale de Dosbox, pero todas se siguen colgando en el mismo sitio, así que seguía sin poder verla bien. Por la misma época tenía también instalado el VirtualPC para los demoshows de las bcnparty, pero no conseguía que funcionara bien tampoco.

Avancemos hasta finales de 2008, principios de 2009. Por motivos que no vienen al caso, he tenido que usar Virtualbox, sobretodo para tener un Linux a mano. Hace una semana, debido a que ya no necesitaba usar mas Linux, borré el disco duro virtual donde estaba alojado, y pensé que podría probar de instalar un MS-DOS, a ver si podía ejecutar las demos antiguas que hace tanto tiempo que no veo. Mirando las features de la aplicación, vi que soportaba una SoundBlaster16 virtual, lo cual me permitiría ver la demo bien.

Una vez instalado MS-DOS en la maquina virtual, configurado el sonido, memoria, etc, para que funcione, consigo ejecutar la demo. Todo ilusionado, me dispongo a verla, y al cabo de 2 minutos se cuelga en el mismo sitio que con Dosbox!

Ya sin ideas, decido mirar si Bochs o Qemu ofrecen algo que no ofrece VirtualBox. Primero probé Bochs, porque encontré un tutorial sobre como instalar MS-DOS 6.22 en él. Luego de una hora de instalar el SO y configurar lo necesario, me decido a ejecutar la demo. El problema es que es un emulador y no un virtualizador (como Dosbox, vaya), con lo cual la velocidad es menos que aceptable. Igualmente, si funciona, al menos podré verla a 1fps: siempre que no se cuelgue en el sitio habitual.

Espero los dos minutos de rigor, viendo la demo a ritmo de tortuga, y para mi sorpresa, no se cuelga! Entonces había dos problemas a superar, el segundo a consecuencia de la solución del primero:

1) La demo va a 1fps, y me pierdo mucho contenido (la demo funciona como si la ejecutara sobre un Pentium 75 aproximadamente). Bochs permite configurar el numero de ciclos por segundo, con lo cual puedo ver la demo como si tuviera un Pentium 500, pero cada actualización de pantalla tarda 4-5 segundos.

2) Bochs no permite capturar la salida por pantalla a vídeo o similares.

El caso ideal seria poder grabar la salida usando en método detallado en el punto 1, con algún sistema. Lo primero que se me ocurrió fue usar Fraps o Hypercam. El primero no me sirvió, porque Bochs no usa OpenGL para la salida a pantalla. El segundo captura cualquier ventana, pero presenta otro problema: no sabía si podría tener en cuenta que solo capturara cuando la ventana se actualizara.

Así que hice lo que cualquier coder pocafeinoso haría: me bajé el código fuente del Bochs, y lo modifiqué para que guardara cuando un fotograma es diferente del anterior dibujado. Para simplificar el logger, hice que grabará en raw a disco. Luego solo es cuestión de dejar al Bochs guardando toda la demo (tarda del orden de 2 horas, aproximadamente), y luego montar esas imágenes capturadas.

El siguiente problema es que no sé mucho de edición de vídeo, así que en vez de buscar un software capaz de crear un vídeo en base a las capturas, ademas de tener que convertir los raw a un formato reconocible por ese software, decidí crearme mi propio conversor. Ademas, como no sabía el framerate exacto al que había captura, metí soporte para ajustar la velocidad del vídeo (y en un futuro no muy lejano, para hacer interpolación temporal, aunque sea chapucero). Después de haber creado el vídeo, solo es necesario unirlo con la música de la demo, y tenemos una captura de la demo: fácil fácil!

Las ventajas de este sistema, es que puedo capturar cualquier cosa que funcione sobre Bochs, que no son pocas. Las desventajas es que es un sistema muy lento y que la sincronización se tiene que hacer a mano (ademas, dista bastante de ser perfecta).

Y esto es todo: espero que ver a que extremos puedo llegar, anime a algunos grupos a rebuscar su código viejuno para que haga ports como dios manda, en vez de tener que hacer chapuzas para poder ver sus demos!

Unos screenshots, y cierro, que esto se ha alargado demasiado:



Y un vídeo montado a prisa, disculpad la calidad general, pero tengo que recapturar todo de nuevo: entendedlo como una muestra previa :)

video

PS: Como scenesp no está funcional, he subido el vídeo con el sistema de google, y se ha zampado la calidad para desayunar.

Tuesday, April 21, 2009

Kings Tools

Solo una entrada corta para recomendar este add-in para VisualStudio. La usé mucho en VStudio 2003, pero no funcionaba en VStudio 2008, así que me quedé sin ella, y sin documentar cómodamente en doxygen ni cambiar entre .cpp y .h rápidamente (si, sé que lo puedes hacer con macros "facilmente", pero a esta herramienta ya estoy acostumbrado).

Como el código esta disponible, alguien que responde al nick/nombre de Green Chilli, dejó en los comentarios la pagina de codeproject (donde se publicó el original para 2003), el codigo modificado para que funcionara sobre 2008: el problema es que esta programado en VBasic, y no lo tenia instalado... HASTA HOY!

Así que os pongo el código modificado, junto con el instalador ya compilado (así no tenéis que instalar la bazofia de VBasic), para facilitar el trabajo a la gente:
Repito que yo solo he compilado el codigo, no soy el autor de la modificación para que funcione en 2008 :)

Wednesday, October 15, 2008

Volviendo a empezar, poco a poco

Hacia mucho que no escribía por aquí. El ultimo post quería decir que vuelvo a verme motivado para producir demos. Aunque muchos ya lo saben, me tomé un descanso porque noté que no producía lo mejor que podía, y no quería seguir creando productos sub-par. No creo que todas mis producciones sean mierda, ni de lejos, pero la ultima 4k, la forma de hacerla (la casi nula intención por crear algo de calidad), fue la razón que decidiera parar.

Durante el parón (y antes de él) me he visto envuelto en bastantes proyectos, algunos de ellos públicos, muchos de ellos privados, que solo han visto las pocas personas en las que confío para mostrar mis trabajos en progreso. Por eso, hoy quiero hacer un poco de resumen, con mas pantallazos que texto. Al fin y al cabo, nadie lee los blogs, para que escribir :P

Me gustaría, pero no sé si conseguiré, que hubiera preguntas respecto a los proyectos. Estoy muy abierto a dar toda la información posible y ayuda. No soy muy partidario de dar código a espuertas, pues creo que coger el vicio de copiar código por sistema es malo. Aprender a hacer algo basado en una explicación concisa me parece mucho mas didáctico. Así pues, preguntad, y intentaré dar todo mi (limitado) conocimiento.

Nada más, empezaré con los visores de formatos de geometría de juegos. Basicamente son cargadores del formato que usan ciertos juegos, tanto sea en sus modelos como en los mapas en si. Luego hay unas cuantas pantallas de mis colaboraciones en emuladores. Por cierto, los shots no están en orden cronológico, sino quedaba algo desestructurado, si alguien quiere saberlo lo comento.


Quake 1 / Quake 2




Quake 3




Portal / Half life 2
(mismo engine porque es el mismo formato)




Visor de modelos del Half Life 2
(lo programé a parte y luego lo integré en el engine de arriba)




Visor de modelos del Doom 3
(también tengo hecho un cargador de mapas, pero no tengo shots a mano)



Visor de modelos del Crysis




Port del mi motor de Quake 3 a DS
(corriendo sobre emulador, también corre en el hardware real)




Port del mi motor de Quake 3 a PSP




Desmume (emulador de DS)
(Colaboración, principalmente, trabajo en el core 3D, pero también en la CPU/2D/optimización)





jpcsp (emulador de PSP)
(Colaboración, principalmente trabajo en el core 3D)



Y esto es todo lo "importante" a mencionar. Contando que estuve activo en la demoscene hasta Julio del 2007, tampoco está tan mal. Por supuesto, podría haber hecho más, pero mucho tiempo se dedicó al emulador de DS, cuyo desarrollo fue muy complejo.

A parte, a ratos voy trabajando, como todo coder gráfico, en un engine 3D, del cual me guardaré shots para otra ocasión.

Nada más que contar ni mostrar por hoy!

Wednesday, July 16, 2008

Se acabaron las gilipolleces

Estoy volviendo. Lo intento con fuerzas, y espero que lo merezca. Es el momento de volver a levantar la cabeza, y dejar a un lado las ideas de una solución sencilla. Si no es hoy, mañana. En breve, lo entenderéis.

Friday, June 16, 2006

Dejando de molar

Como siempre, hace ya tiempo desde la ultima entrada...

Despues de la excursión de 3 dias con mi padre, se ve que volví nuevo, y me dediqué a programar bastante orientado a la scene. En cuestion de 45 dias, hice tres 4k y dos ports a windows. Un mes despues, terminé un tercer port, y desde entonces poca cosa he hecho. Para referencia, las 4k son, en orden cronologico:

- Ifparty'06 invitation / Collapse + Necrostudios
- Extasik / Collapse + Necrostudios
- e-fill / Collapse + Necrostudios

Y los ports:

- Fulcrum / Matrix
- G-Cube / Matrix
- Luxo / Matrix

Estoy especialmente contento con las dos primeras 4k (ifparty'06 invit y la extasik), la primera por el diseño general (que despues se convirtió en la imagen de la party :O) y la otra por ser tecnicamente bastante más potente que cualquiera que hubiera hecho hasta la fecha. Sobre los ports, el de la Fulcrum fué genial hacerlo, siempre me encantó.

Ahora mismo, estoy algo off de la demoscene. Los motivos son varios, y no creo necesario discutirlo aqui, pero simplemente necesito centrarme en otras cosas más interesantes que hackear graficos dentro de una 4k. Almenos ese es mi punto de vista ahora mismo.

Como no quiero (ni puedo) dejar de programar en casa, estoy liado con un engine 3D, centrado en soportar ciertas cosas que hace meses que queria probar. Siento ser parco en detalles, pero de momento poco hay que contar.

Como apunte final, me da la impresión que este verano no asistiré a muchas partys, no me he preocupado de inscribirme decentemente a la euskal, y los billetes a la Buenzli y la evoke estan demasiado caros. UPDATE: se ve que no han enviado aun las invitaciones de la PMP, sino que simplemente soy gilipollas y me creo mis opiniones demasiado rapidamente, por supuesto siempre basadas en humo :P

Ah, y ademas, ahora curro de programador.

Nada más, divertíos.