从 pygame+rabbyt 迁移到 pyglet+rabbyt 时坐标发生变化

发布于 2024-10-05 00:25:11 字数 2764 浏览 0 评论 0原文

我正在开发一款 2D 游戏,并决定从 SDL 切换到 OpenGL。我将 rabbyt 作为 opengl 包装器来渲染我的精灵,并使用 pymunk(花栗鼠)来实现我的物理。我使用 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)

谢谢, 史蒂芬

I'm working on a 2D game and decided to switch from SDL to OpenGL. I took rabbyt as an opengl wrapper for rendering my sprites and using pymunk (chipmunk) for my physics. I used pygame for creating the window and rabbyt for drawing the sprites on the screen.

I discovered that with pygame+rabbyt the (0,0) coordinate is in the middle of the screen. I liked that fact, because the coordinate representation in the physics engine were the same as in my graphics engine (I don't have to recalculate the coordinates when rendering the sprites).

Then I switched to pyglet because I wanted to draw lines with OpenGL - and discovered that suddenly the (0,0) coordinate was at the bottom left of the screen.

I suspected that that has something to do with the glViewport function, but only rabbyt executes that function, pyglet touches it only when the window is resized.

How can I set the (0,0) coordinate at the middle of the Screen?

I'm not very familiar with OpenGL and couldn't find anything after several hours googling and trial&error... I hope someone can help me :)

Edit: Some additional information :)

This is my pyglet screen initialization code:

self.window = Window(width=800, height=600)
rabbyt.set_viewport((800,600))
rabbyt.set_default_attribs()

This is my pygame screen initialization code:

display = pygame.display.set_mode((800,600), \
  pygame.OPENGL | pygame.DOUBLEBUF)
rabbyt.set_viewport((800, 600))
rabbyt.set_default_attribs()

Edit 2: I looked at the sources of pyglet and pygame and didn't discover anything in the screen initialization code that has something to do with the OpenGL viewport... Here is the source of the two rabbyt functions:

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)

Thanks,
Steffen

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦途 2024-10-12 00:25:11

正如 l33tnerd 建议的那样,可以使用 glTranslatef 将原点放置在中心...
我在屏幕初始化代码下面添加了以下内容:

pyglet.gl.glTranslatef(width/2, height/2, 0)

谢谢!

As l33tnerd suggested the origin can be placed at the center with glTranslatef...
I added the following below my screen initialization code:

pyglet.gl.glTranslatef(width/2, height/2, 0)

Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文