c++ - 如何在glVertexPointer/glColorPointer/glNormalPointer中使用自己的类

标签 c++ opengl

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

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*pointer 调用。

最佳答案

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

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

其次,你的偏移量是错误的。你的颜色距离前面有 3 个 float ,而不是 6 个。你似乎已经切换了颜色和法线。


这个:

test + sizeof(GLfloat) != test2;

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

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

因此,如果您想在 test 之后获取 float ,请向其添加一个,而不是 float 的大小。


就个人而言,我一直不明白为什么这么多 OpenGL 程序员喜欢将这些小顶点格式结构放在一起。顶点保存一定的数据排列。它们在当时看起来总是一个好主意,但是当您必须改变它们时,一切都会崩溃。

从长远来看,完全不用为显式的“顶点”对象而烦恼要容易得多。只需拥有网格,其中包含它们所拥有的任何顶点数据。一切都应该在具有属性字节偏移量的内存线性数组中完成。这样,如果您需要插入另一个纹理坐标或需要法线或其他东西,则不必从根本上更改代码。只需修改字节偏移量,一切就可以了。

关于c++ - 如何在glVertexPointer/glColorPointer/glNormalPointer中使用自己的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7115807/

相关文章:

c++ - Visual C++ 2010 fatal error C1083;没有权限

python - dlib 构建失败,无法导入 dlib

c++ - Qt 应用程序从 QtCreator 启动时会找到库,但不能从命令行启动

opengl - 在OpenGL Fragment Shader中,gl_FragColor.a = 0和discard有什么区别?

opengl - 如何缩放glDrawPixels?

c - 在 Windows 上设置 OpenGL(mingw32?)

默认使用 C++11?

c++ - 如何在C++中指向全局函数中的成员函数?

c++ - 如何在 openGL,C++ 中改变视点

c++ - 为什么这不是正确的生产者消费者模型,以及在我使用 STL 队列时导致错误的原因是什么?