【问题标题】:OpenGL glBufferData with data from a pointer带有来自指针的数据的 OpenGL glBufferData
【发布时间】:2014-09-07 19:33:53
【问题描述】:

我是 OpenGL 的初学者,我正在尝试绘制一个彩色正方形,我按照 OpenGL Book 的教程进行操作,我正在使用该示例绘制 here。由于这绘制了一个三角形,我修改了代码以绘制 4 个顶点。我制作了一个 Rectangle 类,它可以以数组格式输出它的数据。这是我试图传递给 glBufferData 函数的数据。

不幸的是,当我使用班级的数据时,它不会在屏幕上绘制任何内容。我什至正在检查 gDebugger,我正在查看我的 VBO,但数据不正确。

为了测试,我从我的类中提取了顶点,并在本地数组中使用它们,而不是从我的类返回的指针。

我的数据现在是:

Vertex Vertices[] =
{
    { { -0.5f, 0.5f, 0.0f, 1.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } },
    { { 0.5f, 0.5f, 0.0f, 1.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } },
    { { -0.5f, -0.5f, 0.0f, 1.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } },
    { { 0.5f, -0.5f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }
};

而不是

Vertex* Vertices = rec->GetVertexData();

(我手动检查了两个数组,它们具有完全相同的值,问题不在我的 Rectangle 代码中)现在调用 glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW); 有效我在屏幕上看到了正确的矩形。 gDebugger 中的数据是

经过一些研究,我意识到 sizeof 没有报告给定指针的正确大小,所以我修复了这个问题。我硬编码(现在) BufferSize = 128; 以便更快地测试。关键是,它适用于 Vertex 数组,但仍然不适用于我类中的 Vertex 指针。

我在谷歌上搜索了 glBufferData 的示例,但实际上没有一个向您展示如何使用指针中的数据,您认为这将是一个很好的示例。

那么如何将一个 Vertex 数组传递给我的 glBufferData ,该数组作为另一个类的指针返回?我正在使用带有 GLEW 和 GLUT 的 OpenGL 版本 4。

更新:

所以错误是我的一部分,我将在这里发布我的调试,希望它可以帮助其他人。我添加了一个名为 Vertice, 8 的 Watch。这表明我的数组有虚假值。一步一步的调试告诉我,当 glGenBuffers 被调用时,它会覆盖我的值。我回去检查了我的代码,我意识到我的错误是调用Vertex vec[4]; 而不是Vertex *vec = new Vertex[4];,并且堆栈的值被另一个函数覆盖了。

【问题讨论】:

  • 从给出的小代码很难说。数组已经是一个指针,所以那里真的没有区别。如果我只是猜测一下:你如何将Vertices传递给glBufferData?一个潜在的问题是您使用&Vertices 有另一个级别的间接性,这是错误的。假设您使用的是 MSVC,请将 Vertices,8 添加到您的手表中,它是否显示正确的值?否则你的数据不连续。
  • 该死,我什至不知道那个 Watch 测试。它真的帮助我调试了我的问题。我正在更新我的帖子。如果您想将您的评论变成答案,我会将其标记为答案。
  • 很高兴你发现了你的错误,我能够提供帮助 :) 给我一个评论,我想不出一个描述性足够的答案让你投票呵呵。

标签: c++ arrays pointers opengl


【解决方案1】:

人们经常误认为数组是指针,而实际上它们不是。数组表达式 在许多情况下会衰减为指针(sizeof 是此规则的例外之一),但数组本身和指针之间存在显着差异。如需更多信息,请阅读this excellent post

至于手头的问题,一旦数组衰减为指针,它的形状(第一维)就会丢失,这就是sizeof返回指针大小而不是整个数组大小的原因。

float arr[3] = { 1.0f, 2.0f, 3.0f };    // sizeof(arr) = 3 * sizeof(float)
float *ptr = arr;                       // sizeof(ptr) = sizeof(float*)

如何将 Vertex 数组传递给从另一个类作为指针返回的 glBufferData?

您有三个选项可以做到这一点。让类返回指向数组的指针(就像你现在所做的那样)添加另一个函数来公开其中元素的计数,即它的长度,你可以用它来计算以字节为单位的大小。然而,这不是一个非常优雅的解决方案,因为在 C++ 中可以引用数组,这将我们带到下一个解决方案 (live example):

float (&MyClass::GetData()) [3] const
{
    return arr;
}

此引用上的sizeof 运算符将正确返回整个数组的大小。您可以改用std::array 来避免像std::array<float, 3>& MyClass::GetData() const; 这样的神秘表达式。

另一个更明智的选择是完全取消数组并使用std::vector,您可以返回一个引用:

std::vector<float> const& MyClass::GetData() const
{
    return vec;
}

在另一端

auto const &vec = obj->GetData();
float *data = vec.data();
size_t data_len = vec.size() * sizeof(float);

使用std::vector 的另一个优点是长度可以在运行时变化;由于hairy nature of arrays,错误也较少。

【讨论】:

  • 非常有趣的阅读!我会尝试将您的答案整合到我的代码中。结果我的数组被分配在我的矩形堆栈的堆栈上,并且被 glGenBuffers 调用覆盖。这就是为什么我的阵列都搞砸了。感谢您的有趣帖子!
  • 数组与否,永远不要返回对局部变量的引用(或指针),因为函数返回它们会自动解构。
猜你喜欢
  • 2020-01-28
  • 2018-03-26
  • 2019-02-10
  • 2016-12-04
  • 2012-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多