--- /dev/null
+src = $(wildcard src/*.cc)
+obj = $(src:.cc=.o)
+dep = $(obj:.o=.d)
+bin = splines
+
+dbg = -g
+opt = -O0
+inc = -Isrc
+
+CXX = g++
+CXXFLAGS = -pedantic -Wall $(dbg) $(opt) $(inc)
+LDFLAGS = -lGL -lGLU -lglut -lGLEW -limago -lgmath
+
+$(bin): $(obj)
+ $(CXX) -o $@ $(obj) $(LDFLAGS)
+
+-include $(dep)
+
+%.d: %.cc
+ @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
+
+.PHONY: clean
+clean:
+ rm -f $(obj) $(bin) $(dep)
--- /dev/null
+#include <GL/glew.h>
+#include <GL/glut.h>
+#include <stdio.h>
+
+#include "tentacle.h"
+
+static bool init();
+static void cleanup();
+
+static void display();
+static void keyboard(unsigned char key, int x, int y);
+
+/* XXX FIXME */
+static Tentacle tentacle;
+
+int main(int argc, char **argv)
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(800, 600);
+ glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
+
+ glutCreateWindow("ludu mice");
+ glutDisplayFunc(display);
+ glutKeyboardFunc(keyboard);
+
+ if (!init())
+ exit(1);
+
+ atexit(cleanup);
+
+ glutMainLoop();
+}
+
+static bool init()
+{
+ glewInit();
+ glClearColor(1.0, 1.0, 0.0, 1.0);
+
+ if (!tentacle.init()) {
+ fprintf(stderr, "Failed to initialize tentacle control points.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void cleanup()
+{
+}
+
+static void display()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ //XXX FIXME
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ tentacle.draw();
+
+ glutSwapBuffers();
+}
+
+static void keyboard(unsigned char key, int x, int y)
+{
+ switch(key) {
+ case 27:
+ exit(0);
+ default:
+ break;
+ }
+}
--- /dev/null
+#include <GL/gl.h>
+#include "tentacle.h"
+
+Tentacle::Tentacle()
+{
+}
+
+Tentacle::~Tentacle()
+{
+}
+
+bool
+Tentacle::init()
+{
+ for (int i=0; i<5; i++) {
+ add_control_point(Vec3(0.5, i / 10.0, 0.0));
+ }
+ return true;
+}
+
+void
+Tentacle::add_control_point(const Vec3 &point)
+{
+ cpoints.push_back(point);
+}
+
+void
+Tentacle::draw()
+{
+ glLineWidth(2.0);
+ glBegin(GL_LINE_STRIP);
+ glColor3f(0.0, 0.0, 1.0);
+ for(size_t i=0; i<cpoints.size(); i++) {
+ glVertex3f(cpoints[i].x, cpoints[i].y, cpoints[i].z);
+ }
+ glEnd();
+
+ // XXX DEBUG
+ glDisable(GL_DEPTH_TEST);
+ glPointSize(5.0);
+ glBegin(GL_POINTS);
+ glColor3f(1.0, 0.0, 0.0);
+ for(size_t i=0; i<cpoints.size(); i++) {
+ glVertex3f(cpoints[i].x, cpoints[i].y, 1.0);
+ }
+ glEnd();
+ glEnable(GL_DEPTH_TEST);
+}
--- /dev/null
+#ifndef TENTACLE_H_
+#define TENTACLE_H_
+
+#include <vector>
+#include <gmath/gmath.h>
+
+class Tentacle {
+private:
+ std::vector<Vec3> cpoints;
+
+public:
+ Tentacle();
+ ~Tentacle();
+
+ bool init();
+ void add_control_point(const Vec3 &point);
+ void draw();
+};
+
+#endif // TENTACLE_H_