Python 3D引擎延迟

时间:2018-01-23 10:58:55

标签: python 3d

最近我一直想学习如何编写3D渲染引擎,我在YouTube上找到了如何在pygame中进行教程,这是python的附加组件,它运行正常,但问题是,一旦你正在逐渐渲染100多个块,它变得非常“滞后”,并且FPS下降到大约30左右,并且在添加更多块时从那时开始变得更糟。

我的问题是:如果一次渲染大量的块,我如何使代码更有效或更好地消除滞后。

这是我的代码。

import pygame, sys, math, time #Imports the required Add-Ons needed for the code

def rotate2d(pos,rad):
    x,y=pos; s,c = math.sin(rad),math.cos(rad); return x*c-y*s,y*c+x*s

class Cam():
    def __init__(self,pos=(0,0,0),rot=(0,0)):
        self.pos = list(pos)
        self.rot = list(rot)
    def events(self,event):
        if event.type == pygame.MOUSEMOTION:
            x,y = event.rel
            x/=200; y/=200
            self.rot[0]+=y; self.rot[1]+=x
            if self.rot[0] > math.pi/2:
                self.rot[0] = math.pi/2
            if self.rot[0] < -math.pi/2:
                self.rot[0] = -math.pi/2
    def update(self,dt,key):
        s=dt*10
        if key[pygame.K_SPACE]: self.pos[1]-=s
        if key[pygame.K_LSHIFT]: self.pos[1]+=s
        x,y = s*math.sin(self.rot[1]),s*math.cos(self.rot[1])
        if key[pygame.K_w]: self.pos[0]+=x; self.pos[2]+= y
        if key[pygame.K_s]: self.pos[0]-=x; self.pos[2]-= y
        if key[pygame.K_a]: self.pos[0]-=y; self.pos[2]+= x
        if key[pygame.K_d]: self.pos[0]+=y; self.pos[2]-= x

pygame.init() #Initialises PyGame
pygame.font.init()
myfont = pygame.font.SysFont('', 30)
w,h = 1440,900 #Width and height of the screen
cx,cy = w//2,h//2 #Co-ords of the middle of the screen
screen = pygame.display.set_mode((w,h))
screen = pygame.display.set_mode((w,h), pygame.FULLSCREEN)

clock = pygame.time.Clock()

class Cube:
    vertices=[(-1,1,-1),(1,1,-1),(1,-1,-1),(-1,-1,-1),(-1,1,1),(1,1,1),(1,-1,1),(-1,-1,1)]
    edges= [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(3,7),(2,6)]

    def __init__(self,pos=(0,0,0)):
        x,y,z = pos
        self.verts = [(x+X/2,y+Y/2,z+Z/2) for X,Y,Z in self.vertices]

cam = Cam((0,0,-5))

cubes_p = [(0,-10,0),(0,-10,1),(1,-10,0),(1,-10,1),(2,0,0),(2,0,1),(3,0,0),(3,0,1),(0,+10,0),(0,+10,1),(1,+10,0),(1,+10,1),(0,-11,-1),(0,-11,0),(1,-11,-1),(1,-11,0),(0,-12,-1),(0,-12,0),(1,-12,-1),(1,-12,0)]
cubes = [Cube(cubes_p[i])for i in range(0,len(cubes_p))]

pygame.event.get(); pygame.mouse.get_rel()
pygame.mouse.set_visible(0); pygame.event.set_grab(1)

ctime = time.time()-1

Colour = 0, 0, 0


while True:
    key = pygame.key.get_pressed()
    ptime = ctime
    ctime = time.time()
    fps = int(1/(ctime-ptime))
    #dt = clock.tick()/1000
    dt = (ctime-ptime)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        cam.events(event)
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit(); sys.exit()
    screen.fill((0,0,0))
    for obj in cubes:
        for edge in obj.edges:
            points = []
            disp = True
            for x,y,z in (obj.verts[edge[0]],obj.verts[edge[1]]):
                x-=cam.pos[0]
                y-=cam.pos[1]
                z-=cam.pos[2]
                x,z = rotate2d((x,z),cam.rot[1])
                y,z = rotate2d((y,z),cam.rot[0])
                f = 400/z
                x,y = x*f, y*f
                if z <= 0:
                    disp = False
                points+=[(cx+int(x),cy+int(y))]
            if disp:
                pygame.draw.line(screen,colour,points[0],points[1],1)
    pygame.draw.line(screen,(200,200,200),(cx,cy-6),(cx,cy+6),1)
    pygame.draw.line(screen,(200,200,200),(cx-6,cy),(cx+6,cy),1)
    textsurface = myfont.render(str(fps)+ '   ' +str(round(cam.pos[0]))+ ',' +str(-(round(cam.pos[1]+2)))+ ',' +str(round(cam.pos[2])), 1, (255,255,255))
    wid,hgt = textsurface.get_width(),textsurface.get_height()
    screen.blit(textsurface,(w-wid,0))
    pressed1, pressed2, pressed3 = pygame.mouse.get_pressed() #P1 = LC, P2 = MC, P3 = RC
    if pressed1:
        if (round(cam.pos[0]),round(cam.pos[1]+2),round(cam.pos[2])) in cubes_p:
            del cubes_p[len(cubes_p)-1]
        cubes_p.append((round(cam.pos[0]),round(cam.pos[1]+2),round(cam.pos[2])))
    if key[pygame.K_RETURN]: cubes_p = []; cubes_p.append((0,0,0))
    cubes = [Cube(cubes_p[i])for i in range(0,len(cubes_p))]
    print(len(cubes))
    if (len(cubes_p)) > 200:
        del cubes_p[0]
    pygame.display.flip()
    key = pygame.key.get_pressed()
    cam.update(dt,key)
    #clock.tick(60)

很抱歉,如果这是一个巨大的代码块或一个糟糕的问题,我真的不知道该怎么做。 PS:我评论时非常糟糕,再次抱歉

0 个答案:

没有答案