我最近开始进入pygame并最终进入pyOpenGL(仅使用两个维度),因为使用pygame口吃将图像绘制到屏幕上。然而,我遇到了两个问题,我,对于我的生活,我无法弄清楚如何解决。即在处理图像时处理两个+纹理并绕过pygame和OpenGL的坐标不兼容性。
我创建了一个名为Thingie1
的简单类:
class Thingie1:
def __init__(self, x, y):
self.x = x
self.y = y
self.width = 0
self.height = 0
self.sprite = "imageOne.png"
self.lastsprite = ""
self.img_data = 0
self.load()
def load(self):
if self.sprite != self.lastsprite:
im = open(self.sprite)
self.width, self.height, self.img_data = im.size[0], im.size[1], im.tobytes("raw", "RGB", 0, -1)
self.lastsprite = self.sprite
self.Texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, self.Texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE, self.img_data)
glEnable(GL_TEXTURE_2D)
else:
return
def draw(self):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslate(self.x, self.y, 0)
glBegin(GL_QUADS)
glVertex(0, 0, 0)
glTexCoord2f(0, 0)
glVertex(self.width, 0, 0)
glTexCoord2f(0, 1)
glVertex(self.width, self.height, 0)
glTexCoord2f(1, 1)
glVertex(0, self.height, 0)
glTexCoord2f(1, 0)
glEnd()
glFlush()
以及所提到的类的精确副本(现在),称为Thingie2
。 (open()
函数来自PILLOW的Image包(from PIL.Image import open
)。)
然后我打电话
pygame.init()
pygame.display.set_mode((1024,768), pygame.DOUBLEBUF | pygame.OPENGL)
if True:
glClearColor(*(0,0,0,255))
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, 1024, 768, 0)
Thing1 = Thingie1(200,200)
Thing2 = Thingie2(0,0)
while True:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
Thing2.load()
Thing1.load()
Thing2.draw()
Thing1.draw()
pygame.display.flip()
在Thing1
上绘制Thing2
,部分工作;之前,当load()
和draw()
函数合并为一个时,它正确地纹理对象,但对我的计算机并不完全友好。现在,它使用Thing2的纹理构造两个类实例,这是第一个问题。
第二个问题是,绘制的图像旋转180°。我已经尝试使用matplotlib,cv2和其他软件包加载图像,但最接近我来修复这个是当我用glTexImage2D
修改glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, self.width, self.height, 0, GL_RGB, GL_UNSIGNED_BYTE, self.img_data[::-1])
线(使用PIL.Image的open()
),但是它绘制的图像为灰色+蓝色比例(?)。
那么,首先,pyOpenGL如何处理纹理?我希望这两种纹理都存储在各自的self.Texture
s中。问题是他们都受到GL_TEXTURE_2D
的约束吗?我如何区分两种纹理?
其次,是否有更好的方法来加载图像,或者是否有办法以某种方式格式化图像像素字节数组,以便它可以轻松反转(这也适用于RGBA图像)?
请注意,glBegin
/glEnd
序列和固定函数矩阵堆栈的绘制几十年来已被弃用。见Fixed Function Pipeline和Legacy OpenGL。阅读Vertex Specification和Shader,了解最先进的渲染方式。
现在,它使用Thing2的纹理构造两个类实例,这是第一个问题。
glEnable(GL_TEXTURE_2D)
启用了二维纹理,可以通过glDisable(GL_TEXTURE_2D)
禁用。
如果启用纹理,则应用当由glBegin
/glEnd
序列绘制几何时当前绑定的纹理。
在绘制几何体之前,必须绑定正确的纹理:
def draw(self):
# [...]
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, self.Texture)
glBegin()
# [...]
glEnd()
glDisable(GL_TEXTURE_2D)
第二个问题是,绘制的图像旋转180°
调用glVertex
时,当前纹理坐标与顶点坐标相关联。纹理坐标由glTexCoord2f
设置。
这意味着glTexCoord2f
必须在glVertex
之前完成。
glBegin(GL_QUADS)
glTexCoord2f(0, 0)
glVertex(0, 0, 0)
glTexCoord2f(0, 1)
glVertex(self.width, 0, 0)
glTexCoord2f(1, 1)
glVertex(self.width, self.height, 0)
glTexCoord2f(1, 0)
glVertex(0, self.height, 0)
glEnd()