如何使用自己的类在glVertexPointer / glColorPointer / glNormalPointer

How to use your own class in glVertexPointer / glColorPointer / glNormalPointer

本文关键字:glColorPointer glNormalPointer glVertexPointer 何使用 自己的      更新时间:2023-10-16

我有一个表示顶点的类,如下所示:

class Vertex
{
public:
Vertex(void);
~Vertex(void);
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat r;
GLfloat g;
GLfloat b;
GLfloat nx;
GLfloat ny;
GLfloat nz;
Vertex getCoords();
Vertex crossProd(Vertex& b);
void normalize();
Vertex operator-(Vertex& b);
Vertex& operator+=(const Vertex& b);
bool operator==(const Vertex& b) const;
};

我初始化我的VBO如下:

glGenBuffers(2, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER, fVertices.size()*sizeof(Vertex), &(fVertices[0].x), GL_STATIC_DRAW);
glVertexPointer(3, GL_UNSIGNED_BYTE, sizeof(Vertex), BUFFER_OFFSET(0));
glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(6*sizeof(GL_FLOAT)));
glNormalPointer( GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(3*sizeof(GL_FLOAT)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, fIndices.size()*sizeof(GLushort), &fIndices[0], GL_STATIC_DRAW);
glIndexPointer(GL_UNSIGNED_SHORT, 0, BUFFER_OFFSET(0));

但是当画的时候,这些都乱了。这可能是因为我传递了错误的步幅和/或缓冲偏移量。

奇怪的是,我在用指针做实验,看看地址是否匹配,试图自己找出答案,我遇到了一些奇怪的事情:

如果我这样做:

GLfloat *test = &(fVertices[0]).x;
GLfloat *test2 = &(fVertices[0]).y;
然后

test + sizeof(GLfloat) != test2;

fVertices是一个std::vector。

希望有人能告诉我应该传递什么给gl*指针调用。

结构体/类(c++认为它们是相同的)中数据的字节排列只有在类是普通旧数据(POD)类型时才能得到保证。在c++ 0x之前,POD类型的规则非常严格。类不能有任何类型的构造函数或析构函数。它也不能容纳非pod类型。它不能有虚函数。等等。

所以你需要删除构造函数和析构函数。

第二,你的偏移量是错误的。颜色是从前面开始的3个浮点数,而不是6个。你好像把你的颜色和常态都换了。


:

test + sizeof(GLfloat) != test2;

是指针算术。如果你有一个指向某种类型T的指针,给这个指针加1并不会给地址加1。基本上,它的工作原理类似于数组访问。

T *p = ...;
&p[1] == p + 1;

所以如果你想在test之后得到浮点数,你可以给加一个,而不是浮点数的大小。


就我个人而言,我一直不明白为什么这么多OpenGL程序员喜欢把这些小顶点格式结构放在一起。其中顶点保存了一定的数据排列。它们在当时看起来总是一个好主意,但是当你不得不改变它们的时候,一切都坏了。

从长远来看,根本不用为显式的"顶点"对象而烦恼要容易得多。只有网格,它们有顶点数据。一切都应该在具有属性字节偏移量的内存线性数组中完成。那样,如果你需要插入另一个纹理坐标或需要法线或其他东西,你不需要从根本上改变代码。