Should i use a c++ Vector class?

What do most people use in their OGL programs for vector operations? Do they use a c++ class with operator overloads or something else? I’m wondering if there are any downsides in using a c++ vector class for doing misc vector calculations in an OGL program. Is this the “wrong” route or the “correct” route?

[This message has been edited by Junkstyle (edited 07-02-2002).]

Hi !

Using a C++ vector class makes life pretty simple for you, the downside is that the code generated is normally pretty slow compared to if you do the same thing with C macros or inline functions, but if you are a bit careful when you create the vector class you should be able to get ok performance, the most common problem is that the operator overloading generates loads of temporary objects on the stack.

For my own use I have a vector class with all the basic stuff, but I also have a set of inline functions to do most common operations (dot/cross prod add mul and so on).

Mikael

In addition to Mikaels advice, you have to think about how your vector class is going to interact with OpenGL.
Using VAR for example puts restrictions on the way the vector data is to be stored before feeding it to OpenGL (arrays of vertices/texcoords as opposed to individual vectors).

HTH

Jean-Marc

With proper design and usage, and a good compiler, the performance hit compared to macros can be close to zero. And don’t forget the fact that it can be more type safe than macros too.

Myself, I use a general matrix class for both matrices and vectors (a vector is a special case of a matrix), letting me define vectors and matrices of arbitrary size and datatype.

…actually you can inline your class methods. So using a vector class is probably best.

i also am on the Vector class bandwagon. careful when using sizeof() with your vector class. if you have any virtual functions, your classes size will increase by 4 (on windows). apparently any virtual functions are stored in a separate table and the 4 bytes are the starting location of the table in memory.

b

Thats right coredump - I was going to say that v functions with such a basic type should be avoided - not only for those practical reasons, but also because it will run like a dog.

Each method in a vector class will be relatively trivial to implement in any case.

I used vectors very often and even used them in my engine to store vertices and all kinds of stuff… I saw using it in the torque engine… Now with Vsiual Studio 6 I had no problem, they worked fine…
I switched over to Visual Studio .NET and the performance went to the mighty hell… I ran a debugger through it and vectors had a huge overhead. I changed my entire code to using arrays and everything worked fine then.

I would not use them and do not recommend them.

mancha - you are thinking of stl vectors. junkstyle was referring to a vector representing 3 points in space.

Thanks for all the input everyone. Seems like using a simple C++ class is the way to go.

To clarify a bit I was asking about if it was an okay design to use a C++ class for vectors and matrix storage and calculations. They would be used for things like calculating camera panning, physics, just about anything to do with vectors.

I don’t think I would store vertex data in them for things like models. I’m thinking I’d just using arrays for that.

So basically my question is should I use:
a) C++ class with operator overloading

or

b) simple 3 dimension array with function calls, i.e. Normalize(), Add(), Dot(), Cross() to do the operations

Hi !

Use a vector/matrix class, but avoid operator overloading, that’s what kills performance on some compilers.

Mikael

Operator overloading is ok in situations where you are doing this:

myvec += myothervec;

No performance hit there. When you are doing this:

myvec = ( myfirstvec + mysecondvec), you have to create and return a temporary vector object, which may hurt a little.

As usual, its often easier to use operator overloading in situations where you need to write a formula and have it look right. For example:

mylen = ( v0 + ( ( v3 - v1 ) ^ v2 ) ).Length ();

With the above, if you want to code it any other way you will have to use temporaries anyway. So you might as well go the whole hog and use operator overloading.

Ok, optimize your algorithms AND THEN micro-optimise your code if you see that the overloading is actually the cause of a performance prob.

Well after thinking for a bit about this I’ve decided to go with the minimalist approach and just do:

typedef float Vector3[3];

for my vector type and use function calls for things like dot products, cross products, normalize, add, subtract, etc, etc.

Now I may regret this a month from now but I’ll let you guys know how it goes. I’m sure the code, especially the “formulas” for doing vector calculations are going to look like a bunch of function calls instead of something thats easier to read but I think the tradeoff is that it will be easier to pass around an array[3] to functions around my program and to opengl.

Thanks for all the input and I’m sure I won’t know how good or bad this idea is until I actually write a few thousand lines of code using it.

I use a class called Point3D for storing both vectors and points. Points and vectors are both represented the same way, and many of the same operations can be done on them, so it makes sense to use one class for both, even though they are technically two different things.

I highly recommend using a point class, and giving it only 3 data members, with no virtual functions. By doing this, the class will line up in memory just as a float[3] or double[3] would. This is important because you can then send your vertices and normals to OpenGL with an array of Point3D’s (or whatever you call your vector/point class)!

Point3D normals [100];
Point3D verts [100];

glNormalPointer(GL_FLOAT,0,normals);
glVertexPointer(3,GL_FLOAT, 0, verts);

That is how I use it JunkStyle…
Do not make your code heavier than it should be.

Originally posted by Junkstyle:
[b]Well after thinking for a bit about this I’ve decided to go with the minimalist approach and just do:

typedef float Vector3[3];

for my vector type and use function calls for things like dot products, cross products, normalize, add, subtract, etc, etc.

Now I may regret this a month from now but I’ll let you guys know how it goes. I’m sure the code, especially the “formulas” for doing vector calculations are going to look like a bunch of function calls instead of something thats easier to read but I think the tradeoff is that it will be easier to pass around an array[3] to functions around my program and to opengl.

Thanks for all the input and I’m sure I won’t know how good or bad this idea is until I actually write a few thousand lines of code using it.[/b]

I’ve been using a typedef vector and function calls lately. I’m finding I do have to use a lot of temp variables. Looking at some vector class code I noticed that the member functions aren’t declared as inline. Any reason for this? They should be inline shouldn’t they?

Anyways I’m not going to get back to this vector class until I’m done wrestling with these object rotations.

Yes my spaceship will fly…its only a matter of time.

Looking at some vector class code I noticed that the member functions aren’t declared as inline. Any reason for this? They should be inline shouldn’t they?

i’m not sure what code you saw, but any member function defined in the class declaration are implicity inline. example:

class MyClass
{
public:
MyClass();

void print() // this is inline
{
cerr << data << endl;
}

private:
char *data;
};

b

Originally posted by Junkstyle:
[b]Well after thinking for a bit about this I’ve decided to go with the minimalist approach and just do:

typedef float Vector3[3];

for my vector type and use function calls for things like dot products, cross products, normalize, add, subtract, etc, etc.
[/b]

I use the same in my proggies.

The advantage over C++ and operator overloading is that I can have functions like

void cross_product (Vector3 a[restrict], const Vector3 b[restrict]);

which is equivalent to “a += b” (no diff to C++),

and

void cross_product_new (Vector3 a[restrict], const Vector3 b[restrict], const Vector3 c[restrict]);

which is equivalent to “a = b + c”, but WITHOUT temporaries or extra constructor invocations.

~velco

Hi

I would use a vector class with operator overloading like += … +/- /* but for often uses calculations I would write some inlined functions wich take vector classes as arguments and minimize using of temporaries.

for example

float s;
vec3 a;
vec3 b;
vec3 c;

c= a*s+(1-s)*b; // linear interpolation

would be

vec3 a,b,c;
float s;

c=a;
lerp(a,b,s);

inline void lerp(vec3& a, const vec3& b, float s)
{
a*=s;
vec3 tmp=b*(1-s);
a+=tmp;
}
Maybe the example is not the best but you should see how it should work;

This will get effective when more objects are involved (matrixes…)

Ideally you will have complete set of functions that do all operations on float[3]and then you will have classe that call these functions for convenience. With functions you can easily implement SSE or 3DNow and recompile the class without any problems

Bye
ScottManDeath

Originally posted by velco:
[b][quote]

void cross_product_new (Vector3 a[restrict], const Vector3 b[restrict], const Vector3 c[restrict]);

which is equivalent to “a = b + c”, but WITHOUT temporaries or extra constructor invocations.

~velco[/b][/QUOTE]

Just make sure you don’t do this accidently or indirectly:

cross_product_new( a, a, b );