dwscr/ss/LightBounce.cc
josh 1c41d64a3a changed LightBounce to use display list for each logo
git-svn-id: svn://anubis/dwscr/trunk@99 5bef9df8-b654-44bb-925b-0ff18baa8f8c
2008-11-13 16:02:14 +00:00

136 lines
3.6 KiB
C++

/* Author: Josh Holtrop
* DornerWorks screensaver
*/
#include <GL/gl.h>
#include <GL/glu.h>
#include "LightBounce.h"
#include <iostream>
#include <vector>
using namespace std;
#define SIZE 5
#define STRIDE_MULTIPLIER 1.0;
#define ZOOM 12.0
LightBounceBox::LightBounceBox(LogoBox * lb,
float x, float y, float z,
float xr, float yr, float zr)
{
this->x = x;
this->y = y;
this->z = z;
this->xr = xr;
this->yr = yr;
this->zr = zr;
this->dist = 0.0;
m_dl = glGenLists(1);
glNewList(m_dl, GL_COMPILE);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(xr, 1, 0, 0);
glRotatef(yr, 0, 1, 0);
glRotatef(zr, 0, 0, 1);
lb->draw();
glPopMatrix();
glEndList();
}
LightBounceBox::~LightBounceBox()
{
glDeleteLists(m_dl, 1);
}
/* construct screensaver mode and do some basic OpenGL setup */
LightBounce::LightBounce(SSMain * _SSMain) : SSMode(_SSMain)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,
(double)m_SSMain->getWidth()
/ (double)m_SSMain->getHeight()
/ (double)m_SSMain->getNumMonitors(),
0.01,
1000.01);
glMatrixMode(GL_MODELVIEW);
float box_stride = m_logoBox.getWidth() * STRIDE_MULTIPLIER;
float half_size = SIZE * box_stride / 2.0;
float y = -half_size + box_stride / 2.0;
int rot = false;
for (int i = 0; i < SIZE; i++)
{
float x = -half_size + box_stride / 2.0;
for (int j = 0; j < SIZE; j++)
{
// front
LightBounceBox * box = new LightBounceBox(
&m_logoBox, x, y, -half_size, 0, 180.0, rot ? 90.0 : 0
);
m_boxes.push_back(box);
// right
box = new LightBounceBox(
&m_logoBox, half_size, y, x, 0, 90.0, rot ? 0 : 90.0
);
m_boxes.push_back(box);
// back
box = new LightBounceBox(
&m_logoBox, x, y, half_size, 0, 0, rot ? 90.0 : 0
);
m_boxes.push_back(box);
// left
box = new LightBounceBox(
&m_logoBox, -half_size, y, x, 0, 270.0, rot ? 0 : 90.0
);
m_boxes.push_back(box);
// top
box = new LightBounceBox(
&m_logoBox, x, half_size, y, 270, 0, rot ? 0 : 90.0
);
m_boxes.push_back(box);
// bottom
box = new LightBounceBox(
&m_logoBox, x, -half_size, y, 90, 0, rot ? 0 : 90.0
);
m_boxes.push_back(box);
rot = !rot;
x += box_stride;
}
y += box_stride;
}
}
LightBounce::~LightBounce()
{
int sz = m_boxes.size();
for (int i = 0; i < sz; i++)
delete m_boxes[i];
}
/* called every time this screensaver mode should redraw the screen */
void LightBounce::update()
{
SSMode::update();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
int numMonitors = m_SSMain->getNumMonitors();
int width = m_SSMain->getWidth();
int height = m_SSMain->getHeight();
for (int i = 0; i < numMonitors; i++)
{
glViewport(i*width/numMonitors, 0, width/numMonitors, height);
glLoadIdentity();
gluLookAt(0, SIZE * ZOOM * 2.0 / 3.0, SIZE * ZOOM, 0, 0, 0, 0, 1, 0);
glRotatef(m_elapsed/66.0f, 0, 1, 0);
int sz = m_boxes.size();
for (int i = 0; i < sz; i++)
{
m_boxes[i]->draw();
}
}
SDL_GL_SwapBuffers();
}