Tuesday 29 September 2009

Fixed functionality beats programmable pipeline 10:0?


Something's terribly wrong somewhere... Blinn-phong shader is wasting all GPU's power!

I've done some optimization, but I'm afraid that writing general code, good for all seasons is not the best way to achieve performance.

I can't imagine how many compromises serious 3D engines hide under the hood!

Thursday 17 September 2009

Arbitrarily turn static functions into individual threads

There's a lot of routines that are supposed to run "behind the scene", accomplishing repetitive and constant taks. For instance, in 3D engine the movements should be time-based, so that things behave the same way indipendently from the underlying architecture. We could define a class that "checks the clock" and computes the "amount of changes" to do in the scene. Our observers - that is a geometry transformers or a physic routine - simply "emphasize" their values proportionally to the elapsed time.

The best way for keeping "background duties classes" and the main engine separate is the use of threads. I already used them in the past, but in a statical way. This time, I wanted some kind of "abstract thread converter" which takes a pointer to a static function and turns it into a thread on its own.

Here comes some brief snippet. First of all, I defined a PLTthread class:

class PLTthread {
public:
  // empty constructor 
  PLTthread() {};
  // links the specified function, using specified  parameters
  void LinkFunction(static DWORD WINAPI fun, void* dwThrdParam = 0); 
private:
  // handler for the created thread
  HANDLE ThreadHandler;
  // thread ID
  DWORD dwThreadId;
}
Many additional methods could be created for handling thread's execution, but I wanna keep this example straightforward: you'll just pass a static method and it will start on its own. The actual code:

void PLTthread::LinkFunction(static DWORD WINAPI fun, void* dwThrdParam) {
    this->ThreadHandler = CreateThread(NULL, 0,
                            (LPTHREAD_START_ROUTINE)fun, &dwThrdParam,
                            0, &this->dwThreadId);  
    }
That's it. Now you can instantiate a PLTthread class and send it your function, casting it as DWORD.

Threads are a bit tricky, MFC are a pain in the ass; everything is a complete mess if you use to think object oriented. But this facility helps me a lot.

Monday 14 September 2009

Meshes from points

It's been an hard job, but an interesting experience. My 3D engine "PLT" now features its own Delaunay triangulation. Now I can turn an arbitrary set of points into a continue, smooth, tridimensional mesh.

The algorythm is well explained on Wikipedia, and practically consists in breaking an encompassing triangle in smaller ones, ensuring that every triangle does not "contain" any other vertex.

This check is the heart of the algorythm and it's achieved by verifying that every vertex lie outside the circle identified by the three points of each triangle.

There's a lot of geometry, trigonometry and even a little bit of calculus inside of this piece of software; the exams of discrete algebra and calculus found a practical, consistent application.

The next step is to speed it up: the algorythm is far from its potential O(n log n) possibilities and must be optimized. It seems to be even greater than the expected O(n²), probably due to the STL internal sorting algorythms.

Thanks to Erazor for the idea and Gerry for the math support. =)

Thursday 3 September 2009

Δελφοί


Delphi, l'ombelico del mondo, sede dell'oracolo più famoso di sempre, il posto "in cui chiunque avrebbe fatto il proprio santuario, se non ci avessero pensato prima i Greci".
Perché un posto del genere si ritrova come eredità moderna un linguaggio di programmazione insulso? Borland accidenti a te!