使用(py)OpenGL进行纹理和图像处理

问题描述 投票:1回答:1

我最近开始进入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.Textures中。问题是他们都受到GL_TEXTURE_2D的约束吗?我如何区分两种纹理?

其次,是否有更好的方法来加载图像,或者是否有办法以某种方式格式化图像像素字节数组,以便它可以轻松反转(这也适用于RGBA图像)?

python opengl pygame python-imaging-library pyopengl
1个回答
0
投票

请注意,glBegin/glEnd序列和固定函数矩阵堆栈的绘制几十年来已被弃用。见Fixed Function PipelineLegacy OpenGL。阅读Vertex SpecificationShader,了解最先进的渲染方式。


现在,它使用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()
© www.soinside.com 2019 - 2024. All rights reserved.