#include #include #include #include #include #include #include #include "Tunnel.h" using namespace std; #define N_INITIAL_LAYERS 5 #define N_LOGOS_PER_RING 12 #define RING_RADIUS 18 #define BREAKOFF_DIST 80 #define RING_LAYER_DIST 10 #define XLATE_RATE 0.02 #define REVOLUTION_TIME 15000 Tunnel::Tunnel() { m_last_ticks = 0; srand(time(NULL) + getpid()); } Tunnel::~Tunnel() { } bool Tunnel::expose (GnomeScreensaver & gs) { if (m_last_ticks == 0) { m_last_ticks = gs.getTicks(); m_start_ticks = m_last_ticks; } uint64_t ticks = gs.getTicks(); int elapsed = ticks - m_last_ticks; m_offset += XLATE_RATE * elapsed; while (m_offset - m_last_ring_offset > RING_LAYER_DIST) { m_last_ring_offset += RING_LAYER_DIST; addRing(m_last_ring_offset); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(360.0 * ((ticks - m_start_ticks) % REVOLUTION_TIME) / REVOLUTION_TIME, 0, 1, 0); for (list::const_iterator it = m_logos.begin(); it != m_logos.end(); it++) { glPushMatrix(); glTranslatef(0, m_offset - it->offset, 0); glRotatef(it->trot, 0, 1, 0); glTranslatef(RING_RADIUS, 0, 0); glRotatef(-90.0, 0, 0, 1); glRotatef(90.0, 1, 0, 0); glRotatef(it->zrot, 0, 0, 1); m_logobox.draw(); glPopMatrix(); } glPopMatrix(); m_last_ticks = ticks; return true; } void Tunnel::addRing(double offset) { for (int j = 0; j < N_LOGOS_PER_RING; j++) { float zrot = ((j + m_ring_rot_idx) & 0x3) * 90.0; float trot = j * 360.0 / N_LOGOS_PER_RING; LBStruct lbs = { offset, zrot, trot, {0, 0, 1} }; m_logos.push_back(lbs); } m_ring_rot_idx++; } bool Tunnel::configure (GnomeScreensaver & gs) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, gs.getAspectRatio() / gs.getNumMonitors(), 0.01, 1000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0, 0, 0, 0, 1, 0, 0, 0, 1); glViewport(0, 0, gs.getWidth(), gs.getHeight()); for (int i = 0; i <= N_INITIAL_LAYERS; i++) { addRing((i - N_INITIAL_LAYERS) * RING_LAYER_DIST); } m_offset = 0.0; m_last_ring_offset = 0.0; return true; } bool Tunnel::update (GnomeScreensaver & gs) { return true; }