我一直在使用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()