diff --git a/Demo/sgi/gl/README b/Demo/sgi/gl/README new file mode 100644 index 00000000000..7a8caaeefb1 --- /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 00000000000..594b8ade259 --- /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 00000000000..6b58f12a9c9 --- /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 00000000000..009206506cd --- /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 00000000000..22285548cf1 --- /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 00000000000..64eb333822f --- /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 00000000000..e0245454dbd --- /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 00000000000..442759319b2 --- /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 00000000000..cf96158187e --- /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 00000000000..c066c4d05bd --- /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 00000000000..97c6bc63748 --- /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 00000000000..d986833d47b --- /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 00000000000..8fb982ee868 --- /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 00000000000..2208f33fb39 --- /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 00000000000..5a94dcbccb3 --- /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 00000000000..d6b9ecfe919 --- /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 00000000000..fb76aa9f395 --- /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 00000000000..fa018400e21 --- /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 ()