Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

tivolo

Member Since 19 Jun 2004
Offline Last Active Today, 02:55 PM
-----

#5058572 Row vs Column Major Matrices: Most Useful?

Posted by tivolo on 02 May 2013 - 03:28 AM

Ignoring row-major storage vs column-major storage for a moment, there's matrices that have been constructed to transform mathematical row-vectors and matrices that have been constructed to transform mathematical column-vectors.

 

Whether you're using row-vectors or column-vectors simply depends on whether you write vec * mat (mat1x4 * mat4x4), or mat * vec (mat4x4 * mat4x1). With the former type of mathematics, the forward/right/up axes will be in the first 3 rows, whereas with the latter, these axes will be in the first 3 columns (they're the mathematical transpose of each other).

 

Therefore, if you work with row-vectors, I'd prefer to store my matrices in row-major order, so that it's easy to extract the basis vectors (this also makes the matrix multiplication code simpler on a lot of hardware).

Likewise if you work with column-vectors, I'd use column-major storage order, for the same reason.

 

Personally, I work with column-vectors (and matrices designed to transform column-vectors), because that's the way that most maths material I've used teaches it -- it seems the be the prevalent convention. Therefore, I prefer column-major storage.

 

One place where I have to mix storage conventions is when saving space. Sometimes you want to pass matrices around as 3rows x 4columns, with a hard-coded/assumed 4th row of [0,0,0,1]. Often your registers (shader uniforms or CPU SIMD) are 4-wide, so this storage format isn't possible with column-major storage (or, it takes the same amount of space: 4 registers). So when storing a 3x4 matrix, I'd use row-major storage (which only uses 3 registers).

This same problem presents itself with the opposite convention: with row-vectors + row-major storage, you'd want to use a 4x3 matrix with an assumed 4th column of [0,0,0,1], forcing you to use column-major storage for space efficiency.

 

Very well put. It's often overlooked to differentiate between row vs. column-major matrices regarding operations, and row vs. column-major regarding storage.

Here's a bit more food for thought why one should try to go for column vectors and write multiplications like v' = M * v.




#5057881 What's the effect of a member volatile function?

Posted by tivolo on 29 April 2013 - 03:13 PM

But really volatile is so rarely used and even then doesn't really cut it for multithreaded stuff (which it is intended for), I wouldn't worry about it.

 

Volatile was never intended for multi-threaded use, people just abused it. It won't work on PowerPC, or any architecture with a weakly-ordered memory model.




#5040787 Attempting to create a pool allocator

Posted by tivolo on 08 March 2013 - 06:58 AM

Using prefixed member variables (e.g. m_) is useful for writing optimized code.

 

You may or may not know it, but all member variables alias other pointer variables (e.g. function arguments and other members) because of the implicit this-pointer. This affects code optimization and often leads to less optimal code because of redundant loads. Therefore I like all member variables to clearly stand out by using a prefix, so they aren't used in e.g. tight inner loops, but moved to a local variable first. Aliasing basically happens all over the place.

 

Google for "pointer aliasing", "strict aliasing rule", "type punning" and "restricted pointers" if you're interested.




#5040374 Attempting to create a pool allocator

Posted by tivolo on 07 March 2013 - 07:21 AM

If you're interested in creating a pool allocator (not a stack allocator, like Hodgman noted), I've written about that on my blog




#5031583 Function Pointer to Class Function

Posted by tivolo on 12 February 2013 - 03:51 PM

I tried searching for this for a bit but everything seemed a little advanced for me.  I have a function pointer:

 

void (*fun)();

 

Then I have class.

 

class info
{
public:
    void think();
};

extern class info player;

 

Is there a way to point fun to the think function?

 

I tried

 

fun=player.think;

 

but that got me

 

 

error C3867: 'info::think': function call missing argument list; use '&info::think' to create a pointer to member

 

I'm sure it's either something simple or that the two functions are just incompatible.  Could anyone please tell me what I'm missing?

 

Thanks for any help!

 

If you are interested in the details behind pointers-to-member-functions, and how you can build an efficient delegate solution, I'd like to refer you to my blog post about exactly that: http://molecularmusings.wordpress.com/2011/09/19/generic-type-safe-delegates-and-events-in-c/

 

Hope that helps!




#5000936 Virtual still the bad way ?

Posted by tivolo on 14 November 2012 - 09:43 AM

Even if the user would like to use a different renderer at compile/linkage time, wouldn't the use of a interface class with virtual methods would still be required, to avoid changing client code to use one renderer or another??


No, that's what #ifdef/different .h files/different .cpp files are for. Virtual functions, abstract base classes/interfaces should be used when you need polymorphism at runtime. If you have different implementations of the same thing that need to be changed at compile-time, then don't use virtual functions.

One thing where I've often seen it is for e.g. building base classes for textures, vertex buffers, index buffers, and the likes.
As an example, consider having an abstract base class ITexture, and two distinct derived classes TexturePS3 and TextureXBox360. Do you need to change these implementations at run-time? No. Could you even *change* the implementations at run-time? No, because the PS3-code likely won't compile on 360, and vice versa. Therefore, there's really no reason to use an interface with virtual functions.


#4996502 Manual construction and destruction

Posted by tivolo on 02 November 2012 - 05:48 AM

How's that work? ::operator new() is saying "use the 'operator new' in global scope". Do classes have implicit operator new()s defined, and the implicit MyClass::operator new() then calls the class constructor? And the implicitly defined MyClass::operator delete() calls the class destructor?

I get that new() constructs the class, but what scope is 'new' in, if ::operator new() does not construct the class?


Short answer: There's a difference between the keyword new (called new operator) and operator new. Yeah, it's misleading :).

If you're interested in details like these, I invite you to read more about that on my blog:
http://molecularmusings.wordpress.com/2011/07/05/memory-system-part-1/

There's five parts in the series, and they detail how to write your own memory manager and allocators.

HTH,
Stefan


PARTNERS