Python 使用pyopengl渲染pygame精灵

Python 使用pyopengl渲染pygame精灵,python,python-3.x,pygame,pyopengl,pygame-surface,Python,Python 3.x,Pygame,Pyopengl,Pygame Surface,在我的游戏中,我使用pygame渲染精灵,但是这项工作是在CPU端完成的,对于性能问题,如何使用pyopengl绘制这些精灵?我开始在C++学习OpenGL,那些时间和Python相似吗?< /p> < p>如果你只想在GPU上渲染精灵,你可以使用。引擎盖下的ModenGL使用OpenGL 编写一个类,该类将子类化并覆盖draw方法。使用和渲染精灵。本机OpenGL(PyOpenGL)也可以做类似的事情,只需要多一点代码。 另见 最简单的例子: 导入pygame 进口现代化 导入ctypes

在我的游戏中,我使用pygame渲染精灵,但是这项工作是在CPU端完成的,对于性能问题,如何使用pyopengl绘制这些精灵?我开始在C++学习OpenGL,那些时间和Python相似吗?< /p> < p>如果你只想在GPU上渲染精灵,你可以使用。引擎盖下的ModenGL使用OpenGL

编写一个类,该类将子类化并覆盖
draw
方法。使用和渲染精灵。本机OpenGL(PyOpenGL)也可以做类似的事情,只需要多一点代码。
另见

最简单的例子:

导入pygame
进口现代化
导入ctypes
顶点_着色器_精灵=”“”
#330版
在vec2中处于_位置;
在vec2的紫外;
输出vec2v_-uv;
void main()
{
v_uv=in_uv;
gl_位置=vec4(处于_位置,0.0,1.0);
}
"""
碎片_着色器_精灵=”“”
#330版
out vec4 fragColor;
均匀的二维u_纹理;
在vec2v_-uv中;
void main()
{
fragColor=纹理(u_纹理,v_uv);
}
"""
类ModernGLGroup(pygame.sprite.Group):
gl_context=None
gl_程序=无
gl_缓冲区=无
gl_vao=无
gl_纹理={}
def uuu init uuu(self,sprites=None):
如果精灵==无:
super()。\uuuu init\uuuuu()
其他:
超级()。\uuuu初始化\uuuu(精灵)
def get_程序():
如果ModernGLGroup.gl_程序==无:
ModernGLGroup.gl_程序=ModernGLGroup.gl_context.program(
顶点着色器=顶点着色器精灵,
片段\着色器=片段\着色器\精灵)
返回ModernGLGroup.gl\u程序
def get_buffer():
如果ModernGLGroup.gl_buffer==无:
ModernGLGroup.gl_buffer=ModernGLGroup.gl_context.buffer(无,保留=6*4*4)
返回ModernGLGroup.gl\u缓冲区
def get_vao():
如果ModernGLGroup.gl_vao==无:
ModernGLGroup.gl_vao=ModernGLGroup.gl_context.vertex_数组(
ModernGLGroup.get_program(),[(ModernGLGroup.get_buffer(),“2f4 2f4”,“in_position”,“in_uv”)])
return ModernGLGroup.gl_vao
def get_纹理(图像):
如果不是ModernGLGroup.gl_纹理中的图像:
rgba_image=image.convert_alpha()
texture=ModernGLGroup.gl_context.texture(rgba_image.get_size(),4,rgba_image.get_buffer())
texture.swizzle='BGRA'
ModernGLGroup.gl_纹理[图像]=纹理
返回ModernGLGroup.gl_纹理[图像]
def convert_顶点(pt,曲面):
返回pt[0]/surface.get_width()*2-1,1-pt[1]/surface.get_height()*2
def渲染(精灵、曲面):
角=[
ModernGLGroup.convert_顶点(sprite.rect.bottomleft,surface),
ModernGLGroup.convert_顶点(sprite.rect.bottomright,surface),
ModernGLGroup.convert_顶点(sprite.rect.topright,surface),
ModernGLGroup.convert_顶点(sprite.rect.topleft,曲面)]
顶点_quad_2d=(ctypes.c_float*(6*4))(
*角点[0]、0.0、1.0、,
*角[1],1.0,1.0,
*角[2],1.0,0.0,
*角点[0]、0.0、1.0、,
*角[2],1.0,0.0,
*角[3],0.0,0.0)
ModernGLGroup.get\u buffer().write(顶点\u四边形\u 2d)
ModernGLGroup.get_纹理(sprite.image)。使用(0)
ModernGLGroup.get_vao().render()
def绘图(自、表面):
对于自我中的精灵:
ModernGLGroup.render(精灵、曲面)
类SpriteObject(pygame.sprite.sprite):
定义初始化(self,x,y):
super()。\uuuu init\uuuuu()
尝试:
self.image=pygame.image.load('AirPlaneFront1-256.png')。convert_alpha()
除:
self.image=pygame.Surface((100100),pygame.SRCALPHA)
pygame.draw.circle(self.image,(255,255,0),(50,50),50)
self.rect=self.image.get_rect(中心=(x,y))
def更新(自我、表面):
keys=pygame.key.get_pressed()
水平=5
如果键[pygame.K_左]:
self.rect.left=max(0,self.rect.left电平)
如果键[pygame.K_RIGHT]:
self.rect.right=min(surface.get_width(),self.rect.right+vel)
如果键[pygame.K_UP]:
self.rect.top=max(0,self.rect.top级别)
如果键[pygame.K_DOWN]:
self.rect.bottom=min(surface.get_height(),self.rect.bottom+vel)
pygame.init()
window=pygame.display.set_模式((500500),pygame.DOUBLEBUF | pygame.OPENGL)
clock=pygame.time.clock()
gl_context=moderngl.create_context()
gl_context.enable(moderngl.BLEND)
ModernGLGroup.gl\u context=gl\u context
精灵对象=精灵对象(*window.get_rect().center)
组=现代化组(精灵对象)
运行=真
运行时:
时钟滴答(60)
event_list=pygame.event.get()
对于事件列表中的事件:
如果event.type==pygame.QUIT:
运行=错误
组更新(窗口)
gl_上下文清除(0.2,0.2,0.2)
组图(窗口)
pygame.display.flip()
pygame.quit()
退出()

这是一个有趣的问题。精灵基本上是一个纹理映射的矩形。如果PyGame默认使用硬件视频加速会很好,但考虑到在广泛的计算生态系统中工作的复杂性,它回避了一个问题:这是必要的吗?IMHO,在Python+PyGame中学习游戏编程很好。不要编写低效的代码,但也不要因为性能问题而烦恼。最好是让一个完成的游戏做一些缓慢的事情,而不是1/2什么都没完成,因为程序员过早地进行了优化。@Kingsley有趣的观点。。。是的,我意识到对性能的追求,但我留下了改进的空间,我已经有了一个基本的系统,易于扩展和工作的游戏,这个问题是看看如何改进pygame上最糟糕的事情。谢谢分享你的观点!