Pyglet不稳定的帧速率

时间:2014-05-06 14:06:35

标签: python opengl animation pyglet

我正在尝试在Pyglet中创建一个简单的程序,它显示一个动画并检索一些鼠标输入并将其保存到文本文件中。即使我没有使用鼠标,我的代码也会显示出非常不稳定的帧速率。

我也查看了类似的问题,答案建议使用子类窗口,或者使用on_draw调用函数schedule_interval。但是,我不知道如何使用子类窗口来显示我的动画,当我尝试用on_draw调用schedule_interval时,我得到on_draw没有收到任何参数的错误

这是我正在使用的代码的一部分:

fps = pyglet.clock.ClockDisplay()# Show FPS

@mywindow.event
def on_mouse_press(x, y, button, modifiers):
    global timeStart, file, count
    timeNow = time.clock() - timeStart

    if button == mouse.LEFT:
        print('left click press in {}').format(timeNow)
        with open(out_file_name, 'a') as file:
            file.write(str(count) +'\t'+ str(timeNow) +'\t'+ '-1\n')
            #file.write('' + count + timeNow + 'left click press\n')                 
    count += 1

def update_frames(dt):
    global x
    x=x+1

@mywindow.event
def on_draw():
    pyglet.gl.glClearColor(0,0,0,0)
    mywindow.clear()
    glColor4f(1,0,0,1)
    drawSquare(x,y)#this draws an opengl square
    fps.draw()# Show FPS


dt = 1/10.0
pyglet.clock.schedule_interval(update_frames,dt)
pyglet.app.run()

为了获得稳定的帧速率,我可以添加哪些代码?

1 个答案:

答案 0 :(得分:1)

我会改用这样的东西:

import pyglet
from pyglet.gl import *
from collections import OrderedDict
from time import time
from os.path import abspath

class GUI(pyglet.window.Window):
    def __init__(self):
        super(GUI, self).__init__(640,340, caption='Test')

        pyglet.gl.glClearColor(1, 1, 1, 1)
        self.alive = True
        self.batches = OrderedDict()
        self.batches['apples'] = pyglet.graphics.Batch()

        self.framerate = 0, time()
        self.count = 0

    def render(self, *args):
        self.clear()

        #glColor4f(1,0,0,1)
        #drawSquare(x,y)

        if time() - self.framerate[1] > 1:
            print('fps:',self.framerate[0])
            self.framerate = 0, time()
        else:
            # Not an optimal way to do it, but it will work.
            self.framerate = self.framerate[0]+1, self.framerate[1]

        self.flip()

    def on_draw(self):
        self.render()

    def on_close(self):
        self.alive = False

    def on_key_press(self, symbol, modkey):
        pass

    def on_key_release(self, symbol, modkey):
        pass

    def on_mouse_release(self, x, y, button, modifiers):
        pass

    def on_mouse_press(self, x, y, button, modifiers):
        self.count += 1
        with open('debug.log', 'w') as fh:
            fh.write(str(count))

    def on_mouse_motion(self, x, y, dx, dy):
        pass

    def on_mouse_drag(self, x, y, dx, dy, buttons, modifiers):
        pass

    def run(self):
        while self.alive:
            event = self.dispatch_events()
            if event:
                print(event)
            self.render()


if __name__ == '__main__':
    x = GUI()
    pyglet.clock.set_fps_limit(60)
    x.run()

首先,这段代码实际产生60 FPS, 您可以更好地控制应用程序和主循环。

其次,编码风格可能是个人偏好,但是把东西扔进类对象而不是做一大堆函数,你附上说@ window.update等更符合我的喜好..代码看起来更清晰。< / p>

试一试,看看它是否有效。

注意:此处的密钥为event = self.dispatch_events(),必须在每次迭代时调用它,它取代了app.run()

将它与对象绑定并渲染它们

class House(pyglet.sprite.Sprite):
    def __init__(self):
        self.texture = pyglet.image.load(abspath('./image.png'))
        super(House, self).__init__(self.texture)

        self.x = 0
        self.y = 0
        self.rotation = 0

        self.name = 'house'
        self.anchor = 'center'

    def swap_image(self, image):
        self.texture = pyglet.image.load(abspath(image))
        self.image = self.texture

    def rotate(self, deg):
        self.image.anchor_x = self.image.width / 2
        self.image.anchor_y = self.image.height / 2
        self.rotation = self.rotation+deg
        if self.anchor != 'center':
            self.image.anchor_x = 0
            self.image.anchor_y = 0
        return True

    def click(self):
        print('Clicked:',self.name)

    def work(self, *args):
        pass

    def click_check(self, x, y):
        if x > self.x and x < (self.x + self.width):
            if y > self.y and y < (self.y + self.height):
                return self

    def move(self, x, y):
        if self.moveable:
            self.x += x
            self.y += y

    def _draw(self):
        self.draw()

GUI()中你会做:

class GUI(pyglet.window.Window):
    def __init__(self):
        super(GUI, self).__init__(640,340, caption='Test')
        ...
        self.house = House()

    def render(self, *args):

        self.house.rotate(1)
        self.house._draw()

这应该创造一个&#34;房子&#34; (或者其他)并将图片旋转1度以用于每个渲染周期,这意味着您将以每秒60度的速度旋转它并获得良好的流动。

除此之外还有更多的东西,但它是我通常用来挤出FPS同时仍保持可读代码的简化。因为图形很快就会变得混乱。