diff --git a/dwss.cc b/dwss.cc index b696e12..89d4f66 100644 --- a/dwss.cc +++ b/dwss.cc @@ -44,8 +44,8 @@ int main (int argc, char *argv[]) glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); + modes[0]->configure(gs); current_mode = modes[0]; - current_mode->configure(gs); gs.mainloop(); diff --git a/modes/Spin.cc b/modes/Spin.cc index 07d3377..de1d084 100644 --- a/modes/Spin.cc +++ b/modes/Spin.cc @@ -1,27 +1,71 @@ +#include +#include + #include #include #include "Spin.h" +#define SWITCH_TIME 5000 + +static const float directions[][3] = { + {0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0} +}; + +Spin::Spin() +{ + m_num_monitors = 1; + m_directions = new int[m_num_monitors]; + m_directions[0] = 1; + m_rotations = new matrix_t[m_num_monitors]; + glGetFloatv(GL_MODELVIEW_MATRIX, &m_rotations[0][0]); + m_last_switch_ticks = 0; + m_last_ticks = 0; + srand(time(NULL)); +} + +Spin::~Spin() +{ + delete[] m_directions; + delete[] m_rotations; +} + bool Spin::expose (GnomeScreensaver & gs) { - int n_monitors = gs.getNumMonitors(); - int width = gs.getWidth() / n_monitors; + if (m_last_ticks == 0) + m_last_switch_ticks = m_last_ticks = gs.getTicks(); + else if (gs.getTicks() - m_last_switch_ticks > SWITCH_TIME) + { + for (int i = 0; i < m_num_monitors; i++) + { + m_directions[i] = (int) (rand() / (double)RAND_MAX * + sizeof(directions) / sizeof(directions[0])); + if (m_directions[i] >= sizeof(directions) / sizeof(directions[0])) + m_directions[i] = 0; + } + m_last_switch_ticks = gs.getTicks(); + } + + int width = gs.getWidth() / m_num_monitors; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - for (int monitor_num = 0; monitor_num < n_monitors; monitor_num++) + for (int monitor_num = 0; monitor_num < m_num_monitors; monitor_num++) { glViewport(width * monitor_num, 0, width, gs.getHeight()); - glPushMatrix(); + glLoadMatrixf(&m_rotations[monitor_num][0]); + + int direction = m_directions[monitor_num]; + glRotatef((gs.getTicks() - m_last_ticks) / 1000.0 * 360.0 / 4.0, + directions[direction][0], + directions[direction][1], + directions[direction][2]); + glGetFloatv(GL_MODELVIEW_MATRIX, &m_rotations[monitor_num][0]); - glRotatef(gs.getTicks() / 1000.0 * 360.0 / 4.0 - * (monitor_num & 0x1 ? -1.0 : 1.0), 0, 1, 0); m_logobox.draw(); - - glPopMatrix(); } + m_last_ticks = gs.getTicks(); return true; } @@ -37,6 +81,20 @@ bool Spin::configure (GnomeScreensaver & gs) glLoadIdentity(); gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0); + m_num_monitors = gs.getNumMonitors(); + delete[] m_directions; + delete[] m_rotations; + m_directions = new int[m_num_monitors]; + m_rotations = new matrix_t[m_num_monitors]; + for (int i = 0; i < m_num_monitors; i++) + { + m_directions[i] = (int) (rand() / (double)RAND_MAX * + sizeof(directions) / sizeof(directions[0])); + if (m_directions[i] >= sizeof(directions) / sizeof(directions[0])) + m_directions[i] = 0; + glGetFloatv(GL_MODELVIEW_MATRIX, &m_rotations[i][0]); + } + return true; } diff --git a/modes/Spin.h b/modes/Spin.h index 5246af8..fc1982a 100644 --- a/modes/Spin.h +++ b/modes/Spin.h @@ -9,11 +9,19 @@ class Spin : public Mode { public: + Spin(); + ~Spin(); bool expose (GnomeScreensaver & gs); bool configure (GnomeScreensaver & gs); bool update (GnomeScreensaver & gs); + typedef float matrix_t[16]; protected: LogoBox m_logobox; + int * m_directions; + matrix_t * m_rotations; + int m_num_monitors; + unsigned int m_last_switch_ticks; + unsigned int m_last_ticks; }; #endif /* SPIN_H */