Doris

patterns.lua

This just draws some objects and allows you to spin them round. There a switches for turning clearing of the colour and depth buffers on and off. With some experimentation you can make quite nice patterns.

Screenshot

patterns.lua screenshot

Source Code


-- Patterns
-- Based on an idea on: http://www.dev-gallery.com/
-- $Id: patterns.lua,v 1.3 2002/06/20 18:16:30 trout Exp $

options = {
  clearZ = 1, -- should we clear the Z buffer before redraw
  clearColour = 1, -- should we clear the colour buffer before redraw
  colourMaterials = 1, -- use coloured materials?
  lit = 1 -- is the scene lit?
}

-- Lua utilities
-- (c) Reuben Thomas 2000 -- tostring and print -- Thanks Reuben!
-- Source: http://www.lua-users.org/wiki/ReubensUtilLib

-- tostring: Extend tostring to work better on tables
-- TODO: make it output in {v1, v2 ..; x1=y1, x2=y2 ..} format; use
-- nexti; show the n field (if any) on the RHS
--   x: object to convert to string
-- returns
--   s: string representation
function tostring(x,indent)
  indent = indent or 1
  local s
  if type(x) == "table" then
    s = "{"
    local i, v = next(x)
    while i do
      s = s .. tostring(i) .. "=" .. tostring(v)
      i, v = next(x, i)
      if i then
        s = s .. ",\n"
      end
    end
    return s .. "} "
  end
  return %tostring(x)
end

-- print: Extend print to work better on tables
--   arg: objects to print
function print(...)
  for i = 1, getn(arg) do
    arg[i] = tostring(arg[i])
  end
  call(%print, arg)
end

Colours = {
    colours = {
        {.8,0,0},{0,.8,0},{1,.8,0},{0,0,.8},{0,1,.6},{.5,0,.4}
    },
    nb = 1
}

function Colours:get()
    local col = self.colours[self.nb]
    self.nb = self.nb+1
    if self.nb>getn(self.colours) then self.nb=1 end
    return col
end


function createBasicScene()
  print("Creating basic scene")
  local scene = { transforms={} }
  local frames = {}
  
  -- inner/central transform
  local rot = Matrix:new()
  tinsert(scene.transforms, { "rotator", "Rotate all", rot })
  local trans = {}
  tinsert(scene.transforms, { "translate", "Translate all", trans })
  local render = function()
        glMultMatrix(%rot)
        glColor(Colours:get())
        glutSolidTorus(0.4,1.0,15,10)
        glRotate(90,1,0,0)
        glColor(Colours:get())
        glutSolidTorus(0.4,1.0,15,10)
      end
  tinsert(frames,render)

  -- create outer objects  -- transform for all of them
  rot = Matrix:new()
  tinsert(scene.transforms, { "rotator", "Rotate outer", rot })
  trans = {}
  tinsert(scene.transforms, { "translate", "Translate outer", trans })
  local nb = 16 -- number of objects
  
  -- draw each object
  for i = 0,nb-1 do
    render = function()
          glPushMatrix()
            local angle = %i * 360/%nb
            -- position relative to centre
            glRotate(angle, 0,1,0)
            glTranslate(0,0,3)
            glMultMatrix(%rot)
            -- choose colour and draw object
            glColor(Colours:get())
            glutSolidTorus(0.4,1.0,15,10)
          glPopMatrix()      
        end
    tinsert(frames, render) -- add to render list
  end

  scene.frames = frames  
  return scene
end


-- Recursive function for rendering frames.
-- Where we encounter a new table we start a new coordinate frame.
-- Objects in the table are render functions.
function renderFrame(s)
  if type(s)=="table" then
    glPushMatrix()
    for i = 1,getn(s) do renderFrame(s[i]) end
    glPopMatrix()
  else
    s() -- render object
  end
end


-- The scene render callback function.
function renderScene()
  -- clear chosen buffers
  if options.clearZ~=0 then
    glClear(GL_DEPTH_BUFFER_BIT)
  end
  if options.clearColour~=0 then
    glClear(GL_COLOR_BUFFER_BIT)
  end
  -- set up view
  gluLookAt(0,0,15, 0,0,0, 0,1,0)
  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  -- draw
  renderFrame(scene.frames)
end

function initScene()
  -- set up scene
  glEnable(GL_LIGHTING)
  glEnable(GL_LIGHT0)
  glLight(GL_LIGHT0, GL_POSITION, {10,10,10})
  glLight(GL_LIGHT0, GL_AMBIENT, {.3,.3,.3})
  glEnable(GL_COLOR_MATERIAL)
  glClearColor(.9,.9,.9,1.0)
  
  scene = createBasicScene() -- set global scene
  if _DEVELOP then
    print(scene) -- for debugging, print out table
  end
end

-- Create the main window
wmain = Window:create{
    title = "Doris: Colourful patterns",
    render = renderScene
}

initScene()

-- Add a window at the side to the right
sw=SubWindow{ parent=wmain, side="right" }

sub = Rollout{ parent=sw, text="Options", open=1 }

Checkbox{ parent=sub, text="Clear z buffer",
    value = options.clearZ,
    update = function (b) options.clearZ = b end
}

Checkbox{ parent=sub, text="Clear colour buffer",
    value = options.clearColour,
    update = function (b) options.clearColour = b end
}

glswitch = { [0] = glDisable, [1] = glEnable }

Checkbox{ parent=sub, text="Lighting",
    value = options.lit,
    update = function (b)
            options.clearColour = b
            glswitch[b](GL_LIGHTING)
          end
}

sub = Rollout{ parent=sw, text="Manual control", open=1 }

-- Create transform widgets specified in scene
for i=1,getn(scene.transforms) do
    local t = scene.transforms[i]
    print("Transform:",t)
    ttype,name,var = t[1],t[2],t[3]
    if ttype=="rotator" then
      Rotator{ parent=sub, value=var, line="h", text=name, spin=1 }
    elseif ttype=="translator" then
    end
end


Back