using Tao.Sdl; using Tao.Sdl.Sdl; using Tao.OpenGl; using Tao.OpenGl.Gl; using Tao.OpenGl.Glu; using Nemerle.IO; variant Node { | Separator { children : list [Node]; } | Translation { x : double; y : double; z : double; } | Material { r : double; g : double; b : double; } | Cube } module sdltest { DrawCube () : void { def coords = array [ (-1.0, -1.0, -1.0), (1.0, -1.0, -1.0), (1.0, 1.0, -1.0), (-1.0, 1.0, -1.0), (-1.0, -1.0, 1.0), (1.0, -1.0, 1.0), (1.0, 1.0, 1.0), (-1.0, 1.0, 1.0) ]; def draw_quad (a, b, c, d) { glBegin (GL_LINES); glVertex3d (coords [a]); glVertex3d (coords [b]); glVertex3d (coords [b]); glVertex3d (coords [c]); glVertex3d (coords [c]); glVertex3d (coords [d]); glVertex3d (coords [d]); glVertex3d (coords [a]); glEnd (); } glPushMatrix (); draw_quad (0, 1, 2, 3); draw_quad (4, 5, 6, 7); draw_quad (1, 5, 6, 2); draw_quad (0, 4, 7, 3); glPopMatrix (); } mutable cam_rx : double; mutable cam_ry : double; mutable cam_rz : double; DrawScene (scene : Node) : void { glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glClear (GL_COLOR_BUFFER_BIT); glLoadIdentity (); gluLookAt (-10.0, -10.0, -10.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0); glRotated (cam_rx, 1.0, 0.0, 0.0); glRotated (cam_ry, 0.0, 1.0, 0.0); glRotated (cam_rz, 0.0, 0.0, 1.0); DisplayNode (scene); Sdl.SDL_GL_SwapBuffers (); } DisplayNode (n : Node) : void { match (n) { | Node.Separator (nodes) => glPushMatrix (); glPushAttrib (GL_CURRENT_BIT); foreach (n in nodes) DisplayNode (n); glPopAttrib (); glPopMatrix (); | Node.Translation (x, y, z) => glTranslated (x, y, z); | Node.Material (r, g, b) => glColor3d (r, g, b); | Node.Cube => DrawCube (); } } Optimize (n : Node) : Node { match (n) { | Node.Separator ([(Node.Cube) as c]) => c | x => x } } Main () : void { def _ = Sdl.SDL_Init (Sdl.SDL_INIT_VIDEO %| Sdl.SDL_INIT_TIMER); Sdl.SDL_WM_SetCaption ("Nemerle + SDL + OpenGl test", null); def _ = Sdl.SDL_SetVideoMode (800, 600, 0, Sdl.SDL_OPENGL); def scene = Node.Separator ( [Node.Material (1.0, 0.6, 0.0), Node.Separator ([ Node.Translation (-2.0, -2.0, 0.0), Node.Cube () ]), Node.Separator ([ Node.Translation (-2.0, 2.0, 0.0), Node.Cube () ]), Node.Separator ([ Node.Translation (2.0, -2.0, 0.0), Node.Cube () ]), Node.Separator ([ Node.Translation (2.0, 2.0, 0.0), Node.Cube () ]) ] ); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (45.0, 800.0 / 600.0, 0.1, 100.0); glMatrixMode (GL_MODELVIEW); def loop () { DrawScene (scene); mutable evt = SDL_Event (); _ = SDL_PollEvent (out evt); def ty = evt.@type :> int; if (ty == SDL_QUIT) {} else { when (ty == SDL_MOUSEMOTION) { def mul = 1.0; def dx = (evt.motion.xrel :> double) * mul; def dy = (evt.motion.yrel :> double) * mul; def state = evt.motion.state :> int; if (state & 1 != 0) { cam_rx += dx; cam_ry += dy; } else if (state & 4 != 0) { cam_rz += (dx + dy) / 2.0; } else {} } loop (); } } loop (); } } // REFERENCE: Tao.Sdl.dll // REFERENCE: Tao.OpenGl.dll