I am writing a small program for learning C++ and 3D.
I have already written a vertex class with usefull methods. (like Dot,Cross, etc...)
class cVector {
...
float x, y, z;
...
float dot(cVector& v);
cVector cross(cVector& v);
...
}
Now I realize OpenGL expects buffers where elements are more like a struct (VBO).
struct sVector {
float x, y, z;
}
So my vertex class is no longer useless, because if i want to manipulate data in the buffer :
1 - I need to extract data of elements in the buffer.
2 - Create a temporary instance of vertex class with the data.
3 - Use vertex class method. (Dot, cross, etc...)
4 - Put the data back to the buffer.
It's not very efficient :(.
I wonder if I should not use a struct to organize my vectors and create global functions that take a pointer to a struct as an argument. I could handle data buffers more efficiently (just moving pointer) but I feel i would lose the "convenient power" of C++.
In every 3D C++ source code i ever see, all use class for vertex but i dont understand how they can manipulate large amount of vertex in a "struct like" buffer.
Can you help me to understand ? What is the best approach ?
The most common approach in a language like C++ is actually neither of these things.
struct Vector3 {
union {
struct {
float x,y,z;
};
float v [3];
};
...
Vector3 (float x_, float y_, float z_) : x (x_), y (y_), z (z_) { };
float Norm (void) { return sqrt ((x * x) + (y * y) + (z * z)); }
void Normalize (void) {
float norm = Norm ();
v [0] /= norm;
v [1] /= norm;
v [2] /= norm;
}
};
The reason for this is because using anonymous unions and structs, you can treat the data as either an array of floats ( v [...]
) or reference the individual components by their name ( x
, y
, z
) without a lot of muss or fuss. You get the best of both worlds by using the language more intelligently.
As for the difference between a struct
and a class
in this particular case, there is none from the perspective of memory representation. The only real difference between a class
and a struct
in C++ is the default access; struct
has public access by default.
When GL needs to access the object's internal memory, you would accomplish this by passing it the pointer: Vector3::v
or the individual components, depending on the particular function.
Vector3 vec (1.0f, 2.0f, 3.0f);
---------------------------------
glVertex3fv (vec.v);
and
glVertex3f (vec.x, vec.y, vec.z);
are equivalent
On a side-note, anonymous structures are a non-standard extension to C++ but supported virtually everywhere. In the case that you have a compiler that does not support them, you may have to qualify access to x
, y
, and z
by giving the struct
a name.
struct Vector3 {
union {
struct {
float x,y,z;
} s;
float v [3];
};
};
If you write your struct this way, then:
Vector3 vec;
assert (vec.v [0] == vec.s.x);
It is messier to have to qualify x
that way (using an anonymous struct you can use vec.x
).
There is exactly one difference between struct
and class
: For class
the default scope is private
, while for struct
it is public
.
So
class cVector {
...
float x, y, z; // data
...
float dot(cVector& v); // just a function
cVector cross(cVector& v); // just a function
...
}
and
struct sVector {
float x, y, z; // data
}
have exactly the same memory layout (given that x,y,z
are the only members variables of cVector
).
You can use &v.x
to get a pointer to (x,y,z)
for OpenGL, eg glVertex3f(&v.x);
.
You can even do the following to get a pointer to a continuous sequence of vertices for usage with OpenGL:
std::vector<cVector> vertices(100);
const float* data = &(vertices[0].x);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.