基本的 openGL、顶点缓冲区和 pyglet
编辑:rotoglup 在我的代码中发现了问题,添加我删除的着色器完成了解决方案。请参阅下面我的答案以获取正确的代码(带有着色器)。
大家好!
我正在尝试从本教程学习现代 OpenGL 的一些基础知识。
我想用 python/pyglet 而不是 C++ 来实现。我知道 pyglet 可以抽象出大部分低级 OpenGL;在继续将它们隐藏在抽象层后面之前,我想了解一些基础知识。
我的问题非常简单:下面的代码只绘制一个点,而不是我期望的 3 个点。 据我所知,我的代码与教程中的 C++ 相同,除了删除顶点和片段着色器(通过 gletools in python),这似乎对我的问题没有影响。
将事情简化为一个点显示了我不理解的行为(第一个坐标似乎是唯一影响任何事情的坐标),使我回到了我的信念,即我根本无法理解有关 pyglet、OpenGL、甚至是一般的 3D :p
这是相关代码:
import pyglet
from pyglet.gl import *
window = pyglet.window.Window()
positionBufferObject = GLuint()
vao = GLuint()
vertexPositions = [0.0, 0.0, 0.0,
0.25, 0.0, 0.0,
1.75, 1.75, 0.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)
@window.event
def on_draw():
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glDrawArrays(GL_POINTS, 0, 3)
glDisableVertexAttribArray(0)
glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glClearColor(0.0, 0.0, 0.0, 0.0)
pyglet.app.run()
Edit: rotoglup found the problems in my code, adding the shaders I had removed completed the solution. See my answer below for the correct code (with shaders).
Hi all !
I'm trying to learn some basics of modern OpenGL from this tutorial.
I'd like to do it with python/pyglet instead of C++ though. I know pyglet can abstract much of the low level OpenGL away; I want to understand some of the basics before moving on to hiding them behind layers of abstraction though.
My problem is extremely simple: the code below only draws a single point instead of the 3 I am expecting.
My code is, as far as I can tell, identical to the C++ in the tutorial, except for the removal of vertex and fragment shaders (done via gletools in python), which appears to make no difference to my problem.
Simplifying things to a single point shows behaviour I do not understand (the first coordinate appears to be the only one that affects anything), leading me back to my belief that I've simply failed to understand something very basic about either pyglet, OpenGL, or even 3D in general :p
Here's the relevant code:
import pyglet
from pyglet.gl import *
window = pyglet.window.Window()
positionBufferObject = GLuint()
vao = GLuint()
vertexPositions = [0.0, 0.0, 0.0,
0.25, 0.0, 0.0,
1.75, 1.75, 0.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)
@window.event
def on_draw():
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
glDrawArrays(GL_POINTS, 0, 3)
glDisableVertexAttribArray(0)
glGenBuffers(1, positionBufferObject)
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glClearColor(0.0, 0.0, 0.0, 0.0)
pyglet.app.run()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
指示绘制 1 点,在您的教程中,1 是 3 :
另请注意,顶点的第四个 (w) 分量应该是 1,而不是 0 :
或者,您可以删除 w 分量,
并将以下调用更改为:
Another事情,我不是 pyglet 的专家,但 glBufferData 可能像它的 C 对应项一样,采用字节大小,而不是元素大小。每个浮点数为 4 个字节,你可以尝试:
instructs to draw 1 point, in your tutorial, 1 is 3 :
Notice also that the 4th (w) component of your vertices should be 1, not 0 :
Alternatively, you could remove the w component,
and change the following call to :
Another thing, I'm not an expert in pyglet, but it's possible that glBufferData, like its C counterpart, take a size in bytes, not in elements. Each float being 4 bytes, you could try :
我终于做对了!
看来我被以下事实误导了:摆弄顶点、glDrawArrays 和 glVertexAttribPointer 有时会导致显示单个点。
这似乎是一个意外:根据 rotoglup 的答案提供的更正,根本没有绘制任何内容。这是我原来问题中代码的“正确”行为。
我的错误清单,以防对任何人有帮助:
将 w 坐标设置为 0,而不是 1,完全缺少教程中对剪辑空间转换的解释。
当 glBufferData 需要字节时,为它提供以顶点为单位的缓冲区大小。
作为记录,下面的代码显示了一个带有直通着色器的三角形,我希望它是最新且正确的 OpenGL。要求是 pyglet 和 gletools。
I finally got this right !
It seems I was being misled by the fact that fiddling with vertices, glDrawArrays and glVertexAttribPointer sometimes resulted in a single dot being shown.
This appears to be an accident: with the corrections provided by rotoglup's answer, nothing at all is drawn. This is the "correct" behaviour for the code in my original question.
An inventory of my mistakes in case it helps anyone:
setting the w coordinate to 0, instead of 1, completely missing the explanations for clip-space transformation in the tutorial.
giving glBufferData the size of the buffer in vertices when it expects bytes.
For the record, the code below displays a single triangle, with pass through shaders, in what I hope to be up to date and correct OpenGL. Requirements are pyglet and gletools.