如何将加载的高度贴图地形保存到文件中并稍后打开文件以节省加载时间?

时间:2015-04-15 18:33:34

标签: python python-2.7 io pygame pyopengl

我一直在使用pickle来保存我想要的任何文件,例如类。它让我以后在启动应用程序时重新加载它们,允许我跳过初始化过程。

然而,当试图保存这个地图类时(我在pygame网站上找到它:它将高度图渲染到pygame / opengl中的地形),我发现地形需要很长时间才能加载。我以为我可以作弊,只在我第一次开始游戏时初始化它,然后将其转储到一个文件(称为map.pom)中,以便在后续游戏开始时使用。这应该让我几乎立即跳入游戏。

但是我遇到了麻烦,因为它根本不会再画在屏幕上了。

以下是我的代码:

地图类:

class glLibObjMap(glLibObj):
    def __init__(self,mapdata,texturing=False,normals=None,heightscalar=1.0):
        texturemap = []
        normalmap = []
        for z in xrange(len(mapdata)):
            normalrow = []
            texturerow = []
            for x in xrange(len(mapdata[0])):
                if normals == GLLIB_VERTEX_NORMALS:
                    Normals = []
                    t = 0
                    flip = True
                    leftpoint = rightpoint = uppoint = downpoint = False
                    normalpoint = (x,  heightscalar*mapdata[z  ][x  ],z  )
                    if x-1 >= 0:                 leftpoint   = (x-1,heightscalar*mapdata[z  ][x-1],z  )#; print "leftpoint", leftpoint
                    if x+1 <= len(mapdata[0])-1: rightpoint  = (x+1,heightscalar*mapdata[z  ][x+1],z  )#; print "rightpoint", rightpoint
                    if z+1 <= len(mapdata)-1:    uppoint     = (x,  heightscalar*mapdata[z+1][x  ],z+1)#; print "uppoint", uppoint
                    if z-1 >= 0:                 downpoint   = (x,  heightscalar*mapdata[z-1][x  ],z-1)#; print "downpoint", downpoint
                    if rightpoint and uppoint:   Normals.append(GetNormal(normalpoint,rightpoint,uppoint,flip))
                    if uppoint and leftpoint:    Normals.append(GetNormal(normalpoint,uppoint,leftpoint,flip))
                    if leftpoint and downpoint:  Normals.append(GetNormal(normalpoint,leftpoint,downpoint,flip))
                    if downpoint and rightpoint: Normals.append(GetNormal(normalpoint,downpoint,rightpoint,flip))
                    xcomp = []; ycomp = []; zcomp = []
                    for n in Normals:
                        xcomp.append(n[0]);ycomp.append(n[1]);zcomp.append(n[2])
                    normal = (sum(xcomp)/len(xcomp),sum(ycomp)/len(ycomp),sum(zcomp)/len(zcomp))
                    l = sqrt((normal[0]**2)+(normal[1]**2)+(normal[2]**2))
                    normal = [normal[0]/l,normal[1]/l,normal[2]/l]
                    normalrow.append(normal)
                if texturing != False:
                    xtexcoord = float(x)/(len(mapdata[0])-1)
                    ytexcoord = float(z)/(len(mapdata)-1)
                    texturerow.append((xtexcoord,ytexcoord))
            normalmap.append(normalrow)
            texturemap.append(texturerow)
        self.list = glGenLists(1)
        glNewList(self.list, GL_COMPILE)
        alreadytexturing = glGetBooleanv(GL_TEXTURE_2D)
        if texturing:
            glLibSelectTexture(texturing)
        for z in xrange(len(mapdata)-1):
            zrow1 = mapdata[z-1]
            zrow2 = mapdata[z-1+1]
            for x in xrange(len(zrow1)-1):
                glBegin(GL_TRIANGLE_FAN)
                # glBegin(GL_LINES)
                if normals == GLLIB_FACE_NORMALS:
                    Normals = []
                    Normals.append(GetNormal((x,  heightscalar*mapdata[z-1 ][x-1  ],z  ),(x,  heightscalar*mapdata[z-1+1][x-1  ],z+1),(x+1,heightscalar*mapdata[z-1  ][x-1+1],z  )))
                    Normals.append(GetNormal((x,  heightscalar*mapdata[z-1+1][x-1  ],z+1),(x+1,heightscalar*mapdata[z-1+1][x-1+1],z+1),(x,  heightscalar*mapdata[z-1  ][x-1  ],z  )))
                    Normals.append(GetNormal((x+1,heightscalar*mapdata[z-1  ][x-1+1],z  ),(x,  heightscalar*mapdata[z-1  ][x-1  ],z  ),(x+1,heightscalar*mapdata[z-1+1][x-1+1],z+1)))
                    Normals.append(GetNormal((x+1,heightscalar*mapdata[z-1+1][x-1+1],z+1),(x+1,heightscalar*mapdata[z-1  ][x-1+1],z  ),(x,  heightscalar*mapdata[z-1+1][x-1  ],z+1)))
                    xcomp = []; ycomp = []; zcomp = []
                    for n in Normals:
                        xcomp.append(n[0]);ycomp.append(n[1]);zcomp.append(n[2])
                    normal = (sum(xcomp)/4.0,sum(ycomp)/4.0,sum(zcomp)/4.0)
                    l = sqrt((normal[0]**2)+(normal[1]**2)+(normal[2]**2))
                    normal = [normal[0]/l,normal[1]/l,normal[2]/l]
                    glNormal3f(*normal)
                if normals == GLLIB_VERTEX_NORMALS: glNormal3f(*normalmap[z-1  ][x-1  ])
                if texturing: glTexCoord2f(*texturemap[z  ][x  ])
                glVertex3f(x,  heightscalar*zrow1[x-1  ],z  )
                if normals == GLLIB_VERTEX_NORMALS: glNormal3f(*normalmap[z-1  ][x-1+1])
                if texturing: glTexCoord2f(*texturemap[z  ][x+1])
                glVertex3f(x+1,heightscalar*zrow1[x-1+1],z  )
                if normals == GLLIB_VERTEX_NORMALS: glNormal3f(*normalmap[z-1+1][x-1+1])
                if texturing: glTexCoord2f(*texturemap[z+1][x+1])
                glVertex3f(x+1,heightscalar*zrow2[x-1+1],z+1)
                if normals == GLLIB_VERTEX_NORMALS: glNormal3f(*normalmap[z-1+1][x-1  ])
                if texturing: glTexCoord2f(*texturemap[z+1][x  ])
                glVertex3f(x,  heightscalar*zrow2[x-1  ],z+1)
                glEnd()
        if alreadytexturing: glEnable(GL_TEXTURE_2D)
        glEndList()
    def draw(self,pos=[0,0,0],rotations=[],scalar=1.0):
        glPushMatrix()
        glTranslatef(*pos)
        for rotation in rotations:
            if rotation[0] != 0: glRotatef(rotation[0],1,0,0)
            if rotation[1] != 0: glRotatef(rotation[1],0,1,0)
            if rotation[2] != 0: glRotatef(rotation[2],0,0,1)
        glScalef(scalar,scalar,scalar)
        glCallList(self.list)
        glPopMatrix()
    def __del__(self):
        del self.list

我的测试程序

from OpenGL import *
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame
from pygame.locals import *
import os, sys
from OpenGLLibrary import *
import pickle

pygame.init()

Screen = (800,600)

Window = glLibWindow(Screen,caption="Map",multisample=True)
View3D = glLibView3D((0,0,Screen[0],Screen[1]),65)
View3D.set_view()

LightFocus = [0,0,0]
LightColor = (255,255,255)
ShadowColor = (153,153,153)
ShadowMapSize = 500

glLibTexturing(True)

glLibLighting(True)
Sun = glLibLight([0,20.0,10],color=LightColor,diffusecolor=ShadowColor)
Sun.enable()

Objects = [glLibObjFromFile("ExamplesData/Spikey.obj"),
           glLibObjFromFile("ExamplesData/UberBall.obj"),
           glLibObjCylinder(0.5,1.0,64),
           glLibObjSphere(64)]
### WHAT ID LIKE TO DO ###


### THIS PART ONLY ON FIRST RUN ###
print 'Loading map...'
Mesh = []
heightmap = pygame.image.load(os.path.join("ExamplesData","heightmap.jpg"))
for x in xrange(heightmap.get_height()):
    xrow = []
    for y in xrange(heightmap.get_height()):
        color = heightmap.get_at((x,y))
        height = color[0]*0.02
        xrow.append(height)
    Mesh.append(xrow)
Map = glLibObjMap(Mesh,texturing=False,normals=GLLIB_VERTEX_NORMALS,heightscalar=10)
pickle.dump(Map, open("ExamplesData/map.pom", 'wb'))
print 'End.'

### THIS PART ON THE NEXT RUNS ###
Map = pickle.load(open("ExamplesData/map.pom", 'rb')) # on other runs


glLibShadowInit([[ShadowMapSize,5]])

# CAMERA ##
pos = [2,-20,2]
amountRotate = [0,0,0,0]
glTranslatef(pos[0],pos[1], pos[2])

print 'Loaded...'

def RenderFloor():
    Map.draw([-100,0,30],[[0,150,0]])
objpos = [2,-100,2]
objectdrawing = 0
def RenderObj():
    Objects[objectdrawing].draw([objpos[0],objpos[1],objpos[2]],scalar=1.0)
def GetInput():
    global CameraRotation, LightPosition, objpos, objectdrawing
    mpress = pygame.mouse.get_pressed()
    mrel = pygame.mouse.get_rel()
    key = pygame.key.get_pressed()
    for event in pygame.event.get():
        if event.type == QUIT or key[K_ESCAPE]:
            pygame.quit(); sys.exit()
        if event.type == KEYDOWN and event.key == K_RETURN:
            objectdrawing += 1
            if objectdrawing == 6:
                objectdrawing = 0
        if event.type == KEYDOWN and (event.key == K_w or event.key == K_UP):
            pos[2] += 5
        elif event.type == KEYDOWN and (event.key == K_a or event.key == K_LEFT):
            pos[0] += 5
        elif event.type == KEYDOWN and (event.key == K_s or event.key == K_DOWN):
            pos[2] -= 5
        elif event.type == KEYDOWN and (event.key == K_d or event.key == K_RIGHT):
            pos[0] -= 5
        elif event.type == KEYDOWN and event.key == K_1:
            amountRotate[0] += 5
        elif event.type == KEYDOWN and event.key == K_2:
            amountRotate[0] -= 5
        elif event.type == KEYDOWN and event.key == K_3:
            amountRotate[1] += 5
        elif event.type == KEYDOWN and event.key == K_4:
            amountRotate[1] -= 5
        elif event.type == KEYDOWN and event.key == K_5:
            amountRotate[2] += 5
        elif event.type == KEYDOWN and event.key == K_6:
            amountRotate[2] -= 5
        elif event.type == KEYDOWN and event.key == K_7:
            amountRotate[3] += 5
        elif event.type == KEYDOWN and event.key == K_8:
            amountRotate[3] -= 5

    if mpress[0]:
        objpos[0] -= 0.1*mrel[0]
        objpos[2] -= 0.1*mrel[1]
    if mpress[2]:
        formerpos = Sun.get_pos()
        Sun.change_pos([formerpos[0]-0.1*mrel[0],formerpos[1],formerpos[2]-0.1*mrel[1]])
def Draw():
    global LightFocus
    #Clear
    Window.clear()
    #glLib step 1
    LightPosition = Sun.get_pos()
    LightFocus = [objpos[0],objpos[1],objpos[2]]
    dist = sqrt(((LightFocus[0]-LightPosition[0])**2)+((LightFocus[1]-LightPosition[1])**2)+((LightFocus[2]-LightPosition[2])**2))
    lightangle = degrees(2*asin((2.9*1.0)/dist))
    near = dist - 2.9
    far = dist + 2.9
    glLibCreateShadowBefore(GLLIB_SHADOW_MAP1,LightPosition,LightFocus,lightviewangle=lightangle,near=near,far=far)
    #Render all objects that should cast shadows
    RenderObj()
    #glLib step 2
    glLibCreateShadowAfter(GLLIB_SHADOW_MAP1)

    #Clear
    Window.clear()
    #Position the camera
    View3D.set_view()
    glTranslatef(pos[0],pos[1], pos[2])
    glRotatef(amountRotate[0],amountRotate[1],amountRotate[2], amountRotate[3])

    #Set the light
    Sun.change_color((153,153,153))
    Sun.change_diffuse_color((255,255,255))
    Sun.draw()
    Sun.draw_as_point()
    #Render everything
    RenderObj()
    RenderFloor()

    #glLib step 3
    glLibRenderShadowCompareBefore(GLLIB_SHADOW_MAP1)
    #Set light color to shadow color
    Sun.change_diffuse_color(ShadowColor)
    #Render all objects where shadows should be cast
    RenderObj()
    RenderFloor()
    #glLib step 4
    glLibRenderShadowCompareAfter()
    #Flip
    Window.flip()
def main():
    while True:
        GetInput()
        Draw()
if __name__ == '__main__': main()

0 个答案:

没有答案