简体   繁体   English

3D顶点类或结构

[英]3D vertices class or struct

I am writing a small program for learning C++ and 3D. 我正在编写一个用于学习C ++和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). 现在,我意识到OpenGL期望缓冲区中的元素更像是结构(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. 1-我需要提取缓冲区中元素的数据。
2 - Create a temporary instance of vertex class with the data. 2-使用数据创建顶点类的临时实例。
3 - Use vertex class method. 3-使用顶点类方法。 (Dot, cross, etc...) (点,叉等)
4 - Put the data back to the buffer. 4-将数据放回缓冲区。
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++. 我可以更有效地处理数据缓冲区(只是移动指针),但是我觉得我会失去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. 在我见过的每个3D C ++源代码中,所有人都为顶点使用类,但是我不明白它们如何在“类似结构的”缓冲区中操纵大量顶点。

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. 实际上,在像C ++这样的语言中,最常见的方法都不是这些。

You are more likely to encounter the following: 您更有可能遇到以下情况:

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. 这样做的原因是因为使用匿名联合和结构,你可以作为float数组处理数据( v [...]或他们的名字(参考各个组件xyz没有很多)混乱或大惊小怪。 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. 至于在这种特殊情况下structclass之间的区别,从内存表示的角度来看,没有区别。 The only real difference between a class and a struct in C++ is the default access; 在C ++中, classstruct之间的唯一真正区别是默认访问权限。 struct has public access by default. struct默认具有公共访问权限。

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. 当GL需要访问对象的内部存储器时,您可以通过向其传递指针: Vector3::v或各个组件来完成此操作,具体取决于特定的函数。

For instance: 例如:

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. 附带说明一下,匿名结构是C ++的非标准扩展,但几乎在所有地方都受支持。 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一个名称来限定对xyz的访问。

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 ). 必须以这种方式限定x vec.x (使用匿名结构可以使用vec.x )。

There is exactly one difference between struct and class : For class the default scope is private , while for struct it is public . structclass之间恰好有一个区别:对于class ,默认范围是private ,而对于struct它是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 ). 具有完全相同的内存布局(假设x,y,zcVector的唯一成员变量)。

You can use &v.x to get a pointer to (x,y,z) for OpenGL, eg glVertex3f(&v.x); 您可以使用&v.x获取OpenGL的(x,y,z)指针,例如glVertex3f(&v.x); .

You can even do the following to get a pointer to a continuous sequence of vertices for usage with OpenGL: 您甚至可以执行以下操作来获取指向连续顶点序列的指针,以供OpenGL使用:

std::vector<cVector> vertices(100);
const float* data = &(vertices[0].x);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM