.Net Compilation, registry accessing and application deployment for both x86 and x64 environments

What a long title, isn’t it?
That’s because, in some cases, there are a bunch of things related to make your .Net applications ready to work in both x86 and x64 environments. Specially if you need to use some unmanaged code or access the registry.
Let´s start!

Compiling and running assemblies

Native code (C++, etc) is compiled into platform-specify binary. That´s why you need to specify the target platform to be x86 or x64…
In .Net, things are a bit different. As you probably know, your VB or C# code will not be compiled into binary, but into MSIL. It´s the JIT Compiler (Just-in-time) who translates this intermediate code into binary, at load time. During this process, it can decide to compile it into 32 bits code or into 64 bits code, to adapt it to the underlying O.S., basing on it’s bitness.
That´s the reason why, in .Net, you can choose not to specify the target platform of your assembly, by choosing the option “Any CPU”. The following picture is a snapshot of VisualStudio project’s properties page, where you select the target platform.
image
Then, why would I want to specify a target platform? Isn’t “Any CPU” the best option always?
Most of the times, yes, as developers usually build pure .Net applications, with no dependency on unmanaged code and no further optimizations, so “Any CPU” would be the best option, letting the JIT compiler decide.
But in there are some situations where you will want to specify the target platform. Some examples:
  • If you use any unmanaged code (which is platform-specific). You will have be careful with this, as your application could fail to load if the JIT compiler decides to put it into a mode not compatible with your unmanaged assemblies.
  • If you want to optimize your assembly for an specific platform. For instance, if you need an application to access huge amounts of RAM memory, you will probably want to make it 64 bits only.
Also, there are other issues related to the target platform that you should be aware of, like registry accessing. We will talk about this later.
This blog post explains target platforms a bit further.

Platforms compatibility

  • If my assembly is compiled as Any CPU:
    • Will it run in a x86 environment –> Yes (JIT compiles it into x86 binary)
    • Will it run in a x64 environment –> Yes (JIT compiles it into x64 binary)
  • If my assembly is compiled as x64 only:
    • Will it run in a x86 environment –> No
    • Will it run in a x64 environment –> Yes
  • If my assembly is compiled as x86 only:
    • Will it run in a x86 environment –> Yes
    • Will it run in a x64 environment –> Yes (In WOW64 Mode)

WOW64 Mode

As backwards compatibility is good for selling licenses, Windows 64 bits offer a compatibility mode for 32bit applications. It´s the so called WOW Mode (Windows on Windows).
Have you played videogames on your PC with a machine emulator, like MAME or a Spectrum emulator? Well, this is something similar. WOW64 is a 32bit emulator that runs on 64bits machines, allowing 32bit applications to run in such environments.
Although we will talk about some issues regarding WOW64 later, you can find more details about WOW mode here.

Detecting the bitness of a “Any CPU” process

What happens if you compiled your assembly to “Any CPU”?
If you know that it will always run in a (modern) x86 environment, you have no doubt about this. Your process is 32 bits.
But what´s its bitness if it can run in both x86 and x64 environments? Even further, if it´s in a x64 O.S., what bitness mode will the JIT compiler decide for it? Normally x64, but… better make sure. How to do this? Extremely easy:
                if (IntPtr.Size == 4)
                    return eArchitecture.x86;
                else if (IntPtr.Size == 8)
                    return eArchitecture.x64;
System.IntPtr is designed to hold a memory address, right? And in .Net, it has a very convenient property that tells us its size. So, if this size is 8 bytes, then we have 64 bits addresses, if it´s 4 bytes, we are in a 32 bits environment. Easy as that.
Please note: If your assembly was compiled as x86, its bitness will always be 32 bits, as even when running in 64-bit environments, it will do in WOW64 mode (emulated 32 bits), and its bitness will remain 32.

Windows 64-bit infrastructure

As mentioned above, Windows 64 bits offers the WOW64 mode, to allow running x86 applications.
Microsoft engineers decided not to mix up 32bits and 64bits applications inside your hard disk, so x64 applications are installed by default in the “Program Files” folder, as usual, and x86 applications are by default installed in a new “Program Files (x86)” folder.

The Windows x64 registry

In Windows x64, WOW64 mode offers separate logical view of the registry for 32-bit and 64-bit applications. It´s like if they were accessing to two separate registries. This is something important to take into account when developing for x64 and when deploying applications, as x86-targeted Setup Projects will also access differently to the registry.
Basically, this works in the following way: Windows intercepts registry calls made by assemblies and applications, and redirects them to the appropriate logical view of the registry, being this completely transparent to the application. More info about registry redirection here.
Although this naming convention is not 100% correct, we will call this two separate logical views as “the 32-bit registry” and “the 64-bit registry”.

Application deployment with Visual Studio setup projects

If you, like many other people, use Visual Studio setup projects and Windows Installer to deploy your applications, there are several things that you need to take care of, if your software needs to be both x86 and x64 compatible.

Target platform in VisualStudio Setup Projects

Just like normal assemblies, setup projects also have a target platform property. You can see it in the properties tab, when you select your project in the solution explorer.
image
Unfortunately, we don´t have the “Any CPU” option here, so we will have to choose the platform manually. This platform selection affects the following aspects (among others):
  • The default installation folder for your application: “Program Files”, or “Program Files (x86)”
  • If the setup project modifies the registry, it will affect the so-called-by-us “64-bit registry”, or the redirected “32-bits registry” for WOW64 processes. This is something important to keep in mind if you are using registry keys in your setup project.

So, which platform should I choose for the Setup Project?

It depends on how well your application is prepared for x64, and on how it is compiled:
  • If your application is compiled as x86: choose x86
  • If your application is compiled as x64: choose x64
  • If your application is compiled as “Any CPU”:
    • If you know it is prepared to be run as x64 (i.e. registry accessing code is aware of WOW64 mode): choose x64
    • If you cannot assure that your application will deal fine with x64 infrastructure: choose x86

Dude, where are my registry keys?

As mentioned above, if your Setup Project is compiled as x86, it won´t modify the “64-bit registry”, but the 32-bit, redirected version, provided by the WOW64 mode. So, if you open regedit.exe normally (which shows you the “64-bit” version of the registry), you won´t find anything.
Instead, you need to open the special version of RegEdit which shows you the “32-bit registry”, using:
[Windows Installation path]\SysWOW64\regedit.exe
Please note: Windows Installation Path is normally “C:\Windows”.

Accessing the registry from C#

Now that you understand how Windows x64 infrastructure is designed, and how your applications will be installed by Setup Projects, you will probably need to learn how to deal with both versions of the Windows x64 Registry. Specially if your application will be compiled as x86, and therefore run in WOW64 mode.

The usual, .Net way to access the registry

Imagine you want to read a certain key inside the “LOCAL_MACHINE\Software” node of the registry. In .Net, you normally do that by using a code similar to the following (using namespace: Microsoft.Win32):

RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\[Your Key Here]");
 
Doing so in a Windows x64 machine will only access the “64-bit” version of the registry, even if your process is running in WOW64 mode. So, if our application was installed with a x86 Setup Project, the keys we are looking for won´t be there. We need to access the “32-bit registry” instead, provided by the WOW64.

Accessing the 32-bit, WOW64 registry from C#

Unfortunately (and by now) there is no way in .Net to specify that we wont to access the “32-bit”, WOW64, version of the registry. To do so, we will have to deal with native API calls, dll-importing “advapi32.dll” and using the RegOpenKeyEx.
This function has a parameter called samDesired, which can be a combination of flags specifying access options for the key. One of those possible options, is specifying we want to open the WOW64 view of the registry.

Table of flags for samDesired

Value Meaning
KEY_ALL_ACCESS (0xF003F) Combines the STANDARD_RIGHTS_REQUIRED, KEY_QUERY_VALUE, KEY_SET_VALUE, KEY_CREATE_SUB_KEY, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, and KEY_CREATE_LINK access rights.
KEY_CREATE_LINK (0x0020) Reserved for system use.
KEY_CREATE_SUB_KEY (0x0004) Required to create a subkey of a registry key.
KEY_ENUMERATE_SUB_KEYS (0x0008) Required to enumerate the subkeys of a registry key.
KEY_EXECUTE (0x20019) Equivalent to KEY_READ.
KEY_NOTIFY (0x0010) Required to request change notifications for a registry key or for subkeys of a registry key.
KEY_QUERY_VALUE (0x0001) Required to query the values of a registry key.
KEY_READ (0x20019) Combines the STANDARD_RIGHTS_READ, KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, and KEY_NOTIFY values.
KEY_SET_VALUE (0x0002) Required to create, delete, or set a registry value.
KEY_WOW64_32KEY (0x0200) Indicates that an application on 64-bit Windows should operate on the 32-bit registry view. For more information, see Accessing an Alternate Registry View.
This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
Windows 2000: This flag is not supported.
KEY_WOW64_64KEY (0x0100) Indicates that an application on 64-bit Windows should operate on the 64-bit registry view. For more information, see Accessing an Alternate Registry View.
This flag must be combined using the OR operator with the other flags in this table that either query or access registry values.
Windows 2000: This flag is not supported.
KEY_WRITE (0x20006) Combines the STANDARD_RIGHTS_WRITE, KEY_SET_VALUE, and KEY_CREATE_SUB_KEY access rights.

The code

The next code is a personal translation to C# of several pieces of code I found, mostly from here:
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, EntryPoint = "RegOpenKeyEx")]
static extern int RegOpenKeyEx(IntPtr hKey, string subKey, uint options, int sam, out IntPtr phkResult);
 
[Flags]
public enum eRegWow64Options : int
{
    None =              0x0000,
    KEY_WOW64_64KEY =   0x0100,
    KEY_WOW64_32KEY =   0x0200,
    // Add here any others needed, from the table of the previous chapter
}
 
[Flags]
public enum eRegistryRights : int
{
    ReadKey =  131097,
    WriteKey = 131078,
}
 
public static RegistryKey OpenSubKey(RegistryKey pParentKey, string pSubKeyName, bool pWriteable,
                                     eRegWow64Options pOptions)
{
    if (pParentKey == null || GetRegistryKeyHandle(pParentKey).Equals(System.IntPtr.Zero))
        throw new System.Exception("OpenSubKey: Parent key is not open");
 
    eRegistryRights Rights = eRegistryRights.ReadKey;
    if (pWriteable)
        Rights = eRegistryRights.WriteKey;
 
    System.IntPtr SubKeyHandle;
    System.Int32 Result = RegOpenKeyEx(GetRegistryKeyHandle(pParentKey), pSubKeyName, 0,
                                      (int)Rights | (int)pOptions, out SubKeyHandle);
    if (Result != 0)
    {
        System.ComponentModel.Win32Exception W32ex = new System.ComponentModel.Win32Exception();
        throw new System.Exception("OpenSubKey: Exception encountered opening key", W32ex);
    }
 
    return PointerToRegistryKey(SubKeyHandle, pWriteable, false);
}
 
private static System.IntPtr GetRegistryKeyHandle(RegistryKey pRegisteryKey)
{
    Type Type = Type.GetType("Microsoft.Win32.RegistryKey");
    FieldInfo Info = Type.GetField("hkey", BindingFlags.NonPublic | BindingFlags.Instance);
 
    SafeHandle Handle = (SafeHandle)Info.GetValue(pRegisteryKey);
    IntPtr RealHandle = Handle.DangerousGetHandle();
 
    return Handle.DangerousGetHandle();
}
 
private static RegistryKey PointerToRegistryKey(IntPtr hKey, bool pWritable, bool pOwnsHandle)
{
    // Create a SafeHandles.SafeRegistryHandle from this pointer - this is a private class
    BindingFlags privateConstructors = BindingFlags.Instance | BindingFlags.NonPublic;
    Type safeRegistryHandleType = typeof(SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType(
                                             "Microsoft.Win32.SafeHandles.SafeRegistryHandle");
 
    Type[] safeRegistryHandleConstructorTypes = new Type[] { typeof(System.IntPtr), typeof(System.Boolean) };
    ConstructorInfo safeRegistryHandleConstructor = safeRegistryHandleType.GetConstructor(privateConstructors,
                                                               null, safeRegistryHandleConstructorTypes, null);
    Object safeHandle = safeRegistryHandleConstructor.Invoke(new Object[] { hKey, pOwnsHandle });
 
    // Create a new Registry key using the private constructor using the safeHandle - this should then behave like
    // a .NET natively opened handle and disposed of correctly
    Type registryKeyType = typeof(Microsoft.Win32.RegistryKey);
    Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(Boolean) };
    ConstructorInfo registryKeyConstructor = registryKeyType.GetConstructor(privateConstructors, null,
                                                                    registryKeyConstructorTypes, null);
    RegistryKey result = (RegistryKey)registryKeyConstructor.Invoke(new Object[] { safeHandle, pWritable });
    return result;
}

How to use the code

The OpenSubKey will return the searched key, allowing you to specify reading from the normal registry, or from the alternative 32-bit, WOW64 registry. The following example reads from the 32-bit WOW64 registry:
try
{
    RegistryKey key = OpenSubKey(Registry.LocalMachine,"Software\\[Key]",false,eRegWow64Options.KEY_WOW64_32KEY);
}
catch
{
    // Parent key not open, exception found at opening (probably related to security permissions requested)
}
You just need to place your key name where “[Key]” is.

How to make your application a bulletproof registry reader

Now that your have a way to read both versions of the registry in x64 environments, I´d suggest you to proceed the following way:
  1. Try to find your key in the usual, standard, .Net way, using the build-in “Registry.LocalMachine.OpenSubKey”. This case will cover your application running in a 32-bit Windows, or running in a 64-bit Windows, but not in WOW64 mode.
  2. If key not found, proceeding in one of the following paths:
    1. Check Windows version
      1. 32 bits: Exception, key not found
      2. 64 bits: Try to find the key in the WOW64 registry with the above code, and launch exception if not found.
    2. Try to read the WOW64 registry directly, enclosing your code in try-catch statement, if any exception is caught, or if key not found, launch exception
In a next article, I´ll talk about detecting which version of Windows your software is running in, and many other things.
Stay tuned!

Writing a correct Main Loop for your application

Have you ever wondered how can Windows run more than one application at a time, even in a single-processor machine? The answer is easy. It doesn’t. The point is that it switches from one application to another so fast that you don´t notice the change, and it seems both applications are running in parallel.
To allow this, running Windows applications should not always be running.
It´d be a waste of resources to massively use the processor just to find out that nothing had to be done, don’t you think?. That´d be kind of a psychotic behavior. Windows has it´s protocols and procedures to avoid this, letting applications or threads enter idle states, even for a few milliseconds, and giving then priority to other, non-idling processes.
So, what would happen if your application never enters idle mode? It would bring down the multi-tasking capability of Windows, slowing down every other application than yours. That´s why I say that running applications should not always be running.
Under this point of view, applications can be divided into three groups:
  1. Psychotic applications that should be updated always, i.e. intense computing applications (not so frequent, nowadays)
  2. Applications that should be updated only as a response to some user interaction (most Windows Forms applications)
  3. Applications that sometimes need to be “always updated”, and sometimes not (like a video-game)
As you know, when an application is run, the Main method is invoked, and the O.S gives the application access to the processor and some memory. Apart from thread priority policies, application´s behavior will be one or another depending on what we do in this Main() method:

Case # 1. Compute, compute, compute

The Main method structure is simple: update as fast as you can, and consume as much processor as possible. The Main() method in pseudo-code:
            while (Application is Alive)
            {
                Compute()
            }
This is the typical behavior of old applications in non multi-tasking environments. They consume as much processing power as is available.

Case # 2. Don´t disturb unless absolutely necessary

What should be done here is easy: if events are pending, process them (DoEvents). If not, just relax and sleep, yielding processor to other threads or applications. The exact implementation of such a procedure can be more complex, as we should decide when to enter sleep modes and when not. Luckily, .Net does that for us. The C# implementation you should use is:
            System.Windows.Forms.Application.Run(mForm);
The Run() method takes care of all the things above mentioned (yielding and many other things), and it does it using the standard .Net procedures and protocols.

Case # 3: The mixed approach

Other situations need a mixed solution. For example, a Windows Forms application that sometimes needs to enter a “running” state, where everything has to be updated, like a Windows Forms-based video-game, or a 3D editor where you want to run an animation. Here, updates will be applied when the application is in Running state, but not when it´s not, saving this way CPU (and batteries, if running in a laptop).
So, we want to combine the efficiency of Case # 2, with the possibility of switching to Case # 1 when needed. The correct implementation for this, in C#, is:
       ...
            System.Windows.Forms.Application.Idle += new EventHandler(Application_Idle);
            System.Windows.Forms.Application.Run(mForm);
        }
        static void Application_Idle(object sender, EventArgs e)
        {
            if(Application.RunningState)
            {
                 while(ApplicationStillIdle)
                      Compute();
            }
        }
The Application_Idle event will be fired each time the application is about to enter in Idle state (where all the pending messages for the windows has been processed).
This way, interaction between our application and others (running at the same time) will be correct: when we decide it (activate running state), we will have all the computing power for ourselves, but when it´s not needed (RunningState is off), we will yield it.

How to check if application is still Idle

The Application_Idle event is fired only once, when the application is about to enter idle state. Here, we will have to update computations while it is still Idle, giving priority to Windows Messages if there are some. How to check if the application is still Idle? Easy, we can use a property like the following:
        /// <summary>Checks to see if the application is still idle</summary>
        private bool AppStillIdle
        {
            get
            {
                NativeMethods.Message msg;
                return !NativeMethods.PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
            }
        }

An extra option to make things even better

We have seen how to activate/deactivate the psychotic (processor consuming) behavior of an application, basing on a state variable, but sometimes it is interesting to also deactivate it when our application does not have the focus (it is not the active application in the O.S.).
Windows controls and forms have a “Focused” property, but that doesn’t help much in this case, as we want to check if the entire application has focus, not an specific form (the main form of the application will loose focus often, when we open a child window, for instance).
Then, how to check if our application is the active application in Windows? Unfortunately, it seems that there is no C# managed code to check that, but we can easily use DLLImport to invoke the “GetForegroundWindow” method, comparing its result to our main form handle:
[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();
 
public bool MyAppFocused
{
    get { return GetForegroundWindow() == this.Handle; }
}
This way, we can put an additional condition to the Compute method, deactivating it also when the application is not focused:
static void Application_Idle(object sender, EventArgs e)
{
   if(Application.RunningState && MyAppFocused)
   {
       while(ApplicationStillIdle)
            Compute();
   }
     }

What should not be done

Some people tend to write the following code when need the mixed solution mentioned:
while (mForm.Created)
{
      System.Windows.Forms.Application.DoEvents();
 
      if(Application.RunningState)
             Compute();
}

Though it works, this approach is not correct, as it doesn’t yield processor to other threads (your application won´t enter idle mode). Use the above Idle event approach instead.

Conclusion

Quality software use the processor when really need it. Adding a few extra lines of code, you software will better share resources with other applications, and will improve laptop or handheld device´s battery life.
Take Care!

AutoBild estudia los efectos del cansancio y del alcohol al volante con simuladores Simax

En el número de esta semana de AutoBild (nº 214, del 18 al 24 de Diciembre de 2009), se publica la primera parte de un estudio realizado en colaboración con Toyota España y Simax, en el que se analizan los efectos del cansancio y del consumo de alcohol en la conducción.

PortadaAutobild¿Y quĆ© mejor manera para hacerlo que realmente analizar la conducción de voluntarios en condiciones de fatiga reales, y despuĆ©s de haber bebido? Y no nos referimos a 10 minutos de test, sino a 2 horas seguidas conduciendo en un entorno monótono como una autovĆ­a, para incrementar todavĆ­a mĆ”s el cansancio y el peligro. AdemĆ”s, y para obtener la mayor cantidad de información posible, hemos comparado sus resultados con los de otros voluntarios, descansados y sobrios.

Por razones obvias, este estudio no puede hacerse en la vía pública, y un circuito cerrado no sirve, ya que tendrían que estar 2 horas dando vueltas a un circuito, sin trÔfico, y que nada tiene que ver con una carretera real.

La solución diseñada por AutoBild ha sido utilizar simuladores Simax, cedidos por Toyota España. Nos propusieron la idea y desde el principio nos encantó, así que nos pusimos manos a la obra.

AdemƔs de permitir a los conductores circular por una vƭa real (autopista), e interactuar con trƔfico, desde Simax diseƱamos un ejercicio en el que, a lo largo de 2 horas, los conductores irƭan enfrentƔndose a incidencias de trƔfico de dificultad creciente. Desde una simple balsa de agua en la calzada, hasta un desprendimiento de rocas.

Los simuladores Simax monitorizan en todo momento todas las reacciones de los conductores y los vehƭculos, lo que nos ha permitido extraer conclusiones de lo mƔs interesantes. TenƩis vuestro ejemplar de AutoBild en el quiosco.

¡No os lo perdĆ”is!

La semana que viene se publica la segunda parte del estudio, y las conclusiones finales.

My ListView won´t show groups! Why?

This is a well documented issue, but just in case it helps someone.

If your ListView doesn't show groups, ensure the following (starting with the most obvious, and ending with the probable cause):

  1. Ensure your ListView has, at least, one column
  2. Ensure you have created Groups correctly
  3. Properly assign a group to each Item, through their “Group” property
  4. Set listView.ShowGroups property = True
  5. Ensure you have called System.Windows.Forms.Application.EnableVisualStyles() method at the beginning of your application

ListView groups rely on VisualStyles of the application, what is only available on Windows XP systems and above. So, groups won´t work on anything below Windows XP.

Here, you can find some explanations, like the following:

“ListView groups are available only on Windows XP and Windows Server 2003 when your application calls the Application.EnableVisualStyles method. On earlier operating systems, any code relating to groups has no effect and the groups will not appear. As a result, any code that depends on the grouping feature might not work correctly.”

Cheers!

Combos de controles en DotNetManĆ­a

El número 64 de la gran revista DotNetManía publica un artículo que he escrito sobre creación de combos de controles en Windows Forms con un solo click, ademÔs de muchas otras cosas muy muy interesantes. Espero os resulte de ayuda. Saludos!

  portadagr

http://www.dotnetmania.com/Articulos/064/index.html

Autonomous car driving by V.A.I.L

Autoblog has published today a very interesting video on autonomous driving. It surely worth the time you´ll invest watching it…

 

During the first seconds, you can see some Java code. It appears there because that’s the “yesterday” part of the video. I´m sure that they were just about putting some .Net code in the “tomorrow” chapter. They probably run out of time… ;)

Specially beautiful the close look at the accelerating wheel, at the end of the video.

Hope you enjoy it.

Simax ECO-Driving goes U.K.

Simax is starting to distribute the ECO-Experience Simax Simulator in the U.K. Of course, they drive on the left, so we had to develop new environments, with a British look.

Want it real? Check this…

IQ1lond7lond1  lond8

Simax ECO-Experience allows drivers to improve their driving skills, with a special focus on ecological driving concepts. Simax ECO-Experience has been installed in several 1st line Motor Shows around Europe, where thousands of drivers learned how to save tons of CO2 emissions. To know more:

www.simaxvirt.com

The real simulation experience

Usuario y Password para configuración del router ADSL de timofónica

Si, como a mi, no te dieron el usuario y password para configurar tu router de telefónica no desesperes. Todos suelen tener los mismos. Aqui va una recopilación:

  • Usuario: admin, Password: admin
  • Usuario: adminttd, Password: adminttd
  • Usuario: 1234, Password: 1234
  • Usuario: user, Password: admin
  • Usuario: admin, Password: 1234
  • etc

Nota: Para acceder a la config de tu router tienes que ir en el navegador web (IE) a una dirección IP concreta, que suele ser: http://192.168.1.1

Espero que te sirva…

Properly scaling Point Sprites in DirectX

When rendering point sprites with DirectX, many people deals with the issue of point sprite scaling. There are many options regarding this, but in the 99% of the cases, people just wants one of the following two things:

1.- Point Sprites with a constant screen-space size

Ver imagen en tamaƱo completo

This sprites are rendered at the 3D position (projected to the viewport of course), but with a constant size, in pixels. So, if you move the camera towards the point sprite, it feels like if it shrinks, and if you move the camera away from the sprite, it will look like if “growing”.

This effect is sometimes desirable, specially if you are using point sprites to simulate 2D effects, post-processing or camera effects like Lens Flares (on your left).

To setup this kind of Point Sprite rendering in DirectX, you just need to disable PointSprite scaling. This way, you will be able to specify point sizes both with a default value or in each point vertex information. These are the render states you need to modify:

Disable point scaling: D3DRS_POINTSCALEENABLE = false

Set default point size (remember, in pixels): D3DRS_POINTSIZE = XX

2.- Point Sprites with a real 3D size

By contrary to what’s shown in the previous chapter, sometimes you need point sprites to behave like real 3D objects, i.e. when using them to simulate a particle system, or that kind of stuff.

In this case, you don’t want sprites to remain at the same size if you move away from them, as real 3D objects get smaller as we get farther from them and vice versa. It is obvious that we need to change the size of sprites (remember, it’s a 2D size, in pixels), accordingly to our 3D movements, to give the illusion of 3D behavior.

DirectX is already prepared for that, with a built-in system to handle point sprite scaling. You just need to activate it setting the render state D3DRS_POINTSCALEENABLE to true, and setting up some other parameters. If you take a look at the docs, you will find the following:

Point Size Computations

Point size is determined by D3DRS_POINTSCALEENABLE. If this value is set to FALSE, the application-specified point size is used as the screen-space (post-transformed) size. Vertices that are passed to Direct3D in screen space do not have point sizes computed; the specified point size is interpreted as screen-space size.

If D3DRS_POINTSCALEENABLE is TRUE, Direct3D computes the screen-space point size according to the following formula. The application-specified point size is expressed in camera space units.

S s = Vh * S i * sqrt(1/(A + B * D e + C *( D e2 )))

In this formula, the input point size, S i, is either per-vertex or the value of the D3DRS_POINTSIZE render state. The point scale factors, D3DRS_POINTSCALE_A, D3DRS_POINTSCALE_B, and D3DRS_POINTSCALE_C, are represented by the points A, B, and C. The height of the viewport, V h, is the D3DVIEWPORT9 structure's Height member representing the viewport. D e, the distance from the eye to the position (the eye at the origin), is computed by taking the eye space position of the point (Xe, Ye, Ze) and performing the following operation.

D e = sqrt (Xe2 + Y e2 + Z e2)

The maximum point size, Pmax, is determined by taking the smaller of either the D3DCAPS9 structure's MaxPointSize member or the D3DRS_POINTSIZE_MAX render state. The minimum point size, Pmin, is determined by querying the value of D3DRS_POINTSIZE_MIN. Thus the final screen-space point size, S, is determined in the following manner.

  • If Ss > Pmax, then S = P max
  • if S < Pmin, then S = P min
  • Otherwise, S = S s

Well, that´s all. Clear ugh? Just kidding…

Setting the A,B,C scaling parameters for a correct, 3D, point scaling

In order to achieve the behavior you want, you just have to set the following configuration:

D3DRS_POINTSCALE_A = 0.0f
D3DRS_POINTSCALE_B = 0.0f
D3DRS_POINTSCALE_C = 1.0f
D3DRS_POINTSIZE_MIN = 0.0f
D3DRS_POINTSIZE_MAX = 9999.0f

Et voilĆ” ! 3D point sprites…

Ultimas apariciones en prensa de Simax

SimaxReflect_256x128Simax ha aparecido últimamente en prensa y radio, a raíz del galardón en los premios Bancaja, e interesÔndose especialmente por nuestros productos para formación en conducción ecológica. Ahí van los links:

La razón:

http://www.larazon.es/noticia/conduccion-ecologica-virtual

Punto Radio (con audio de la entrevista):

http://actual.lasprovincias.es/jovenesemprendedores/etiquetas/inaki-ayucar/

Saludos.

Dell XPS 630i, the BT Mini-Receiver, download managers, and other crap…

If you are one of the owners of a Dell computer, you´ll probably be happy with it, like me. However, nothing´s perfect, and of course dell is not either.

One of the things I hate most on Earth is that too-usual way of managing download from websites. Every company has it’s own download manager, and in a few months you end up with a dozen of them installed on your computer or on your browser: Adobe Update Manager, Dell Download Manager, Apple Update Manager, Google updater, Aaaaarrgggllll !!!! I just want to download the f**ing file !!!!! Stop selling me your crap !!!!

Well, back to business. If you own an XPS 630i (and probably other Dell models), and you don’t install all the crap that comes with your system (Dell tune up utility, Dell application, Dell recovery, Dell diagnostics, Dell sandwich maker and the Dell fantastasystem), or if you simply lost your original CD drivers, you will probably miss one: the driver for the BlueTooth Mini-Receiver.

It is not initially listed in the default downloads list at www.dell.com for the 630i (a very deficient list, I must say. Is it that difficult to include a small description of the purpose of each application or update?), and believe me, it’s not easy to find.

I also tried to use one of the magnificent Dell helper-applications to find it, but the one it suggested didn’t work. Finally, I found it here, thanks to the people of My630i.

Thanks a lot!