Re: [PyOpenGL-Users] example 3d visualization program
Brought to you by:
mcfletch
|
From: Yannick G. <ygi...@yg...> - 2004-02-15 14:36:03
|
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On February 11, 2004 19:20, Bob Roberts wrote:
> I am looking for a example pyopengl program that can read in a bunch of
> points and display them, with the ability to zoom and rotate. Where can
> I find something like this?
This one is ugly and slow but it's complete except for collision
detection. I dumped the object list from Blender with a small python
plug-in. You I'll post it too if you want but the Blender API is so
simple that I encourage you to write your own so you dump exactly what
you want.
Use the arrow to move the "player" and the wheel to "zoom". If you do
a FPS, change the FOV instead of translating, thats the way a scope
works.
#----8<--------8<--------8<---- cut here ----8<--------8<--------8<----
#!/usr/bin/python
# Author: Yannick Gingras <ygi...@yg...>
# largely based on pygame + PyOpenGL version of Nehe's OpenGL lesson07
# by Paul Furber 2001 - m...@ve...
import os
import math
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame, pygame.image
from pygame.locals import *
from pprint import pprint
from operator import mul, add
WHEEL_UP = 4
WHEEL_DOWN = 5
X = 0
Y = 1
Z = 2
SPEED_INC = 0.05
objs = {'cameras': [{'loc': [0.0, -8.1288509368896484, 0.0],
'name': 'Camera',
'rot': [1.5707966089248657, 0.0, 0.0],
'size': [1.0, 1.0, 1.0]}],
'lamps': [{'col': [1.0, 1.0, 1.0],
'energy': 1.0,
'loc': [-2.917271614074707,
-20.990573883056641,
-5.8118243217468262],
'name': 'Lamp',
'rot': [-1.8678504228591919,
-0.041752655059099197,
-3.1845359802246094],
'size': [1.5281403064727783,
1.5281403064727783,
1.5281403064727783]}],
'meshs': [ {'faces': [{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, 0.99999988079071045, -1.0],
[1.0, -1.0, -0.99999994039535522],
[-1.0000001192092896,
-0.99999988079071045,
-1.0],
[-0.99999958276748657,
1.0000003576278687,
-1.0000001192092896]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352]],
'uvs': [],
'verts': [[1.0000004768371582,
0.9999995231628418,
1.0],
[-1.0, 1.0, 0.99999994039535522],
[-1.0000003576278687,
-0.99999958276748657,
1.0],
[0.9999992847442627,
-1.0000005960464478,
1.0000001192092896]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, 0.99999988079071045, -1.0],
[1.0000004768371582,
0.9999995231628418,
1.0],
[0.9999992847442627,
-1.0000005960464478,
1.0000001192092896],
[1.0, -1.0, -0.99999994039535522]]},
{'image': '',
'normals': [[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, -1.0, -0.99999994039535522],
[0.9999992847442627,
-1.0000005960464478,
1.0000001192092896],
[-1.0000003576278687,
-0.99999958276748657,
1.0],
[-1.0000001192092896,
-0.99999988079071045,
-1.0]]},
{'image': '',
'normals': [[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[-1.0000001192092896,
-0.99999988079071045,
-1.0],
[-1.0000003576278687,
-0.99999958276748657,
1.0],
[-1.0, 1.0, 0.99999994039535522],
[-0.99999958276748657,
1.0000003576278687,
-1.0000001192092896]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352]],
'uvs': [],
'verts': [[1.0000004768371582,
0.9999995231628418,
1.0],
[1.0, 0.99999988079071045, -1.0],
[-0.99999958276748657,
1.0000003576278687,
-1.0000001192092896],
[-1.0, 1.0, 0.99999994039535522]]}],
'loc': [6.7445888519287109,
6.4222369194030762,
-6.185572624206543],
'name': 'Player',
'rot': [1.5707963705062866,
-4.2663355487304599e-17,
1.5707963705062866],
'size': [1.0, 1.0, 1.0]},
{'faces': [{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, 0.99999994039535522, -1.0],
[1.0, -1.0, -1.0],
[-1.0000001192092896,
-0.99999982118606567,
-1.0],
[-0.99999964237213135,
1.0000003576278687,
-1.0]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352]],
'uvs': [],
'verts': [[1.0000004768371582,
0.99999946355819702,
1.0],
[-0.99999994039535522, 1.0, 1.0],
[-1.0000003576278687,
-0.99999964237213135,
1.0],
[0.99999934434890747,
-1.0000005960464478,
1.0]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, 0.99999994039535522, -1.0],
[1.0000004768371582,
0.99999946355819702,
1.0],
[0.99999934434890747,
-1.0000005960464478,
1.0],
[1.0, -1.0, -1.0]]},
{'image': '',
'normals': [[0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[1.0, -1.0, -1.0],
[0.99999934434890747,
-1.0000005960464478,
1.0],
[-1.0000003576278687,
-0.99999964237213135,
1.0],
[-1.0000001192092896,
-0.99999982118606567,
-1.0]]},
{'image': '',
'normals': [[-0.57734918594360352,
-0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
-0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352]],
'uvs': [],
'verts': [[-1.0000001192092896,
-0.99999982118606567,
-1.0],
[-1.0000003576278687,
-0.99999964237213135,
1.0],
[-0.99999994039535522, 1.0, 1.0],
[-0.99999964237213135,
1.0000003576278687,
-1.0]]},
{'image': '',
'normals': [[0.57734918594360352,
0.57734918594360352,
0.57734918594360352],
[0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
-0.57734918594360352],
[-0.57734918594360352,
0.57734918594360352,
0.57734918594360352]],
'uvs': [],
'verts': [[1.0000004768371582,
0.99999946355819702,
1.0],
[1.0, 0.99999994039535522, -1.0],
[-0.99999964237213135,
1.0000003576278687,
-1.0],
[-0.99999994039535522, 1.0, 1.0]]}],
'loc': [-1.3737921714782715,
17.224937438964844,
3.9241774082183838],
'name': 'Cube',
'rot': [1.5708620548248291,
1.3671789395042211e-16,
1.3672688044059689e-16],
'size': [1.0, 1.0, 1.0]}]}
xrot = yrot = 0.0
xspeed = yspeed = zspeed = 0.0
z = 0.0
textures = []
texMap = {}
filter = 0
light = 0
zoom = 0.0
LightAmbient = ( (0.5, 0.5, 0.5, 1.0) );
LightDiffuse = ( (1.0, 1.0, 1.0, 1.0) );
LightPosition = ( (0.0, 0.0, 2.0, 1.0) );
def resize((width, height)):
if height==0:
height=1
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45, 1.0*width/height, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def getTexMap():
texMap = {}
for obj in objs["meshs"]:
for face in obj["faces"]:
if face["image"]:
texMap[face["image"]] = None
return texMap
def load_textures():
global textures, texMap
texMap = getTexMap()
textures = glGenTextures(len(texMap.keys()))
# undo the magic
try:
len(textures)
except TypeError:
textures = [textures]
for key, tex in zip(texMap.keys(), textures):
texMap[key] = tex
texturefile = os.path.join(os.curdir, key)
textureSurface = pygame.image.load(texturefile)
textureData = pygame.image.tostring(textureSurface, "RGBX", 1)
glBindTexture(GL_TEXTURE_2D, tex)
glTexParameteri( GL_TEXTURE_2D,
GL_TEXTURE_MIN_FILTER,
GL_LINEAR )
glTexParameteri( GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_LINEAR )
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA,
textureSurface.get_width(),
textureSurface.get_height(),
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
textureData )
def init():
glEnable(GL_TEXTURE_2D)
load_textures()
glShadeModel(GL_SMOOTH)
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LEQUAL)
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
lamps = objs["lamps"]
if len(lamps) > GL_MAX_LIGHTS:
raise Exception("To many lamps !")
for lamp, i in zip(lamps, range(len(lamps))):
glLightfv( GL_LIGHT0 + i, GL_AMBIENT, LightAmbient )
glLightfv( GL_LIGHT0 + i, GL_DIFFUSE, LightDiffuse )
glLightfv( GL_LIGHT0 + i, GL_POSITION, lamp["loc"] + [1.0] )
glEnable( GL_LIGHT0 + i )
glEnable(GL_LIGHTING)
def rad2deg(radAngle):
degs = radAngle * 360.0 / math.pi / 2.0
return degs
def draw():
global xrot, yrot, xspeed, yspeed, z, filter, texMap
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# we always use the 1st camera
cam = objs["cameras"][0]
for obj in objs["meshs"]:
glLoadIdentity()
# cam use rev. coords
# I don't know why but Z must rotate 1st
glRotated(-rad2deg(cam["rot"][Z]), 0.0, 0.0, 1.0)
glRotated(-rad2deg(cam["rot"][Y]), 0.0, 1.0, 0.0)
glRotated(-rad2deg(cam["rot"][X])+xrot, 1.0, 0.0, 0.0)
glTranslatef( -cam["loc"][X],
-cam["loc"][Y] - zoom,
-cam["loc"][Z] )
loc = list(obj["loc"])
loc[2] += z
glTranslatef(*loc)
# I don't know why but Z must rotate 1st
glRotated(rad2deg(obj["rot"][Z]), 0.0, 0.0, 1.0)
glRotated(rad2deg(obj["rot"][Y]), 0.0, 1.0, 0.0)
glRotated(rad2deg(obj["rot"][X]), 1.0, 0.0, 0.0)
for face in obj["faces"]:
image = face["image"]
if image:
glBindTexture(GL_TEXTURE_2D, texMap[image])
else:
glColor3f(1.0, 1.0, 1.0)
glBegin(GL_POLYGON)
uvs = (face["uvs"] or [None] * len(face["verts"]))
for vert, normal, uv in zip(face["verts"],
face["normals"],
uvs):
vert = map(mul, vert, obj["size"])
glNormal3f(*normal)
if image:
glTexCoord2f(*uv)
glVertex3f(*vert)
glEnd();
def getPlayer():
for mesh in objs["meshs"]:
if mesh["name"] == "Player":
return mesh
def handle_keys(key):
global filter, light, z, xspeed, yspeed, zspeed, xrot
if key == K_ESCAPE:
return 0
if key == K_f:
filter = filter + 1
if filter == 3:
filter = 0
elif key == K_PAGEUP:
z -= 0.5
elif key == K_PAGEDOWN:
z += 0.5
elif key == K_UP:
zspeed += SPEED_INC
elif key == K_DOWN:
zspeed -= SPEED_INC
elif key == K_RIGHT:
xspeed += SPEED_INC
elif key == K_LEFT:
xspeed -= SPEED_INC
return 1
def handle_key_up(key):
global filter, light, z, xspeed, yspeed, zspeed, xrot
if key == K_UP:
zspeed -= SPEED_INC
elif key == K_DOWN:
zspeed += SPEED_INC
elif key == K_RIGHT:
xspeed -= SPEED_INC
elif key == K_LEFT:
xspeed += SPEED_INC
def move_player():
player = getPlayer()
player["loc"][Z] += zspeed
player["loc"][X] += xspeed
def handle_mouse(event):
global zoom
zoomFact = 0.5
if event.button == WHEEL_UP:
zoom += zoomFact
elif event.button == WHEEL_DOWN:
zoom -= zoomFact
def main():
video_flags = OPENGL|DOUBLEBUF
pygame.init()
surface = pygame.display.set_mode((640,480), video_flags)
resize((640,480))
init()
frames = 0
ticks = pygame.time.get_ticks()
while 1:
event = pygame.event.poll()
if event.type == QUIT:
break
if event.type == KEYDOWN:
if handle_keys(event.key) == 0:
break
if event.type == KEYUP:
handle_key_up(event.key)
if event.type == MOUSEBUTTONDOWN:
handle_mouse(event)
move_player()
draw()
pygame.display.flip()
frames = frames+1
print "fps: %d" % ((frames*1000)/(pygame.time.get_ticks()-ticks))
if __name__ == '__main__': main()
#----8<--------8<--------8<---- cut here ----8<--------8<--------8<----
- --
Yannick Gingras "please call it ``GNU/Linux''"
Coder for OBB : Overhead Bloodshot Berit -- Richard M. Stallman
http://OpenBeatBox.org
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
iD8DBQFAL4MUZJ8/OobqizMRAqvdAJkBRdHnQZQqL/AZpg2KOtLYRfqFuQCgozpG
jZen8EA1Pdma4ZizPDQUYPE=
=2eHy
-----END PGP SIGNATURE-----
|