Thread: [PyOpenGL-Users] example 3d visualization program
Brought to you by:
mcfletch
From: Bob R. <bob...@co...> - 2004-02-12 00:21:45
|
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? |
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----- |