;;;; cube.scm - A simple OpenGL demo (very simple)

#>
#include <GL/glut.h>
<#

#>?
#define GL_COLOR_BUFFER_BIT			0x00004000
#define GL_DEPTH_BUFFER_BIT			0x00000100

#define GL_MATRIX_MODE				0x0BA0
#define GL_MODELVIEW				0x1700
#define GL_PROJECTION				0x1701
#define GL_TEXTURE				0x1702

#define GLAPI
#define GLAPIENTRY

typedef unsigned int	GLenum;
typedef float		GLclampf;	/* single precision float in [0,1] */
typedef unsigned int	GLbitfield;
typedef float		GLfloat;	/* single precision float */
typedef double		GLdouble;	/* double precision float */
typedef int		GLsizei;	/* 4-byte signed */
typedef int		GLint;		/* 4-byte signed */

GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
GLAPI void GLAPIENTRY glClear( GLbitfield mask );
GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue );
GLAPI void GLAPIENTRY glMatrixMode( GLenum mode );
GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right,
                                 GLdouble bottom, GLdouble top,
                                 GLdouble near_val, GLdouble far_val );
GLAPI void GLAPIENTRY glViewport( GLint x, GLint y,
                                    GLsizei width, GLsizei height );
GLAPI void GLAPIENTRY glPushMatrix( void );
GLAPI void GLAPIENTRY glPopMatrix( void );
GLAPI void GLAPIENTRY glLoadIdentity( void );
GLAPI void GLAPIENTRY glRotatef( GLfloat angle,
                                   GLfloat x, GLfloat y, GLfloat z );
GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z );

GLAPI void GLAPIENTRY gluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);

#define GLUT_DOUBLE			2
#define GLUT_SINGLE			0
#define GLUT_RGB			0

#define GLUTAPI
#define GLUTAPIENTRY

GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
GLUTAPI void GLUTAPIENTRY glutMainLoop(void);
GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title);
GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void *);
GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size);
GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void *);
GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void *);
GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void *, int value);
GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void);
GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void);
<#

(define wait 25)
(define rot 0)
(define light-pos '#f32(-50 50 -100 0))


(define-external (render_scene) void
  (glClear (+ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
  (glMatrixMode GL_MODELVIEW)
  (glPushMatrix)
  (glTranslatef 0 0 -300)
  (glColor3f 1 0 0)
  (glRotatef rot 0 1 0)
  (glutWireCube 100)
  (glPopMatrix)
  (set! rot (+ rot 1))
  (glutSwapBuffers) ) 

(define-external (change_size (int w) (int h)) void
  (when (zero? h) (set! h 1))
  (glViewport 0 0 w h)
  (glMatrixMode GL_PROJECTION)
  (glLoadIdentity)
  (let ([aspect (/ w h)])
    (gluPerspective 45 aspect 1 425) )
  (glMatrixMode GL_MODELVIEW)
  (glLoadIdentity) )

(define-external (timer_function (int val)) void
  (glutPostRedisplay)
  (glutTimerFunc wait (location timer_function) 1) )

(define-external (keyboard_handler (char key) (int x) (int y)) void
  (exit) )

(glutInitDisplayMode (+ GLUT_DOUBLE GLUT_RGB))
(glutCreateWindow "oink!")
(glutDisplayFunc (location render_scene))
(glutReshapeFunc (location change_size))
(glutTimerFunc wait (location timer_function) 1)
(glutKeyboardFunc (location keyboard_handler))
(glClearColor 0 0 0 1)

(glutMainLoop) 
