fp - Haskell Community Server

parakeetincurableΛογισμικό & κατασκευή λογ/κού

13 Δεκ 2013 (πριν από 3 χρόνια και 8 μήνες)

78 εμφανίσεις

FunWorlds

the story continues..

Fp group, 04/07/2002


work
-
in
-
progress overview

Claus Reinke

Background & Goals


turn computers into expressive tools..


create a platform for functional graphics


look at language design issues at the
borders between


functional programming


3d graphics & animation (

HCIs)


concurrent systems


Input from: Fran, VRML, process
calculi,..

The story so far..


Various works on functional graphics..


Fran (Elliot et.al.)


functional reactive
animation as a DSL embedded in
Haskell


FunWorlds/VRML (myself)


experiments in merging ideas from Fran
and VRML; realized as an embedded
compiler generating
VRML+ECMAScript from programs in
another Haskell DSEL

VRML'97


Declarative description

of static scene graphs
,
combined with sensor
nodes and event routing


Imperative script nodes

and
external authoring
interface

for complex
scenes and animations
(Java, ECMAScript)


Authoring tools

generate complex
scene elements

Script

routes

eventOuts

eventIns

Transform/group

geometry

External authoring

sensor

Fran


Behaviour a

continuous time
dependent values


Event a

streams of time
-
stamped values


Mutually recursive
integral equations,
interspersed with
reactivity and with fp

t

a

t

a

predicate

stepper

until/then

snapshot

fp

Problems with Fran?


Focus on combinators & 2d graphics


3d
shapes can be imported and animated by
external transformation behaviours, but they
don't behave themselves


Monolithic approach to behaviours and
events (functions from times to values,
streams of all events)


leads to lots of low
-
level trickery


the history of functional i/o taught us to first to hide
stream
-
plumbing, then to dump monolithic/global
approaches in favour of stepwise/local ones


There is definitely something fishy going on
with user arguments and integral start times

Opportunities for Fran?


It gets a lot of things right, but it makes
you feel as if it tried to make too many
things look the same, being too abstract
for its own good


not everything is best expressed as an
eternal set of mutually recursive integral
equations in global time


concurrency & communication!


reactivity? progress/change (without u)?

Where to, then?


more clearly
distinguish behaviour
descriptions from their evaluation


Move away from monolithic/global
descriptions in favour of
stepwise/local

ones


use ideas from process calculi to specify
concurrency and communication


get rid of global time in favour of
local clocks

(keep implicitly globally synchronized
evaluation for now)


drop idealised continuity in favour of
stepped
approximations (or: let's be practical;
-
)

Interlude
-

OpenGL


OpenGL is a widely implemented industry
standard for 2d/3d graphics


Software implementation possible, but more
typically, it's
the API by which to program
special
-
purpose graphics boards


A rare occasion of special
-
purpose hardware
paying off


two separate processors in your
machine! Good graphics engines get
impressive results, bad ones the CPU won't
rescue ..


The API is
thoroughly imperative
, and close
to the metal; you set state elements, then
keep throwing vectors at the pipeline,
grouped into simple objects (typically
polygons)

The OpenGL rendering
pipeline

Source:
The Design

of the

OpenGL Graphics Interface

Mark Segal Kurt Akeley

Silicon Graphics Computer Systems

2011 N. Shoreline Blvd., Mountain View, CA 94039

http://www.opengl.org/developers/documentation/white_papers/opengl/


The OpenGL rendering state


Rendering pipeline is modal, with results
depending on setable/getable internal state


Current colour; Lighting on/off


Shading flat/smooth (shading, not shadows!)


Depth
-
buffering; blending; texturing; ..


Matrix stack


Model
-
view matrices (transform the scene or the
"camera" position)


Projection matrix (project the scene onto viewport)


Texture matrix

/* Copyright (c) 1993
-
1999, Silicon Graphics,

Inc.

..

OpenGL(R) is a registered trademark of

Silicon Graphics, Inc. */


#include <GL/glut.h>

#include <stdlib.h>

static int year = 0, day = 0;

void init(void)

{


glClearColor (0.0, 0.0, 0.0, 0.0);


glShadeModel (GL_FLAT);

}


void display(void)

{


glClear (GL_COLOR_BUFFER_BIT);


glColor3f (1.0, 1.0, 1.0);



glPushMatrix();


glutWireSphere(1.0, 20, 16); /* sun */


glRotatef ((GLfloat) year, 0.0, 1.0, 0.0);


glTranslatef (2.0, 0.0, 0.0);


glRotatef ((GLfloat) day, 0.0, 1.0, 0.0);


glutWireSphere(0.2, 10, 8); /* smaller planet */


glPopMatrix();


glutSwapBuffers();

}

void reshape (int w, int h)

{ glViewport (0, 0, (GLsizei) w, (GLsizei) h);


glMatrixMode (GL_PROJECTION);


glLoadIdentity ();


gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);


glMatrixMode(GL_MODELVIEW);


glLoadIdentity();


gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);}


void keyboard (unsigned char key, int x, int y)

{ switch (key) {


case 'd': day = (day + 10) % 360;




glutPostRedisplay(); break;

...


case 27: exit(0); break; default: break; }}


int main(int argc, char** argv)

{ glutInit(&argc, argv);


glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);


glutInitWindowSize (500, 500);


glutInitWindowPosition (100, 100);


glutCreateWindow (argv[0]);


init ();


glutDisplayFunc(display);


glutReshapeFunc(reshape);


glutKeyboardFunc(keyboard);


glutMainLoop();


return 0;}

Interlude
-

HOpenGL


Sven Panne's Haskell binding to OpenGL


on windows systems, grab ghc
-
5.02.3, recent
greencard and cygwin, and HOpenGL1.2;
straightforward installation and use as a new ghc
package; includes bindings to GLU and GLUT; get
it from
www.haskell.org/HOpenGL/



comes with no docs, but with all examples from
the OpenGL programming guide (in both Haskell
and C forms); the API is a slightly sanitized
version of the original, so the original docs apply
(see
www.opengl.org

for specs, docs, tutorials,
stories..)


OpenGL is available on most platforms, typically
with hw
-
support; HOpenGL is currently limited to
GHC, but is expected to switch to the new FFI

{
-

Planet.hs
..

Copyright(C) 2000 Sven Panne
..
-
}

import IOExts(IORef, newIORef, readIORef,




writeIORef)

import System(ExitCode(..), exitWith)

import GL

import GLU

import GLUT


myInit :: IO ()

myInit = do


clearColor (Color4 0.0 0.0 0.0 0.0)


shadeModel GL.Flat


display :: IORef Int
-
>IORef Int
-
>DisplayAction

display day year = do


clear [ColorBufferBit]


color (Color3 1.0 1.0 1.0 :: Color3 GLfloat)


pushMatrix


wireSphere 1.0 20 16
--

draw sun


y <
-

readIORef year


rotate (fromIntegral y::GLfloat) (Vector3 0 1 0)


translate (Vector3 2 0 0 :: Vector3 GLfloat)


d <
-

readIORef day


rotate (fromIntegral d::GLfloat) (Vector3 0 1 0)


wireSphere 0.2 10 8
--

draw smaller planet


popMatrix


swapBuffers

reshape :: ReshapeAction

reshape screenSize@(WindowSize w h) = do


viewport (WindowPosition 0 0) screenSize


matrixMode Projection


loadIdentity


perspective 60.0 (fromIntegral w/fromIntegral h) 1.0 20.0


matrixMode Modelview


loadIdentity


lookAt (0.0, 0.0, 5.0) (0.0, 0.0, 0.0) (0.0, 1.0, 0.0)

..

keyboard :: IORef Int
-
> IORef Int
-
> KeyboardAction

keyboard day _ 'd' _ = do


updateIORef day (
\
d
-
> (d+10) `mod` 360);


postRedisplay

..

keyboard _ _ '
\
27' _ = exitWith ExitSuccess

keyboard _ _ _ _ = return ()


main = do


(progName, _args) <
-

GLUT.init Nothing


day <
-

newIORef 0


year <
-

newIORef 0


createWindow progName (display day year)




[GLUT.Double, GLUT.Rgb ]


(Just (WindowPosition 100 100))


(Just (WindowSize 500 500))


myInit


reshapeFunc (Just reshape)


keyboardFunc (Just (keyboard day year))


mainLoop

FunWorlds as a scene graph
library


Who wants to bother with those details?


Let users specify scene graphs, a la VRML


Add behaviours, a la Fran


Add communication a la process calculi


Fiddle with design until satisfied

(never!
-
)


Translate the resulting "
communicating
concurrent behavioural scene graphs"

or
whatever into GLUT callbacks and
instructions for the OpenGL rendering
pipeline..

module Main where

import Behavior

import Scene

import FunWorlds


main :: IO ()

main = start (KeyBoard scene)


scene keyb =


Group [ Appearance{material=colored $




Color4 1 1 1 1}



, sun, planet ]


where


sun = Sphere 1


planet = Rotate (R year (Vector3 0 1 0)) $


Translate (Vector3 2 0 0) $


Rotate (R day (Vector3 0 1 0)) $


Sphere 0.2



key = Observe Nothing keyb


keyPressed p = lift1 (maybe False p) key




year, day :: Beh GLdouble


year = integral (ifB (keyPressed (=='y')) 5


(ifB (keyPressed (=='Y')) (
-
5)


0))



day = integral (ifB (keyPressed (=='d')) 10


(ifB (keyPressed (=='D')) (
-
10)


0))


Use the source, Luke!
-
)


From here, it's source code, examples,
whiteboard, and hand
-
waving..