moved files to trunk directory
git-svn-id: svn://anubis/dwscr/trunk@83 5bef9df8-b654-44bb-925b-0ff18baa8f8c
This commit is contained in:
1 parent
78092ee118
commit
68d41e9c63
26 files changed
+2184
No files matched your search
+112
@@ -0,0 +1,112 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* This module can be used to create "LogoBox" objects
|
||||
* which consist of a 3D DW logo and possibly have a
|
||||
* mass and boundary associated with them if physics
|
||||
* is being used
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <ode/ode.h>
|
||||
#include "../wfobj/WFObj.hh"
|
||||
#include "LogoBox.h"
|
||||
#include "../LoadFile/LoadFile.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
static GLuint _logoList = 0;
|
||||
static float _logoAABB[6];
|
||||
static GLuint _drawList;
|
||||
|
||||
/* construct a LogoBox object
|
||||
* The first time the constructor is called it loads the
|
||||
* Alias Wavefront object model. Subsequent calls will
|
||||
* reuse the same module. If physics are being used
|
||||
* (world and space are not NULL), then the constructor
|
||||
* initializes an ODE body and geometry for each
|
||||
* constructed logo.
|
||||
*/
|
||||
LogoBox::LogoBox(dWorldID world, dSpaceID space)
|
||||
{
|
||||
if (_logoList == 0)
|
||||
{
|
||||
WFObj obj;
|
||||
if (obj.load("dwlogo.obj", NULL, &LoadFile))
|
||||
{
|
||||
_logoList = obj.render();
|
||||
const float * aabb = obj.getAABB();
|
||||
memcpy(_logoAABB, aabb, sizeof(_logoAABB));
|
||||
|
||||
float c_x = (_logoAABB[0] + _logoAABB[3]) / 2.0f;
|
||||
float c_y = (_logoAABB[1] + _logoAABB[4]) / 2.0f;
|
||||
float c_z = (_logoAABB[2] + _logoAABB[5]) / 2.0f;
|
||||
_drawList = glGenLists(1);
|
||||
glNewList(_drawList, GL_COMPILE);
|
||||
glPushMatrix();
|
||||
glTranslatef(-c_x, -c_y, -c_z);
|
||||
glCallList(_logoList);
|
||||
glPopMatrix();
|
||||
glEndList();
|
||||
}
|
||||
}
|
||||
|
||||
m_body = 0;
|
||||
m_geom = 0;
|
||||
|
||||
if (world != 0)
|
||||
{
|
||||
dMass mass;
|
||||
|
||||
m_body = dBodyCreate(world);
|
||||
dMassSetBox(&mass, 1.0, getWidth(), getDepth(), getHeight());
|
||||
dBodySetMass(m_body, &mass);
|
||||
|
||||
if (space != 0)
|
||||
{
|
||||
m_geom = dCreateBox(space, getWidth(), getDepth(), getHeight());
|
||||
dGeomSetBody(m_geom, m_body);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up ODE resources */
|
||||
LogoBox::~LogoBox()
|
||||
{
|
||||
if (m_geom)
|
||||
{
|
||||
dGeomDestroy(m_geom);
|
||||
}
|
||||
if (m_body)
|
||||
{
|
||||
dBodyDestroy(m_body);
|
||||
}
|
||||
}
|
||||
|
||||
void LogoBox::draw()
|
||||
{
|
||||
glCallList(_drawList);
|
||||
}
|
||||
|
||||
/* return a pointer to the axis-aligned bounding box for a DW logo */
|
||||
const float * const LogoBox::getAABB() const
|
||||
{
|
||||
return _logoAABB;
|
||||
}
|
||||
|
||||
float LogoBox::getWidth() const
|
||||
{
|
||||
return _logoAABB[3] - _logoAABB[0];
|
||||
}
|
||||
|
||||
float LogoBox::getHeight() const
|
||||
{
|
||||
return _logoAABB[5] - _logoAABB[2];
|
||||
}
|
||||
|
||||
float LogoBox::getDepth() const
|
||||
{
|
||||
return _logoAABB[4] - _logoAABB[1];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* The LogoBox class
|
||||
*/
|
||||
|
||||
#ifndef LOGOBOX_H
|
||||
#define LOGOBOX_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <ode/ode.h>
|
||||
|
||||
class LogoBox
|
||||
{
|
||||
public:
|
||||
LogoBox(dWorldID world = 0, dSpaceID space = 0);
|
||||
~LogoBox();
|
||||
void draw();
|
||||
const float * const getAABB() const;
|
||||
float getWidth() const;
|
||||
float getHeight() const;
|
||||
float getDepth() const;
|
||||
dBodyID getBody() { return m_body; }
|
||||
dGeomID getGeom() { return m_geom; }
|
||||
|
||||
protected:
|
||||
dBodyID m_body;
|
||||
dGeomID m_geom;
|
||||
};
|
||||
|
||||
#endif
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
|
||||
OBJS := SSMain.o
|
||||
OBJS += SSMode.o
|
||||
OBJS += LogoBox.o
|
||||
OBJS += PlainSpin.o
|
||||
OBJS += TumblingLogos.o
|
||||
OBJS += Towers.o
|
||||
AROBJS := $(foreach o,$(OBJS),ss.a($(o)))
|
||||
|
||||
all: ss.a
|
||||
|
||||
ss.a: $(AROBJS)
|
||||
|
||||
clean:
|
||||
-$(RM) -f *~ *.o *.a
|
||||
@@ -0,0 +1,46 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* This module implements a very simple screensaver mode.
|
||||
* It just creates a DW logo and then continuously spins around it.
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "PlainSpin.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
/* construct screensaver mode and do some basic OpenGL setup */
|
||||
PlainSpin::PlainSpin(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);
|
||||
}
|
||||
|
||||
/* called every time this screensaver mode should redraw the screen */
|
||||
void PlainSpin::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, 0, 12, 0, 0, 0, 0, 1, 0);
|
||||
glRotatef(m_elapsed/33.0f, 0, 1, 0);
|
||||
m_logoBox.draw();
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* A simple spinning logo screensaver mode object
|
||||
*/
|
||||
|
||||
#ifndef PLAINSPIN_H
|
||||
#define PLAINSPIN_H
|
||||
|
||||
#include "SSMain.h"
|
||||
#include "SSMode.h"
|
||||
#include "LogoBox.h"
|
||||
|
||||
class PlainSpin : public SSMode
|
||||
{
|
||||
public:
|
||||
PlainSpin(SSMain * _SSMain);
|
||||
void update();
|
||||
protected:
|
||||
LogoBox m_logoBox;
|
||||
};
|
||||
|
||||
#endif
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* This module implements the main functionality of the DW screensaver.
|
||||
* It is responsible for handling input and timer events, as well
|
||||
* as instantiating and rotating through the various screensaver modes
|
||||
* that have been implemented.
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* srand() */
|
||||
#include <time.h> /* time() */
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include <SDL/SDL.h>
|
||||
#include "SSMain.h"
|
||||
#include "PlainSpin.h"
|
||||
#include "TumblingLogos.h"
|
||||
#include "Towers.h"
|
||||
|
||||
/* switch to the next screensaver mode after this many milliseconds */
|
||||
#define SSMODE_TIMEOUT_MSEC (1000*45)
|
||||
|
||||
static SDL_Event event;
|
||||
|
||||
/* create the main screensaver object */
|
||||
SSMain::SSMain(int width, int height, int numMonitors, SDL_Surface * sdlSurface)
|
||||
: m_width (width), m_height (height),
|
||||
m_numMonitors (numMonitors), m_sdlSurface (sdlSurface),
|
||||
m_mode(NULL), m_drawing(false)
|
||||
{
|
||||
/* set up some common OpenGL defaults */
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_LIGHT0);
|
||||
glEnable(GL_CULL_FACE);
|
||||
GLfloat ambient[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
|
||||
|
||||
/* setup redraw SDL event structure */
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = 0;
|
||||
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
/* called by SDL when the update timer expires */
|
||||
Uint32 SSMain::updateCallback(Uint32 interval, void * param)
|
||||
{
|
||||
SSMain * ssmain = (SSMain *) param;
|
||||
return ssmain->updateCallback(interval);
|
||||
}
|
||||
|
||||
/* member update function to be called by our registered
|
||||
* SDL callback non-member function */
|
||||
Uint32 SSMain::updateCallback(Uint32 interval)
|
||||
{
|
||||
if (!m_drawing)
|
||||
{
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
return interval;
|
||||
}
|
||||
|
||||
/* called to begin the screensaver,
|
||||
* exits when the screensaver should terminate */
|
||||
void SSMain::run()
|
||||
{
|
||||
Uint32 elapsed_msec;
|
||||
Uint32 lastChanged_msec = 0;
|
||||
SDL_Event event;
|
||||
|
||||
/* initially set the screensaver mode */
|
||||
m_mode = startMode();
|
||||
|
||||
/* register a screen redrawing SDL event */
|
||||
SDL_AddTimer(12, &updateCallback, this);
|
||||
|
||||
/* draw the screen */
|
||||
update();
|
||||
|
||||
/* main event loop */
|
||||
while (SDL_WaitEvent(&event))
|
||||
{
|
||||
elapsed_msec = SDL_GetTicks(); /* get the time the event occurred at */
|
||||
if (elapsed_msec - lastChanged_msec > SSMODE_TIMEOUT_MSEC)
|
||||
{
|
||||
delete m_mode;
|
||||
m_mode = startMode();
|
||||
lastChanged_msec = elapsed_msec;
|
||||
}
|
||||
|
||||
switch (event.type)
|
||||
{
|
||||
#ifndef WINDOW_MODE
|
||||
case SDL_KEYDOWN: /* terminate screensaver upon */
|
||||
#endif
|
||||
case SDL_QUIT: /* key press or quit event */
|
||||
goto RET;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
if (event.button.button == 1)
|
||||
{
|
||||
delete m_mode;
|
||||
m_mode = startMode();
|
||||
lastChanged_msec = elapsed_msec;
|
||||
}
|
||||
break;
|
||||
case SDL_USEREVENT:
|
||||
if (event.user.code == 0)
|
||||
{
|
||||
update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
RET:
|
||||
;
|
||||
}
|
||||
|
||||
/* return a new screensaver mode object to start displaying */
|
||||
SSMode * SSMain::startMode()
|
||||
{
|
||||
static int mode = 0;
|
||||
const int numModes = 3;
|
||||
|
||||
mode++;
|
||||
if (mode >= numModes)
|
||||
mode = 0;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case 0:
|
||||
return new PlainSpin(this);
|
||||
case 1:
|
||||
return new Towers(this);
|
||||
default:
|
||||
return new TumblingLogos(this);
|
||||
}
|
||||
}
|
||||
|
||||
/* call the update function to redraw the screen from the
|
||||
* currently active screensaver mode.
|
||||
* Uses a pseudo-semaphore to block new redraw requests
|
||||
* from coming in while current ones are being serviced.
|
||||
*/
|
||||
void SSMain::update()
|
||||
{
|
||||
m_drawing = true;
|
||||
m_mode->update();
|
||||
m_drawing = false;
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* The main screensaver module
|
||||
*/
|
||||
|
||||
#ifndef SSMAIN_H
|
||||
#define SSMAIN_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
class SSMode;
|
||||
|
||||
#include "SSMode.h"
|
||||
|
||||
class SSMain
|
||||
{
|
||||
public:
|
||||
SSMain(int width, int height, int numMonitors, SDL_Surface * sdlSurface);
|
||||
void run();
|
||||
int getWidth() { return m_width; }
|
||||
int getHeight() { return m_height; }
|
||||
int getNumMonitors() { return m_numMonitors; }
|
||||
SDL_Surface * getSurface() { return m_sdlSurface; }
|
||||
Uint32 updateCallback(Uint32 interval);
|
||||
|
||||
protected:
|
||||
static Uint32 updateCallback(Uint32 interval, void * param);
|
||||
void update();
|
||||
SSMode * startMode();
|
||||
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_numMonitors;
|
||||
SDL_Surface * m_sdlSurface;
|
||||
SSMode * m_mode;
|
||||
bool m_drawing;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* SSMode is base class that provides common functionality for
|
||||
* screensaver modes. It should be extended by a screensaver
|
||||
* mode implementing class.
|
||||
*/
|
||||
|
||||
#include "SSMode.h"
|
||||
|
||||
SSMode::SSMode(SSMain * _SSMain)
|
||||
: m_SSMain(_SSMain)
|
||||
{
|
||||
m_startTick = SDL_GetTicks();
|
||||
}
|
||||
|
||||
SSMode::~SSMode()
|
||||
{
|
||||
}
|
||||
|
||||
/* update the number of elapsed milliseconds */
|
||||
void SSMode::update()
|
||||
{
|
||||
Uint32 ticks = SDL_GetTicks();
|
||||
m_elapsed = ticks - m_startTick;
|
||||
}
|
||||
|
||||
/* push an OpenGL matrix onto the matrix stack for a given
|
||||
* ODE body position and rotation */
|
||||
void SSMode::pushTransform(const float pos[3], const float R[12])
|
||||
{
|
||||
GLfloat matrix[16];
|
||||
matrix[0] = R[0];
|
||||
matrix[1] = R[4];
|
||||
matrix[2] = R[8];
|
||||
matrix[3] = 0;
|
||||
matrix[4] = R[1];
|
||||
matrix[5] = R[5];
|
||||
matrix[6] = R[9];
|
||||
matrix[7] = 0;
|
||||
matrix[8] = R[2];
|
||||
matrix[9] = R[6];
|
||||
matrix[10] = R[10];
|
||||
matrix[11] = 0;
|
||||
matrix[12] = pos[0];
|
||||
matrix[13] = pos[1];
|
||||
matrix[14] = pos[2];
|
||||
matrix[15] = 1;
|
||||
glPushMatrix();
|
||||
glMultMatrixf(matrix);
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* A base class for deriving concrete screensaver mode implementations
|
||||
*/
|
||||
|
||||
#ifndef SSMODE_H
|
||||
#define SSMODE_H
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <GL/gl.h>
|
||||
|
||||
class SSMain;
|
||||
|
||||
#include "SSMain.h"
|
||||
|
||||
class SSMode
|
||||
{
|
||||
public:
|
||||
SSMode(SSMain * _SSMain);
|
||||
virtual ~SSMode();
|
||||
virtual void update();
|
||||
void pushTransform(const float pos[3], const float R[12]);
|
||||
|
||||
protected:
|
||||
SSMain * m_SSMain;
|
||||
Uint32 m_startTick;
|
||||
Uint32 m_elapsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* A slightly more interesting screensaver mode involving
|
||||
* towers of DW logos with randomly disappearing ones
|
||||
*/
|
||||
|
||||
#include <math.h> /* fmax(), sin() */
|
||||
#include <stdlib.h> /* rand() */
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "Towers.h"
|
||||
#include <ode/ode.h>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define WORLD_STEP 0.001
|
||||
/* time at beginning of mode to not remove any logos (msec) */
|
||||
#define WAIT_TIME 6000
|
||||
/* amount of time to wait before removing another logo (msec) */
|
||||
#define REMOVE_TIME 3000
|
||||
#define GROUND_ALPHA 0.5
|
||||
|
||||
Towers::Towers(SSMain * _SSMain) : SSMode(_SSMain)
|
||||
{
|
||||
/* set up our specific openGL settings */
|
||||
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);
|
||||
|
||||
/* create the ground texture */
|
||||
float tex[] = {1.0, 0.0, 0.0, GROUND_ALPHA,
|
||||
1.0, 1.0, 1.0, GROUND_ALPHA,
|
||||
1.0, 1.0, 1.0, GROUND_ALPHA,
|
||||
1.0, 0.0, 0.0, GROUND_ALPHA};
|
||||
glGenTextures(1, &m_groundTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, m_groundTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, 4, 2, 2, 0, GL_RGBA, GL_FLOAT, tex);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* create the ODE world */
|
||||
createWorld();
|
||||
|
||||
m_lastElapsed = 0;
|
||||
m_logoToRemove = -1;
|
||||
m_logosList = glGenLists(1);
|
||||
}
|
||||
|
||||
Towers::~Towers()
|
||||
{
|
||||
int sz = m_logos.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
delete m_logos[i];
|
||||
}
|
||||
dJointGroupDestroy(m_contactJointGroup);
|
||||
dWorldDestroy(m_world);
|
||||
dSpaceDestroy(m_space);
|
||||
glDeleteTextures(1, &m_groundTexture);
|
||||
glDeleteLists(m_logosList, 1);
|
||||
}
|
||||
|
||||
void Towers::createWorld()
|
||||
{
|
||||
/* set up the ODE world and collision space */
|
||||
m_world = dWorldCreate();
|
||||
// dWorldSetCFM(m_world, 1e-5);
|
||||
dWorldSetGravity(m_world, 0, -9.81, 0);
|
||||
dWorldSetERP(m_world, 0.8);
|
||||
m_space = dHashSpaceCreate(0);
|
||||
// dVector3 center = {0, 10, 0};
|
||||
// dVector3 extents = {100, 40, 100};
|
||||
// m_space = dQuadTreeSpaceCreate(0, center, extents, 5);
|
||||
m_contactJointGroup = dJointGroupCreate(0);
|
||||
|
||||
double lHeight = 0.0;
|
||||
const double towerBaseOffset = 0.0;
|
||||
const int towerHeight = 6;
|
||||
const double towerSpacing = 10.0;
|
||||
const double logoTierSpacing = 3.75;
|
||||
bool turn = false;
|
||||
for (double xoffset = -towerSpacing;
|
||||
xoffset < towerSpacing*1.1;
|
||||
xoffset += towerSpacing*2.0)
|
||||
{
|
||||
for (double zoffset = -towerSpacing;
|
||||
zoffset < towerSpacing*1.1;
|
||||
zoffset += towerSpacing*2.0)
|
||||
{
|
||||
double towerOffset = 0.0;
|
||||
for (int i = 0;
|
||||
i < towerHeight;
|
||||
i++, towerOffset += lHeight, turn = !turn)
|
||||
{
|
||||
double localXOffset = 0.0;
|
||||
double localZOffset = 0.0;
|
||||
if (turn)
|
||||
localXOffset = -logoTierSpacing;
|
||||
else
|
||||
localZOffset = -logoTierSpacing;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
LogoBox * lb = new LogoBox(m_world, m_space);
|
||||
if (lHeight == 0.0)
|
||||
lHeight = lb->getDepth();
|
||||
dMatrix3 rotation;
|
||||
dRFromEulerAngles(rotation,
|
||||
0,
|
||||
turn ? M_PI_2 : 0,
|
||||
0);
|
||||
dBodySetRotation(lb->getBody(), rotation);
|
||||
dBodySetPosition(lb->getBody(),
|
||||
xoffset + localXOffset,
|
||||
towerBaseOffset + towerOffset + lb->getDepth()/2.0,
|
||||
zoffset + localZOffset);
|
||||
m_logos.push_back(lb);
|
||||
|
||||
if (turn)
|
||||
localXOffset += logoTierSpacing * 2;
|
||||
else
|
||||
localZOffset += logoTierSpacing * 2;
|
||||
}
|
||||
}
|
||||
turn = !turn;
|
||||
}
|
||||
}
|
||||
|
||||
/* create ground plane */
|
||||
dCreatePlane(m_space, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
void Towers::update()
|
||||
{
|
||||
SSMode::update();
|
||||
|
||||
if (m_lastElapsed == 0)
|
||||
m_lastElapsed = m_elapsed;
|
||||
|
||||
if (m_logoToRemove == -1 && m_elapsed > WAIT_TIME)
|
||||
{
|
||||
if (m_logos.size() > 0)
|
||||
{
|
||||
m_lastRemoveTime = m_elapsed;
|
||||
m_logoToRemove = rand() % m_logos.size();
|
||||
}
|
||||
}
|
||||
else if (m_elapsed - m_lastRemoveTime > REMOVE_TIME)
|
||||
{
|
||||
if (m_logoToRemove >= 0)
|
||||
{
|
||||
std::vector<LogoBox *>::iterator it = m_logos.begin();
|
||||
for (int i = 0; i < m_logoToRemove; i++)
|
||||
it++;
|
||||
delete *it;
|
||||
m_logos.erase(it);
|
||||
m_logoToRemove = (m_logos.size() > 0) ? rand() % m_logos.size() : -1;
|
||||
m_lastRemoveTime = m_elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 delta = m_elapsed - m_lastElapsed;
|
||||
for (unsigned int i = 0; i < delta / 2; i++)
|
||||
worldStep();
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
int numMonitors = m_SSMain->getNumMonitors();
|
||||
int width = m_SSMain->getWidth();
|
||||
int height = m_SSMain->getHeight();
|
||||
bool drewLogos = false;
|
||||
for (int i = 0; i < numMonitors; i++)
|
||||
{
|
||||
glViewport(i*width/numMonitors, 0, width/numMonitors, height);
|
||||
glLoadIdentity();
|
||||
gluLookAt(0, 30, 55, /* eye position */
|
||||
0, 12, 0, /* focal point */
|
||||
0, 1, 0); /* up vector */
|
||||
glRotatef(m_elapsed/60.0f, 0, 1, 0); /* rotate view over time */
|
||||
|
||||
/* draw logo reflection */
|
||||
glPushAttrib(GL_POLYGON_BIT);
|
||||
glFrontFace(GL_CW); /* polygon vertex order reversed when
|
||||
reflecting across a plane */
|
||||
glPushMatrix();
|
||||
glScalef(1.0, -1.0, 1.0);
|
||||
if (drewLogos)
|
||||
glCallList(m_logosList);
|
||||
else
|
||||
{
|
||||
glNewList(m_logosList, GL_COMPILE_AND_EXECUTE);
|
||||
drawLogos();
|
||||
glEndList();
|
||||
drewLogos = true;
|
||||
}
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
|
||||
drawGround();
|
||||
|
||||
/* draw logos normally */
|
||||
// drawLogos();
|
||||
glCallList(m_logosList);
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
m_lastElapsed = m_elapsed;
|
||||
}
|
||||
|
||||
void Towers::drawLogos()
|
||||
{
|
||||
/* draw the logos */
|
||||
int sz = m_logos.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
dBodyID body = m_logos[i]->getBody();
|
||||
pushTransform(dBodyGetPosition(body),
|
||||
dBodyGetRotation(body));
|
||||
if (i == m_logoToRemove)
|
||||
{
|
||||
float amt = fabsf(sin(1.9*M_PI*
|
||||
(m_elapsed-m_lastRemoveTime)/REMOVE_TIME));
|
||||
GLfloat emission[] = {0.0, 0.0, amt, 1.0};
|
||||
glPushAttrib(GL_LIGHTING_BIT);
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, emission);
|
||||
}
|
||||
m_logos[i]->draw();
|
||||
if (i == m_logoToRemove)
|
||||
{
|
||||
glPopAttrib();
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
void Towers::drawGround()
|
||||
{
|
||||
const float gs = 120; /* ground size */
|
||||
const float tt = 20; /* texture tiles */
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBegin(GL_QUADS);
|
||||
glNormal3f(0, 1, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(-gs, 0, gs);
|
||||
glTexCoord2f(tt, 0);
|
||||
glVertex3f(gs, 0, gs);
|
||||
glTexCoord2f(tt, tt);
|
||||
glVertex3f(gs, 0, -gs);
|
||||
glTexCoord2f(0, tt);
|
||||
glVertex3f(-gs, 0, -gs);
|
||||
glEnd();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
/* used by ODE to perform collision detection */
|
||||
void Towers_collide_callback(void * data, dGeomID o1, dGeomID o2)
|
||||
{
|
||||
const int maxNumContacts = 2;
|
||||
Towers * t = (Towers *) data;
|
||||
static dContact contact[maxNumContacts];
|
||||
dBodyID b1 = dGeomGetBody(o1);
|
||||
dBodyID b2 = dGeomGetBody(o2);
|
||||
if (b1 && b2 && dAreConnected(b1, b2))
|
||||
return;
|
||||
int num = dCollide(o1, o2, maxNumContacts,
|
||||
&contact[0].geom, sizeof(dContact));
|
||||
int i;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
contact[i].surface.mode =
|
||||
dContactSlip1 | dContactSlip2 | dContactBounce |
|
||||
dContactSoftERP | dContactSoftCFM | dContactApprox1;
|
||||
contact[i].surface.mu = 0.5;
|
||||
contact[i].surface.slip1 = 0.0;
|
||||
contact[i].surface.slip2 = 0.0;
|
||||
contact[i].surface.soft_erp = 0.8;
|
||||
contact[i].surface.soft_cfm = 0.01;
|
||||
contact[i].surface.bounce = 0.0;
|
||||
dJointID joint = dJointCreateContact(t->m_world,
|
||||
t->m_contactJointGroup, contact + i);
|
||||
dJointAttach(joint, b1, b2);
|
||||
}
|
||||
}
|
||||
|
||||
/* invokes ODE to do physics on our world */
|
||||
void Towers::worldStep()
|
||||
{
|
||||
dSpaceCollide(m_space, this, Towers_collide_callback);
|
||||
dWorldQuickStep(m_world, WORLD_STEP);
|
||||
dJointGroupEmpty(m_contactJointGroup);
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* A slightly more interesting screensaver mode involving
|
||||
* towers of DW logos with randomly disappearing ones
|
||||
*/
|
||||
|
||||
#ifndef TOWERS_H
|
||||
#define TOWERS_H
|
||||
|
||||
#include "SSMain.h"
|
||||
#include "SSMode.h"
|
||||
#include "LogoBox.h"
|
||||
#include <ode/ode.h>
|
||||
#include <vector>
|
||||
|
||||
class Towers : public SSMode
|
||||
{
|
||||
public:
|
||||
Towers(SSMain * _SSMain);
|
||||
~Towers();
|
||||
void update();
|
||||
|
||||
protected:
|
||||
void createWorld();
|
||||
void worldStep();
|
||||
void drawLogos();
|
||||
void drawGround();
|
||||
friend void Towers_collide_callback(void * data, dGeomID o1, dGeomID o2);
|
||||
|
||||
dWorldID m_world;
|
||||
dSpaceID m_space;
|
||||
dJointGroupID m_contactJointGroup;
|
||||
std::vector<LogoBox *> m_logos;
|
||||
Uint32 m_lastElapsed;
|
||||
GLuint m_groundTexture;
|
||||
int m_logoToRemove;
|
||||
Uint32 m_lastRemoveTime;
|
||||
GLuint m_logosList;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,244 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* This module implements a slightly more interesting screensaver
|
||||
* mode that contains many DornerWorks logos that "tumble" around
|
||||
* inside a cube-shaped container as gravity randomly shifts every
|
||||
* few seconds
|
||||
*/
|
||||
|
||||
#include <math.h> /* fmax() */
|
||||
#include <stdlib.h> /* rand() */
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "TumblingLogos.h"
|
||||
#include <ode/ode.h>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define WORLD_STEP 0.001
|
||||
/* number of milliseconds after which to switch gravity */
|
||||
#define GRAVITY_CHANGE_MSEC 4000
|
||||
|
||||
static double randDbl()
|
||||
{
|
||||
return ((double) rand() / (double) RAND_MAX);
|
||||
}
|
||||
|
||||
TumblingLogos::TumblingLogos(SSMain * _SSMain) : SSMode(_SSMain)
|
||||
{
|
||||
/* set up our specific openGL settings */
|
||||
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);
|
||||
|
||||
/* create the ODE world */
|
||||
createWorld();
|
||||
|
||||
m_lastGravityChangeTime = m_lastElapsed = 0;
|
||||
}
|
||||
|
||||
TumblingLogos::~TumblingLogos()
|
||||
{
|
||||
int sz = m_logos.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
delete m_logos[i];
|
||||
}
|
||||
dJointGroupDestroy(m_contactJointGroup);
|
||||
dWorldDestroy(m_world);
|
||||
dSpaceDestroy(m_space);
|
||||
}
|
||||
|
||||
void TumblingLogos::createWorld()
|
||||
{
|
||||
/* set up the ODE world and collision space */
|
||||
m_world = dWorldCreate();
|
||||
// dWorldSetCFM(m_world, 1e-5);
|
||||
dWorldSetGravity(m_world, 0, -9.81, 0);
|
||||
dWorldSetERP(m_world, 0.8);
|
||||
m_space = dHashSpaceCreate(0);
|
||||
m_contactJointGroup = dJointGroupCreate(0);
|
||||
|
||||
m_logoSize = 0.0;
|
||||
m_boxSize = 0.0;
|
||||
double logo_offset = 0.0;
|
||||
double logoCellSize = 0.0;
|
||||
|
||||
/* create the logos to fill the tumble box */
|
||||
for (int x = 0; x < TUMBLE_BOX_CELLS; x++)
|
||||
{
|
||||
for (int y = 0; y < TUMBLE_BOX_CELLS; y++)
|
||||
{
|
||||
for (int z = 0; z < TUMBLE_BOX_CELLS; z++)
|
||||
{
|
||||
LogoBox * lb = new LogoBox(m_world, m_space);
|
||||
|
||||
if (m_boxSize == 0.0)
|
||||
{
|
||||
m_logoSize = fmax(fmax(lb->getWidth(), lb->getDepth()),
|
||||
lb->getHeight());
|
||||
logoCellSize = m_logoSize * 1.3;
|
||||
m_boxSize = logoCellSize * TUMBLE_BOX_CELLS;
|
||||
logo_offset = logoCellSize/2.0 - m_boxSize/2.0;
|
||||
}
|
||||
|
||||
dMatrix3 rotation;
|
||||
dRFromEulerAngles(rotation,
|
||||
randDbl() * M_PI * 2.0,
|
||||
randDbl() * M_PI * 2.0,
|
||||
randDbl() * M_PI * 2.0);
|
||||
dBodySetPosition(lb->getBody(),
|
||||
x * logoCellSize + logo_offset +
|
||||
(randDbl() - 0.5) * 0.1 * m_logoSize,
|
||||
y * logoCellSize + logo_offset +
|
||||
(randDbl() - 0.5) * 0.1 * m_logoSize,
|
||||
z * logoCellSize + logo_offset +
|
||||
(randDbl() - 0.5) * 0.1 * m_logoSize);
|
||||
dBodySetRotation(lb->getBody(), rotation);
|
||||
m_logos.push_back(lb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* tumble box will be size m_boxSize X m_boxSize X m_boxSize
|
||||
* centered at the origin */
|
||||
/* create planes surrounding the tumble box */
|
||||
dCreatePlane(m_space, -1, 0, 0, -m_boxSize/2.0);
|
||||
dCreatePlane(m_space, 1, 0, 0, -m_boxSize/2.0);
|
||||
dCreatePlane(m_space, 0, -1, 0, -m_boxSize/2.0);
|
||||
dCreatePlane(m_space, 0, 1, 0, -m_boxSize/2.0);
|
||||
dCreatePlane(m_space, 0, 0, -1, -m_boxSize/2.0);
|
||||
dCreatePlane(m_space, 0, 0, 1, -m_boxSize/2.0);
|
||||
}
|
||||
|
||||
void TumblingLogos::update()
|
||||
{
|
||||
SSMode::update();
|
||||
|
||||
if (m_lastElapsed == 0)
|
||||
m_lastGravityChangeTime = m_lastElapsed = m_elapsed;
|
||||
|
||||
/* change gravity if it has been GRAVITY_CHANGE_MSEC milliseconds */
|
||||
if (m_elapsed - m_lastGravityChangeTime > GRAVITY_CHANGE_MSEC)
|
||||
{
|
||||
changeGravity();
|
||||
m_lastGravityChangeTime = m_elapsed;
|
||||
}
|
||||
|
||||
Uint32 delta = m_elapsed - m_lastElapsed;
|
||||
for (unsigned int i = 0; i < delta / 2; i++)
|
||||
worldStep();
|
||||
|
||||
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, 0, m_boxSize * 1.25, 0, 0, 0, 0, 1, 0);
|
||||
glRotatef(m_elapsed/60.0f, 0, 1, 0);
|
||||
|
||||
/* draw the logos */
|
||||
int sz = m_logos.size();
|
||||
for (int i = 0; i < sz; i++)
|
||||
{
|
||||
dBodyID body = m_logos[i]->getBody();
|
||||
pushTransform(dBodyGetPosition(body),
|
||||
dBodyGetRotation(body));
|
||||
m_logos[i]->draw();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
/* draw the wireframe bounding box */
|
||||
glColor3f(1, 1, 1);
|
||||
double halfBox = m_boxSize/2.0;
|
||||
glPushAttrib(GL_LIGHTING_BIT);
|
||||
glDisable(GL_LIGHTING);
|
||||
for (int i = -1; i <= 1; i += 2)
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(-halfBox, -halfBox, m_boxSize*i/2.0);
|
||||
glVertex3f(-halfBox, halfBox, m_boxSize*i/2.0);
|
||||
glVertex3f(halfBox, halfBox, m_boxSize*i/2.0);
|
||||
glVertex3f(halfBox, -halfBox, m_boxSize*i/2.0);
|
||||
glEnd();
|
||||
glBegin(GL_LINES);
|
||||
glVertex3f(m_boxSize*i/2.0, -halfBox, -halfBox);
|
||||
glVertex3f(m_boxSize*i/2.0, -halfBox, halfBox);
|
||||
glVertex3f(m_boxSize*i/2.0, halfBox, -halfBox);
|
||||
glVertex3f(m_boxSize*i/2.0, halfBox, halfBox);
|
||||
glEnd();
|
||||
}
|
||||
glPopAttrib();
|
||||
}
|
||||
SDL_GL_SwapBuffers();
|
||||
|
||||
m_lastElapsed = m_elapsed;
|
||||
}
|
||||
|
||||
/* used by ODE to perform collision detection */
|
||||
void TumblingLogos_collide_callback(void * data, dGeomID o1, dGeomID o2)
|
||||
{
|
||||
TumblingLogos * tl = (TumblingLogos *) data;
|
||||
static dContact contact[4];
|
||||
dBodyID b1 = dGeomGetBody(o1);
|
||||
dBodyID b2 = dGeomGetBody(o2);
|
||||
if (b1 && b2 && dAreConnected(b1, b2))
|
||||
return;
|
||||
int num = dCollide(o1, o2, 4, &contact[0].geom, sizeof(dContact));
|
||||
int i;
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
contact[i].surface.mode =
|
||||
dContactSlip1 | dContactSlip2 | dContactBounce |
|
||||
dContactSoftERP | dContactSoftCFM | dContactApprox1;
|
||||
contact[i].surface.mu = 0.5;
|
||||
contact[i].surface.slip1 = 0.0;
|
||||
contact[i].surface.slip2 = 0.0;
|
||||
contact[i].surface.soft_erp = 0.8;
|
||||
contact[i].surface.soft_cfm = 0.01;
|
||||
contact[i].surface.bounce = 0.4;
|
||||
dJointID joint = dJointCreateContact(tl->m_world,
|
||||
tl->m_contactJointGroup, contact + i);
|
||||
dJointAttach(joint, b1, b2);
|
||||
}
|
||||
}
|
||||
|
||||
/* invokes ODE to do physics on our world */
|
||||
void TumblingLogos::worldStep()
|
||||
{
|
||||
dSpaceCollide(m_space, this, TumblingLogos_collide_callback);
|
||||
dWorldQuickStep(m_world, WORLD_STEP);
|
||||
dJointGroupEmpty(m_contactJointGroup);
|
||||
}
|
||||
|
||||
/* randomly chooses a gravity direction */
|
||||
void TumblingLogos::changeGravity()
|
||||
{
|
||||
double g[3] = {0.0, 0.0, 0.0};
|
||||
double r = randDbl();
|
||||
if (r < 0.7)
|
||||
{
|
||||
/* gravitate towards one of the six sides */
|
||||
g[(int) (randDbl() * 3)] = ((randDbl() < 0.5) ? -1 : 1) * 9.81;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* gravitate towards one of the eight corners */
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
g[i] = ((randDbl() < 0.5) ? -1 : 1) * 9.81;
|
||||
}
|
||||
}
|
||||
dWorldSetGravity(m_world, g[0], g[1], g[2]);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
|
||||
/* Author: Josh Holtrop
|
||||
* DornerWorks screensaver
|
||||
* A slightly more interesting screensaver mode involving
|
||||
* colliding DW logos contained in a cube that spins while
|
||||
* gravity randomly changes direction
|
||||
*/
|
||||
|
||||
#ifndef TUMBLING_LOGOS_H
|
||||
#define TUMBLING_LOGOS_H
|
||||
|
||||
#include "SSMain.h"
|
||||
#include "SSMode.h"
|
||||
#include "LogoBox.h"
|
||||
#include <ode/ode.h>
|
||||
#include <vector>
|
||||
|
||||
#define TUMBLE_BOX_CELLS 4
|
||||
|
||||
class TumblingLogos : public SSMode
|
||||
{
|
||||
public:
|
||||
TumblingLogos(SSMain * _SSMain);
|
||||
~TumblingLogos();
|
||||
void update();
|
||||
|
||||
protected:
|
||||
void createWorld();
|
||||
void worldStep();
|
||||
void changeGravity();
|
||||
friend void TumblingLogos_collide_callback(void * data, dGeomID o1, dGeomID o2);
|
||||
|
||||
dWorldID m_world;
|
||||
dSpaceID m_space;
|
||||
double m_logoSize;
|
||||
double m_boxSize;
|
||||
dJointGroupID m_contactJointGroup;
|
||||
std::vector<LogoBox *> m_logos;
|
||||
Uint32 m_lastGravityChangeTime;
|
||||
Uint32 m_lastElapsed;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user