Current.com uses my photo of olympic torch
http://current.com/items/88950599_after_china_quake_olympic_torch_rela y_shortened
Yes that’s my photo (of the Torino 2006 torch, taken in corso Racconigi) from http://www.mastropaolo.com/2006/02/11/olympic-torch/ ![]()
3D in managed mode (WPF, and not only)
In this week I had the chance to do a little work with WPF 3D capabilities.
I wanted to implement a user control implementing a visualizer of “something” in 2D for a Windows.Forms application. I decided to add a 3D view capability. Language used was C#.
I started with Managed DirectX. It’s crap. Simply put, there exist just two versions of MDX and they are not compatible (!). Plus the first one is very buggy (if you write a 50 lines program and find a bug in the SDK, you can claim it’s very buggy :(). The DLLs do not come with the framework. Last but not least they are abandoned, because MS decided to develop XNA.
I could go with XNA, but XNA is not, again, distributed with the framework, and is very game oriented. I didn’t want to force business users to run an XNA installer for a non-game application, specially taking into account that the 3D visualization is not a requirement, it’s an added feature of the component.
OpenGL wrappers exist, but the first one I found has been abandoned. Not the solution I wanted, but still better than MDX/XNA.
So I went to WPF. The 3D is not very complex and so WPF it’s enough.
I developed a 2D control using Windows.Forms and System.Drawing and then left the 3D part to an internal, hidden, control developed using WPF (thus my control is in the end what MS calls an hybrid control — supported scenario ;)).
So, let’s go with some considerations about WPF.
- I found WPF nothing to go crazy about. MDX allows you to easily render some complex things (like 3D text) at the price of difficult rendering of basic primitives. OpenGL is the opposite. With WPF you might think it will all be easier. 3D Text is no easier at all (there is wrapper class from Petzold somewhere in the net, but nothing native and easy). Simple primitives are absent (no sphere, cylinder, plane ?!).
- There is not a meaningful level of knowledge; they are masking out the product of matrices but in the same help page they speak about quaternions.. the result is an API which is hard to be used both for a 3D expert and for a 3D primer. Some informations (like if the translation is in the last row or last column of the 4×4 matrix - it depends on how the product is implemented etc.) is hard to be found.
- MeshGeometry3D is a cool class, well implemented.
- You will spend quite some time experimenting things you shouldn’t experiment with.. because it’s not easy to predict how material concatenation work or similar things without trying at first (it’s done differently from other 3D toolsets).
- They somewhat idiotically reimplemented many basic types. So you’ll find yourself converting System.Drawing colors in WPF colors, or WinForms mouse arguments in WPF mouse arguments. I can understand the latter but not so much the former (at least, implement a converting constructor). The same goes for images, etc. At now the easiest way to convert an image I found (the easiest, not the fastest) is serializing on a memory stream!
- You must work with (their) scenegraph. This is generally good (to have a scenegraph to work with!) but in my case an “immediate mode” approach would have been better.
- 3D Hit-testing is easy.
- Good Exporters/Importers are hard to find. The 3ds one works.. “almost”. It has defects and working only on basic models. Plus it doesn’t fix 3dsmax inverted axis issues.
- Antialiasing is not supported (apart from registry hacks) on Windows XP/2003. Vista only. Marketing crap.
- Keyboard.Modifiers doesn’t work in hybrid scenarios (at least doesn’t seem to work). Had to rely on System.Windows.Forms.Control.ModifierKeys (using WinForms code in a WPF event handler… bah).
- Downloading someone else code is helpful to work around stupid issues like not understanding how to define a resource.
- I hate XAML.
Edit :
I was forgetting a very important consideration.
WPF is fixed function, sadly. No shaders. In 2007 this is like releasing a single tasking operative system. I don’t know if I will use this Windows 3.1 of 3D in the future, on second thought.
Wow! Your Guest Book - Is Awesome!
OK.
I was on holidays (Porto Santo.. wonderful place!
I will upload my photos on flickr sooner or later) and got back to work a couple of weeks ago. I sorted out comments just today.
In the next few weeks I will surely be busy because I have found a few ONLINE CHEAPEST PHARMACY with the “cheap cialis” I just needed and then I have so many porn and “teen amateur cams” to watch I just can’t get the time to read comments; so I (temporarily ?) disabled them. As soon as my penis is large enough thanks to the new techniques coming in every day, I will reenable them.
Now some notes to spammers :
1) Santa Maria Novella is a church in Ravenna (and a station in Florence), not a porn star (at least I hope there isn’t one).
2) “This is test-spam message, if you want stop spam on your site - just email me: xxxx@xxx.xx and your site will be immediately removed from spam-base.” Is not a good technique to get new mail addresses to be spammed, although we should never underestimate people stupidity… Beside, I think offering protection from spam using spam could be considered .. mafia.
3) If you translate your message in Italian, use a real translator. The following messages are not italian :
Scusilo,
voi compartecipe creativo luogo
Ci era un alberino e un autore come a legga circa:
Per trasmettere una Biglietti Auguri libera, scatti prego sopra una delle categorie cartoline scheda qui sotto. Saluti elettronici cartoline, mentre altri non possono caricarsi affatto auguri: frasi onomastico .. Luigi auguri di soggetti sms scrivere cartoline buon virtuali inviare lettera scaricare frasi d amore! Hm.. Noi non poteva scelga unico luoghi dove presenti, From questo link http://—–.com/ - frasi per laurea . Dal facciale in molle cartoline virtuali mia scusa attendente!Saluti..
voi ottenuto piacevole fatto lavoro
Qualcuno qui desideri a ritrovamento:
Gt materia cellulari dall gprs elettrico macchina sierosa giochi cellulare
Beta ed funzione insulto diabete diffusi cellulari vegetale! Hm.. Noi gradirebbe elimini favorevole pagine circa, From che del here http://—.com/ - cellulari symbian
Ammetta quello cercato male
That said, I would like to thank the two users posting real comments in these weeks and I will reply them soon. My real comments / spam ratio is then 0.2%. Wow.
Unbelievable Optimization X
This is something which happened some years ago.
There was some-project I won’t name(*) (let’s just say it was a server emulator of some popular MMORPG), with their development forum. I found a post suggesting an optimization they were going to implement. Basically the file saving phase was something like this :
if (someplayer->hp != 0) fprintf(fout, "hp=%d", someplayer->hp);
if (someplayer->something != 0) fprintf(fout, "hp=%d", someplayer->something );
if (someplayer->foobar != 0) fprintf(fout, "hp=%d", someplayer->foobar );
if (someplayer->purplet != 0) fprintf(fout, "hp=%d", someplayer->purplet );
if (someplayer->dontknow != 0) fprintf(fout, "hp=%d", someplayer->dontknow );
Of course, most attributes were defaulting at 0 (or the value was different in the if — whatever) and many I/O operations were saved (also file length was greatly reduced due to this “optimization”). The reason of this high effectiveness was that most attributes were not used unless in a particular condition, and so most of the time they had a default value.
Comes the Pentium 4 and its light-years long pipeline.
Developers forums started writing about how crappy was the new architecture (the P4 debuted at 1.5GHz - at that speed it was slower than a P3 1GHz, not to mention the Athlon - the real power of the P4 was revealed only when it debuted a new revision and frequencies of 2.0GHz and above) and how much a single conditional jump could stall the pipeline and lose tiny precious clock cycles.
Then the idea struck a developer of that project. What if we remove all the if conditions ? No more conditional jumps yippieee!
This is the kind of ideas you feel dumber only hearing it. Ok, so you pull out the ifs and suddenly you have about double the number of fprintf. Since there is file caching (so that not particular much time is lost waiting for the disk I/O) the performances should be higher, right ? Wrong.
And the reason is simple. A single fprintf may be something like hundreds of conditional jumps. Really. (Not to mention the additional load in terms of disk I/O which whatever superscsi you have, it’s slower than the slowest of the P4s)
Let’s analyze (lightly) what happens on a call to fprintf. After all the arguments are pushed on the stack, the procedure is called. Here the format string is parsed to find the % sign. There is comparison/conditional jump for every character, but we can be sure that most of this conditionals are correctly predicted and only a fraction of them are mispredicted (probably the ones where the % is found). After the % char is found, a quite complex loop (thus involving a number of conditional jumps) parses the input string. For %d tokens this loop ends quite quickly but for more complex tokens this can be quite expensive. In the meantime, parsed characters were being passed to the file buffers, ready to be written out (we’ll see later what this means). When the %something token is parsed, the argument is written out to the disk. This involves things like sign extension and stuff like that and no, most of it (in Visual C++ RTL at least) is not done using movsx and alikes, but with slow C code using various if, to mantain compatibility across platforms (the VC++ RTL should run on x86, x86/64, IA64, Alpha, Mips and PowerPC, even if the support for most of the listed architectures is now dropped) . After this a number should be converted from the internal representation to the decimal one, and this involves a bazillion of jumps and divisions by 10 (in M$ Visual C++ you can see all this code in the crt/src/output.c file). After the string is prepared it’s stored in the files buffers. Overflows checks must be made (more jumps! and memory copies, with an high chance of trashing what is in L1 cache if not even L2) and when they are emptied (and sooner or later they will be) controls goes to ring-0 code. Apart from the jumps, going to ring-0 is an uber-slow operation in itself. Also ring-0 code has quite an high chance of accessing a resource which needs a synchronization lock with an high chance of a spinlock loop or, worse, an anticipated task switch.
But boy, you saved a conditional jump.
(*) There is a secret hint hidden in the post about the identity of this project…
Edit : I wrote Pentium 4 1.5MHz :D. While it would be funny to check if the P4 1.5MHz could beat the 8086 at 4.77MHz or the 286 at 8-12Mhz, usually Pentium 4 users runs them slightly faster ![]()
