--- /dev/null
+#include <stdio.h>
+#include <assert.h>
+#include "opengl.h"
+#include "app.h"
+#include "gmath/gmath.h"
+#include "mesh.h"
+#include "meshgen.h"
+#include "sdr.h"
+
+int win_width, win_height;
+float win_aspect;
+long time_msec;
+
+static float cam_theta, cam_phi;
+static Mesh *mesh_torus;
+
+static bool bnstate[16];
+static int prev_x, prev_y;
+
+static unsigned int sdr_grid;
+
+bool app_init(int argc, char **argv)
+{
+ if(init_opengl() == -1) {
+ return false;
+ }
+
+ glEnable(GL_MULTISAMPLE);
+
+ int aasamples = 0;
+ glGetIntegerv(GL_SAMPLES, &aasamples);
+ printf("got %d samples per pixel\n", aasamples);
+
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_DEPTH_TEST);
+ //glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+
+ Mesh::use_custom_sdr_attr = false;
+
+ mesh_torus = new Mesh;
+ gen_torus(mesh_torus, 1.0, 0.25, 32, 32);
+
+ if(!(sdr_grid = create_program_load("sdr/grid.v.glsl", "sdr/grid.p.glsl"))) {
+ return false;
+ }
+
+ return true;
+}
+
+void app_cleanup()
+{
+}
+
+void app_draw()
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ Mat4 view_mat;
+ view_mat.pre_rotate_x(deg_to_rad(cam_phi));
+ view_mat.pre_rotate_y(deg_to_rad(cam_theta));
+ view_mat.pre_translate(0, -1.65, 0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadMatrixf(view_mat[0]);
+
+ //mesh_torus->draw();
+
+ Mat4 xform;
+ xform.scaling(500.0);
+ glPushMatrix();
+ glMultMatrixf(xform[0]);
+
+ bind_program(sdr_grid);
+ glBegin(GL_QUADS);
+ glNormal3f(0, 1, 0);
+ glVertex3f(-1, 0, 1);
+ glVertex3f(1, 0, 1);
+ glVertex3f(1, 0, -1);
+ glVertex3f(-1, 0, -1);
+ glEnd();
+ bind_program(0);
+
+ glPopMatrix();
+
+ app_swap_buffers();
+ assert(glGetError() == GL_NO_ERROR);
+}
+
+void app_reshape(int x, int y)
+{
+ glViewport(0, 0, x, y);
+
+ Mat4 mat;
+ mat.perspective(deg_to_rad(50), win_aspect, 0.5, 500.0);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadMatrixf(mat[0]);
+}
+
+void app_keyboard(int key, bool pressed)
+{
+ if(pressed) {
+ switch(key) {
+ case 27:
+ app_quit();
+ break;
+ }
+ }
+}
+
+void app_mouse_button(int bn, bool pressed, int x, int y)
+{
+ bnstate[bn] = pressed;
+ prev_x = x;
+ prev_y = y;
+}
+
+void app_mouse_motion(int x, int y)
+{
+ int dx = x - prev_x;
+ int dy = y - prev_y;
+ prev_x = x;
+ prev_y = y;
+
+ if(!dx && !dy) return;
+
+ if(bnstate[0]) {
+ cam_theta += dx * 0.5;
+ cam_phi += dy * 0.5;
+
+ if(cam_phi < -90) cam_phi = -90;
+ if(cam_phi > 90) cam_phi = 90;
+ }
+ app_redraw();
+}