summaryrefslogtreecommitdiffstats
path: root/Demo/sgi/gl
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-03-30 13:18:37 (GMT)
committerGuido van Rossum <guido@python.org>1992-03-30 13:18:37 (GMT)
commit453bd408bdd9287bb020e6ec5411983c8d176c89 (patch)
treec92cf78d2e602855b408990ed510819657cab3fa /Demo/sgi/gl
parent6da6aebfdb680a5340deae59088f9e68525723b5 (diff)
downloadcpython-453bd408bdd9287bb020e6ec5411983c8d176c89.zip
cpython-453bd408bdd9287bb020e6ec5411983c8d176c89.tar.gz
cpython-453bd408bdd9287bb020e6ec5411983c8d176c89.tar.bz2
Initial revision
Diffstat (limited to 'Demo/sgi/gl')
-rw-r--r--Demo/sgi/gl/README29
-rwxr-xr-xDemo/sgi/gl/backface.py140
-rw-r--r--Demo/sgi/gl/glstdwin/fontchart.py34
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwdraw.py135
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwin.py400
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwmenu.py60
-rw-r--r--Demo/sgi/gl/glstdwin/glstdwwin.py139
-rw-r--r--Demo/sgi/gl/glstdwin/stdwingl.py10
-rw-r--r--Demo/sgi/gl/glstdwin/tcolor.py43
-rw-r--r--Demo/sgi/gl/glstdwin/tglsw.py70
-rw-r--r--Demo/sgi/gl/glstdwin/tmenu.py44
-rwxr-xr-xDemo/sgi/gl/kites.py194
-rwxr-xr-xDemo/sgi/gl/kunst.py446
-rwxr-xr-xDemo/sgi/gl/mclock.doc60
-rwxr-xr-xDemo/sgi/gl/mclock.py731
-rwxr-xr-xDemo/sgi/gl/mixing.py116
-rwxr-xr-xDemo/sgi/gl/nurbs.py171
-rwxr-xr-xDemo/sgi/gl/zrgb.py168
18 files changed, 2990 insertions, 0 deletions
diff --git a/Demo/sgi/gl/README b/Demo/sgi/gl/README
new file mode 100644
index 0000000..7a8caae
--- /dev/null
+++ b/Demo/sgi/gl/README
@@ -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.
diff --git a/Demo/sgi/gl/backface.py b/Demo/sgi/gl/backface.py
new file mode 100755
index 0000000..594b8ad
--- /dev/null
+++ b/Demo/sgi/gl/backface.py
@@ -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 ()
diff --git a/Demo/sgi/gl/glstdwin/fontchart.py b/Demo/sgi/gl/glstdwin/fontchart.py
new file mode 100644
index 0000000..6b58f12
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/fontchart.py
@@ -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()
diff --git a/Demo/sgi/gl/glstdwin/glstdwdraw.py b/Demo/sgi/gl/glstdwin/glstdwdraw.py
new file mode 100644
index 0000000..0092065
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/glstdwdraw.py
@@ -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)
+ #
diff --git a/Demo/sgi/gl/glstdwin/glstdwin.py b/Demo/sgi/gl/glstdwin/glstdwin.py
new file mode 100644
index 0000000..2228554
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/glstdwin.py
@@ -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
diff --git a/Demo/sgi/gl/glstdwin/glstdwmenu.py b/Demo/sgi/gl/glstdwin/glstdwmenu.py
new file mode 100644
index 0000000..64eb333
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/glstdwmenu.py
@@ -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
+ #
diff --git a/Demo/sgi/gl/glstdwin/glstdwwin.py b/Demo/sgi/gl/glstdwin/glstdwwin.py
new file mode 100644
index 0000000..e024545
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/glstdwwin.py
@@ -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
+ #
diff --git a/Demo/sgi/gl/glstdwin/stdwingl.py b/Demo/sgi/gl/glstdwin/stdwingl.py
new file mode 100644
index 0000000..4427593
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/stdwingl.py
@@ -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
diff --git a/Demo/sgi/gl/glstdwin/tcolor.py b/Demo/sgi/gl/glstdwin/tcolor.py
new file mode 100644
index 0000000..cf96158
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/tcolor.py
@@ -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()
diff --git a/Demo/sgi/gl/glstdwin/tglsw.py b/Demo/sgi/gl/glstdwin/tglsw.py
new file mode 100644
index 0000000..c066c4d
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/tglsw.py
@@ -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.'
diff --git a/Demo/sgi/gl/glstdwin/tmenu.py b/Demo/sgi/gl/glstdwin/tmenu.py
new file mode 100644
index 0000000..97c6bc6
--- /dev/null
+++ b/Demo/sgi/gl/glstdwin/tmenu.py
@@ -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()
diff --git a/Demo/sgi/gl/kites.py b/Demo/sgi/gl/kites.py
new file mode 100755
index 0000000..d986833
--- /dev/null
+++ b/Demo/sgi/gl/kites.py
@@ -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 ()
diff --git a/Demo/sgi/gl/kunst.py b/Demo/sgi/gl/kunst.py
new file mode 100755
index 0000000..8fb982e
--- /dev/null
+++ b/Demo/sgi/gl/kunst.py
@@ -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)
diff --git a/Demo/sgi/gl/mclock.doc b/Demo/sgi/gl/mclock.doc
new file mode 100755
index 0000000..2208f33
--- /dev/null
+++ b/Demo/sgi/gl/mclock.doc
@@ -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"
diff --git a/Demo/sgi/gl/mclock.py b/Demo/sgi/gl/mclock.py
new file mode 100755
index 0000000..5a94dcb
--- /dev/null
+++ b/Demo/sgi/gl/mclock.py
@@ -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()
diff --git a/Demo/sgi/gl/mixing.py b/Demo/sgi/gl/mixing.py
new file mode 100755
index 0000000..d6b9ecf
--- /dev/null
+++ b/Demo/sgi/gl/mixing.py
@@ -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 ()
diff --git a/Demo/sgi/gl/nurbs.py b/Demo/sgi/gl/nurbs.py
new file mode 100755
index 0000000..fb76aa9
--- /dev/null
+++ b/Demo/sgi/gl/nurbs.py
@@ -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()
diff --git a/Demo/sgi/gl/zrgb.py b/Demo/sgi/gl/zrgb.py
new file mode 100755
index 0000000..fa01840
--- /dev/null
+++ b/Demo/sgi/gl/zrgb.py
@@ -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 ()