UVAtlas. D3DXCreateTextureGutterHelper fails with some Meshes

I finally found the solution to a problem that was driving me nuts.

D3DXCreateTextureGutterHelper (or the constructor of TextureGutterHelper, if on MDX) throws an "Invalid Call" exception with certain meshes.

I came to a situation where the method worked for a Mesh generated by D3DXCreateUVAtlas, but failed for the (aparently) SAME mesh created by me:

* Same number of vertices/faces
* Same attribute table
* Same vertex format
* Same Mesh Options
* Same declarations
* Same indices at IndexBuffer
* SAME EVERYTHING

Then, what was the cause?

My meshes have 2 or more different sets of TexCoords. One of them to address the UVAtlas, and others for other kind of textures. Aparently, D3DXCreateTextureGutterHelper will fail if the coordinates addressing the UVAtlas are not in the 1st set of TexCoords.

In my case, UVAtlas TexCoords are always in the 2nd set of TexCoords. That´s why it was failing.

Workaround: create a temp Mesh and copy the UVAtlas coordinates to the first set. Then, the method will succeed.

PS To the Microsoft DirectX Team:

The work done with all the UVAtlas functions is priceless. They are really useful, but please, document things like this a little bit.

This kind of problems are very easy to work around when known, but finding the cause by brute-force investigation can take hours and hours.

Instalar aplicación Compact Framework/Windows Mobile en 4 pasos

Últimamente, en mis pocos ratos libres, estoy dedicando tiempo a estudiar el Compact Framework y el desarrollo para dispositivos móbiles, trasteando con DirectX Mobile, WinForms y todo lo que se me ocurre.

El caso es que quería que un programilla bastante útil que he terminado apareciera en la lista de programas instalados, para poder añadirlo al menú de acceso rápido de mi HTC Touch.

Para conseguir esto, hay que crear un pequeño instalador que, en lugar de símplemente copiar la aplicación al dispositivo móvil, efectúe todo el registro habitual de un proceso de instalación. Ésto se puede hacer con un instalador "User Friendly", con ventanitas y demás, o con la variante más rápida, pero menos elegante, que usa ficheros CAB. Por motivos de rapidez iremos por ésta última vía.

La tarea es muy sencilla y rápida, así que voy a explicarla en cuatro pasos:

1.- En la solución donde tengas tu proyecto para Compact Framework, añade un nuevo proyecto escogiendo: Add -> New Project. Después, escoge la categoría "Other Project Types" -> "Setup and Deployment" -> "SmartDevice CAB Project".

2.- Si hacéis "click" en el nuevo proyecto, podrás especificar en sus propiedades el nombre del producto, propietario, etc, etc. Si hacéis "right click", aparecerá un menú contextual, donde podréis elegir: "View -> File System". Se abrirá una pestaña en la ventana principal de Visual Studio. Ésta contiene los contenidos del sistema de ficheros que queremos dejar en la máquina donde se va a instalar nuestra aplicación.

3.- Seleccionamos "Application Folder" en la mitad izda. de esta pestaña, y en la mitad dcha, hacemos "right click" y seleccionamos: Add -> Project Output. Se abrirá una ventanita donde podrás elegir (en el ComboBox de arriba) qué otro proyecto de la solución será el que queremos instalar. Escogéis el que queráis, dejáis marcada la opción "Primary Output" y pulsáis en Aceptar.

4.- Hacéis "right click" sobre el nuevo proyecto de setup y pulsais sobre "Build". Si todo va bien, en la carpeta de salida del proyecto encontraréis el nuevo y flamante CAB de instalación.


Así de fácil.

VisibleChanged Event, missing in the Compact Framework

If you need to do something in the VisibleChanged event of a form or control, using the Compact Framework, you´ll see that this event is missing.

You can easily fix this shadowing the Visible property with a newer one, and firing the event by yourself. Just like this:

public event System.EventHandler VisibleChanged;
public new bool Visible
{
get { return base.Visible; }
set
{
if (base.Visible != value)
{
base.Visible = value;
if (VisibleChanged != null)
VisibleChanged(this, EventArgs.Empty);
}
}
}