python - glVertexAttribPointer() 上的 pyopengl 错误
问题描述
我在 glVertexAttribPointer 上遇到错误,可能是因为值或任何东西(?)有人知道如何解决这个问题吗?
import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
from PIL import Image
def main():
if not glfw.init():
return
window = glfw.create_window(720, 720, "08_A_xxx: PyOpengl dan tekstur", None, None)
if not window:
glfw.terminate()
return
glfw.make_context_current(window)
#posisi warna koordinat tekstur
rectangle = [-0.5, -0.5, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0]
# ubah ke 32 bit (float)
rectangle = np.array(rectangle, dtype=np.float32)
indices = [0,1,2,
2,3,0]
indices = np.array(indices, dtype = np.uint32)
VERTEX_SHADER = """
#version 330
in vec3 position;
in vec3 color;
in vec2 InTexCoords;
out vec3 newColor;
out vec2 OutTexCoords;
void main() {
gl_Position = vec4(position, 1.0);
newColor = color;
OutTexCoords = InTexCoords;
}
"""
FRAGMENT_SHADER = """
#version 330
in vec3 newColor;
in vec2 OutTexCoords;
out vec4 outColor;
uniform sampler2D samplerTex;
void main() {
outColor = texture(samplerTex, OutTexCoords);
}
"""
# Kompilasi program dan shaders
shader = OpenGL.GL.shaders.compileProgram(OpenGL.GL.shaders.compileShader(VERTEX_SHADER, GL_VERTEX_SHADER),
OpenGL.GL.shaders.compileShader(FRAGMENT_SHADER, GL_FRAGMENT_SHADER))
# Buat objek buffer dalam gpu
VBO = glGenBuffers(1)
# Bind the buffer
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, 128, rectangle, GL_STATIC_DRAW)
# Buat EBO
EBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
# mendapatkan posisi dari shader
position = glGetAttribLocation(shader, 'position')
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
glEnableVertexAttribArray(position)
# mendapatkan warna dari shader
color = glGetAttribLocation(shader, 'color')
glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
glEnableVertexAttribArray(color)
texCoords = glGetAttribLocation(shader, "InTexCoords")
glVertexAttribPointer(texCoords,2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
glEnableVertexAttribArray(texCoords)
# Buat Tekstur
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
# texture wrapping params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
# texture filtering params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
image = Image.open("hello.jpg")
img_data = np.array(list(image.getdata()), np.uint8)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
glUseProgram(shader)
glClearColor(0.0, 0.0, 0.0, 1.0)
while not glfw.window_should_close(window):
glfw.poll_events()
glClear(GL_COLOR_BUFFER_BIT)
# Gambar segiempat
glDrawElements(GL_TRIANGLES,6, GL_UNSIGNED_INT, None)
glfw.swap_buffers(window)
glfw.terminate()
if __name__ == "__main__":
main()
解决方案
该属性color
不是活动程序资源,因为该属性未在着色器程序中“使用”。该属性从顶点传递到片段着色器,但片段着色器忽略输入变量newColor
。优化算法对属性进行排序color
。
因此glGetAttribLocation
返回 -1 并最终glVertexAttribPointer
失败。
没有必要为属性指定顶点属性数据数组color
,因为它根本不需要。评估是否glGetAttribLocation
返回大于或等于 0 的值,以解决问题:
color = glGetAttribLocation(shader, 'color')
if color >= 0:
glVertexAttribPointer(color, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
glEnableVertexAttribArray(color)
推荐阅读
- java - 如何使用带有 Spring Boot 的 Lombok 访问 JPA 实体的 Builder()?
- python - 裁剪音频文件时 Python3 中的 MemoryError
- python - 如何将 MSSQL 连接到 Django
- mysql - docker-compose:MySQL 服务未运行
- java - GET 请求上的 I/O 错误 --Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
- ponyorm - 在 PonyORM 中从一对多关系访问值
- typescript - Mobx-State-Tree - 分配给数组类型
- intellij-idea - 在Json文件中导出intelliJidea代码样式只能使用xml代码样式schema有什么用
- python - Sqlalchemy 将列表与查询进行比较,以便更新、删除和添加
- neo4j - 如何在neo4j中找到两个图之间的相似性