从pygame+rabbyt迁移到pyglet+rabbyt时坐标发生变化
我正在做一个2D游戏,决定从SDL切换到OpenGL。我选择了rabbyt作为OpenGL的包装器来渲染我的精灵,并使用pymunk(chipmunk)来处理物理效果。我用pygame来创建窗口,用rabbyt在屏幕上绘制精灵。
我发现使用pygame和rabbyt时,坐标(0,0)是在屏幕的中间。我觉得这个设计挺好的,因为物理引擎和图形引擎的坐标表示是一样的(这样在渲染精灵时就不用重新计算坐标了)。
然后我切换到pyglet,因为我想用OpenGL绘制线条,结果发现坐标(0,0)突然变成了屏幕的左下角。
我怀疑这可能和glViewport函数有关,但只有rabbyt执行了这个函数,而pyglet只在窗口调整大小时才会触碰到它。
我该如何把坐标(0,0)设置在屏幕的中间呢?
我对OpenGL不太熟悉,经过几个小时的搜索和尝试也没找到解决办法……希望有人能帮帮我 :)
编辑:一些额外的信息 :)
这是我的pyglet屏幕初始化代码:
self.window = Window(width=800, height=600)
rabbyt.set_viewport((800,600))
rabbyt.set_default_attribs()
这是我的pygame屏幕初始化代码:
display = pygame.display.set_mode((800,600), \
pygame.OPENGL | pygame.DOUBLEBUF)
rabbyt.set_viewport((800, 600))
rabbyt.set_default_attribs()
编辑2:我查看了pyglet和pygame的源代码,没发现任何与OpenGL视口有关的屏幕初始化代码……这里是两个rabbyt函数的源代码:
def set_viewport(viewport, projection=None):
"""
``set_viewport(viewport, [projection])``
Sets how coordinates map to the screen.
``viewport`` gives the screen coordinates that will be drawn to. It
should be in either the form ``(width, height)`` or
``(left, top, right, bottom)``
``projection`` gives the sprite coordinates that will be mapped to the
screen coordinates given by ``viewport``. It too should be in one of the
two forms accepted by ``viewport``. If ``projection`` is not given, it
will default to the width and height of ``viewport``. If only the width
and height are given, ``(0, 0)`` will be the center point.
"""
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
if len(viewport) == 4:
l, t, r, b = viewport
else:
l, t = 0, 0
r, b = viewport
for i in (l,t,r,b):
if i < 0:
raise ValueError("Viewport values cannot be negative")
glViewport(l, t, r-l, b-t)
if projection is not None:
if len(projection) == 4:
l, t, r, b = projection
else:
w,h = projection
l, r, t, b = -w/2, w/2, -h/2, h/2
else:
w,h = r-l, b-t
l, r, b, t = -w/2, w/2, -h/2, h/2
glOrtho(l, r, b, t, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def set_default_attribs():
"""
``set_default_attribs()``
Sets a few of the OpenGL attributes that sprites expect.
Unless you know what you are doing, you should call this at least once
before rendering any sprites. (It is called automatically in
``rabbyt.init_display()``)
"""
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
glEnable(GL_BLEND)
#glEnable(GL_POLYGON_SMOOTH)
谢谢,
Steffen
1 个回答
0
正如l33tnerd所建议的,可以通过glTranslatef把原点放在中心位置...我在我的屏幕初始化代码下面添加了以下内容:
pyglet.gl.glTranslatef(width/2, height/2, 0)
谢谢!