domingo, 15 de julio de 2007

XNA: Escribir por pantalla

Hello! Hoy he completado el código fuente del otro día, para que se pueda escribir por pantalla.

De esta forma, a parte de poner un mensaje en la parte superior, cada vez que le demos a una de los números de nuestro teclado, cambiara el color que estamos limitando y cambiara le mensaje de la esquina inferior, en la que aparece que color es el que estamos dejando ver y cual es su valor en el formato RGB.



Para poder escribir, hemos tenido que usar un nuevo fichero y una nueva clase.

  • Un fichero que describe la fuente que usamos, con su nombre y sus características. Tened presente que tiene que existir una fuente con este nombre en la carpeta de windows donde almacenamos las fuentes para las letras.
  • La clase SpriteFont, que es la que almacenará la fuente, para que la clase SpriteBach, que es la que pinta, pueda ejecutar el metodo DrawString, al que le pasaremos la fuente (SpriteFont), el texto a escribir, la posición (con un Vector2) y el color de la letra.
Ale, aquí tenéis el código.

Ejemplo escribir por pantalla

sábado, 14 de julio de 2007

XNA: Teclado y limitar los colores

Buenas, usando el codigo fuente de nuestro ejemploanterior de comocargar una imagen y pintarla, he alterado el codigo para darle uso al tercer parametro del metodo SpriteBatch->Draw, el color.

Este parametro si se deja en blanco pinta la imagen sin alterarla, ¿porque? porque el bloanco incluye todo la gama de colores. Y es que el color que le pasemos a SpriteBatch sera el unico que veremos por pantalla.

El codigo que teneis mas abajo lee los numeros que pulseis de vuestro teclado y cambia el color que estamos diciendo quesolo puede pintar.

Asi, si enviamos colores primarios como el rojo, el verde y el azul (o formato RGB en el que estan implementados los colores de la clase Colors) solo veremos las partes de la imagen que tengan este color.

Estos son loscoloresque permitiremos ver para las teclas numericas en el ejemplo:

1 -> Blanco (veremos la imagen original porque todos los colores stan incluidos en el blanco)
2 -> Rojo
3 -> Verde
4 -> Azul
5 -> Oro
6 -> Rosa
7 -> Amarillo
8 -> Naranja
9 -> Negro (no veremos nada (oscuridad total), porque el negro no incluye ningun color)

Como vereis, para recoger el estado del teclado y saber si alguien pulsa una tecla he usado Keyboard.GetState().IsKeyDown(Keys.LATECLAQUEQUERAMOS) que nos devuelve un booleano si alguien la esta pulsando.

Esta comprobacion, como cualquiera que sea de control en XNA es recomendable hacerla en el metodo "Update" ya que constituye un thread especifico para este tipo de comprobaciones de estado de perifericos.

Aqui teneis el codigo fuente:
Ejemplo XNA Colores y Teclado

XNA: ¿Que necesito?

Bueno, por si alguien esta interesado en programar mediante estas herramientas necesitara descargarse tan solo 2 programas:

Instalad las aplicaciones en este este orden, pues el XNA Game Studio se instala sobre el Visual C#.

Ambas aplicaciones son gratuitas (el Visual C# te pide que te registres nada más, pero es gratis).

XNA: Pintar una imagen por pantalla

Buenas, he creado este mini-tutorial para pintar una imagen por pantallamediante XNA.

  1. Creamos un nuevo proyecto con XNA Game Studio Express de tipo Game Windows (para Xbox 360 seria lo mismo en realidad).
  2. Agregamos la imagen que queremos pintar al proyecto ( Proyecto -> Agregar Elemento Existente..).
  3. En la ventana de propiedades (Ver -> ventana de Propiedades) si clicamos sobre la imagen podemos ver el nombre que le da el sistema a nuestra imagen, es el que usaremos para cargarla mediante código fuente.




Ok, aquí empieza lo bueno, pintemos:
  • Crearemos una Texture2D que contendrá nuestra imagen tal que así Texture2D t2d = content.load("nombredelaimagen"); como veis la clase content esla encargada de cargar contenido, par el ejemplo definimos t2d global y la cargamos.
  • SpriteBatch, esta clase se encargara de pintar la imagen mediante su método Draw y es un shader sencillo que lleva XNA de serie, lo crearemos así SpriteBatch sb = new SpriteBatch(graphics.GraphicsDevice);
  • Ahora ya estamos listos para pintar, asi que vayamos al metodo Draw donde XNA tiene el thread que se encargara de pintar. Para usar SpriteBatch tenemos que indicárselo a la clase sb.Begin(), pintar, y después decirle que ya hemos terminado sb.End(). Esto es importante, porque de no hacerlo ais no veremos nada.
  • Y para terminar, el método que pinta sb.Draw(t2d, new Rectangle(0,0,800,600), Color.White), bien, como veis tienes 3 parametros en este caso, el primero, la imagen que queremos pintar,el segundo un rectángulo que XNA definira como el espacio en el que se pintara nuestra imagen y por ultimo, un color, que si lo dejamos blanco no afectara a nuestra imagen final.
Y ya tenemos listo el programa.

Aquí os dejo el código fuente con todo el material para el XNA Game Studio Express.

Ejemplo XNA Pintar Imagen

miércoles, 4 de julio de 2007

Blender y Phyton: programando en el lado oscuro

Buenas, he estado estas semanas llevando a la practica un algoritmo de remallado para la facultad.

El algoritmo lo he implementado como un script del conocido programa Blender, magnífico programa gratuito de edición 3D y para el código, el lenguaje Python.

Estas tecnologias eran nuevas para mi y la verdad, me ha costado algo "adaptarme" al tipo de codigo que uno genera con Python.


Y es que la documentacion que circula por Internet al respecto por lo general suele ser incompleta y poco precisa, incluso desde la especificación oficial que uno puede consultar desde el website oficial de Blender he detectad problemas de este tipo.

La verdad me ha dejado un sabor bastante amago la experiencia, pero como se que en el futuro, habrá gente en mi situación he decido publicar estos enlaces con tutoriales y redactar mis propios consejos. Creo que es un conocimiento que puede resultar realmente útil.

Enlaces
Consejos&Info
  • Mesh&Nmesh: Las clases de Blender Mesh y NMesh representan la malla de un objeto 3D, solo que la NMesh es una clase con lso dias contados pero ofrece una ventaja, si tenemos una escena animada en Blender en la que se modifica nuestra malla mediante una transformacion, la clase NMesh tendra la malla ya transformada, pero la clase Mesh NO. Tened en cuenta, como vereis en la especificación que los metodos son diferentes.

  • Listas de listas: para crear una lista de listas en Python hay que hacer un par de trapis. Por ejemplo, queremos crar una lista con coordenadas, y que cada posición de la lista se corresponda con la posicion del vertice en su estructura original haremos esto:

    ListaCoordenadas=[ ]
    for v in Mesh.verts:
    ListaCoordenadas.append(v.co)

    Si hicieramos un print ListaCoordenadas obtendriamos algo similar a esto:
    [ [0 , -1 , 2.76] , [2,-2.4 , 1] , ... ]

    Las listas de Blender son vomitibamente flexibles asi que podeis meter listas de listas de apuntadores, de palabras, un pupurri, etc.
    Señalar también que el metodo append añade un elemento al final de la lista, siemrpe al final, más info en el tutorial que os he facilitado.
  • Eliminar vertices, arestas o caras: las librerias de Blender, como se ve en la especificación permiten eliminar vertices, aristas y caras, pero hay una cosa que no te dicen, y es que, si tienes 50 vertices, y eliminas el 45, los vertices superiores (del 46 al 50) seran modificados y se decrementaran sus indices en una posicion:

    Vertices: ... 43 44 45 46 47 48 49 50 -> Eliminamos vertice 45 -> ... 43 44 45 46 47 48 49

    Problema! Si volvemos a referenciar el vetice 45, ahora sera el 46 de antes, y asi para todos los demas que tengan un indice >=45
    Ademas si accedemos al vertice 50, nos saldremos de rango.
    Este hecho genera unos problemas brutales si utilizamos estructuras auxiliares que se conectan a la maya mediante indices o si simplemente tenemos indices almacenados en una variable local
    Consejo importante, reactualiza todas tus estructuras/variables globales/locales si eliminas un vertice, cara o aresta y estabas indexandolos.
    Una buena solucion, si hemos eliminado el indice 45 y tenemos una variable local llamada vMolon:

    me.verts.delete( me.verts[45] )
    if vMolon >= 45:
    vMolon-=1

    Como vereis he metido me.verts[45] en vez del indice, y es que como dije, a pesar de lo que diga la especificación muchas cosas no hacen lo que deberían y es mejor pasarle el objeto MVert como he hecho directamente y adios problemas.
    La actualizacion de los indices es vital, porque no petara hasta que nos salgamos de rano y eso, puede simplemente no pasar y que el programa haga cosas raras y no tengamos ni idea y queramos suicidarnos de forma llamativa.

Bueno, de momento no tengo más consejos.

La experiencia no ha sido muy de mi agrado y es que la el lenguaje ya de por si no me convence, prefiero lenguajes mas estrictos como Java y C++ y tirar de librerias tipo OpenGL para aplicaciones 3D que sabes lo que hacen y no te dan sorpresas como es el caso de las librerias de Blender, que son algo asi como un expediante X que solo puede ser resuelto mediante paranoia y mucho cafe.

Presentación

Bienvenidos, este blog nace con la idea de proporcionar pequeñas ayudas de programación, tutoriales, presentar proyectos, etc.

Me centraré seguramente en el tema de la programación gráfica que es mi preferida, pero bueno, se me suele ir la pinza y lo más probable es que sea un popurrí.

Espero que a alguien le sea de ayuda.

Un saludo.