Nic*_*vre 6 python opengl pyglet
编辑:rotoglup在我的代码中发现了问题,添加了我删除的着色器完成了解决方案.请参阅下面的答案以获取正确的代码(使用着色器).
大家好 !
我正在尝试从本教程中学习一些现代OpenGL的基础知识.
我想用python/pyglet而不是C++来做.我知道pyglet可以抽取大部分低级OpenGL; 我想先了解一些基础知识,然后再将它们隐藏在抽象层之后.
我的问题非常简单:下面的代码只绘制一个点而不是我期望的3个点.据我所知,我的代码与教程中的C++相同,除了删除顶点和片段着色器(通过python中的gletools完成),这似乎对我的问题没有任何影响.
将事物简化为单点显示我不理解的行为(第一个坐标似乎是唯一影响任何事物的坐标),这让我回想起我完全不理解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()
Run Code Online (Sandbox Code Playgroud)
glDrawArrays(GL_POINTS, 0, 1)
Run Code Online (Sandbox Code Playgroud)
指示画1点,在你的教程中,1是3:
glDrawArrays(GL_POINTS, 0, 3)
Run Code Online (Sandbox Code Playgroud)
另请注意,顶点的第4(w)分量应为1,而不是0:
vertexPositions = [0.0, 0.0, 0.0, 1.0,
0.25, 0.0, 0.0, 1.0,
1.75, 1.75, 0.0, 1.0]
Run Code Online (Sandbox Code Playgroud)
或者,您可以删除w组件,
vertexPositions = [0.0, 0.0, 0.0,
0.25, 0.0, 0.0,
1.75, 1.75, 0.0]
Run Code Online (Sandbox Code Playgroud)
并将以下调用更改为:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0)
Run Code Online (Sandbox Code Playgroud)
另一件事,我不是pyglet的专家,但glBufferData可能像C语言一样采用字节大小而不是元素.每个浮点数为4个字节,您可以尝试:
glBufferData(GL_ARRAY_BUFFER, len(vertexPositionsGl)*4, vertexPositionsGl, GL_STATIC_DRAW)
Run Code Online (Sandbox Code Playgroud)
我终于做对了!
看来我被以下事实误导了:摆弄顶点、glDrawArrays 和 glVertexAttribPointer 有时会导致显示单个点。这似乎是一个意外:根据 rotoglup 的答案提供的更正,根本没有绘制任何内容。这是我原来问题中代码的“正确”行为。
我的错误清单,以防对任何人有帮助:
将 w 坐标设置为 0,而不是 1,完全缺少教程中对剪辑空间变换的解释。
当 glBufferData 需要字节时,为它提供以顶点为单位的缓冲区大小。
作为记录,下面的代码显示了一个带有直通着色器的三角形,我希望它是最新且正确的 OpenGL。要求是 pyglet 和 gletools。
import pyglet
from pyglet.gl import *
from gletools import ShaderProgram, FragmentShader, VertexShader
window = pyglet.window.Window()
positionBufferObject = GLuint()
vertexPositions = [0.75, 0.75, 0.0, 1.0,
0.75, -0.75, 0.0, 1.0,
-0.75, -0.75, 0.0, 1.0]
vertexPositionsGl = (GLfloat * len(vertexPositions))(*vertexPositions)
program = ShaderProgram(
FragmentShader('''
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}'''),
VertexShader('''
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}''')
)
@window.event
def on_draw():
with program:
glBindBuffer(GL_ARRAY_BUFFER, positionBufferObject)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0)
glDrawArrays(GL_TRIANGLES, 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)
pyglet.app.run()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4855 次 |
| 最近记录: |