繁体   English   中英

OpenGL绘制顶点缓冲区对象

[英]OpenGL Draw Vertex Buffer Object

我有两个'std :: vector's,一个用于索引,一个用于顶点,用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()也不会给出任何错误)。 我什至不知道这是否几乎可以纠正,因为我搜索了无数教程和其他stackoverflow问题,并尝试了许多其他方法来解决它。 我还要提一提

glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glOrtho(0.0f, windowX, windowY, 0.0f, 0.0f, 1000.0f);

在程序开始时,我也不知道这是否正确(如您所见,在这方面我还很陌生)。

问题是您期望sizeof(vertices)可以为您提供向量中存储的字节总数。 但是,它仅给出矢量对象本身的大小,而不给出其包含的动态数据。

相反,您应该使用vertices.size() * sizeof(vertices[0])

您误解了sizeof运算符的工作方式。 它是一个运算符,在编译时执行,并返回指定类型或变量的大小(以字节为单位)。

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的大小是恒定的,因此编译器会知道它,并在sizeof(array1)上以字节为单位返回它的实际大小。

在第二种情况下,我们在堆上分配的动态数组上使用sizeof 理想情况下,在编译时无法知道array2的大小(否则,如果适合堆栈,则应使用静态数组),因此编译器对数组array2的大小一无所知,因此它将指针大小返回给我们阵列。

在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)返回向量的大小,为什么不返回4 * 50? std :: vector管理一个基础动态分配的数组(在前面的示例中为第二种情况),因此编译器对该基础数组的大小一无所知。 这就是为什么它返回矢量对象的整体封装(隐藏)变量的大小,包括指向实际数组数据的指针的大小的原因。 如果需要基础数组中的元素数量,则需要使用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上使用图形调试器。 这样可以节省大量时间和头痛。

如果再次出现空白屏幕。 在连接了调试器的情况下运行您的应用,然后按照管道进行操作。

您应该看到输入到顶点着色器的数据,因为它比您预期的要短,所以它会标记问题,您可以从那里开始。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM