[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
Re: [pygame] PyOpenGL Screenshots
Here it is. I didn't spend any time making this code nice, but you can
just rip out the parts you need.
2008/5/8 Alistair Buxton <a.j.buxton@xxxxxxxxx>:
> I have a full example of doing exactly this task using python to
> render to a series of png images (which you can load into something
> like adobe premier), or a raw RV24 file (which you can transcode under
> linux using... transcode). Will post it as soon as I've dug it out and
> tested it still works. Includes examples of using transcode too.
>
> 2008/5/8 Ian Mallett <geometrian@xxxxxxxxx>:
>
>
> > I figured out a way to do it in my program--Animation Shop Pro. It would
> > still be cool to have examples of how to do this without Animation Shop. I
> > was thinking ffmpeg or pil for doing so. I looked around, but couldn't find
> > anything.
> > Thanks everyone,
> > Ian
> >
>
>
>
> --
> Alistair Buxton
> a.j.buxton@xxxxxxxxx
>
--
Alistair Buxton
a.j.buxton@xxxxxxxxx
#!/usr/bin/env python
# Python OpenGL -> Video file
# (c) 2008 Alistair Buxton <a.j.buxton@xxxxxxxxx>
# Handy for doing procedural animations for compositing with other
# videos in <your favourite video editing package.>
import os, random, math
from OpenGL.GL import *
from OpenGL.GLU import *
import pygame, pygame.image, pygame.key
from pygame.locals import *
from PIL import Image
######################################################################################
# render settings
# 1 = best
QUALITY = 16
# whether to actually write output files or just preview
render_on = True
# If you don't want to write separate png files, you can just dump the output
# from glReadPixels() into one huge file and encode it with transcode:
# transcode --use_rgb -i whatever.rv24 -x raw=RGB,null -y xvid4 -o output.xvid.avi -k -z -f 25
# (for xvid)
# But beware that whatever.rv24 will be HUGE as it is uncompressed (not even RLE).
# the size will be width*height*numframes*3 bytes, that's 31mb/sec for standard PAL video.
# Also worth mentioning: RV24 export is RGB, but png export is RGBA - thus if you use
# RV24 method, you will loose the alpha channel of your video.
# render type
# if true, write one big RV24 raw video file
# if false, write a png sequence
render_rv24 = False
if render_on:
# size of final render
w = 720
h = 576
else:
# size for preview
w = 720
h = 576
# how many frames to render before exiting
max_frames = 25
# framerate of rendered video
fps = 25.0
if render_rv24:
framefile = file("whatever.rv24", "wb")
######################################################################################
# the snowflake animation stuff
flakes = []
class SnowFlake(object):
def __init__(self):
self.x = random.randrange(0,720)
self.y = random.randrange(0,576)
self.z = 3 + (random.randrange(3,20) / random.randrange(3,25))
self.dy = random.randrange(1,10)
self.drift = random.randrange(1,100)/1000.0
self.rad = random.randrange(1,100)/100.0
def draw(self):
glColor4f(1.0,1.0,1.0,1.0)
if self.z < 0:
return
glBegin(GL_POLYGON)
r = math.floor(self.z * 4)
for i in range(int(r)):
glVertex2f( self.x+(self.z*math.sin(2*math.pi*(i/r))), self.y+(self.z*math.cos(2*math.pi*(i/r))) )
glVertex2f( self.x, self.y+self.z )
glEnd()
def update(self, ftime):
self.rad += ((ftime*0.5)+self.drift)
self.x += math.sin(self.rad)
self.y -= 0.7*ftime*(40.0+self.dy)*self.z;
if (self.y < -10):
self.y = 586
if (self.x < -10):
self.x = 730
if (self.x > 730):
self.x = -10
# standard opengl stuff init/draw/update/resize
def resize((width, height)):
if height==0:
height=1.0
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, 720, 0, 576)
# gluOrtho2D(-(width/(2*height)), width/(2*height), 0, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
def init():
glShadeModel(GL_SMOOTH)
glClearColor(0.3,0.5,0.7,0.0)
glClearDepth(1.0)
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
glDisable(GL_DEPTH_TEST)
for i in range(100):
flakes.append(SnowFlake())
def update(ftime):
for f in flakes:
f.update(ftime)
def draw():
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glDisable(GL_TEXTURE_2D)
for f in flakes:
f.draw()
#######################################################################################
# write a png file from GL framebuffer data
def png_file_write(name, number, data):
im = Image.frombuffer("RGBA", (720,576), data, "raw", "RGBA", 0, 0)
fnumber = "%05d" % number
im.save(name + fnumber + ".png")
######################################################################################
# main
def main():
video_flags = OPENGL|DOUBLEBUF#|FULLSCREEN
pygame.init()
surface = pygame.display.set_mode((w,h), video_flags)
pygame.key.set_repeat(100,30)
resize((w,h))
init()
frames = 0
done = 0
ftime = 0
oldticks = newticks = ticks = pygame.time.get_ticks()
while not done:
while 1:
event = pygame.event.poll()
if event.type == NOEVENT:
break
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
done = 1
if event.type == QUIT:
done = 1
draw()
########### This is where the output gets written ###########
# NOTE: the GL_RGB / GL_RGBA difference
if render_on == 1:
if render_rv24:
framefile.write(glReadPixels(0,0, w, h, GL_RGB, GL_UNSIGNED_BYTE))
else:
png_file_write("snow", frames, glReadPixels( 0,0, w, h, GL_RGBA, GL_UNSIGNED_BYTE))
pygame.display.flip()
newticks = pygame.time.get_ticks()
# if rendering then set the frame time to fixed amount
if render_on == 1:
thistime = 1.0 / fps # change this to the desired framerate of your video!
# else if previewing, use varying frame length to approximate actual output
else:
thistime = (newticks - oldticks) / 1000.0
oldticks = newticks
ftime += thistime
frames += 1
update(thistime)
print "frame %d : ftime %f" % (frames,ftime)
if (frames) > max_frames:
if render_on == 1:
break
else:
pass
if __name__ == '__main__': main()