透明图像在pyopengl中无限渲染

svgewumm  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(174)

我从这篇文章here中提取了代码。我的主要目标是用OpenGL绘制我的整个PyGame项目,以便它能够更好地运行。我遇到的问题是,我有一个有点透明的图像,它看起来像是被无限绘制,失去了颜色和不透明度。我也尝试了其他非透明图像,它似乎在做同样的事情。
Link for the transparent image I am using.

代码:

import pygame
from OpenGL.GL import *
from pygame.locals import *

pygame.init()
pygame.display.set_mode((1900, 900), OPENGL | DOUBLEBUF | pygame.OPENGLBLIT)
pygame.display.init()
info = pygame.display.Info()

# basic opengl configuration

glViewport(0, 0, info.current_w, info.current_h)
glDepthRange(0, 1)
glMatrixMode(GL_PROJECTION)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDisable(GL_DEPTH_TEST)
glDisable(GL_LIGHTING)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glEnable(GL_BLEND)

# Images

sun = pygame.image.load("menuimages/sun.png").convert_alpha()

texID = glGenTextures(1)
def surfaceToTexture( pygame_surface ):
    global texID
    rgb_surface = pygame.image.tostring(pygame_surface, 'RGB')
    glBindTexture(GL_TEXTURE_2D, texID)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    surface_rect = pygame_surface.get_rect()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, surface_rect.width, surface_rect.height, 0, GL_RGB, GL_UNSIGNED_BYTE, rgb_surface)
    glGenerateMipmap(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)

clock = pygame.time.Clock()

# make an offscreen surface for drawing PyGame to

offscreen_surface = pygame.Surface((info.current_w, info.current_h))

while True:
    offscreen_surface.blit(sun, (50, 250))

    # prepare to render the texture-mapped rectangle
    glClear(GL_COLOR_BUFFER_BIT)
    glLoadIdentity()
    glDisable(GL_LIGHTING)
    glEnable(GL_TEXTURE_2D)

    #draw texture openGL Texture
    surfaceToTexture( offscreen_surface )
    glBindTexture(GL_TEXTURE_2D, texID)
    glBegin(GL_QUADS)
    glTexCoord2f(0, 0); glVertex2f(-1, 1)
    glTexCoord2f(0, 1); glVertex2f(-1, -1)
    glTexCoord2f(1, 1); glVertex2f(1, -1)
    glTexCoord2f(1, 0); glVertex2f(1, 1)
    glEnd()

    pygame.display.flip()
    clock.tick(60)

任何帮助都是感激不尽的。

k75qkfdt

k75qkfdt1#

在应用循环中不需要调用surfaceToTexture,在循环前调用一次,但在循环中绑定纹理。
此外,您还必须处理应用程序循环中的事件。请分别参见pygame.event.get()pygame.event.pump()
对于游戏的每一帧,你都需要对事件队列进行某种调用。这确保了你的程序可以在内部与操作系统的其他部分进行交互。

offscreen_surface.blit(sun, (50, 250))
surfaceToTexture( offscreen_surface )

run = True
while run:
    for event in pygame.event.get():
        if event.type == QUIT:
            run = False

    # prepare to render the texture-mapped rectangle
    glClear(GL_COLOR_BUFFER_BIT)
    glLoadIdentity()
    glDisable(GL_LIGHTING)
    glEnable(GL_TEXTURE_2D)

    #draw texture openGL Texture
    glBindTexture(GL_TEXTURE_2D, texID)
    glBegin(GL_QUADS)
    glTexCoord2f(0, 0); glVertex2f(-1, 1)
    glTexCoord2f(0, 1); glVertex2f(-1, -1)
    glTexCoord2f(1, 1); glVertex2f(1, -1)
    glTexCoord2f(1, 0); glVertex2f(1, 1)
    glEnd()

    pygame.display.flip()
    clock.tick(60)

可以使用glTexSubImage2D更改现有纹理对象(texID):

def updateTexture(pygame_surface, texID):
    rgb_surface = pygame.image.tostring(pygame_surface, 'RGB')
    surface_rect = pygame_surface.get_rect()
    glBindTexture(GL_TEXTURE_2D, texID)
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface_rect.width, surface_rect.height, GL_RGB, GL_UNSIGNED_BYTE, rgb_surface)

当你想移动的时候,你最好只画和移动“小”图像。用glOrtho设置一个Orthographic projection,并用窗口坐标指定四边形顶点。
另请参见使用pyopengl或PyGame and OpenGL immediate mode (Legacy OpenGL)渲染pygame精灵
完整示例:

import pygame
from OpenGL.GL import *
from pygame.locals import *

pygame.init()
screen = pygame.display.set_mode((1900, 900), OPENGL | DOUBLEBUF | pygame.OPENGLBLIT)
pygame.display.init()
info = pygame.display.Info()

# basic opengl configuration

glViewport(0, 0, info.current_w, info.current_h)
glDepthRange(0, 1)
glMatrixMode(GL_PROJECTION)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDisable(GL_LIGHTING)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)

# Images

sun = pygame.image.load("menuimages/sun.png").convert_alpha()

def surfaceToTexture(pygame_surface):
    texID = glGenTextures(1)
    rgb_surface = pygame.image.tostring(pygame_surface, 'RGBA')
    glBindTexture(GL_TEXTURE_2D, texID)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    surface_rect = pygame_surface.get_rect()
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface_rect.width, surface_rect.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgb_surface)
    glGenerateMipmap(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)
    return texID

def drawTextureImage(textureId, rect):
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, textureId)
    glBegin(GL_QUADS)
    glTexCoord2f(0, 0); glVertex2f(rect.left, rect.bottom)
    glTexCoord2f(0, 1); glVertex2f(rect.left, rect.top)
    glTexCoord2f(1, 1); glVertex2f(rect.right, rect.top)
    glTexCoord2f(1, 0); glVertex2f(rect.right, rect.bottom)
    glEnd()
    glDisable(GL_TEXTURE_2D)

clock = pygame.time.Clock()

sun_x = 0
texID = surfaceToTexture(sun)

run = True
while run:
    for event in pygame.event.get():
        if event.type == QUIT:
            run = False

    sun_x = (sun_x + 1) % screen.get_width()
    sun_rect = sun.get_rect(topleft = (sun_x, 250))

    glViewport(0, 0, screen.get_width(), screen.get_height())
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    glOrtho(0, screen.get_width(), 0, screen.get_height(), -1, 1)
    glMatrixMode(GL_MODELVIEW)

    # prepare to render the texture-mapped rectangle
    glClear(GL_COLOR_BUFFER_BIT)
    glLoadIdentity()
    glDisable(GL_LIGHTING)
    glDisable(GL_DEPTH_TEST)
    glEnable(GL_BLEND)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

    #draw texture openGL Texture
    drawTextureImage(texID, sun_rect)

    pygame.display.flip()
    clock.tick(60)

相关问题