Initial revision

This commit is contained in:
Guido van Rossum 1992-03-30 13:18:37 +00:00
parent 6da6aebfdb
commit 453bd408bd
18 changed files with 2990 additions and 0 deletions

29
Demo/sgi/gl/README Normal file
View file

@ -0,0 +1,29 @@
These demos run only on SGI machines and require the 'gl' built-in module.
The demonstrate the abilities of SGI's GL library as well as the ease of
GL programming in Python. Most demos require the Z-buffer (aka
24-bitplane) option. Press ESC to get out of any of them.
backface.py Demonstrates the 'backface' GL function.
kites.py Show 3 flying kites. Demonstrates the rendering speed
obtainable by Python programs.
mclock.py A colorful clock with more options than you can
remember. Works on 8-bit machines, but allows more
colors on 24-bit machines. See mclock.doc for more
info.
mixing.py Demonstrates the effect of color mixing: through
frequent color switching it gives the effect of white
light.
nurbs.py A simple demonstration of the 'nurbs' GL functions.
Press left mouse button to toggle surface trimming.
zrgb.py Displays a 3-D Gouraud-shaded figure which can be moved
around with the mouse.
glstdwin/ This is quite different: a partial STDWIN emulation
using GL! Requires only small changes to Python
programs that use STDWIN. Some features not yet
implemented, e.g., scroll bars.

140
Demo/sgi/gl/backface.py Executable file
View file

@ -0,0 +1,140 @@
#! /usr/local/python
# backface
#
# draw a cube that can run with backface() turned on or off.
# cube is moved when LEFTMOUSE is pressed and mouse itself is moved.
from gl import *
from DEVICE import *
from GL import *
CUBE_SIZE = 200.0
CUBE_OBJ = 1
def main () :
#
x = 0
y = 0
moveit = 0
#
initialize()
#
while (1) :
#
while (qtest()) :
dev, val = qread()
#
if dev == ESCKEY :
backface(0)
return
#
elif dev == REDRAW :
reshapeviewport()
drawcube(x,y)
#
elif dev == LEFTMOUSE :
#
# LEFTMOUSE down
moveit = val
#
elif dev == BKEY :
backface(1)
drawcube(x,y)
#
elif dev == FKEY :
backface(0)
drawcube(x,y)
#
if moveit :
x = getvaluator(MOUSEX)
y = getvaluator(MOUSEY)
drawcube(x,y)
def initialize () :
foreground ()
keepaspect (1, 1)
gid = winopen('backface')
winset(gid)
winconstraints()
#
doublebuffer()
gconfig()
shademodel(FLAT)
#
ortho(-1024.0, 1024.0, -1024.0, 1024.0, -1024.0, 1024.0)
#
qdevice(ESCKEY)
qdevice(REDRAW)
qdevice(LEFTMOUSE)
qdevice(BKEY)
qdevice(FKEY)
qenter(REDRAW,gid)
#
backface(1)
#
# define a cube
def cube () :
#
# front face
pushmatrix()
translate(0.0,0.0,CUBE_SIZE)
color(RED)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
#
# right face
pushmatrix()
translate(CUBE_SIZE, 0.0, 0.0)
rotate(900, 'y')
color(GREEN)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
#
# back face
pushmatrix()
translate(0.0, 0.0, -CUBE_SIZE)
rotate(1800, 'y')
color(BLUE)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
#
# left face
pushmatrix()
translate(-CUBE_SIZE, 0.0, 0.0)
rotate(-900, 'y')
color(CYAN)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
#
# top face
pushmatrix()
translate(0.0, CUBE_SIZE, 0.0)
rotate(-900, 'x')
color(MAGENTA)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
#
# bottom face
pushmatrix()
translate(0.0, -CUBE_SIZE, 0.0)
rotate(900, 'x')
color(YELLOW)
rectf(-CUBE_SIZE,-CUBE_SIZE,CUBE_SIZE,CUBE_SIZE)
popmatrix()
def drawcube(x,y) :
#
pushmatrix()
rotate(2*x, 'x')
rotate(2*y, 'y')
color(BLACK)
clear()
cube()
popmatrix()
swapbuffers()
main ()

View file

@ -0,0 +1,34 @@
import stdwingl
import stdwin
from stdwinevents import *
def main():
size = 12
w = stdwin.open('Font chart ' + `size`)
while 1:
type, window, detail = stdwin.getevent()
if type == WE_CLOSE:
break
if type == WE_DRAW:
width, height = w.getwinsize()
d = w.begindrawing()
d.setsize(size)
h, v = 0, 0
for c in range(32, 256):
ch = chr(c)
chw = d.textwidth(ch)
if h + chw > width:
v = v + d.lineheight()
h = 0
if v >= height:
break
d.text((h, v), ch)
h = h + chw
del d
if type == WE_MOUSE_UP:
size = size + 1
w.settitle('Font chart ' + `size`)
w.change((0, 0), (2000, 2000))
main()

View file

@ -0,0 +1,135 @@
# Define drawing operations for GL stdwin
import gl
import fm
from GL import LO_XOR, LO_SRC
from glstdwin import MASK
class DrawingObject:
#
def _init(self, win):
self.fg = win._fg
self.bg = win._bg
self.font = win._font
self.size = win._size
self.width, self.height = win._area[1]
gl.winset(win._gid)
gl.color(self.fg)
return self
#
def setfont(self, fontname):
self.font = fm.findfont(fontname).scalefont(self.size)
#
def setsize(self, size):
ratio = float(size) / float(self.size)
self.size = size
self.font = self.font.scalefont(ratio)
#
def setfgcolor(self, color):
self.fg = color
gl.color(self.fg)
#
def setbgcolor(self, color):
self.bg = color
#
def cliprect(self, area):
#print 'cliprect', area
(left, top), (right, bottom) = area
gl.scrmask(left, right, self.height-bottom, self.height-top)
#
def noclip(self):
#print 'noclip()'
gl.scrmask(0, self.width, 0, self.height)
#
def paint(self, ((left, top), (right, bottom))):
gl.rectf(left, top, right, bottom)
#
def box(self, ((left, top), (right, bottom))):
#print 'box', ((left, top), (right, bottom))
gl.rect(left, top, right, bottom)
#
def circle(self, ((h, v), radius)):
gl.circ(h, v, radius)
#
def elarc(self, (center, (rh, rv), a1, a2)):
pass # XXX
#
def erase(self, ((left, top), (right, bottom))):
#print 'erase', ((left, top), (right, bottom))
gl.color(self.bg)
gl.rectf(left, top, right, bottom)
gl.color(self.fg)
#
def invert(self, ((left, top), (right, bottom))):
#print 'invert', ((h0, v0), (h1, v1))
gl.logicop(LO_XOR)
gl.color(self.bg)
gl.rectf(left, top, right, bottom)
gl.color(self.fg)
gl.logicop(LO_SRC)
#
def line(self, ((h0, v0), (h1, v1))):
#print 'line', ((h0, v0), (h1, v1))
gl.bgnline()
gl.v2i(h0, v0)
gl.v2i(h1, v1)
gl.endline()
#
def xorline(self, ((h0, v0), (h1, v1))):
#print 'xorline', ((h0, v0), (h1, v1))
gl.logicop(LO_XOR)
gl.color(self.bg)
gl.bgnline()
gl.v2i(h0, v0)
gl.v2i(h1, v1)
gl.endline()
gl.color(self.fg)
gl.logicop(LO_SRC)
#
def point(self, (h, v)):
#print 'point', (h, v)
gl.bgnpoint()
gl.v2i(h, v)
gl.endpoint()
#
def text(self, ((h, v), string)):
#print 'text', ((h, v), string)
if h < 0:
# If the point is outside the window
# the whole string isn't drawn.
# Skip the beginning of the string.
# XXX What if the font is bigger than 20 pixels?
i, n = 0, len(string)
while h < -MASK and i < n:
h = h + self.font.getstrwidth(string[i])
i = i + 1
string = string[i:]
gl.cmov2(h, v + self.baseline())
self.font.setfont()
fm.prstr(string)
#
def shade(self, ((h, v), percent)):
pass # XXX
#
def baseline(self):
(printermatched, fixed_width, xorig, yorig, xsize, ysize, \
height, nglyphs) = self.font.getfontinfo()
return height - yorig
#
def lineheight(self):
(printermatched, fixed_width, xorig, yorig, xsize, ysize, \
height, nglyphs) = self.font.getfontinfo()
return height
#
def textbreak(self, (string, width)):
# XXX Slooooow!
n = len(string)
nwidth = self.textwidth(string[:n])
while nwidth > width:
n = n-1
nwidth = self.textwidth(string[:n])
return n
#
def textwidth(self, string):
return self.font.getstrwidth(string)
#

View file

@ -0,0 +1,400 @@
# GL STDWIN
#
# See stdwingl for a convenient hack to use this instead of built-in stdwin
# without modifying your application, except for one line in the main file.
#
# Intrinsic differences with built-in stdwin (hard or impossible to fix):
# - Need to call w.close() to close a window !!!
# - Need to call m.close() to remove a menu !!!
# - Doesn't enforce the existence of at most one drawing object
# - No textedit package
# - No X11 selections
#
# Not yet implemented:
# - shade drawing
# - elliptical arc drawing (need to play with transformation)
# - more than one mouse button
# - scroll bars (need to redo viewport handling to get this)
# - partial redraws
# - dialog boxes
# - timer events
# - cursors
#
# Extra features:
# - color (for now, you need to know the colormap index)
import gl
import fm
from GL import *
from DEVICE import *
from stdwinevents import *
# Customizable constants
#
DEF_FONT = 'Times-Roman' # Default font
DEF_SIZE = 12 # Default font size (points)
MASK = 20 # Viewport minus scrmask
# A structure to hold global variables
#
class Struct: pass
G = Struct()
#
G.queue = [] # Pending STDWIN events
G.drawqueue = [] # Windows that need WE_REDRAW
G.windowmap = {} # Map window id to window object
G.windowmap['0'] = None # For convenience
G.focus = None # Input focus
G.fg = BLACK # Foreground color
G.bg = WHITE # Background color
G.def_size = 0, 0 # Default window size
G.def_pos = 0, 0 # Default window position
#
G.size = DEF_SIZE
G.font = fm.findfont(DEF_FONT).scalefont(G.size)
# Initialize GL
#
gl.foreground()
gl.noport()
dummygid = gl.winopen('')
# Ask for all sorts of events
#
# Both REDRAW (= resize and/or redraw!) and INPUTCHANGE are implicitly queued
#qdevice(REDRAW)
#qdevice(INPUTCHANGE)
#
# Keyboard
gl.qdevice(KEYBD)
gl.qdevice(LEFTARROWKEY)
gl.qdevice(RIGHTARROWKEY)
gl.qdevice(UPARROWKEY)
gl.qdevice(DOWNARROWKEY)
gl.qdevice(LEFTALTKEY)
gl.qdevice(RIGHTALTKEY)
#
# Mouse
gl.qdevice(LEFTMOUSE)
#gl.qdevice(MIDDLEMOUSE)
gl.qdevice(RIGHTMOUSE) # Menu button
# NB MOUSEX, MOUSEY events are queued on button down
#
# Window close requests
gl.qdevice(WINQUIT)
gl.qdevice(WINSHUT)
#
# These aren't needed
#gl.qdevice(TIMER0)
#gl.qdevice(WINFREEZE)
#gl.qdevice(WINTHAW)
#gl.qdevice(REDRAWICONIC)
# STDWIN: create a new window
#
def open(title):
h, v = G.def_pos
width, height = G.def_size
if h > 0 or v > 0:
# Choose arbitrary defaults
if h < 0: h = 10
if v < 0: v = 30
if width <= 0: width = 400
if height <= 0: height = 300
gl.prefposition(h, h+width, 1024-v, 1024-v-height)
elif width > 0 or height > 0:
if width <= 0: width = 400
if height <= 0: height = 300
gl.prefsize(width, height)
from glstdwwin import WindowObject
win = WindowObject()._init(title)
G.windowmap[`win._gid`] = win
return win
# STDWIN: set default initial window position (0 means use default)
#
def setdefwinpos(h, v):
G.def_pos = h, v
# STDWIN: set default window size (0 means use default)
#
def setdefwinsize(width, height):
G.def_size = width, height
# STDWIN: beep or ring the bell
#
def fleep():
gl.ringbell()
# STDWIN: set default foreground color
#
def setfgcolor(color):
G.fg = color
# STDWIN: set default background color
#
def setbgcolor(color):
G.bg = color
# STDWIN: get default foreground color
#
def getfgcolor():
return G.fgcolor
# STDWIN: get default background color
#
def getbgcolor():
return G.bgcolor
# Table mapping characters to key codes
#
key2code = key = {}
key['A'] = AKEY
key['B'] = BKEY
key['C'] = CKEY
key['D'] = DKEY
key['E'] = EKEY
key['F'] = FKEY
key['G'] = GKEY
key['H'] = HKEY
key['I'] = IKEY
key['J'] = JKEY
key['K'] = KKEY
key['L'] = LKEY
key['M'] = MKEY
key['N'] = NKEY
key['O'] = OKEY
key['P'] = PKEY
key['Q'] = QKEY
key['R'] = RKEY
key['S'] = SKEY
key['T'] = TKEY
key['U'] = UKEY
key['V'] = VKEY
key['W'] = WKEY
key['X'] = XKEY
key['Y'] = YKEY
key['Z'] = ZKEY
key['0'] = ZEROKEY
key['1'] = ONEKEY
key['2'] = TWOKEY
key['3'] = THREEKEY
key['4'] = FOURKEY
key['5'] = FIVEKEY
key['6'] = SIXKEY
key['7'] = SEVENKEY
key['8'] = EIGHTKEY
key['9'] = NINEKEY
del key
#
code2key = {}
codelist = []
for key in key2code.keys():
code = key2code[key]
code2key[`code`] = key
codelist.append(code)
del key
# STDWIN: wait for the next event
#
commands = {}
commands['\r'] = WC_RETURN
commands['\b'] = WC_BACKSPACE
commands['\t'] = WC_TAB
#
def getevent():
while 1:
#
# Get next event from the processed queue, if any
#
if G.queue:
event = G.queue[0]
del G.queue[0]
#print 'getevent from queue -->', event
return event
#
# Get next event from the draw queue, if any,
# but only if there is nothing in the system queue.
#
if G.drawqueue and not gl.qtest():
win = G.drawqueue[0]
del G.drawqueue[0]
gl.winset(win._gid)
gl.color(win._bg)
gl.clear()
event = WE_DRAW, win, win._area
#print 'getevent from drawqueue -->', event
return event
#
# Get next event from system queue, blocking if necessary
# until one is available.
# Some cases immediately return the event, others do nothing
# or append one or more events to the processed queue.
#
dev, val = gl.qread()
#
if dev == REDRAW:
win = G.windowmap[`val`]
old_area = win._area
win._fixviewport()
win._needredraw()
if old_area <> win._area:
#print 'getevent --> WE_SIZE'
return WE_SIZE, win, None
elif dev == KEYBD:
if val == 3:
raise KeyboardInterrupt # Control-C in window
character = chr(val)
if commands.has_key(character):
return WE_COMMAND, G.focus, commands[character]
return WE_CHAR, G.focus, character
elif dev == LEFTARROWKEY:
if val:
return WE_COMMAND, G.focus, WC_LEFT
elif dev == RIGHTARROWKEY:
if val:
return WE_COMMAND, G.focus, WC_RIGHT
elif dev == UPARROWKEY:
if val:
return WE_COMMAND, G.focus, WC_UP
elif dev == DOWNARROWKEY:
if val:
return WE_COMMAND, G.focus, WC_DOWN
elif dev in (LEFTALTKEY, RIGHTALTKEY):
if val:
for code in codelist:
gl.qdevice(code)
else:
for code in codelist:
gl.unqdevice(code)
elif dev in codelist:
if val:
event = G.focus._doshortcut(code2key[`dev`])
if event:
return event
elif dev == LEFTMOUSE:
G.mousex = gl.getvaluator(MOUSEX)
G.mousey = gl.getvaluator(MOUSEY)
if val:
type = WE_MOUSE_DOWN
gl.qdevice(MOUSEX)
gl.qdevice(MOUSEY)
else:
type = WE_MOUSE_UP
gl.unqdevice(MOUSEX)
gl.unqdevice(MOUSEY)
return _mouseevent(type)
elif dev == MOUSEX:
G.mousex = val
return _mouseevent(WE_MOUSE_MOVE)
elif dev == MOUSEY:
G.mousey = val
return _mouseevent(WE_MOUSE_MOVE)
elif dev == RIGHTMOUSE: # Menu button press/release
if val: # Press
event = G.focus._domenu()
if event:
return event
elif dev == INPUTCHANGE:
if G.focus:
G.queue.append(WE_DEACTIVATE, G.focus, None)
G.focus = G.windowmap[`val`]
if G.focus:
G.queue.append(WE_ACTIVATE, G.focus, None)
elif dev in (WINSHUT, WINQUIT):
return WE_CLOSE, G.windowmap[`val`], None
else:
print '*** qread() --> dev:', dev, 'val:', val
# Helper routine to construct a mouse (up, move or down) event
#
def _mouseevent(type):
gl.winset(G.focus._gid)
orgx, orgy = gl.getorigin()
sizex, sizey = gl.getsize()
x = G.mousex - orgx
y = G.mousey - orgy
return type, G.focus, ((x, sizey-y), 1, 0, 0)
# STDWIN: text measuring functions
def baseline():
(printermatched, fixed_width, xorig, yorig, xsize, ysize, \
height, nglyphs) = G.font.getfontinfo()
return height - yorig
def lineheight():
(printermatched, fixed_width, xorig, yorig, xsize, ysize, \
height, nglyphs) = G.font.getfontinfo()
return height
def textbreak(string, width):
# XXX Slooooow!
n = len(string)
nwidth = textwidth(string[:n])
while nwidth > width:
n = n-1
nwidth = textwidth(string[:n])
return n
def textwidth(string):
return G.font.getstrwidth(string)
# STDWIN: set default font and size
def setfont(fontname):
G.font = fm.findfont(fontname).scalefont(G.size)
def setsize(size):
ratio = float(size) / float(G.size)
G.size = size
G.font = G.font.scalefont(ratio)
# Utility functions
# Exclusive-or of two BYTES
#
def xor(x, y):
a = bits(x)
b = bits(y)
c = [0, 0, 0, 0, 0, 0, 0, 0]
for i in range(8):
c[i] = (a[i] + b[i]) % 2
return stib(c)
# Return the bits of a byte as a list of 8 integers
#
def bits(x):
b = [0, 0, 0, 0, 0, 0, 0, 0]
for i in range(8):
x, b[i] = divmod(x, 2)
return b
# Convert a list of 8 integers (0|1) to a byte
#
def stib(b):
x = 0
shift = 1
for i in range(8):
x = x + b[i]*shift
shift = shift*2
return x

View file

@ -0,0 +1,60 @@
# Define menu operations for GL stdwin
import gl
from glstdwin import key2code
class MenuObject:
#
def _init(self, (win, title)):
self._win = win
self._title = title
self._items = []
return self
#
def close(self):
self._win.remove(self)
del self._win
#
def additem(self, arg):
if type(arg) == type(()):
text, shortcut = arg
else:
text, shortcut = arg, None
self._items.append([text, shortcut, 1, 0])
#
def setitem(self, (i, text)):
self._items[i][0] = text
#
def enable(self, (i, flag)):
self._items[i][2] = flag
#
def check(self, (i, flag)):
self._items[i][3] = flag
#
def _makepup(self, firstitem):
pup = gl.newpup()
if self._title:
gl.addtopup(pup, self._title + '%t', 0)
for item in self._items:
text = item[0]
if not item[2]: # Disabled
text = ' ( ' + text + ' )%x-1'
else:
if item[3]: # Check mark
text = '-> ' + text
else:
text = ' ' + text
if key2code.has_key(item[1]):
text = text + ' [Alt-' + item[1] + ']'
text = text + '%x' + `firstitem`
gl.addtopup(pup, text, 0)
firstitem = firstitem + 1
return pup
#
def _checkshortcut(self, char):
for i in range(len(self._items)):
item = self._items[i]
if item[2] and item[1] == char:
return i
return -1
#

View file

@ -0,0 +1,139 @@
# Define window operations for STDWIN
import gl
from stdwinevents import *
from glstdwin import G # Global variables
from glstdwin import MASK # Tunable constant
class WindowObject:
#
def _init(self, title):
self._docsize = (0, 0)
self._fg = G.fg
self._bg = G.bg
self._title = title
self._font = G.font
self._size = G.size
self._menus = []
self._gid = gl.winopen(title)
gl.winconstraints() # To remove prefsize() effect
self._fixviewport()
self._needredraw()
return self
#
def close(self):
del G.windowmap[`self._gid`]
gl.winclose(self._gid)
self._gid = 0
#
def _needredraw(self):
if self in G.drawqueue:
G.drawqueue.remove(self)
G.drawqueue.append(self)
#
def begindrawing(self):
from glstdwdraw import DrawingObject
return DrawingObject()._init(self)
#
def change(self, area):
self._needredraw()
# XXX Should record the area to be drawn?
#
def gettitle(self):
return self._title
#
def getdocsize(self):
return self._docsize
#
def getorigin(self):
return self._area[0]
#
def getwinsize(self):
return self._area[1]
#
def scroll(self, (area, by)):
# XXX ought to use gl.rectcopy()
if by <> (0, 0):
self.change(area)
#
def setdocsize(self, docsize):
self._docsize = docsize
#
def setorigin(self, origin):
pass # XXX
#
def settimer(self, decisecs):
pass # XXX
#
def settitle(self, title):
self._title = title
gl.wintitle(title)
#
def show(self, area):
pass # XXX
#
def _fixviewport(self):
#
# Called after redraw or resize, and initially.
#
# Fix the coordinate system so that (0, 0) is top left,
# units are pixels, and positive axes point right and down.
#
# Make the viewport slightly larger than the window,
# and set the screenmask exactly to the window; this
# help fixing character clipping.
#
# Set self._area to the window rectangle in STDWIN coords.
#
gl.winset(self._gid)
gl.reshapeviewport()
x0, x1, y0, y1 = gl.getviewport()
width, height = x1-x0, y1-y0
gl.viewport(x0-MASK, x1+MASK, y0-MASK, y1+MASK)
gl.scrmask(x0, x1, y0, y1)
gl.ortho2(-MASK, width+MASK, height+MASK, -MASK)
self._area = (0, 0), (width, height)
#
def menucreate(self, title):
from glstdwmenu import MenuObject
menu = MenuObject()._init(self, title)
self._menus.append(menu)
return menu
#
def _domenu(self):
if not self._menus:
return None
if len(self._menus) == 1:
pup = self._menus[0]._makepup(0)
val = gl.dopup(pup)
gl.freepup(pup)
if val < 0:
return None
return WE_MENU, self, (self._menus[0], val)
#
# More than one menu: use nested menus.
#
pups = []
firstitem = 0
for menu in self._menus:
pups.append(menu._makepup(firstitem))
firstitem = firstitem + 100
pup = gl.newpup()
for i in range(len(self._menus)):
gl.addtopup(pup, self._menus[i]._title + '%m', pups[i])
val = gl.dopup(pup)
gl.freepup(pup)
for pup in pups:
gl.freepup(pup)
if val < 0:
return None
i_menu, i_item = divmod(val, 100)
return WE_MENU, self, (self._menus[i_menu], i_item)
#
def _doshortcut(self, char):
for menu in self._menus:
i = menu._checkshortcut(char)
if i >= 0:
return WE_MENU, self, (menu, i)
return None
#

View file

@ -0,0 +1,10 @@
# If you put 'import stdwin_gl' in front of the main program of a program
# using stdwin (before it has a chance to import the real stdwin!),
# it will use glstdwin and think it is stdwin.
import sys
if sys.modules.has_key('stdwin'):
raise RuntimeError, 'too late -- stdwin has already been imported'
import glstdwin
sys.modules['stdwin'] = glstdwin

View file

@ -0,0 +1,43 @@
# Try colors -- display all 256 possible colors, with their color index
# import stdwingl
import stdwin
from stdwinevents import *
NROWS = 16
NCOLS = 16
def main():
stdwin.setdefwinsize(NCOLS * stdwin.textwidth('12345'), \
NROWS * stdwin.lineheight() * 3)
w = stdwin.open('TestColors')
#
while 1:
type, window, detail = stdwin.getevent()
if type == WE_CLOSE:
print 'Bye.'
break
elif type == WE_SIZE:
w.change((0,0), (10000, 10000))
elif type == WE_DRAW:
width, height = w.getwinsize()
d = w.begindrawing()
for row in range(NROWS):
for col in range(NCOLS):
color = row*NCOLS + col
d.setfgcolor(color)
p = col*width/NCOLS, row*height/NROWS
q = (col+1)*width/NCOLS, \
(row+1)*height/NROWS
d.paint(p, q)
d.setfgcolor(0)
d.box(p, q)
d.text(p, `color`)
p = p[0] , p[1]+ d.lineheight()
d.setfgcolor(7)
d.text(p, `color`)
del d
#
main()

View file

@ -0,0 +1,70 @@
import sys
if len(sys.argv) < 2:
import stdwingl
color = 1
needclose = 1
else:
color = 0
needclose = 0
import stdwin
import time
from stdwinevents import *
from GL import BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE
def main():
#
stdwin.setdefwinsize(300, 300)
stdwin.setdefwinpos(0, 0)
if color: stdwin.setbgcolor(YELLOW)
w1 = stdwin.open('Hello, world')
w1.box = (10, 10), (90, 90)
#
stdwin.setdefwinsize(0, 0)
stdwin.setdefwinpos(50, 50)
if color: stdwin.setbgcolor(GREEN)
w2 = stdwin.open('Second window')
w2.box = (10, 10), (90, 90)
#
while w1 or w2:
type, window, detail = stdwin.getevent()
if type == WE_DRAW:
d = window.begindrawing()
if window == w1:
if color: d.setfgcolor(BLACK)
d.box((50, 50), (250, 250))
if color: d.setfgcolor(RED)
d.cliprect((50, 50), (250, 250))
d.paint(w1.box)
d.noclip()
if color: d.setfgcolor(BLUE)
d.line((0, 0), w1.box[0])
elif window == w2:
if color: d.setfgcolor(WHITE)
d.box(w2.box)
if color: d.setfgcolor(BLACK)
d.text(w2.box[0], 'Hello world')
else:
print 'Strange draw???', window, detail
del d
elif type == WE_CLOSE:
if needclose: window.close()
if window == w1:
w1 = None
elif window == w2:
w2 = None
else:
print 'weird close event???', window, detail
elif type in (WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP):
h, v = detail[0]
window.box = (h, v), (h+80, v+80)
window.change((0,0), (2000, 2000))
elif type == WE_CHAR:
print 'character', `detail`
else:
print type, window, detail
#
main()
print 'Done.'

View file

@ -0,0 +1,44 @@
# Test menus
import stdwingl
import stdwin
from stdwinevents import *
def main():
w = stdwin.open('TestMenus')
#
items1 = 'Aap', 'Noot', 'Mies'
m1 = w.menucreate('Menu-1')
for item in items1:
m1.additem(item, item[0])
#
items2 = 'Wim', 'Zus', 'Jet', 'Teun', 'Vuur'
m2 = w.menucreate('Menu-2')
for item in items2:
m2.additem(item, `len(item)`)
#
m1.enable(1, 0)
m2.check(1, 1)
#
while 1:
type, window, detail = stdwin.getevent()
if type == WE_CLOSE:
break
elif type == WE_DRAW:
d = w.begindrawing()
d.box((50,50), (100,100))
del d
elif type == WE_MENU:
mp, i = detail
if mp == m1:
print 'Choice:', items1[i]
elif mp == m2:
print 'Choice:', items2[i]
else:
print 'Not one of my menus!'
elif type == WE_CHAR:
print 'Character', `detail`
#
main()

194
Demo/sgi/gl/kites.py Executable file
View file

@ -0,0 +1,194 @@
#! /usr/local/python
# *** This only works correctly on a 24 bit-plane machine. ***
#
# A simple Python program that tests the some parts of the
# GL library. It shows the speed that can be obtained when
# doing simple graphics.
#
# The bottleneck in this program is NOT Python but the graphics
# engine; i.e Python can feed the graphics pipeline fast enough
# on the 4D/25G.
#
# This program show 3 kites flying around the screen. It uses
#
# * bgnpolygon, endpolygon
# * v3, n3
# * lmdef, lmbind
#
# Usage :
#
# ESC -> exit program
# MOUSE3 -> freeze toggle
# MOUSE2 -> one step (use this in freeze state)
from GL import *
from gl import *
import DEVICE
from math import *
#
# viewobj : sets the rotation, translation and scaling
# set appropiate material, call drawobject()
#
def viewobj (r, s, t, mat) :
pushmatrix()
rot (r * 10.0, 'X')
rot (r * 10.0, 'Y')
rot (r * 10.0, 'Z')
scale (s[0], s[1], s[2])
translate (t[0], t[1], t[2])
lmbind(MATERIAL, mat)
drawobject()
popmatrix()
#
# makeobj : the contructor of the object
#
def mkobj () :
v0 = (-5.0 ,0.0, 0.0)
v1 = (0.0 ,5.0, 0.0)
v2 = (5.0 ,0.0, 0.0)
v3 = (0.0 ,2.0, 0.0)
n0 = (sqrt(2.0)/2.0, sqrt(2.0)/2.0, 0.0)
vn = ((v0, n0), (v1, n0), (v2, n0), (v3, n0))
#
return vn
#
# the object itself as an array of vertices and normals
#
kite = mkobj ()
#
# drawobject : draw a triangle. with bgnpolygon
#
def drawobject () :
#
bgnpolygon()
vnarray (kite)
endpolygon()
#
# identity matrix
#
idmat=[1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0]
#
# the rgb-value of light-blue
#
LightBlue = (43,169,255)
#
# the different materials.
#
m1=[SPECULAR,0.0,0.0,0.6,DIFFUSE,0.0,0.0,0.8,SHININESS,20.0,LMNULL]
m2=[SPECULAR,0.8,0.0,0.1,DIFFUSE,0.8,0.0,0.3,SHININESS,120.0,LMNULL]
m3=[SPECULAR,0.0,1.0,0.0,DIFFUSE,0.0,0.6,0.0,SHININESS,120.0,LMNULL]
#
# lightsources
#
light1 = [LCOLOR,1.0,1.0,1.0,POSITION,15.0,15.0,0.0,1.0,LMNULL]
light2 = [LCOLOR,1.0,1.0,1.0,POSITION,-15.0,15.0,0.0,1.0,LMNULL]
#
# the lightmodel
#
model = [AMBIENT,0.2,0.2,0.2,LMNULL]
#
# initgl : opens the window, configures the pipeline to 2buf and zbuf,
# sets the viewing, defines and binds the materials
#
def initgl () :
#
# open window
#
foreground ()
keepaspect (1, 1)
prefposition (100, 500, 100, 500)
w = winopen ('PYTHON lights')
keepaspect (1, 1)
winconstraints()
#
# configure pipeline (zbuf, 2buf, GOURAUD and RGBmode)
#
zbuffer (1)
doublebuffer ()
shademodel (GOURAUD)
RGBmode ()
gconfig ()
#
# define and bind materials (set perspective BEFORE loadmat !)
#
mmode(MVIEWING)
perspective (900, 1.0, 1.0, 20.0)
loadmatrix(idmat)
lmdef(DEFMATERIAL, 1, m1)
lmdef(DEFMATERIAL, 2, m2)
lmdef(DEFMATERIAL, 3, m3)
lmdef(DEFLIGHT, 1, light1)
lmdef(DEFLIGHT, 2, light2)
lmdef(DEFLMODEL, 1, model)
lmbind(LIGHT0,1)
lmbind(LIGHT1,2)
lmbind(LMODEL,1)
#
# set viewing
#
lookat (0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0)
#
# ask for the REDRAW and ESCKEY events
#
qdevice(DEVICE.MOUSE3)
qdevice(DEVICE.MOUSE2)
qdevice(DEVICE.REDRAW)
qdevice(DEVICE.ESCKEY)
#
# GoForIT : use 2buf to redraw the object 2n times. index i is used as
# the (smoothly changing) rotation angle
#
def GoForIt(i) :
freeze = 1
while 1 :
if freeze <> 0 :
i = i + 1
#
# clear z-buffer and clear background to light-blue
#
zclear()
c3i (LightBlue)
clear()
#
# draw the 3 traiangles scaled above each other.
#
viewobj(float(i),[1.0,1.0,1.0],[1.0,1.0,1.0],1)
viewobj(float(i),[0.75,0.75,0.75],[0.0,2.0,2.0],2)
viewobj(float(i),[0.5,0.5,0.5],[0.0,4.0,4.0],3)
#
swapbuffers()
#
if qtest() <> 0 :
dev, val = qread()
if dev == DEVICE.ESCKEY :
break
elif dev == DEVICE.REDRAW :
reshapeviewport ()
elif dev == DEVICE.MOUSE3 and val <> 0 :
freeze = 1 - freeze
elif dev == DEVICE.MOUSE2 and val <> 0 :
i = i + 1
# the main program
#
def main () :
initgl ()
GoForIt (0)
#
# exec main
#
main ()

446
Demo/sgi/gl/kunst.py Executable file
View file

@ -0,0 +1,446 @@
#!/ufs/guido/bin/sgi/python
# Simulate the artwork in the hall.
# Jack Jansen, Feb 91.
#
# Please please please don't try to read this code.
# It is the first GL program I ever wrote, and used to do
# very different things before it's current function:-)
from gl import *
from GL import *
from math import *
from DEVICE import *
import sys
import __main__
main_dict = __main__.__dict__
SPOTDIRECTION = 103
SPOTLIGHT = 104
#
# Make a cylinder paralel with the Z axis with center (X,Y,0)
# and radius 1
def mkcyl(nslice, nparts, docircle):
cyl = []
step = 2.0 / float(nslice)
z = -1.0
for i in range(nslice):
cyl.append(mkslice(z, z+step, nparts, docircle))
z = z + step
return drawcylinder(cyl)
#
# Make one part of a cylinder
#
def mkslice(z1, z2, nparts, docircle):
if docircle:
w1 = z1
w2 = z2
w1 = sqrt(1.0-w1*w1)
w2 = sqrt(1.0-w2*w2)
normalz = 1.0
else:
w1 = 1.0
w2 = 1.0
normalz = 0.0
slice = []
step = (2.0*pi)/float(nparts)
angle = 0.0
for i in range(nparts+1):
vx = cos(angle)
vy = sin(angle)
slice.append( ((vx*w1,vy*w1,z1), (vx*w1, vy*w1, z1*normalz)) )
slice.append( ((vx*w2,vy*w2,z2), (vx*w2, vy*w2, z2*normalz)) )
angle = angle + step
return slice
#
# Drawcylinder : draw the cylinder
#
class struct(): pass
curobj = struct()
curobj.curobj = 1
def drawcylinder(cyl):
obj = curobj.curobj
curobj.curobj = curobj.curobj+1
makeobj(obj)
for slice in cyl:
bgntmesh()
vnarray(slice)
endtmesh()
closeobj()
return obj
#
def drawnormals(cyl):
for slice in cyl:
for triang in slice:
bgnline()
v3f(triang[0])
v3f(triang[0][0] + triang[1][0], triang[0][1] + triang[1][1], triang[0][2] + triang[1][2])
endline()
def drawfloors():
obj = curobj.curobj
curobj.curobj = curobj.curobj+1
makeobj(obj)
bgnpolygon()
v3i(4,6,-6)
v3i(-6,6,-6)
v3i(-6,-6,-6)
v3i(4,-6,-6)
endpolygon()
for floor in range(3):
pos = -1 + 5*floor
bgnpolygon()
v3i(4,4,pos)
v3i(-6,4,pos)
v3i(-6,6,pos)
v3i(4,6,pos)
endpolygon()
bgnpolygon()
v3i(-4,4,pos)
v3i(-4,-4,pos)
v3i(-6,-4,pos)
v3i(-6,4,pos)
endpolygon()
bgnpolygon()
v3i(-6,-4,pos)
v3i(-6,-6,pos)
v3i(4,-6,pos)
v3i(4,-4,pos)
endpolygon()
closeobj()
return obj
def drawdoors():
obj = curobj.curobj
curobj.curobj = curobj.curobj+1
makeobj(obj)
for floor in range(3):
pos = -1+5*floor
bgnpolygon()
v3i(-2,6,pos)
v3i(-2,6,pos+3)
v3i(0,6,pos+3)
v3i(0,6,pos)
endpolygon()
closeobj()
return obj
def drawrailing():
obj = curobj.curobj
curobj.curobj = curobj.curobj+1
makeobj(obj)
for floor in range(3):
pos = -1 + 5*floor
bgnpolygon()
v3i(4,4,pos)
v3i(4,4,pos-1)
v3i(-4,4,pos-1)
v3i(-4,4,pos)
endpolygon()
bgnpolygon()
v3i(-4,4,pos)
v3i(-4,4,pos-1)
v3i(-4,-4,pos-1)
v3i(-4,-4,pos)
endpolygon()
bgnpolygon()
v3i(-4,-4,pos)
v3i(-4,-4,pos-1)
v3i(4,-4,pos-1)
v3i(4,-4,pos)
endpolygon()
closeobj()
return obj
def drawwalls():
obj = curobj.curobj
curobj.curobj = curobj.curobj+1
makeobj(obj)
bgnpolygon()
v3i(4,6,-6)
v3i(4,6,18)
v3i(-6,6,18)
v3i(-6,6,-6)
endpolygon()
bgnpolygon()
v3i(-6,6,-6)
v3i(-6,6,18)
v3i(-6,-6,18)
v3i(-6,-6,-6)
endpolygon()
bgnpolygon()
v3i(-6,-6,-6)
v3i(-6,-6,18)
v3i(4,-6,18)
v3i(4,-6,-6)
endpolygon()
bgnpolygon()
v3i(4,-6,-6)
v3i(4,-6,18)
v3i(4,4,18)
v3i(4,4,-6)
endpolygon()
closeobj()
return obj
def axis():
bgnline()
cpack(0xff0000)
v3i(-1,0,0)
v3i(1,0,0)
v3f(1.0, 0.1, 0.1)
endline()
bgnline()
cpack(0xff00)
v3i(0,-1,0)
v3i(0,1,0)
v3f(0.1, 1.0, 0.1)
endline()
bgnline()
cpack(0xff)
v3i(0,0,-1)
v3i(0,0,1)
v3f(0.1,0.1,1.0)
endline()
#
silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \
SHININESS, 40.0, LMNULL]
floormat = [ AMBIENT, 0.5, 0.25, 0.15, DIFFUSE, 0.5, 0.25, 0.15, SPECULAR, 0.6, 0.3, 0.2, SHININESS, 20.0, LMNULL]
wallmat = [ DIFFUSE, 0.4, 0.2, 0.1, AMBIENT, 0.4, 0.20, 0.10, SPECULAR, 0.0, 0.0, 0.0, SHININESS, 20.0, LMNULL]
offwhite = [ DIFFUSE, 0.8, 0.8, 0.6, AMBIENT, 0.8, 0.8, 0.6, SPECULAR, 0.9, 0.9, 0.9, SHININESS, 30.0, LMNULL]
doormat = [ DIFFUSE, 0.1, 0.2, 0.5, AMBIENT, 0.2, 0.4, 1.0, SPECULAR, 0.2, 0.4, 1.0, SHININESS, 60.0, LMNULL]
toplight = [ LCOLOR, 1.0, 1.0, 0.5, \
POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL]
floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \
SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL]
lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL]
#
def lighting():
INDIGO=1 # XXXX Seems indigo only has one light.
lmdef(DEFMATERIAL, 2, silver)
lmdef(DEFMATERIAL, 3, floormat)
lmdef(DEFMATERIAL, 4, wallmat)
lmdef(DEFMATERIAL, 5, offwhite)
lmdef(DEFMATERIAL, 6, doormat)
lmdef(DEFLIGHT, 1, toplight)
if not INDIGO:
lmdef(DEFLIGHT, 2, floor1light)
lmdef(DEFLMODEL, 1, lmodel)
lmbind(LIGHT0, 1)
if not INDIGO:
lmbind(LIGHT1, 2)
lmbind(LMODEL, 1)
IdMat=[1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0]
#
wrongrange='Wrong Range'
def defun(axis):
done = 0
res = 0.0 # Hack around exec(...)
while not done:
print 'F'+axis+'(t) = ',
s = sys.stdin.readline(100)
print
try:
s = 'def f'+axis+'(t): return '+s
exec(s, main_dict)
exec('res = f'+axis+'(0.0)\n')
if res < -10.0 or res > 10.0:
raise wrongrange
exec('res = f'+axis+'(100.0)\n')
if res < -10.0 or res > 10.0:
raise wrongrange
done = 1
except RuntimeError:
print 'Sorry, there is a syntax error in your expression'
except TypeError:
print 'Please remember to use floating point numbers'
except wrongrange:
print 'Sorry, function values out of range (non-periodic function?)'
def getfunctions():
print 'Welcome to the CWI art simulator. You can now enter X, Y and Z'
print 'coordinates as a function of t.'
print 'Alternatively, you can specify the name of a python module'
print 'defining functions fx(t), fy(t) and fz(t) on the command line'
print 'Normal trig functions are available. Please use floating point'
print 'values only (so 0.0 for 0). Comments to jack@cwi.nl'
defun('x')
defun('y')
defun('z')
print 'Ok, here you go. Use mouse+right button to move up/down,'
print 'mouse+middle to speed up/slow down time. type ESC to quit simulation'
def main():
if len(sys.argv) > 1:
exec('from '+sys.argv[1]+' import *\n')
else:
getfunctions()
foreground()
prefposition(100,600,100,600)
void = winopen('cyl')
qdevice(ESCKEY)
qdevice(MOUSE1)
qdevice(MOUSE2)
qdevice(PKEY)
RGBmode()
doublebuffer()
gconfig()
zbuffer(1)
mmode(MVIEWING)
perspective(600, 1.0, 0.01, 20.0)
loadmatrix(IdMat)
vx = 0.0
vy = -3.9
vz = 0.0
lookat(0.0, -3.9, 0.0, 0.0, 0.0, 0.0, 0)
lighting()
t = -1.0
step = 0.2
bol = mkcyl(12,24, 1)
cable = mkcyl(1, 6, 0)
floors = drawfloors()
walls = drawwalls()
pillar = mkcyl(1,4,0)
railing = drawrailing()
doors = drawdoors()
shademodel(GOURAUD)
mousing = -1
pausing = 0
while 1:
#
# Check for some user input
#
if qtest():
dev, value = qread()
if dev == PKEY and value == 1:
pausing = 1
if dev == ESCKEY:
break
elif (dev==MOUSE1 or dev==MOUSE2) and value == 1:
if mousing > 0:
vx = 0.0
vy = -3.9
vz = 0.0
mousing = dev
oldx = getvaluator(MOUSEX)
oldy = getvaluator(MOUSEY)
elif (dev==MOUSE1 or dev==MOUSE2):
mousing = -1
if mousing >= 0:
newx = getvaluator(MOUSEX)
newy = getvaluator(MOUSEY)
if newy <> oldy and mousing==MOUSE1:
vz = vz + float(newy - oldy)/100.0
if vz < -5.99:
vz = -5.99
dist = sqrt(vx*vx + vy*vy + vz*vz)
perspective(600, 1.0, 0.01, dist+16.0)
loadmatrix(IdMat)
if vz < 0.0:
lookat(vx, vy, vz, 0.0, 0.0, 0.0, 1800)
else:
lookat(vx, vy, vz, 0.0, 0.0, 0.0, 0)
if newy <> oldy and mousing==MOUSE2:
step = step * exp(float(newy-oldy)/400.0)
if getbutton(CTRLKEY) == 0:
t = t + step
else:
t = t - step
if getbutton(LEFTSHIFTKEY) == 0:
shademodel(GOURAUD)
else:
shademodel(FLAT)
#
# Draw background and axis
czclear(0x802020,getgdesc(GD_ZMAX))
#axis()
#
# draw the floors
#
lmbind(MATERIAL, 3)
callobj(floors)
lmbind(MATERIAL, 4)
callobj(walls)
lmbind(MATERIAL, 5)
pushmatrix()
translate(-4.5,4.5,3.0)
scale(0.2,0.2,9.0)
rotate(450,'z')
callobj(pillar)
popmatrix()
callobj(railing)
lmbind(MATERIAL, 6)
pushmatrix()
translate(0.0, -0.01, 0.0)
callobj(doors)
popmatrix()
#
# Draw object
#
bolx = fx(t)
boly = fy(t)
bolz = fz(t)
err = ''
if bolx < -4.0 or bolx > 4.0:
err = 'X('+`bolx`+') out of range [-4,4]'
if boly < -4.0 or boly > 4.0:
err = 'Y('+`boly`+') out of range [-4,4]'
if bolz < -4.0 or bolz > 8.0:
err = 'Z('+`bolz`+') out of range [-4,8]'
if not err:
pushmatrix()
translate(bolx, boly, bolz)
scale(0.3, 0.3, 0.3)
lmbind(MATERIAL, 2)
blendfunction(BF_ONE, BF_ONE)
callobj(bol)
blendfunction(BF_ONE, BF_ZERO)
popmatrix()
#
# Draw the cables
#
bolz = bolz + 0.3
pushmatrix()
#linesmooth(SML_ON)
bgnline()
v3i(-4,-4,9)
v3f(bolx, boly, bolz)
endline()
bgnline()
v3i(-4,4,9)
v3f(bolx, boly, bolz)
endline()
bgnline()
v3i(4,-4,9)
v3f(bolx, boly, bolz)
endline()
bgnline()
v3i(4,4,9)
v3f(bolx, boly, bolz)
endline()
popmatrix()
if mousing == MOUSE2 or err:
cpack(0xff0000)
cmov(0.0, 0.0, 0.4)
charstr('t='+`t`)
if mousing == MOUSE2:
cpack(0xff0000)
cmov(0.0, 0.0, 0.2)
charstr('delta-t='+`step`)
if err:
cpack(0xff00)
cmov(0.0, 0.0, 0.2)
charstr(err)
pausing = 1
if pausing:
cpack(0xff00)
cmov(0.0, 0.0, 0.0)
charstr('Pausing, type P to continue')
swapbuffers()
if pausing:
while 1:
dv=qread()
if dv==(PKEY,1):
break
if dv==(ESCKEY,1):
sys.exit(0)
pausing = 0
#
try:
main()
except KeyboardInterrupt:
sys.exit(1)

60
Demo/sgi/gl/mclock.doc Executable file
View file

@ -0,0 +1,60 @@
Newsgroups: cwi.sgi
Subject: Re: new clock
Distribution: cwi.sgi
References: <2246@charon.cwi.nl>
Last week I wrote:
>For your enjoyment I have implemented a colorful clock.
The clock has now been extended with some new facilities: a menu, an
alarm and a gong. These may require some explanation beyond what's in
the usage message.
Menu
----
The right mouse button now pops up a menu that allows you to turn the
seconds hand on or off and to switch the alarm off.
Alarm
-----
The left and middle buttons set the alarm. When it is on, the alarm
time is displayed as a time on a 24 hour clock in the bottom left
corner. It is also indicated by two red triangles, corresponding to the
little (hours) and big (minutes) hand. These hands can be moved around:
the left mouse button moves the minutes hand, the middle button moves
the hourds hand. Watch out for differences of twelve hours (always
check the digital display); these can be corrected by dragging the hours
hand once around the dial.
When the alarm goes off, two things happen: a shell command specified on
the command line with the -a option is executed (in the background), and
the clock's colors change every two seconds, for five minutes. You can
also turn the alarm off by using the menu accessible through the right
mouse button.
There is no default command for the -a option; if it is not specified,
only the changing of the colors happens. If you have an 8 ohm speaker
connected to the audio output of your Personal Iris, a suitable command
would be:
mclock -a '/ufs/guido/bin/sgi/play /ufs/guido/lib/sounds/alarm'
Gong
----
Some people like a clock that makes noises every hour, or even more
often. This is supported by the -g and -G options. With -g you specify
a shell command to be executed to sound the gong; with -G you can
specify the interval between gong calls, in seconds (default is one hour).
The shell command is executed in the background. It is given two
arguments: the hours (on a 24 hour clock!) and the minutes. The
executable Python script /ufs/guido/bin/sgi/chime is a suitable example.
Again, this only works if you have installed a speaker (I bet 8 ohm
speakers are going to be in demand!)
--
Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam
guido@cwi.nl or ..!hp4nl!cwi.nl!guido or guido%cwi.nl@uunet.uu.net
"A thing of beauty is a joy till sunrise"

731
Demo/sgi/gl/mclock.py Executable file
View file

@ -0,0 +1,731 @@
#! /usr/local/python
#############################################################################
# NOTA BENE: Before installing, fix TZDIFF to reflect your local time zone! #
#############################################################################
# "M Clock"
#
# An implementation in software of an original design by Rob Juda.
# Clock implementation: Guido van Rossum.
# Alarm and Gong features: Sape Mullender.
#
# XXX TO DO:
# add arguments to specify initial window position and size
# find out local time zone difference automatically
# add a date indicator
# allow multiple alarms
# allow the menu to change more parameters
import sys
from gl import *
from GL import *
from DEVICE import *
import time
import getopt
import string
import os
from math import pi
import math
FULLC = 3600 # Full circle in 1/10-ths of a degree
MIDN = 900 # Angle of the 12 o'clock position
R, G, B = 0, 1, 2 # Indices of colors in RGB list
HOUR = 3600 # Number of seconds per hour
MINUTE = 60 # Number of seconds per minute
class struct: pass # Class to define featureless structures
Gl = struct() # Object to hold writable global variables
# Default constants (used in multiple places)
SCREENBG = 127, 156, 191
NPARTS = 9
TITLE = 'M Clock'
TZDIFF = -2*HOUR # <--- change this to reflect your local time zone
# Default parameters
Gl.foreground = 0 # If set, run in the foreground
Gl.fullscreen = 0 # If set, run on full screen
Gl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time)
Gl.nparts = NPARTS # Number of parts each circle is divided in (>= 2)
Gl.debug = 0 # If set, print debug output
Gl.doublebuffer = 1 # If set, use double buffering
Gl.update = 0 # Update interval; seconds hand is suppressed if > 1
Gl.colorsubset = 0 # If set, display only a subset of the colors
Gl.cyan = 0 # If set, display cyan overlay (big hand)
Gl.magenta = 0 # If set, display magenta overlay (little hand)
Gl.yellow = 0 # If set, display yellow overlay (fixed background)
Gl.black = 0 # If set, display black overlay (hands)
Gl.colormap = 0 # If set, use colormap mode instead of RGB mode
Gl.warnings = 0 # If set, print warnings
Gl.title = '' # Window title (default set later)
Gl.name = 'mclock' # Window title for resources
Gl.border = 1 # If set, use a window border (and title)
Gl.bg = 0, 0, 0 # Background color R, G, B value
Gl.iconic = 0 # Set in iconic state
Gl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm)
Gl.ox,Gl.oy = 0,0 # Window origin
Gl.cx,Gl.cy = 0,0 # Window size
Gl.alarm_set = 0 # Alarm on or off
Gl.alarm_on = 0 # Alarm is ringing
Gl.alarm_time = 0 # Alarm time in seconds after midnight
Gl.alarm_hours = 0 # Alarm hour setting, 24 hour clock
Gl.alarm_minutes = 0 # Alarm minutes setting
Gl.alarm_rgb = 0,0,0 # Alarm display RGB colors
Gl.alarm_cmd = '' # Command to execute when alarm goes off
Gl.mouse2down = 0 # Mouse button state
Gl.mouse3down = 0 # Mouse button state
Gl.gong_cmd = '' # Command to execute when chimes go off
Gl.gong_int = 3600 # Gong interval
Gl.indices = R, G, B # Colors (permuted when alarm is on)
def main():
#
sys.stdout = sys.stderr # All output is errors/warnings etc.
#
try:
args = getoptions()
except string.atoi_error, value:
usage(string.atoi_error, value)
except getopt.error, msg:
usage(getopt.error, msg)
#
if args:
realtime = 0
hours = string.atoi(args[0])
minutes = seconds = 0
if args[1:]: minutes = string.atoi(args[1])
if args[2:]: seconds = string.atoi(args[2])
localtime = ((hours*60)+minutes)*60+seconds
else:
realtime = 1
#
if Gl.title == '':
if realtime:
Gl.title = TITLE
else:
title = ''
for arg in args: title = title + ' ' + arg
Gl.title = title[1:]
del title
#
wid = makewindow()
Gl.ox,Gl.oy = getorigin()
Gl.cx,Gl.cy = getsize()
initmenu()
clearall()
#
if not Gl.update:
Gl.update = 60
#
if Gl.update <= 1:
Gl.timernoise = 6
else:
Gl.timernoise = 60
noise(TIMER0, Gl.timernoise)
#
qdevice(WINSHUT)
qdevice(WINQUIT)
qdevice(ESCKEY)
if realtime:
qdevice(TIMER0)
qdevice(REDRAW)
qdevice(WINFREEZE)
qdevice(WINTHAW)
qdevice(MENUBUTTON) # MOUSE1
qdevice(MOUSE3) # Left button
qdevice(MOUSE2) # Middle button
unqdevice(INPUTCHANGE)
#
lasttime = 0
Gl.change = 1
while 1:
if realtime:
localtime = time.time() - Gl.tzdiff
if Gl.alarm_set:
if localtime%(24*HOUR) == Gl.alarm_time:
# Ring the alarm!
if Gl.debug:
print 'Rrrringg!'
Gl.alarm_on = 1
if Gl.alarm_cmd <> '':
d = os.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &')
Gl.change = 1
clearall()
if Gl.alarm_on:
if (localtime - Gl.alarm_time) % (24*HOUR) > 300:
# More than 5 minutes away from alarm
Gl.alarm_on = 0
if Gl.debug:
print 'Alarm turned off'
Gl.change = 1
clearall()
Gl.indices = R, G, B
else:
if localtime % 2 == 0:
# Permute color indices
Gl.indices = Gl.indices[2:] + Gl.indices[:2]
Gl.change = 1
if Gl.gong_cmd <> '' and localtime%Gl.gong_int == 0:
d = os.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &')
if localtime/Gl.update <> lasttime/Gl.update:
if Gl.debug: print 'new time'
Gl.change = 1
if Gl.change:
if Gl.debug: print 'drawing'
doit(localtime)
lasttime = localtime
Gl.change = 0
dev, data = qread()
if Gl.debug and dev <> TIMER0:
print dev, data
if dev == TIMER0:
if Gl.debug > 1:
print dev, data
elif dev == MOUSE3:
mousex = getvaluator(MOUSEX)
mousey = getvaluator(MOUSEY)
if mouseclick(3, data, mousex, mousey):
Gl.change = 1
elif dev == MOUSE2:
mousex = getvaluator(MOUSEX)
mousey = getvaluator(MOUSEY)
if mouseclick(2, data, mousex, mousey):
Gl.change = 1
elif dev == MOUSEX:
mousex = data
if Gl.mouse2down:
mouse2track(mousex, mousey)
if Gl.mouse3down:
mouse3track(mousex, mousey)
elif dev == MOUSEY:
mousey = data
if Gl.mouse2down:
mouse2track(mousex, mousey)
if Gl.mouse3down:
mouse3track(mousex, mousey)
elif dev == REDRAW or dev == REDRAWICONIC:
if Gl.debug:
if dev == REDRAW: print 'REDRAW'
else: print 'REDRAWICONIC'
reshapeviewport()
Gl.ox,Gl.oy = getorigin()
Gl.cx,Gl.cy = getsize()
Gl.change = 1
clearall()
elif dev == MENUBUTTON:
if Gl.debug: print 'MENUBUTTON'
handlemenu()
elif dev == WINFREEZE:
if Gl.debug: print 'WINFREEZE'
Gl.iconic = 1
noise(TIMER0, 60*60) # Redraw every 60 seconds only
elif dev == WINTHAW:
if Gl.debug: print 'WINTHAW'
Gl.iconic = 0
noise(TIMER0, Gl.timernoise)
Gl.change = 1
elif dev == ESCKEY or dev == WINSHUT or dev == WINQUIT:
if Gl.debug: print 'Exit'
sys.exit(0)
def getoptions():
optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK')
for optname, optarg in optlist:
if optname == '-A':
Gl.fg = eval(optarg) # Should be (r,g,b)
elif optname == '-a':
Gl.alarm_cmd = optarg
elif optname == '-B':
Gl.bg = eval(optarg) # Should be (r,g,b)
elif optname == '-b':
Gl.border = 0
elif optname == '-c':
Gl.colormap = string.atoi(optarg)
elif optname == '-d':
Gl.debug = Gl.debug + 1
Gl.warnings = 1
elif optname == '-F':
Gl.foreground = 1
elif optname == '-f':
Gl.fullscreen = 1
elif optname == '-G':
Gl.gong_int = 60*string.atoi(optarg)
elif optname == '-g':
Gl.gong_cmd = optarg
elif optname == '-n':
Gl.nparts = string.atoi(optarg)
elif optname == '-s':
Gl.doublebuffer = 0
elif optname == '-T':
Gl.title = Gl.name = optarg
elif optname == '-t':
Gl.tzdiff = string.atoi(optarg)
elif optname == '-u':
Gl.update = string.atoi(optarg)
elif optname == '-w':
Gl.warnings = 1
elif optname == '-C':
Gl.cyan = Gl.colorsubset = 1
elif optname == '-M':
Gl.magenta = Gl.colorsubset = 1
elif optname == '-Y':
Gl.yellow = Gl.colorsubset = 1
elif optname == '-K':
Gl.black = Gl.colorsubset = 1
else:
print 'Unsupported option', optname
return args
def usage(exc, msg):
if sys.argv:
progname = os.path.basename(sys.argv[0])
else:
progname = 'mclock'
#
print progname + ':',
if exc == string.atoi_error:
print 'non-numeric argument:',
print msg
#
print 'usage:', progname, '[options] [hh [mm [ss]]]'
#
print '-A r,g,b : alarm background red,green,blue [255,0,0]'
print '-a cmd : shell command executed when alarm goes off'
print '-B r,g,b : background red,green,blue [0,0,0]'
print ' (-B SCREENBG uses the default screen background)'
print '-b : suppress window border and title'
print '-c cmapid : select explicit colormap'
print '-d : more debug output (implies -F, -w)'
print '-F : run in foreground'
print '-f : use full screen'
print '-G intrvl : interval between chimes in minutes [60]'
print '-g cmd : shell command executed when chimes go off'
print '-s : single buffer mode'
print '-w : print various warnings'
print '-n nparts : number of parts [' + `NPARTS` + ']'
print '-T title : alternate window title [\'' + TITLE + '\']'
print '-t tzdiff : time zone difference [' + `TZDIFF` + ']'
print '-u update : update interval [60]'
print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only'
print 'if hh [mm [ss]] is specified, display that time statically'
print 'on machines with < 12 bitplanes, -c and -s are forced on'
#
sys.exit(2)
def doit(localtime):
hands = makehands(localtime)
list = makelist(hands)
render(list, hands)
def makehands(localtime):
localtime = localtime % (12*HOUR)
seconds_hand = MIDN + FULLC - (localtime*60) % FULLC
big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC
little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC
return little_hand, big_hand, seconds_hand
def makelist(little_hand, big_hand, seconds_hand):
total = []
if Gl.cyan or not Gl.colorsubset:
total = total + makesublist(big_hand, Gl.indices[0])
if Gl.magenta or not Gl.colorsubset:
total = total + makesublist(little_hand, Gl.indices[1])
if Gl.yellow or not Gl.colorsubset:
total = total + makesublist(MIDN, Gl.indices[2])
total.sort()
return total
def makesublist(first, icolor):
list = []
alpha = FULLC/Gl.nparts
a = first - alpha/2
for i in range(Gl.nparts):
angle = (a + i*alpha + FULLC) % FULLC
value = 255*(Gl.nparts-1-i)/(Gl.nparts-1)
list.append(angle, icolor, value)
list.sort()
a, icolor, value = list[0]
if a <> 0:
a, icolor, value = list[len(list)-1]
t = 0, icolor, value
list.insert(0, t)
return list
def rgb_fg():
return Gl.fg
# Obsolete code:
if Gl.alarm_on:
return Gl.bg
else:
return Gl.fg
def rgb_bg():
return Gl.bg
# Obsolete code:
if Gl.alarm_on:
return Gl.fg
else:
return Gl.bg
def clearall():
Gl.c3i(rgb_bg())
clear()
if Gl.doublebuffer:
swapbuffers()
clear()
def draw_alarm(color):
frontbuffer(TRUE)
Gl.c3i(color)
pushmatrix()
rotate(-((Gl.alarm_time/12)%3600), 'z')
bgnpolygon()
v2f( 0.00,1.00)
v2f( 0.04,1.05)
v2f(-0.04,1.05)
endpolygon()
popmatrix()
#
pushmatrix()
rotate(-((Gl.alarm_time)%3600), 'z')
bgnpolygon()
v2f( 0.00,1.05)
v2f( 0.07,1.10)
v2f(-0.07,1.10)
endpolygon()
popmatrix()
#
cmov2(-1.06, -1.06)
charstr(string.rjust(`Gl.alarm_time/3600`,2))
charstr(':')
charstr(string.zfill((Gl.alarm_time/60)%60,2))
frontbuffer(FALSE)
def render(list, (little_hand, big_hand, seconds_hand)):
#
if Gl.colormap:
resetindex()
#
if not list:
Gl.c3i(255, 255, 255) # White
circf(0.0, 0.0, 1.0)
else:
list.append(3600, 0, 255) # Sentinel
#
rgb = [255, 255, 255]
a_prev = 0
for a, icolor, value in list:
if a <> a_prev:
[r, g, b] = rgb
if Gl.debug > 1:
print rgb, a_prev, a
Gl.c3i(r, g, b)
arcf(0.0, 0.0, 1.0, a_prev, a)
rgb[icolor] = value
a_prev = a
#
if Gl.black or not Gl.colorsubset:
#
# Draw the hands -- in black
#
Gl.c3i(0, 0, 0)
#
if Gl.update == 1 and not Gl.iconic:
# Seconds hand is only drawn if we update every second
pushmatrix()
rotate(seconds_hand, 'z')
bgnline()
v2f(0.0, 0.0)
v2f(1.0, 0.0)
endline()
popmatrix()
#
pushmatrix()
rotate(big_hand, 'z')
rectf(0.0, -0.01, 0.97, 0.01)
circf(0.0, 0.0, 0.01)
circf(0.97, 0.0, 0.01)
popmatrix()
#
pushmatrix()
rotate(little_hand, 'z')
rectf(0.04, -0.02, 0.63, 0.02)
circf(0.04, 0.0, 0.02)
circf(0.63, 0.0, 0.02)
popmatrix()
#
# Draw the alarm time, if set or being set
#
if Gl.alarm_set:
draw_alarm(rgb_fg())
#
if Gl.doublebuffer: swapbuffers()
def makewindow():
#
if Gl.debug or Gl.foreground:
foreground()
#
if Gl.fullscreen:
scrwidth, scrheight = getgdesc(GD_XPMAX), getgdesc(GD_YPMAX)
prefposition(0, scrwidth-1, 0, scrheight-1)
else:
keepaspect(1, 1)
prefsize(100, 100)
#
if not Gl.border:
noborder()
wid = winopen(Gl.name)
wintitle(Gl.title)
#
if not Gl.fullscreen:
keepaspect(1, 1)
minsize(10, 10)
maxsize(2000, 2000)
iconsize(66, 66)
winconstraints()
#
nplanes = getplanes()
nmaps = getgdesc(GD_NMMAPS)
if Gl.warnings:
print nplanes, 'color planes,', nmaps, 'color maps'
#
if nplanes < 12 or Gl.colormap:
if not Gl.colormap:
Gl.colormap = nmaps - 1
if Gl.warnings:
print 'not enough color planes available',
print 'for RGB mode; forcing colormap mode'
print 'using color map number', Gl.colormap
if not Gl.colorsubset:
needed = 3
else:
needed = Gl.cyan + Gl.magenta + Gl.yellow
needed = needed*Gl.nparts
if Gl.bg <> (0, 0, 0):
needed = needed+1
if Gl.fg <> (0, 0, 0):
needed = needed+1
if Gl.doublebuffer:
if needed > available(nplanes/2):
Gl.doublebuffer = 0
if Gl.warnings:
print 'not enough colors available',
print 'for double buffer mode;',
print 'forcing single buffer mode'
else:
nplanes = nplanes/2
if needed > available(nplanes):
# Do this warning always
print 'still not enough colors available;',
print 'parts will be left white'
print '(needed', needed, 'but have only',
print available(nplanes), 'colors available)'
#
if Gl.doublebuffer:
doublebuffer()
gconfig()
#
if Gl.colormap:
Gl.c3i = pseudo_c3i
fixcolormap()
else:
Gl.c3i = c3i
RGBmode()
gconfig()
#
if Gl.fullscreen:
# XXX Should find out true screen size using getgdesc()
ortho2(-1.1*1.280, 1.1*1.280, -1.1*1.024, 1.1*1.024)
else:
ortho2(-1.1, 1.1, -1.1, 1.1)
#
return wid
def available(nplanes):
return pow(2, nplanes) - 1 # Reserve one pixel for black
def fixcolormap():
multimap()
gconfig()
nplanes = getplanes()
if Gl.warnings:
print 'multimap mode has', nplanes, 'color planes'
imap = Gl.colormap
Gl.startindex = pow(2, nplanes) - 1
Gl.stopindex = 1
setmap(imap)
mapcolor(0, 0, 0, 0) # Fixed entry for black
if Gl.bg <> (0, 0, 0):
r, g, b = Gl.bg
mapcolor(1, r, g, b) # Fixed entry for Gl.bg
Gl.stopindex = 2
if Gl.fg <> (0, 0, 0):
r, g, b = Gl.fg
mapcolor(2, r, g, b) # Fixed entry for Gl.fg
Gl.stopindex = 3
Gl.overflow_seen = 0
resetindex()
def resetindex():
Gl.index = Gl.startindex
r0g0b0 = (0, 0, 0)
def pseudo_c3i(rgb):
if rgb == r0g0b0:
index = 0
elif rgb == Gl.bg:
index = 1
elif rgb == Gl.fg:
index = 2
else:
index = definecolor(rgb)
color(index)
def definecolor(rgb):
index = Gl.index
if index < Gl.stopindex:
if Gl.debug: print 'definecolor hard case', rgb
# First see if we already have this one...
for index in range(Gl.stopindex, Gl.startindex+1):
if rgb == getmcolor(index):
if Gl.debug: print 'return', index
return index
# Don't clobber reserverd colormap entries
if not Gl.overflow_seen:
# Shouldn't happen any more, hence no Gl.warnings test
print 'mclock: out of colormap entries'
Gl.overflow_seen = 1
return Gl.stopindex
r, g, b = rgb
if Gl.debug > 1: print 'mapcolor', (index, r, g, b)
mapcolor(index, r, g, b)
Gl.index = index - 1
return index
# Compute n**i
def pow(n, i):
x = 1
for j in range(i): x = x*n
return x
def mouseclick(mouse, updown, x, y):
if updown == 1:
# mouse button came down, start tracking
if Gl.debug:
print 'mouse', mouse, 'down at', x, y
if mouse == 2:
Gl.mouse2down = 1
mouse2track(x, y)
elif mouse == 3:
Gl.mouse3down = 1
mouse3track(x, y)
else:
print 'fatal error'
qdevice(MOUSEX)
qdevice(MOUSEY)
return 0
else:
# mouse button came up, stop tracking
if Gl.debug:
print 'mouse', mouse, 'up at', x, y
unqdevice(MOUSEX)
unqdevice(MOUSEY)
if mouse == 2:
mouse2track(x, y)
Gl.mouse2down = 0
elif mouse == 3:
mouse3track(x, y)
Gl.mouse3down = 0
else:
print 'fatal error'
Gl.alarm_set = 1
return 1
def mouse3track(x, y):
# first compute polar coordinates from x and y
cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
x, y = x - cx, y - cy
if (x, y) == (0, 0): return # would cause an exception
minutes = int(30.5 + 30.0*math.atan2(float(-x), float(-y))/pi)
if minutes == 60: minutes = 0
a,b = Gl.alarm_minutes/15, minutes/15
if (a,b) == (0,3):
# Moved backward through 12 o'clock:
Gl.alarm_hours = Gl.alarm_hours - 1
if Gl.alarm_hours < 0: Gl.alarm_hours = Gl.alarm_hours + 24
if (a,b) == (3,0):
# Moved forward through 12 o'clock:
Gl.alarm_hours = Gl.alarm_hours + 1
if Gl.alarm_hours >= 24: Gl.alarm_hours = Gl.alarm_hours - 24
Gl.alarm_minutes = minutes
seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
if seconds <> Gl.alarm_time:
draw_alarm(rgb_bg())
Gl.alarm_time = seconds
draw_alarm(rgb_fg())
def mouse2track(x, y):
# first compute polar coordinates from x and y
cx, cy = Gl.ox + Gl.cx/2, Gl.oy + Gl.cy/2
x, y = x - cx, y - cy
if (x, y) == (0, 0): return # would cause an exception
hours = int(6.5 - float(Gl.alarm_minutes)/60.0 + 6.0*math.atan2(float(-x), float(-y))/pi)
if hours == 12: hours = 0
if (Gl.alarm_hours,hours) == (0,11):
# Moved backward through midnight:
Gl.alarm_hours = 23
elif (Gl.alarm_hours,hours) == (12,11):
# Moved backward through noon:
Gl.alarm_hours = 11
elif (Gl.alarm_hours,hours) == (11,0):
# Moved forward through noon:
Gl.alarm_hours = 12
elif (Gl.alarm_hours,hours) == (23,0):
# Moved forward through midnight:
Gl.alarm_hours = 0
elif Gl.alarm_hours < 12:
Gl.alarm_hours = hours
else:
Gl.alarm_hours = hours + 12
seconds = Gl.alarm_hours * HOUR + Gl.alarm_minutes * MINUTE
if seconds <> Gl.alarm_time:
draw_alarm(rgb_bg())
Gl.alarm_time = seconds
draw_alarm(rgb_fg())
def initmenu():
Gl.pup = pup = newpup()
addtopup(pup, 'M Clock%t|Alarm On/Off|Seconds Hand On/Off|Quit', 0)
def handlemenu():
item = dopup(Gl.pup)
if item == 1:
# Toggle alarm
if Gl.alarm_set:
Gl.alarm_set = 0
Gl.alarm_on = 0
else:
Gl.alarm_set = 1
Gl.change = 1
clearall()
elif item == 2:
# Toggle Seconds Hand
if Gl.update == 1:
Gl.update = 60
Gl.timernoise = 60
else:
Gl.update = 1
Gl.timernoise = 6
Gl.change = 1
elif item == 3:
if Gl.debug: print 'Exit'
sys.exit(0)
main()

116
Demo/sgi/gl/mixing.py Executable file
View file

@ -0,0 +1,116 @@
#! /usr/local/python
# Use Gouraud shading to mix colors. Requires Z-buffer.
# It changes the color assignments so fast that you see white.
# Left button pauses, middle rotates the square. ESC to quit.
# Experiment with a larger window (too slow) or smaller window (really white).
from GL import *
from gl import *
import DEVICE
from math import *
#
# tekenvlak : draw a square. with bgnpolygon
#
def tekenvlak (vc) :
bgnpolygon()
#vcarray (vc)
for i in vc :
c3f (i[1])
v3f (i[0])
endpolygon()
#
# tekendoos : draw a box
#
def tekendoos (col) :
v = [(-5.0,0.0,0.0),(0.0,5.0,0.0),(5.0,0.0,0.0),(0.0,-5.0,0.0)]
vc = [(v[0],col[0]),(v[1],col[1]),(v[2],col[2]),(v[3],col[1])]
tekenvlak (vc)
#
# initialize gl
#
def initgl () :
#
# open window
#
foreground ()
keepaspect (1, 1)
prefposition (100, 500, 100, 500)
w = winopen ('PYTHON RGB')
keepaspect (1, 1)
winconstraints()
#
# configure pipeline (2buf, GOURAUD and RGBmode)
#
doublebuffer ()
zbuffer (1)
shademodel (GOURAUD)
RGBmode ()
gconfig ()
#
# set viewing
#
perspective (900, 1, 1.0, 10.0)
polarview (10.0, 0, 0, 0)
#
# ask for the REDRAW and ESCKEY events
#
qdevice(DEVICE.MOUSE2)
qdevice(DEVICE.MOUSE3)
qdevice(DEVICE.REDRAW)
qdevice(DEVICE.ESCKEY)
#
# the color black
#
black = 0
#
# GoForIT : use 2buf to redraw the object 2n times. index i is used as
# the (smoothly changing) rotation angle
#
def GoForIt(i) :
col = [(255.0,0.0,0.0), (0.0,255.0,0.0), (0.0,0.0,255.0)]
twist = 0
freeze = 1
while 1 :
if freeze <> 0 :
col[0],col[1],col[2] = col[1],col[2],col[0]
#
# clear z-buffer and clear background to light-blue
#
zclear()
cpack (black)
clear()
#
tekendoos (col)
#
swapbuffers()
#
if qtest() <> 0 :
dev, val = qread()
if dev == DEVICE.ESCKEY :
break
elif dev == DEVICE.REDRAW :
reshapeviewport ()
elif dev == DEVICE.MOUSE2 and val <> 0 :
twist = twist + 30
perspective (900, 1, 1.0, 10.0)
polarview (10.0, 0, 0, twist)
elif dev == DEVICE.MOUSE3 and val <> 0 :
freeze = 1 - freeze
# the main program
#
def main () :
initgl ()
GoForIt (0)
#
# exec main
#
main ()

171
Demo/sgi/gl/nurbs.py Executable file
View file

@ -0,0 +1,171 @@
#! /usr/local/python
# Rotate a 3D surface created using NURBS.
#
# Press left mouse button to toggle surface trimming.
# Press ESC to quit.
#
# See the GL manual for an explanation of NURBS.
from gl import *
from GL import *
from DEVICE import *
TRUE = 1
FALSE = 0
ORDER = 4
idmat = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1]
surfknots = [-1, -1, -1, -1, 1, 1, 1, 1]
def make_ctlpoints():
c = []
#
ci = []
ci.append(-2.5, -3.7, 1.0)
ci.append(-1.5, -3.7, 3.0)
ci.append(1.5, -3.7, -2.5)
ci.append(2.5, -3.7, -0.75)
c.append(ci)
#
ci = []
ci.append(-2.5, -2.0, 3.0)
ci.append(-1.5, -2.0, 4.0)
ci.append(1.5, -2.0, -3.0)
ci.append(2.5, -2.0, 0.0)
c.append(ci)
#
ci = []
ci.append(-2.5, 2.0, 1.0)
ci.append(-1.5, 2.0, 0.0)
ci.append(1.5, 2.0, -1.0)
ci.append(2.5, 2.0, 2.0)
c.append(ci)
#
ci = []
ci.append(-2.5, 2.7, 1.25)
ci.append(-1.5, 2.7, 0.1)
ci.append(1.5, 2.7, -0.6)
ci.append(2.5, 2.7, 0.2)
c.append(ci)
#
return c
ctlpoints = make_ctlpoints()
trimknots = [0., 0., 0., 1., 1., 2., 2., 3., 3., 4., 4., 4.]
def make_trimpoints():
c = []
c.append(1.0, 0.0, 1.0)
c.append(1.0, 1.0, 1.0)
c.append(0.0, 2.0, 2.0)
c.append(-1.0, 1.0, 1.0)
c.append(-1.0, 0.0, 1.0)
c.append(-1.0, -1.0, 1.0)
c.append(0.0, -2.0, 2.0)
c.append(1.0, -1.0, 1.0)
c.append(1.0, 0.0, 1.0)
return c
trimpoints = make_trimpoints()
def main():
init_windows()
setup_queue()
make_lights()
init_view()
#
set_scene()
setnurbsproperty( N_ERRORCHECKING, 1.0 )
setnurbsproperty( N_PIXEL_TOLERANCE, 50.0 )
trim_flag = 0
draw_trim_surface(trim_flag)
#
while 1:
while qtest():
dev, val = qread()
if dev == ESCKEY:
return
elif dev == WINQUIT:
dglclose(-1) # this for DGL only
return
elif dev == REDRAW:
reshapeviewport()
set_scene()
draw_trim_surface(trim_flag)
elif dev == LEFTMOUSE:
if val:
trim_flag = (not trim_flag)
set_scene()
draw_trim_surface(trim_flag)
def init_windows():
foreground()
#prefposition(0, 500, 0, 500)
wid = winopen('nurbs')
wintitle('NURBS Surface')
doublebuffer()
RGBmode()
gconfig()
lsetdepth(0x000, 0x7fffff)
zbuffer( TRUE )
def setup_queue():
qdevice(ESCKEY)
qdevice(REDRAW)
qdevice(RIGHTMOUSE)
qdevice(WINQUIT)
qdevice(LEFTMOUSE) #trimming
def init_view():
mmode(MPROJECTION)
ortho( -4., 4., -4., 4., -4., 4. )
#
mmode(MVIEWING)
loadmatrix(idmat)
#
lmbind(MATERIAL, 1)
def set_scene():
lmbind(MATERIAL, 0)
RGBcolor(150,150,150)
lmbind(MATERIAL, 1)
clear()
zclear()
#
rotate( 100, 'y' )
rotate( 100, 'z' )
def draw_trim_surface(trim_flag):
bgnsurface()
nurbssurface(surfknots, surfknots, ctlpoints, ORDER, ORDER, N_XYZ)
if trim_flag:
bgntrim()
nurbscurve(trimknots, trimpoints, ORDER-1, N_STW)
endtrim()
endsurface()
swapbuffers()
def make_lights():
lmdef(DEFLMODEL,1,[])
lmdef(DEFLIGHT,1,[])
#
# define material #1
#
a = []
a = a + [EMISSION, 0.0, 0.0, 0.0]
a = a + [AMBIENT, 0.1, 0.1, 0.1]
a = a + [DIFFUSE, 0.6, 0.3, 0.3]
a = a + [SPECULAR, 0.0, 0.6, 0.0]
a = a + [SHININESS, 2.0]
a = a + [LMNULL]
lmdef(DEFMATERIAL, 1, a)
#
# turn on lighting
#
lmbind(LIGHT0, 1)
lmbind(LMODEL, 1)
main()

168
Demo/sgi/gl/zrgb.py Executable file
View file

@ -0,0 +1,168 @@
#! /usr/local/python
# zrgb (Requires Z buffer.)
#
# This program demostrates zbuffering 3 intersecting RGB polygons while
# in doublebuffer mode where, movement of the mouse with the LEFTMOUSE
# button depressed will, rotate the 3 polygons. This is done by compound
# rotations allowing continuous screen-oriented rotations.
#
# Press the "Esc" key to exit.
from gl import *
from GL import *
from DEVICE import *
idmat=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
def main() :
#
# old and new mouse position
#
#
mode = 0
omx = 0
mx = 0
omy = 0
my = 0
#
objmat=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
#
initialize ()
#
draw_scene (objmat)
#
while (1) :
#
dev, val = qread()
#
if dev == ESCKEY :
if val :
break
# exit when key is going up, not down
# this avoids the scenario where a window
# underneath this program's window
# would otherwise "eat up" the up-
# event of the Esc key being released
return
#
elif dev == REDRAW :
reshapeviewport()
draw_scene(objmat)
#
elif dev == LEFTMOUSE:
omx = mx
omy = my
if val :
mode = 1
else :
mode = 0
elif dev == MOUSEX :
omx = mx
mx = val
#print omx, mx
objmat = update_scene(objmat,mx,my,omx,omy,mode)
#
elif dev == MOUSEY :
omy = my
my = val
#print omy, my
objmat = update_scene(objmat,mx,my,omx,omy,mode)
#
def initialize () :
#
foreground ()
keepaspect(5, 4)
w = winopen('Zbuffered RGB')
#
doublebuffer()
RGBmode()
gconfig()
zbuffer(1)
lsetdepth(0x0, 0x7FFFFF)
#
qdevice(ESCKEY)
qdevice(LEFTMOUSE)
qdevice(MOUSEX)
qdevice(MOUSEY)
def update_scene (mat, mx, my, omx, omy, mode) :
#
if mode == 1 :
mat = orient(mat, mx, my, omx, omy)
draw_scene(mat)
return mat
def orient (mat, mx, my, omx, omy) :
#
#
pushmatrix()
loadmatrix(idmat)
#
if mx - omx : rot (float (mx - omx), 'y')
if omy - my : rot (float (omy - my), 'x')
#
multmatrix(mat)
mat = getmatrix()
#
popmatrix()
#
return mat
def draw_scene (mat) :
RGBcolor(40, 100, 200)
clear()
zclear()
#
perspective(400, 1.25, 30.0, 60.0)
translate(0.0, 0.0, -40.0)
multmatrix(mat)
#
# skews original view to show all polygons
#
rotate(-580, 'y')
draw_polys()
#
swapbuffers()
polygon1 = [(-10.0,-10.0,0.0),(10.0,-10.0,0.0),(-10.0,10.0,0.0)]
polygon2 = [(0.0,-10.0,-10.0),(0.0,-10.0,10.0),(0.0,5.0,-10.0)]
polygon3 = [(-10.0,6.0,4.0),(-10.0,3.0,4.0),(4.0,-9.0,-10.0),(4.0,-6.0,-10.0)]
def draw_polys():
bgnpolygon()
cpack(0x0)
v3f(polygon1[0])
cpack(0x007F7F7F)
v3f(polygon1[1])
cpack(0x00FFFFFF)
v3f(polygon1[2])
endpolygon()
#
bgnpolygon()
cpack(0x0000FFFF)
v3f(polygon2[0])
cpack(0x007FFF00)
v3f(polygon2[1])
cpack(0x00FF0000)
v3f(polygon2[2])
endpolygon()
#
bgnpolygon()
cpack(0x0000FFFF)
v3f(polygon3[0])
cpack(0x00FF00FF)
v3f(polygon3[1])
cpack(0x00FF0000)
v3f(polygon3[2])
cpack(0x00FF00FF)
v3f(polygon3[3])
endpolygon()
main ()