gpt4 book ai didi

python - PyOpenGL、Pygame 和着色器似乎不合作

转载 作者:太空狗 更新时间:2023-10-30 02:49:10 25 4
gpt4 key购买 nike

我一直在研究这个 excellent tutorial关于现代 OpenGL 编程,我正在慢慢调整它以在 PyOpenGL 和 pygame 上工作。但是,我很难得到一个应该是“微不足道”的例子来处理透视几何。代码如下:

import pygame
import numpy as np
from OpenGL.GL import *

##########################################
# Define the simple pass-through shaders
##########################################
import cStringIO
vshade = cStringIO.StringIO("""
#version 110

uniform mat4 p_matrix;
uniform mat4 mv_matrix;

attribute vec4 position;

void main()
{
vec4 eye_position = mv_matrix * position;
gl_Position = p_matrix * eye_position;
}
""")

fshade = cStringIO.StringIO("""
#version 110

void main()
{
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
""")

###################################################
# Set up a simple square composed of two triangles
###################################################
verts = np.array([[0,0,0,1],[1,0,0,1],[1,1,0,1],[0,1,0,1]]).astype(np.float32)
polys = np.array([[0,1,3],[1,2,3]]).astype(np.ushort)
mv_matrix = np.eye(4)
mv_matrix[:3,-1] = [0,0,2]
projection = np.array([ [ 1.071429, 0. , 0. , 0. ],
[ 0. , 1.428571, 0. , 0. ],
[ 0. , 0. , 1.000489, -0.125031],
[ 0. , 0. , 1. , 0. ]])

def _make_shader(stype, src):
shader = glCreateShader(stype)
glShaderSource(shader, src)
glCompileShader(shader)

if not glGetShaderiv(shader, GL_COMPILE_STATUS):
err = glGetShaderInfoLog(shader)
glDeleteShader(shader)
raise Exception(err)
return shader

##################################
# Initialize pygame and opengl
##################################
flags = pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.OPENGL
pygame.display.set_mode((800,600), flags)

glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glClearColor(0.5,0.5,0.5,1)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glEnable(GL_TEXTURE_2D)


######################################
# Make the shaders and programs
######################################
vshade = _make_shader(GL_VERTEX_SHADER, vshade.read())
fshade = _make_shader(GL_FRAGMENT_SHADER, fshade.read())

program = glCreateProgram()
glAttachShader(program, vshade)
glAttachShader(program, fshade)
glLinkProgram(program)

#######################################
# Fetch positions, push poly to card
#######################################
posidx = glGetAttribLocation(program, "position")
pidx = glGetUniformLocation(program, "p_matrix")
mvidx = glGetUniformLocation(program, "mv_matrix")

vbuf = glGenBuffers(1)
ebuf = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbuf)
glBufferData(GL_ARRAY_BUFFER,
verts.astype(np.float32).ravel(), GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf)
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
polys.astype(np.uint16).ravel(), GL_STATIC_DRAW)

#####################################
# Enter main drawing loop!
#####################################
glViewport(0,0,800,600)
while True:
# Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glUseProgram(program)

# Push the transforms to the card
glUniformMatrix4fv(pidx, 1, GL_TRUE, projection.astype(np.float32))
glUniformMatrix4fv(mvidx, 1, GL_TRUE, mv_matrix.astype(np.float32))

# Enable the position attribute
glEnableVertexAttribArray(posidx)
glBindBuffer(GL_ARRAY_BUFFER, vbuf)
glVertexAttribPointer( posidx, 4, GL_FLOAT, GL_FALSE, 4*4, 0)

# Draw the two triangles
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf);
glDrawElements(
GL_TRIANGLES, # mode
len(polys)*3, # count
GL_UNSIGNED_SHORT, # type
0 # element array buffer offset
)
glDisableVertexAttribArray(posidx)

#inspect the values -- does it make sense?
glBindBuffer(GL_ARRAY_BUFFER, vbuf)
l, l2 = (GLfloat*16)() , (GLushort*6)()
glGetBufferSubData(GL_ARRAY_BUFFER, 0, 4*4*4, l)
print list(l)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebuf)
glGetBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 2*6, l2)
print list(l2)
glGetUniformfv(program, pidx, l)
print list(l)
glGetUniformfv(program, mvidx, l)
print list(l)

pygame.display.flip()

根据我的理解,我应该得到一个红色方 block 来覆盖屏幕的右上象限,但我所做的似乎没有影响全灰屏幕。任何对错误的见解将不胜感激!

最佳答案

在进一步压缩问题并在 C 中进行了几乎逐行匹配之后,我意识到这是 pyopengl 独有的问题,而不是 pygame 中的问题。我将示例代码发布在他们的邮件列表上,并找到了答案:

http://sourceforge.net/mailarchive/message.php?msg_id=28875534

他们为 glDrawElements 实现 ctypes 包装器的方式似乎存在轻微的“缺陷”。给出偏移量的最后一个参数需要类型 (void*)。简单的0传入的值是不行的,需要用GLvoidp(0)包裹。

关于python - PyOpenGL、Pygame 和着色器似乎不合作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9393907/

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