OpenGL 绘制顶点缓冲区对象
OpenGL Draw Vertex Buffer Object
我有两个'std::vector',一个用于索引,一个用于顶点,我用std::vector.push_back()填充。那我做
glGenBuffers(1, &verticesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*EDITED-->*/vertices.size() * sizeof(vertices[0])/*<--EDITED*/, &vertices[0], GL_STATIC_DRAW);
为每个缓冲区创建缓冲区,然后尝试使用
绘制多边形
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer);
glDrawElements(
GL_TRIANGLES,
indices.size(),
GL_UNSIGNED_INT,
&indices[0]
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
当我运行程序时,没有任何显示。我可以使用 glBegin() / glEnd() 方法让它工作,但是索引的 vbo 不起作用(glGetError() 也没有给出任何错误)。我什至不知道这是否接近正确,因为我已经搜索了无数教程和其他 Whosebug 问题,并尝试了许多不同的方法来修复它。我还应该提到我打电话给
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0.0f, windowX, windowY, 0.0f, 0.0f, 1000.0f);
在程序的开头,我也不知道这是否正确(如您所见,我对这方面很陌生)。
问题是您期望 sizeof(vertices)
给出向量中存储的字节总数。但是,它只给出了矢量对象本身的大小,而不是它包含的动态数据。
相反,您应该使用 vertices.size() * sizeof(vertices[0])
。
您误解了 sizeof
运算符的工作原理。它是一个在编译时执行的运算符,returns 指定类型或变量的大小(以字节为单位)。
float f;
std::cout << sizeof(f); // prints 4
std::cout << sizeof(float); // prints 4
但是当我们在指向数组的指针上使用 sizeof
时会发生什么?让我们检查以下情况:
float array1[50]; // static size array, allocated on the stack
float *array2 = new float[50]; // dynamic size array, allocated on the heap
std::cout << sizeof(array1); // prints 200, which is ok (50*4 == 200)
std::cout << sizeof(array2); // prints out the size of a float pointer, not the array
在第一种情况下,我们对分配在堆栈上的静态数组使用sizeof
。由于 array1 的大小是常量,编译器知道它并且 returns 它是 sizeof(array1)
.
上的实际大小(以字节为单位)
在第二种情况下,我们在堆上分配的动态数组上使用sizeof
。理想情况下 array2
的大小在编译时是未知的(否则你应该使用静态数组,如果适合堆栈),所以编译器对数组 array2[= 的大小一无所知44=],所以它 return 是指向我们数组的指针 的 大小。
当您在 std::vector 上使用 sizeof
时会发生什么?
std::vector<float> vec(50);
std::cout << sizeof(vec); // prints out the size of the vector (but it's not 4*50)
但是如果sizeof(vec)
return是向量的大小,为什么return 4*50不是? std::vector 管理一个底层动态分配的数组(上例中的第二种情况),因此编译器不知道该底层数组的大小。这就是为什么它 returns 向量对象的整体封装(隐藏)变量的大小,包括指向实际数组数据的指针的大小。如果你想要底层数组中的元素数量,你需要使用 vec.size()。 要获取底层浮点数组的大小(以字节为单位),只需使用 vec.size() * sizeof(float)
.
用上面的知识修复你的代码:
std::vector<float> vertices;
// ...add vertices with push_back()...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
或
std::vector<float> vertices;
// ..add vertices with push_back()...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
以后您还可以使用图形调试器来帮助解决这些问题。根据您的显卡,您可以在 windows 上使用 AMD 的 gpu perf studio 或 nVidia nsight,或者在 Linux 上使用图形调试器。这样可以节省大量时间和麻烦。
如果您再次出现黑屏。 运行 您的应用程序附加了调试器并遵循管道。
您应该会看到输入顶点着色器的数据,因为它比您预期的要短,所以它会标记一个问题,您可以从那里开始。
我有两个'std::vector',一个用于索引,一个用于顶点,我用std::vector.push_back()填充。那我做
glGenBuffers(1, &verticesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, /*EDITED-->*/vertices.size() * sizeof(vertices[0])/*<--EDITED*/, &vertices[0], GL_STATIC_DRAW);
为每个缓冲区创建缓冲区,然后尝试使用
绘制多边形glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBindBuffer(GL_ARRAY_BUFFER, verticesbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesbuffer);
glDrawElements(
GL_TRIANGLES,
indices.size(),
GL_UNSIGNED_INT,
&indices[0]
);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
当我运行程序时,没有任何显示。我可以使用 glBegin() / glEnd() 方法让它工作,但是索引的 vbo 不起作用(glGetError() 也没有给出任何错误)。我什至不知道这是否接近正确,因为我已经搜索了无数教程和其他 Whosebug 问题,并尝试了许多不同的方法来修复它。我还应该提到我打电话给
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0.0f, windowX, windowY, 0.0f, 0.0f, 1000.0f);
在程序的开头,我也不知道这是否正确(如您所见,我对这方面很陌生)。
问题是您期望 sizeof(vertices)
给出向量中存储的字节总数。但是,它只给出了矢量对象本身的大小,而不是它包含的动态数据。
相反,您应该使用 vertices.size() * sizeof(vertices[0])
。
您误解了 sizeof
运算符的工作原理。它是一个在编译时执行的运算符,returns 指定类型或变量的大小(以字节为单位)。
float f;
std::cout << sizeof(f); // prints 4
std::cout << sizeof(float); // prints 4
但是当我们在指向数组的指针上使用 sizeof
时会发生什么?让我们检查以下情况:
float array1[50]; // static size array, allocated on the stack
float *array2 = new float[50]; // dynamic size array, allocated on the heap
std::cout << sizeof(array1); // prints 200, which is ok (50*4 == 200)
std::cout << sizeof(array2); // prints out the size of a float pointer, not the array
在第一种情况下,我们对分配在堆栈上的静态数组使用sizeof
。由于 array1 的大小是常量,编译器知道它并且 returns 它是 sizeof(array1)
.
在第二种情况下,我们在堆上分配的动态数组上使用sizeof
。理想情况下 array2
的大小在编译时是未知的(否则你应该使用静态数组,如果适合堆栈),所以编译器对数组 array2[= 的大小一无所知44=],所以它 return 是指向我们数组的指针 的 大小。
当您在 std::vector 上使用 sizeof
时会发生什么?
std::vector<float> vec(50);
std::cout << sizeof(vec); // prints out the size of the vector (but it's not 4*50)
但是如果sizeof(vec)
return是向量的大小,为什么return 4*50不是? std::vector 管理一个底层动态分配的数组(上例中的第二种情况),因此编译器不知道该底层数组的大小。这就是为什么它 returns 向量对象的整体封装(隐藏)变量的大小,包括指向实际数组数据的指针的大小。如果你想要底层数组中的元素数量,你需要使用 vec.size()。 要获取底层浮点数组的大小(以字节为单位),只需使用 vec.size() * sizeof(float)
.
用上面的知识修复你的代码:
std::vector<float> vertices;
// ...add vertices with push_back()...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STATIC_DRAW);
或
std::vector<float> vertices;
// ..add vertices with push_back()...
glBufferData(GL_ELEMENT_ARRAY_BUFFER, vertices.size() * sizeof(vertices[0]), &vertices[0], GL_STATIC_DRAW);
以后您还可以使用图形调试器来帮助解决这些问题。根据您的显卡,您可以在 windows 上使用 AMD 的 gpu perf studio 或 nVidia nsight,或者在 Linux 上使用图形调试器。这样可以节省大量时间和麻烦。
如果您再次出现黑屏。 运行 您的应用程序附加了调试器并遵循管道。
您应该会看到输入顶点着色器的数据,因为它比您预期的要短,所以它会标记一个问题,您可以从那里开始。