gpt4 book ai didi

opengl - glDrawArrays 与 glDrawElements

转载 作者:行者123 更新时间:2023-12-04 08:37:53 25 4
gpt4 key购买 nike

好的,所以我仍在努力让它发挥作用。我的代码的重要部分是:

def __init__(self, vertices, normals, triangles):
self.bufferVertices = glGenBuffersARB(1)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(vertices), ADT.voidDataPointer(vertices), GL_STATIC_DRAW_ARB)
self.vertices = vertices
self.bufferNormals = glGenBuffersARB(1)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
glBufferDataARB(GL_ARRAY_BUFFER_ARB, ADT.arrayByteCount(normals), ADT.voidDataPointer(normals), GL_STATIC_DRAW_ARB)
self.normals = normals
self.bufferTriangles = glGenBuffersARB(1)

glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)

self.triangles = triangles
glDisableClientState(GL_VERTEX_ARRAY) **(Not sure if any of the following influence in any way)**
glDisableClientState(GL_NORMAL_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)

从我目前所读到的关于 VBO 的内容来看,我认为这里没有任何问题。所以现在我有了顶点、法线(尚未使用)和三角形索引缓冲区。现在进行实际抽奖:
def draw(self, type):
glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_NORMAL_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0)
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0)
**Again above line not sure if they have any use.**
glEnableClientState(GL_VERTEX_ARRAY)
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferVertices)
glVertexPointer(3, GL_FLOAT, 0, None)

glEnableClientState(GL_NORMAL_ARRAY);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, self.bufferNormals)
glNormalPointer(GL_FLOAT, 0, None)

if type == GL_POINTS:
#glDrawArrays( GL_POINTS, 0, len(self.vertices) );
glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)
else:
#glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)**(If I uncomment this doesnt seem to make any difference?!)**
#glDrawArrays( GL_TRIANGLES, 0, len(self.triangles) );
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)**(What does it draw now since GL_ELEMENT_ARRAY_BUFFER_ARB is binded to 0 ?!)**

现在 glDrawArrays 工作。但是在我必须绘制三角形的情况下,它不会绘制我在 bufferTriangles 中定义的三角形(这从我读过的内容来看是正常的,因为 drawArrays 不使用索引?还是我错了?)。问题是,如果我尝试使用 glDrawElements 一切都会崩溃:
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x000000003150ebbc
Crashed Thread: 0

Thread 0 Crashed:
0 com.apple.GeForce8xxxGLDriver 0x1a3e7050 gldGetTextureLevel + 743600
1 com.apple.GeForce8xxxGLDriver 0x1a3e7563 gldGetTextureLevel + 744899
2 GLEngine 0x1a206eee gleDrawArraysOrElements_VBO_Exec + 1950

现在我在这里错过了什么?据我所知,我可能在某处传递了一个错误的指针?请注意,即使我尝试使用 glDrawElements(type, 24, GL_UNSIGNED_INT, 0) 它仍然会崩溃,即使定义的三角形数量要大得多,所以我认为它与大小没有任何关系。

问候,
波格丹

编辑:
好的,所以现在我做了一些额外的检查,这是我目前的情况:我已经将 len(triangles) 更改为 ADT.byteCount,还没有解决方案。所以我检查了我得到的所有数据,它是这样的:顶点数组包含〜60000 * 3 = 180000 GL_Float 类型的顶点条目,法线数组也是如此。由于只有 < 62535 个顶点,因此我对三角形使用 unsigned short 。所以我有 len(triangles) 是 ~135000。我还更改了 glDrawElements(GL_TRIANGLES, len(self.triangles), GL_UNSIGNED_SHORT , 0) 。我还检查了三角形数组中的所有数据都在 0 和 62534 之间,就像我一样思考也许一些超出范围的指数跌至谷底。这里还有什么问题?
哦,glDrawElements(GL_POINTS, ...) 是如何工作的?它还需要某种索引吗?

编辑2
我已经更新了上面的代码,正如那里所说,现在绘制元素绘制了我的 GL_POINTS,但我不确定他从哪里获得索引?还是在 GL_POINTS 的情况下不需要它们?对于 GL_TRIANGLES,它的工作原理是这样的,带有 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles) 注释,但是现在元素缓冲区绑定(bind)到 0 时又需要什么样的索引?!另一件事是 glDrawElements 不会绘制 glDrawArrays 所做的所有点。为了更好地解释:
glDrawArrays( GL_POINTS, 0, len(self.vertices) );

这正确地得出了我的所有观点:
glDrawElements(type, len(self.vertices), GL_UNSIGNED_SHORT, 0)

这似乎比 glDrawArrays 绘制的点明显少得多。现在有趣的是,如果我通过像 10 * len(self.vertices) 这样的大小来绘制元素,它将绘制所有点(有些可能两次或更多;我可以检查一下吗?)但它不会崩溃吗?

问候

编辑3

有关数组的一些更精确的信息:

vertices - 一个浮点数组,

长度(顶点)= 180000
字节数(顶点)= 720000

三角形 - numpy.uint16 数组

len(三角形)= 353439
字节计数(三角形)= 706878
最小(三角形)= 0
max(triangles) = 59999 ,所以它们应该指向有效顶点

绘制完成:

glDrawElements(GL_TRIANGLES, len(self.triangles), GL_UNSIGNED_SHORT, 0)

更新

好的,就在我知道这应该如何工作时,我试图跳过元素的 VBO,然后就去了:
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, ADT.voidDataPointer(self.triangles))

现在,这不仅可以完美地绘制我所有的三角形,而且 FPS 更好。 VBO不应该更快吗?什么可能导致上述方法工作但以下崩溃:
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, self.bufferTriangles)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ADT.arrayByteCount(triangles), ADT.voidDataPointer(triangles), GL_STATIC_DRAW_ARB)
glDrawElements(GL_TRIANGLES, len(self.triangles) , GL_UNSIGNED_SHORT, 0)

最佳答案

我没有使用 Python GL 的经验,但我想我发现了一些东西。您使用 len(self.triangles)在调用 glDrawElements ,所以我想这会给你三角形数组中的索引数。但是为什么然后使用 len(triangles)glBufferData 中的大小而不是 ADT.arrayByteCount就像其他电话一样。所以你的缓冲区太小了,因为它包含 len(triangles)字节,尽管三角形包含无符号整数。如果三角形确实包含字节(我怀疑),您将不得不使用 GL_UNSIGNED_BYTEglDrawElements .

编辑:根据您的编辑,我得到了更多答案。当然 glDrawElements(GL_POINTS, ...)也需要索引。它只是使用每个索引来绘制一个点,而不是每三个索引绘制一个三角形。只是对于你经常不需要的点glDrawElements ,因为无论如何您都不会重用顶点,但您仍然需要它的索引。它不会神奇地变成 glDrawArrays在引擎盖下调用。

请记住,vertices数组包含浮点数和 glDrawArrays绘制顶点,所以你必须绘制 len(vertices)/3顶点。 Juts 记住,一个元素是一个索引(单个顶点),而不是一个三角形,一个顶点是 3 个浮点数(或者你在 glVertexPointer 中指定的),而不仅仅是一个。

但是,如果您的 triangles数组确实包含 3 个索引的元组(因此 len(triangles) 是三角形计数而不是索引计数),您必须绘制 3*len(triangles)元素(索引)。如果您的 vertices数组包含向量而不仅仅是浮点数,然后绘制 len(vertices) glDrawArrays 调用中的顶点是正确的。因此,很高兴看到他们的声明是肯定的。

关于opengl - glDrawArrays 与 glDrawElements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6124636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com