c++ - 如何使用混合类型的 c++ 结构并只将一些值传递给 OpenGL?

标签 c++ opengl struct vertex

我阅读了高低,并认为我了解 C++ 和 OpenGL 顶点数据布局,但我一定是哪里错了......

我有一个结构来创建一个 Line 对象。因此它有两个点(每个 3 个 float 代表一个 vector 位置)。它还必须有一个对象 ID,以便我可以在稍后的应用程序中跟踪创建碰撞等的特定对象。结构如下所示。

struct Point
{
    Vector position = { 0.0f, 0.0f, 0.0f };
};

struct Line
{
    Point B = { 0.0f,0.0f,0.0f };
    Point C = { 0.0f,0.0f,0.0f };
    int ID = 0;
};

然后我创建了一个 simpe c++ STL 线 vector 并推回两个线对象:

vector<Line> lines; 

Line w0;
    w0.B = { 2.0f,2.0f, 0.0f };
    w0.C = { 8.0f,2.0f, 0.0f }; 
    w0.ID = 0; 
    lines.push_back(w0);

Line w1;
    w1.B = { 10.0f,4.0f, 0.0f };
    w1.C = { 18.0f,4.0f, 0.0f };
    w1.ID = 1;
    lines.push_back(w1);

我进一步指定 glVertexAttribPointer 如下:

glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0));
glEnableVertexAttribArray(4);

这只绘制了 1 条线,而不是我为 (!) 创建的两个对象。 如果我从我的结构中删除 ID int 变量,我会正确显示两行。 后来发现可能是我没有正确指定glVertexAttribPointer,所以顺理成章地改成如下:

glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Line), (void*)offsetof(Line, B));

然后它只在完全不同的坐标处绘制了 1 条线!偏移等的不同组合没有帮助。我最终能否使用一个与结构的其余部分不同的 int 值,并仅将 float 传递给 OpenGL?我确实需要对象的 ID 并稍后在应用程序中使用它。一定有办法-我一定是遗漏了什么……请帮忙。

最佳答案

仅仅因为您需要在您的应用程序中以某种方式表示线条并不意味着您必须以完全相同的方式将该数据准确地提供给 OpenGL 进行绘图。 OpenGL 不需要这个 ID 字段。似乎没有理由将此 ID 数据上传到 GPU。除此之外,没有办法让 OpenGL 顶点属性数组使用像 Line 结构数组那样的内存布局。想一想多个 Line 在内存中是什么样子的:

B1 C1 ID1  B2 C2 ID2  B3 C3 ID3  …

请注意连续顶点位置之间的间隙是如何不固定的,而是在同一线段的两点之间为 0 或在一条线的结束顶点和一条线的起始顶点之间为 sizeof(int)下一行。没有办法只用步长和基本偏移量来描述这样的顶点属性数组。所有这一切都忽略了一个事实,即编译器可以自由地以他们认为合适的任何方式在结构成员之间添加填充字节。因此,您的内存布局甚至不能保证看起来像那样,并且至少在理论上可能会根据您使用的编译器版本和编译选项而有所变化。

我建议放弃这样的想法,即 Line 结构是给定的,您的应用程序的每个方面都必须绝对使用该确切的数据表示。无论如何,您必须在某个时候将数据上传到 GPU 进行绘图。当你这样做时,只需复制起点和终点并跳过 id。除此之外,请考虑这样一个事实,即您通常也可以从 Array of Structures approach 切换到您现在(在其中保留一组 Line 结构)采用数组结构方法,即,一个数组用于所有线的起点,一个用于所有终点,一个用于身份证。根据您处理数据的精确程度,即使在 CPU 上,这通常也是有益的。最后,可以选择将数据上传到 Shader Storage Buffer。并在顶点着色器中手动查找顶点属性。不过,我认为我不建议在这里走那条路……

关于c++ - 如何使用混合类型的 c++ 结构并只将一些值传递给 OpenGL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55260708/

相关文章:

c++ - 常量字符* a[4];我可以更改 a[] 值吗?

c++ - Visual Studio 2013 终端应用程序在启动(空)std::thread 后崩溃

linux - 在 OpenGL/Glut 中如何判断按钮是否被按下? (Linux)

C++:如何将 int 转换为 unsigned long 而不更改任何位?

c++ - 在类结构中, "this"是如何工作的?

unit-testing - 如何比较两个作为结构但作为接口(interface)返回的值

C,弃用结构成员的可移植方式

c - 将Node插入第一名C编程

c++ - 在 OpenGL 中,如何指定步长的索引?

opengl - 如何在X窗口中指定OpenGL版本?