diff --git a/LoadFile/LoadFile.cc b/LoadFile/LoadFile.cc new file mode 100644 index 0000000..d3112f9 --- /dev/null +++ b/LoadFile/LoadFile.cc @@ -0,0 +1,42 @@ + +#include +#include +#include "LoadFile.h" + +typedef struct { + const char * filename; + unsigned char * data; + int length; +} fileref_t; + +/* The data section is generated by a perl script. The contents of the + * included file are part of this logical program unit, which is why it + * is directly included instead of compiling it separately. + */ +#include "LoadFile-gen.inc" + +const static int numFiles = sizeof(LoadFileData)/sizeof(fileref_t); + +static std::map< std::string, fileref_t * > * LoadFileMap = NULL; + +void * LoadFile(const char * filename, unsigned int * length) +{ + if (LoadFileMap == NULL) + { + LoadFileMap = new std::map< std::string, fileref_t * >(); + for (int i = 0; i < numFiles; i++) + { + (*LoadFileMap)[std::string(LoadFileData[i].filename)] = &LoadFileData[i]; + } + } + + std::map< std::string, fileref_t * >::iterator it = + LoadFileMap->find(std::string(filename)); + + if (it == LoadFileMap->end()) + return NULL; + + *length = it->second->length; + return it->second->data; +} + diff --git a/LoadFile/LoadFile.h b/LoadFile/LoadFile.h new file mode 100644 index 0000000..7261b72 --- /dev/null +++ b/LoadFile/LoadFile.h @@ -0,0 +1,2 @@ + +void * LoadFile(const char * filename, unsigned int * length); diff --git a/LoadFile/Makefile b/LoadFile/Makefile new file mode 100644 index 0000000..ca32666 --- /dev/null +++ b/LoadFile/Makefile @@ -0,0 +1,17 @@ + +GENLOADFILE := perl genLoadFile.pl +LOGO_PATH := ../logo +LOADFILES += dwlogo.obj +LOADFILES += dwlogo.mtl +ABSLOADFILES := $(foreach lf,$(LOADFILES),$(LOGO_PATH)/$(lf)) + +all: LoadFile.o + +LoadFile.o: LoadFile.cc LoadFile-gen.inc + $(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) + +LoadFile-gen.inc: genLoadFile.pl $(ABSLOADFILES) + $(GENLOADFILE) --root=$(LOGO_PATH) $(LOADFILES) + +clean: + -$(RM) -f *~ *.o LoadFile-gen.inc diff --git a/LoadFile/genLoadFile.pl b/LoadFile/genLoadFile.pl new file mode 100755 index 0000000..46885b6 --- /dev/null +++ b/LoadFile/genLoadFile.pl @@ -0,0 +1,58 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use Getopt::Long; + +my $root = '.'; +GetOptions('root=s' => \$root); + +my @fileList = @ARGV; +if ($#fileList < 0) +{ + print "$0 \n"; + exit(42); +} + +my %fileData; +my $index = 0; + +open(OUTPUT, '>', 'LoadFile-gen.inc'); +chdir($root); +foreach my $fileName (@fileList) +{ + local $/; + open(FILE, '<', $fileName); + my $fileContents = ; + close(FILE); + my $length = length($fileContents); + my @fileContents = split(//, $fileContents); + my $cname = "dat$index"; + print OUTPUT "\nstatic unsigned char ${cname}[] = {\n"; + for (my $byteNum = 0; $byteNum <= $#fileContents; $byteNum++) + { + print OUTPUT " " if ($byteNum % 12 == 0); + printf OUTPUT ("0x%02x", ord($fileContents[$byteNum])); + print OUTPUT ", " unless ($byteNum == $#fileContents); + print OUTPUT "\n" if ($byteNum % 12 == 11); + } + print OUTPUT "\n};\n"; + $index++; + $fileData{$fileName} = [$cname, $length]; +} + +print OUTPUT "\nfileref_t LoadFileData[] = {\n"; + +my @fileNames = keys(%fileData); +for (my $fileIndex = 0; $fileIndex <= $#fileNames; $fileIndex++) +{ + my $fileName = $fileNames[$fileIndex]; + printf OUTPUT (' {"%s", %s, %s}', + $fileName, + $fileData{$fileName}->[0], + $fileData{$fileName}->[1]); + print OUTPUT "," unless ($fileIndex == $#fileNames); + print OUTPUT "\n"; +} +print OUTPUT "};\n"; +close(OUTPUT); diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..64a535b --- /dev/null +++ b/Makefile @@ -0,0 +1,74 @@ + +# Author: Josh Holtrop +# DornerWorks screensaver + +# set this to compile in "debug" mode +#DEBUG := 1 +# set this to be in "window mode" - i.e. do not hide mouse +# cursor and grab input +#WINDOW_MODE := 1 + +OBJS = dwscr.o wfobj/WFObj.o LoadFile/LoadFile.o ss/ss.a +TARGET = dwscr +export CXXFLAGS := -O2 -Wall +export CPPFLAGS +ifdef DEBUG +CPPFLAGS += -DDEBUG +endif +ifdef WINDOW_MODE +CPPFLAGS += -DWINDOW_MODE +endif +ifdef WIN32 +export CP := copy +export MV := rename +export CC := mingw32-gcc +export CXX := mingw32-g++ +SDL_BASE := C:\apps\SDL-1.2.13 +ODE_BASE := C:\apps\ode-0.9 +export CPPFLAGS += -I$(SDL_BASE)\include -I$(ODE_BASE)\include -D_GNU_SOURCE=1 -Dmain=SDL_main +LDFLAGS += -L$(SDL_BASE)\lib -L$(ODE_BASE)\lib\releasedll -lopengl32 -lglu32 -lmingw32 -mwindows -lSDLmain -lSDL -lode +TARGET := $(TARGET).exe +SSNAME := dwscr.scr +INSTALLDIR := C:\WINDOWS +OBJS += displayinfo-win32.o +else +export CP := cp +export MV := mv +export CC := gcc +export CXX := g++ +export AR := ar +export CPPFLAGS += `sdl-config --cflags` `ode-config --cflags` +LDFLAGS += `sdl-config --libs` `ode-config --libs` -lGL -lGLU +OBJS += displayinfo.o +endif + + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -o $@ $(OBJS) $(LDFLAGS) + +.PHONY: wfobj/WFObj.o +wfobj/WFObj.o: + $(MAKE) -C wfobj + +.PHONY: LoadFile/LoadFile.o +LoadFile/LoadFile.o: + $(MAKE) -C LoadFile + +.PHONY: ss/ss.a +ss/ss.a: + $(MAKE) -C ss + +ifdef WIN32 +.PHONY: install +install: + $(CP) $(TARGET) $(INSTALLDIR)\$(SSNAME) +endif + +.PHONY: clean +clean: + $(MAKE) -C wfobj clean + $(MAKE) -C LoadFile clean + $(MAKE) -C ss clean + -$(RM) -f *~ *.o $(TARGET) diff --git a/displayinfo-win32.cc b/displayinfo-win32.cc new file mode 100644 index 0000000..5da659b --- /dev/null +++ b/displayinfo-win32.cc @@ -0,0 +1,55 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + * This Windows-specific module will get the screen size + * and return the number of monitors present. Right now the + * screensaver will only work properly with two identically + * sized monitors... + */ + +#include +#include +#include "displayinfo.h" + +static int numMonitors = 0; + +void getDisplaySize(int * width, int * height) +{ + std::string nullStr = ""; + int w = 0; + int h = 0; + + /* loop through the display devices to get their dimensions */ + for (int i = 0; i < 10; i++) + { + DISPLAY_DEVICE dev; + dev.cb = sizeof(DISPLAY_DEVICE); + if (!EnumDisplayDevices(NULL, i, &dev, 0)) + break; + /* we only want real display devices to matter */ + if (dev.DeviceID != nullStr) + { + HDC hdc = CreateDC(TEXT("DISPLAY"), dev.DeviceString, NULL, NULL); + if (hdc != NULL) + { + numMonitors++; + w += GetDeviceCaps(hdc, HORZRES); + int thisHeight = GetDeviceCaps(hdc, VERTRES); + if (thisHeight > h) + h = thisHeight; + } + } + } + + /* only update width and height if we have valid data */ + if (w != 0 && h != 0) + { + *width = w; + *height = h; + } +} + +int getNumMonitors() +{ + return numMonitors; +} diff --git a/displayinfo.cc b/displayinfo.cc new file mode 100644 index 0000000..a66df8e --- /dev/null +++ b/displayinfo.cc @@ -0,0 +1,30 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + */ + +#include +#include "displayinfo.h" +#include + +void getDisplaySize(int * width, int * height) +{ + Display * display; + if ((display = XOpenDisplay(NULL)) == NULL) + { + /* fall back on hard-coded defaults */ + *width = 1600; + *height = 1200; + } + else + { + int screen_num = DefaultScreen(display); + *width = DisplayWidth(display, screen_num); + *height = DisplayHeight(display, screen_num); + } +} + +int getNumMonitors() +{ + return 1; +} diff --git a/displayinfo.h b/displayinfo.h new file mode 100644 index 0000000..789ff22 --- /dev/null +++ b/displayinfo.h @@ -0,0 +1,9 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + * Common interface for obtaining display information from either + * Windows or linux + */ + +void getDisplaySize(int * width, int * height); +int getNumMonitors(); diff --git a/dwscr.cc b/dwscr.cc new file mode 100644 index 0000000..b4e9f0c --- /dev/null +++ b/dwscr.cc @@ -0,0 +1,97 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + * This was a for-fun project I started working on in November '07 + * because I like 3D graphics. I modeled the DornerWorks logo in + * blender, exported it to an Alias WaveFront object and material + * file, wrote an Alias Wavefront object loader, and then wrapped + * some OpenGL and ODE logic around it for various screensaver modes + */ + +#include +#include +#include +#include +#include "displayinfo.h" +#include "ss/SSMain.h" +using namespace std; + +#define PROGNAME "dwscr" +#define DEFAULT_WIDTH 1024 +#define DEFAULT_HEIGHT 768 + +/* main function, called upon program invocation */ +int main(int argc, char * argv[]) +{ + const string startString = "/s"; +#ifdef WIN32 + bool start = false; +#else + bool start = true; +#endif + SDL_Surface * sdlSurface; + int width = DEFAULT_WIDTH; + int height = DEFAULT_HEIGHT; + +#ifdef DEBUG + start = true; +#endif + + /* make the SDL window appear in the top-left corner of the screen */ + putenv("SDL_VIDEO_WINDOW_POS=0,0"); + + /* do not disable power management (this will allow monitors + * to power off at the normally configured timeout) */ + putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1"); + + /* extremely simple command-line argument handling */ + for (int i = 1; i < argc; i++) + { + if (startString == argv[i]) + start = true; + } + + if (!start) + return 0; + + getDisplaySize(&width, &height); + + /* initialize SDL library */ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) + { + cerr << "Error initializing video!" << endl; + return -1; + } + + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + /* Enable multisampling */ + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4); + + if ((sdlSurface = SDL_SetVideoMode(width, height, 0, + SDL_HWSURFACE +#ifndef WINDOW_MODE + | SDL_NOFRAME +#endif + | SDL_OPENGL)) == NULL) + { + cerr << "Error setting video mode!" << endl; + return -2; + } + + SDL_WM_SetCaption("dwscr", "dwscr"); +#ifndef WINDOW_MODE + SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_ShowCursor(SDL_DISABLE); +#endif + + /* after our window is created and SDL and OpenGL are initialized, + * start the main screensaver functionality */ + SSMain ss(width, height, getNumMonitors(), sdlSurface); + ss.run(); + + SDL_Quit(); + return 0; +} diff --git a/logo/dwlogo.blend b/logo/dwlogo.blend new file mode 100644 index 0000000..b01601b Binary files /dev/null and b/logo/dwlogo.blend differ diff --git a/logo/dwlogo.mtl b/logo/dwlogo.mtl new file mode 100644 index 0000000..06fff4a --- /dev/null +++ b/logo/dwlogo.mtl @@ -0,0 +1,22 @@ +# Blender3D MTL File: dwlogo.blend +# Material Count: 2 +newmtl Material.002 +Ns 96.078431 +Ka 0.396 0.392 0.078 +Kd 0.396 0.392 0.078 +Ks 0.2 0.2 0.2 +Ni 1.000000 +d 1.000000 +illum 2 + + +newmtl Material.001 +Ns 96.078431 +Ka 0.000000 0.326 0.341 +Kd 0.000000 0.326 0.341 +Ks 0.2 0.2 0.2 +Ni 1.000000 +d 1.000000 +illum 2 + + diff --git a/logo/dwlogo.obj b/logo/dwlogo.obj new file mode 100644 index 0000000..9f0a1bf --- /dev/null +++ b/logo/dwlogo.obj @@ -0,0 +1,645 @@ +# Blender3D v245 OBJ File: dwlogo.blend +# www.blender3d.org +mtllib dwlogo.mtl +v -1.967500 3.292557 0.000000 +v -1.539864 2.771481 0.000000 +v -1.222102 2.176990 0.000000 +v -1.026424 1.531928 0.000000 +v -0.969990 1.037352 0.000000 +v -0.578603 1.035548 0.000000 +v 0.007450 -0.426248 0.000000 +v 1.376684 3.048505 0.000000 +v 2.744326 -0.341223 0.000000 +v 3.879164 2.783177 0.000000 +v 4.794436 2.784227 0.000000 +v 4.794755 3.733678 0.000000 +v -2.503128 3.729895 0.000000 +v -2.503128 3.729895 0.500000 +v 4.794755 3.733678 0.500000 +v 4.794436 2.784227 0.500000 +v 3.879164 2.783177 0.500000 +v 2.744326 -0.341223 0.500000 +v 1.376684 3.048505 0.500000 +v 0.007450 -0.426248 0.500000 +v -0.578603 1.035548 0.500000 +v -0.969990 1.037352 0.500000 +v -1.026424 1.531928 0.500000 +v -1.222102 2.176990 0.500000 +v -1.539864 2.771481 0.500000 +v -1.967500 3.292557 0.500000 +vn 0.000000 0.000000 -1.000000 +vn -0.928184 -0.372121 0.000000 +vn -0.000518 1.000000 0.000000 +vn 1.000000 -0.000336 0.000000 +vn 0.001147 -0.999999 0.000000 +vn 0.939920 -0.341396 0.000000 +vn -0.927364 -0.374160 0.000000 +vn 0.930373 -0.366615 0.000000 +vn -0.004611 -0.999989 0.000000 +vn 0.000000 0.000000 1.000000 +g Cube.005_Cube.006_Material.002 +usemtl Material.002 +s off +f 11//1 13//1 12//1 +f 8//1 1//1 13//1 +f 11//1 8//1 13//1 +f 2//1 1//1 8//1 +f 3//1 2//1 8//1 +f 6//1 3//1 8//1 +f 7//1 6//1 8//1 +f 10//1 9//1 8//1 +f 11//1 10//1 8//1 +f 6//1 4//1 3//1 +f 6//1 5//1 4//1 +f 7//2 20//2 21//2 6//2 +f 13//3 14//3 15//3 12//3 +f 12//4 15//4 16//4 11//4 +f 11//5 16//5 17//5 10//5 +f 10//6 17//6 18//6 9//6 +f 9//7 18//7 19//7 8//7 +f 8//8 19//8 20//8 7//8 +f 6//9 21//9 22//9 5//9 +f 14//10 16//10 15//10 +f 26//10 19//10 14//10 +f 19//10 16//10 14//10 +f 25//10 19//10 26//10 +f 25//10 24//10 19//10 +f 24//10 21//10 19//10 +f 21//10 20//10 19//10 +f 18//10 17//10 19//10 +f 17//10 16//10 19//10 +f 23//10 21//10 24//10 +f 22//10 21//10 23//10 +v 2.768149 -1.634091 0.000000 +v 1.384947 1.793045 0.000000 +v 0.012920 -1.618155 0.000000 +v -0.883670 0.580436 0.000000 +v -0.972935 0.581641 0.000000 +v -1.028585 0.087289 0.000000 +v -1.218865 -0.539980 0.000000 +v -1.527863 -1.118075 0.000000 +v -1.943704 -1.624779 0.000000 +v -2.450409 -2.040621 0.000000 +v -2.782750 -2.236504 0.000000 +v 4.806163 -2.230783 0.000000 +v 4.807395 2.336444 0.000000 +v 4.206083 2.335061 0.000000 +v 4.206083 2.335061 0.500000 +v 4.807395 2.336444 0.500000 +v 4.806163 -2.230783 0.500000 +v -2.782750 -2.236504 0.500000 +v -2.450409 -2.040621 0.500000 +v -1.943704 -1.624779 0.500000 +v -1.527863 -1.118075 0.500000 +v -1.218865 -0.539980 0.500000 +v -1.028585 0.087289 0.500000 +v -0.972935 0.581641 0.500000 +v -0.883670 0.580436 0.500000 +v 0.012920 -1.618155 0.500000 +v 1.384947 1.793045 0.500000 +v 2.768149 -1.634091 0.500000 +vn 0.000754 -1.000000 0.000000 +vn -0.940203 0.340614 0.000000 +vn -0.002300 0.999997 0.000000 +vn 1.000000 -0.000270 0.000000 +vn 0.013502 0.999909 0.000000 +vn 0.925965 0.377610 0.000000 +vn -0.927767 0.373159 0.000000 +vn 0.927320 0.374269 0.000000 +g Cube.004_Cube.005_Material.001 +usemtl Material.001 +s off +f 38//1 40//1 39//1 +f 38//1 27//1 40//1 +f 27//1 29//1 28//1 +f 30//1 32//1 31//1 +f 29//1 32//1 30//1 +f 29//1 33//1 32//1 +f 29//1 34//1 33//1 +f 29//1 35//1 34//1 +f 27//1 35//1 29//1 +f 27//1 36//1 35//1 +f 36//1 27//1 38//1 +f 38//1 37//1 36//1 +f 38//11 43//11 44//11 37//11 +f 27//12 54//12 41//12 40//12 +f 40//13 41//13 42//13 39//13 +f 39//14 42//14 43//14 38//14 +f 31//15 50//15 51//15 30//15 +f 30//16 51//16 52//16 29//16 +f 29//17 52//17 53//17 28//17 +f 54//18 27//18 28//18 53//18 +f 41//10 43//10 42//10 +f 54//10 43//10 41//10 +f 52//10 54//10 53//10 +f 49//10 51//10 50//10 +f 49//10 52//10 51//10 +f 48//10 52//10 49//10 +f 47//10 52//10 48//10 +f 46//10 52//10 47//10 +f 46//10 54//10 52//10 +f 45//10 54//10 46//10 +f 45//10 43//10 54//10 +f 44//10 43//10 45//10 +v -3.414269 0.996186 0.000000 +v -3.360440 0.922096 0.000000 +v -3.332140 0.834999 0.000000 +v -3.332140 0.743420 0.000000 +v -3.360440 0.656322 0.000000 +v -3.414269 0.582233 0.000000 +v -3.488358 0.528404 0.000000 +v -3.575455 0.500104 0.000000 +v -3.667035 0.500104 0.000000 +v -3.754132 0.528404 0.000000 +v -3.828222 0.582233 0.000000 +v -3.882050 0.656322 0.000000 +v -3.910350 0.743420 0.000000 +v -3.910350 0.834999 0.000000 +v -3.882050 0.922097 0.000000 +v -3.828221 0.996186 0.000000 +v -3.754131 1.050015 0.000000 +v -3.667034 1.078314 0.000000 +v -3.575454 1.078314 0.000000 +v -3.488358 1.050014 0.000000 +v -3.488358 1.050014 0.500000 +v -3.575454 1.078314 0.500000 +v -3.667034 1.078314 0.500000 +v -3.754131 1.050015 0.500000 +v -3.828221 0.996186 0.500000 +v -3.882050 0.922097 0.500000 +v -3.910350 0.834999 0.500000 +v -3.910350 0.743420 0.500000 +v -3.882050 0.656322 0.500000 +v -3.828222 0.582233 0.500000 +v -3.754132 0.528404 0.500000 +v -3.667035 0.500104 0.500000 +v -3.575455 0.500104 0.500000 +v -3.488358 0.528404 0.500000 +v -3.414269 0.582233 0.500000 +v -3.360440 0.656322 0.500000 +v -3.332140 0.743420 0.500000 +v -3.332140 0.834999 0.500000 +v -3.360440 0.922096 0.500000 +v -3.414269 0.996186 0.500000 +g Cube.003_Cube.004_Material.002 +usemtl Material.002 +s off +f 73//1 71//1 72//1 +f 74//1 71//1 73//1 +f 74//1 70//1 71//1 +f 55//1 70//1 74//1 +f 55//1 69//1 70//1 +f 69//1 55//1 56//1 +f 56//1 68//1 69//1 +f 57//1 68//1 56//1 +f 57//1 67//1 68//1 +f 58//1 67//1 57//1 +f 58//1 66//1 67//1 +f 59//1 66//1 58//1 +f 59//1 65//1 66//1 +f 60//1 65//1 59//1 +f 60//1 64//1 65//1 +f 61//1 64//1 60//1 +f 61//1 63//1 64//1 +f 62//1 63//1 61//1 +f 78//10 76//10 77//10 +f 78//10 75//10 76//10 +f 79//10 75//10 78//10 +f 79//10 94//10 75//10 +f 80//10 94//10 79//10 +f 80//10 93//10 94//10 +f 81//10 93//10 80//10 +f 81//10 92//10 93//10 +f 82//10 92//10 81//10 +f 82//10 91//10 92//10 +f 83//10 91//10 82//10 +f 83//10 90//10 91//10 +f 84//10 90//10 83//10 +f 84//10 89//10 90//10 +f 85//10 89//10 84//10 +f 85//10 88//10 89//10 +f 86//10 88//10 85//10 +f 86//10 87//10 88//10 +v -2.327900 2.981822 0.000000 +v -1.946631 2.517246 0.000000 +v -1.663324 1.987213 0.000000 +v -1.488863 1.412095 0.000000 +v -1.441604 0.586849 0.000000 +v -1.488863 0.215889 0.000000 +v -1.663323 -0.359229 0.000000 +v -1.946631 -0.889262 0.000000 +v -2.327900 -1.353839 0.000000 +v -2.792477 -1.735108 0.000000 +v -3.322510 -2.018416 0.000000 +v -3.897629 -2.192876 0.000000 +v -4.747342 -2.200104 0.000000 +v -4.747336 3.727444 0.000000 +v -3.550383 3.725241 0.000000 +v -3.322504 3.646397 0.000000 +v -2.792472 3.363088 0.000000 +v -3.110140 1.315794 0.000000 +v -2.962800 1.105371 0.000000 +v -2.943537 1.031374 0.000000 +v -2.924606 0.589536 0.000000 +v -3.027266 0.368530 0.000000 +v -3.208907 0.186889 0.000000 +v -3.441719 0.078327 0.000000 +v -3.697621 0.055938 0.000000 +v -3.945747 0.122423 0.000000 +v -4.156171 0.269763 0.000000 +v -4.303511 0.480187 0.000000 +v -4.369996 0.728313 0.000000 +v -4.347608 0.984215 0.000000 +v -4.239046 1.217027 0.000000 +v -4.057405 1.398669 0.000000 +v -3.824593 1.507231 0.000000 +v -3.568691 1.529619 0.000000 +v -3.320565 1.463135 0.000000 +v -1.442270 1.039348 0.000000 +v -1.442270 1.039348 0.500000 +v -3.320565 1.463135 0.500000 +v -3.568691 1.529619 0.500000 +v -3.824593 1.507231 0.500000 +v -4.057405 1.398669 0.500000 +v -4.239046 1.217027 0.500000 +v -4.347608 0.984215 0.500000 +v -4.369996 0.728313 0.500000 +v -4.303511 0.480187 0.500000 +v -4.156171 0.269763 0.500000 +v -3.945747 0.122423 0.500000 +v -3.697621 0.055938 0.500000 +v -3.441719 0.078327 0.500000 +v -3.208907 0.186889 0.500000 +v -3.027266 0.368530 0.500000 +v -2.924606 0.589536 0.500000 +v -2.943537 1.031374 0.500000 +v -2.962800 1.105371 0.500000 +v -3.110140 1.315794 0.500000 +v -2.792472 3.363088 0.500000 +v -3.322504 3.646397 0.500000 +v -3.550383 3.725241 0.500000 +v -4.747336 3.727444 0.500000 +v -4.747342 -2.200104 0.500000 +v -3.897629 -2.192876 0.500000 +v -3.322510 -2.018416 0.500000 +v -2.792477 -1.735108 0.500000 +v -2.327900 -1.353839 0.500000 +v -1.946631 -0.889262 0.500000 +v -1.663323 -0.359229 0.500000 +v -1.488863 0.215889 0.500000 +v -1.441604 0.586849 0.500000 +v -1.488863 1.412095 0.500000 +v -1.663324 1.987213 0.500000 +v -1.946631 2.517246 0.500000 +v -2.327900 2.981822 0.500000 +vn 0.001812 0.999998 0.000000 +vn 0.005311 -0.999986 0.000000 +vn -1.000000 0.000001 0.000000 +vn 0.001840 0.999998 0.000000 +vn 0.008506 -0.999964 0.000000 +g Cylinder.001_Cylinder.001_Material.001 +usemtl Material.001 +s off +f 124//1 107//1 108//1 +f 125//1 124//1 108//1 +f 126//1 125//1 108//1 +f 109//1 126//1 108//1 +f 110//1 126//1 109//1 +f 111//1 126//1 110//1 +f 95//1 126//1 111//1 +f 126//1 95//1 96//1 +f 127//1 126//1 96//1 +f 128//1 127//1 96//1 +f 97//1 128//1 96//1 +f 98//1 128//1 97//1 +f 98//1 129//1 128//1 +f 98//1 112//1 129//1 +f 130//1 112//1 98//1 +f 130//1 113//1 112//1 +f 130//1 114//1 113//1 +f 123//1 107//1 124//1 +f 122//1 107//1 123//1 +f 99//1 116//1 115//1 +f 100//1 116//1 99//1 +f 121//1 107//1 122//1 +f 100//1 117//1 116//1 +f 120//1 107//1 121//1 +f 101//1 117//1 100//1 +f 101//1 118//1 117//1 +f 119//1 107//1 120//1 +f 101//1 119//1 118//1 +f 101//1 107//1 119//1 +f 102//1 107//1 101//1 +f 103//1 107//1 102//1 +f 104//1 107//1 103//1 +f 105//1 107//1 104//1 +f 106//1 107//1 105//1 +f 115//19 146//19 162//19 99//19 +f 130//20 131//20 147//20 114//20 +f 107//21 154//21 153//21 108//21 +f 108//22 153//22 152//22 109//22 +f 106//23 155//23 154//23 107//23 +f 154//10 137//10 153//10 +f 137//10 136//10 153//10 +f 136//10 135//10 153//10 +f 135//10 152//10 153//10 +f 135//10 151//10 152//10 +f 135//10 150//10 151//10 +f 135//10 166//10 150//10 +f 135//10 165//10 166//10 +f 135//10 134//10 165//10 +f 134//10 133//10 165//10 +f 133//10 164//10 165//10 +f 133//10 163//10 164//10 +f 132//10 163//10 133//10 +f 149//10 163//10 132//10 +f 149//10 131//10 163//10 +f 148//10 131//10 149//10 +f 147//10 131//10 148//10 +f 154//10 138//10 137//10 +f 154//10 139//10 138//10 +f 145//10 162//10 146//10 +f 145//10 161//10 162//10 +f 154//10 140//10 139//10 +f 144//10 161//10 145//10 +f 154//10 141//10 140//10 +f 144//10 160//10 161//10 +f 143//10 160//10 144//10 +f 154//10 142//10 141//10 +f 142//10 160//10 143//10 +f 154//10 160//10 142//10 +f 154//10 159//10 160//10 +f 154//10 158//10 159//10 +f 154//10 157//10 158//10 +f 154//10 156//10 157//10 +f 154//10 155//10 156//10 +v -1.967500 3.292557 0.000000 +v -1.539864 2.771481 0.000000 +v -1.222102 2.176990 0.000000 +v -1.026424 1.531928 0.000000 +v -0.969990 1.037352 0.000000 +v -2.503128 3.729895 0.000000 +v -2.503128 3.729895 0.500000 +v -0.969990 1.037352 0.500000 +v -1.026424 1.531928 0.500000 +v -1.222102 2.176990 0.500000 +v -1.539864 2.771481 0.500000 +v -1.967500 3.292557 0.500000 +vn -0.706198 -0.707968 0.000000 +vn -0.632435 -0.774590 0.000000 +vn -0.993530 -0.113346 0.000000 +vn -0.979247 -0.202643 0.000000 +vn -0.923856 -0.382672 0.000000 +vn -0.831446 -0.555559 0.000000 +g Cube.002_Cube.003_Material.002 +usemtl Material.002 +s 1 +f 167//24 178//24 173//25 172//25 +f 171//26 174//26 175//27 170//27 +f 170//27 175//27 176//28 169//28 +f 169//28 176//28 177//29 168//29 +f 178//24 167//24 168//29 177//29 +v -3.414269 0.996186 0.000000 +v -3.360440 0.922096 0.000000 +v -3.332140 0.834999 0.000000 +v -3.332140 0.743420 0.000000 +v -3.360440 0.656322 0.000000 +v -3.414269 0.582233 0.000000 +v -3.488358 0.528404 0.000000 +v -3.575455 0.500104 0.000000 +v -3.667035 0.500104 0.000000 +v -3.754132 0.528404 0.000000 +v -3.828222 0.582233 0.000000 +v -3.882050 0.656322 0.000000 +v -3.910350 0.743420 0.000000 +v -3.910350 0.834999 0.000000 +v -3.882050 0.922097 0.000000 +v -3.828221 0.996186 0.000000 +v -3.754131 1.050015 0.000000 +v -3.667034 1.078314 0.000000 +v -3.575454 1.078314 0.000000 +v -3.488358 1.050014 0.000000 +v -3.488358 1.050014 0.500000 +v -3.575454 1.078314 0.500000 +v -3.667034 1.078314 0.500000 +v -3.754131 1.050015 0.500000 +v -3.828221 0.996186 0.500000 +v -3.882050 0.922097 0.500000 +v -3.910350 0.834999 0.500000 +v -3.910350 0.743420 0.500000 +v -3.882050 0.656322 0.500000 +v -3.828222 0.582233 0.500000 +v -3.754132 0.528404 0.500000 +v -3.667035 0.500104 0.500000 +v -3.575455 0.500104 0.500000 +v -3.488358 0.528404 0.500000 +v -3.414269 0.582233 0.500000 +v -3.360440 0.656322 0.500000 +v -3.332140 0.743420 0.500000 +v -3.332140 0.834999 0.500000 +v -3.360440 0.922096 0.500000 +v -3.414269 0.996186 0.500000 +vn 0.707083 0.707083 0.000000 +vn 0.453963 0.890988 0.000000 +vn 0.156407 0.987671 0.000000 +vn -0.156407 0.987671 0.000000 +vn -0.453963 0.890988 0.000000 +vn -0.707083 0.707083 0.000000 +vn -0.890988 0.453993 0.000000 +vn -0.987671 0.156407 0.000000 +vn -0.987671 -0.156407 0.000000 +vn -0.890988 -0.453963 0.000000 +vn -0.707083 -0.707083 0.000000 +vn -0.453963 -0.890988 0.000000 +vn -0.156407 -0.987671 0.000000 +vn 0.156407 -0.987671 0.000000 +vn 0.453963 -0.890988 0.000000 +vn 0.707083 -0.707083 0.000000 +vn 0.890988 -0.453963 0.000000 +vn 0.987671 -0.156407 0.000000 +vn 0.987671 0.156407 0.000000 +vn 0.890988 0.453963 0.000000 +g Cube.001_Cube.002_Material.002 +usemtl Material.002 +s 1 +f 218//30 179//30 198//31 199//31 +f 197//32 200//32 199//31 198//31 +f 196//33 201//33 200//32 197//32 +f 195//34 202//34 201//33 196//33 +f 194//35 203//35 202//34 195//34 +f 193//36 204//36 203//35 194//35 +f 192//37 205//37 204//36 193//36 +f 191//38 206//38 205//37 192//37 +f 190//39 207//39 206//38 191//38 +f 189//40 208//40 207//39 190//39 +f 188//41 209//41 208//40 189//40 +f 187//42 210//42 209//41 188//41 +f 186//43 211//43 210//42 187//42 +f 185//44 212//44 211//43 186//43 +f 184//45 213//45 212//44 185//44 +f 183//46 214//46 213//45 184//45 +f 182//47 215//47 214//46 183//46 +f 181//48 216//48 215//47 182//47 +f 180//49 217//49 216//48 181//48 +f 179//30 218//30 217//49 180//49 +v -0.972935 0.581641 0.000000 +v -1.028585 0.087289 0.000000 +v -1.218865 -0.539980 0.000000 +v -1.527863 -1.118075 0.000000 +v -1.943704 -1.624779 0.000000 +v -2.450409 -2.040621 0.000000 +v -2.782750 -2.236504 0.000000 +v -2.782750 -2.236504 0.500000 +v -2.450409 -2.040621 0.500000 +v -1.943704 -1.624779 0.500000 +v -1.527863 -1.118075 0.500000 +v -1.218865 -0.539980 0.500000 +v -1.028585 0.087289 0.500000 +v -0.972935 0.581641 0.500000 +vn -0.507767 0.861476 0.000000 +vn -0.572771 0.819697 0.000000 +vn -0.831446 0.555559 0.000000 +vn -0.923856 0.382672 0.000000 +vn -0.979400 0.201910 0.000000 +vn -0.993713 0.111850 0.000000 +g Cube_Cube.001_Material.001 +usemtl Material.001 +s 1 +f 225//50 226//50 227//51 224//51 +f 224//51 227//51 228//35 223//35 +f 223//35 228//35 229//52 222//52 +f 222//52 229//52 230//53 221//53 +f 221//53 230//53 231//54 220//54 +f 232//55 219//55 220//54 231//54 +v -2.327900 2.981822 0.000000 +v -1.946631 2.517246 0.000000 +v -1.663324 1.987213 0.000000 +v -1.488863 1.412095 0.000000 +v -1.441604 0.586849 0.000000 +v -1.488863 0.215889 0.000000 +v -1.663323 -0.359229 0.000000 +v -1.946631 -0.889262 0.000000 +v -2.327900 -1.353839 0.000000 +v -2.792477 -1.735108 0.000000 +v -3.322510 -2.018416 0.000000 +v -3.897629 -2.192876 0.000000 +v -3.550383 3.725241 0.000000 +v -3.322504 3.646397 0.000000 +v -2.792472 3.363088 0.000000 +v -3.110140 1.315794 0.000000 +v -2.962800 1.105371 0.000000 +v -2.943537 1.031374 0.000000 +v -2.924606 0.589536 0.000000 +v -3.027266 0.368530 0.000000 +v -3.208907 0.186889 0.000000 +v -3.441719 0.078327 0.000000 +v -3.697621 0.055938 0.000000 +v -3.945747 0.122423 0.000000 +v -4.156171 0.269763 0.000000 +v -4.303511 0.480187 0.000000 +v -4.369996 0.728313 0.000000 +v -4.347608 0.984215 0.000000 +v -4.239046 1.217027 0.000000 +v -4.057405 1.398669 0.000000 +v -3.824593 1.507231 0.000000 +v -3.568691 1.529619 0.000000 +v -3.320565 1.463135 0.000000 +v -1.442270 1.039348 0.000000 +v -1.442270 1.039348 0.500000 +v -3.320565 1.463135 0.500000 +v -3.568691 1.529619 0.500000 +v -3.824593 1.507231 0.500000 +v -4.057405 1.398669 0.500000 +v -4.239046 1.217027 0.500000 +v -4.347608 0.984215 0.500000 +v -4.369996 0.728313 0.500000 +v -4.303511 0.480187 0.500000 +v -4.156171 0.269763 0.500000 +v -3.945747 0.122423 0.500000 +v -3.697621 0.055938 0.500000 +v -3.441719 0.078327 0.500000 +v -3.208907 0.186889 0.500000 +v -3.027266 0.368530 0.500000 +v -2.924606 0.589536 0.500000 +v -2.943537 1.031374 0.500000 +v -2.962800 1.105371 0.500000 +v -3.110140 1.315794 0.500000 +v -2.792472 3.363088 0.500000 +v -3.322504 3.646397 0.500000 +v -3.550383 3.725241 0.500000 +v -3.897629 -2.192876 0.500000 +v -3.322510 -2.018416 0.500000 +v -2.792477 -1.735108 0.500000 +v -2.327900 -1.353839 0.500000 +v -1.946631 -0.889262 0.500000 +v -1.663323 -0.359229 0.500000 +v -1.488863 0.215889 0.500000 +v -1.441604 0.586849 0.500000 +v -1.488863 1.412095 0.500000 +v -1.663324 1.987213 0.500000 +v -1.946631 2.517246 0.500000 +v -2.327900 2.981822 0.500000 +vn 0.978118 0.207892 0.000000 +vn 0.992248 0.124027 0.000000 +vn -0.422590 -0.906308 0.000000 +vn -0.087130 -0.996185 0.000000 +vn 0.258797 -0.965911 0.000000 +vn 0.573565 -0.819147 0.000000 +vn 0.819147 -0.573565 0.000000 +vn 0.965911 -0.258797 0.000000 +vn 0.996185 0.087130 0.000000 +vn 0.906278 0.422590 0.000000 +vn 0.422590 0.906278 0.000000 +vn 0.087130 0.996185 0.000000 +vn -0.258797 0.965911 0.000000 +vn -0.573565 0.819147 0.000000 +vn -0.819575 0.572954 0.000000 +vn -0.906919 0.421277 0.000000 +vn -0.967742 -0.251930 0.000000 +vn -0.907804 -0.419385 0.000000 +vn 0.555559 0.831446 0.000000 +vn 0.400403 0.916318 0.000000 +vn 0.326945 0.945006 0.000000 +vn 0.382672 -0.923856 0.000000 +vn 0.290262 -0.956938 0.000000 +vn 0.555559 -0.831446 0.000000 +vn 0.831446 -0.555559 0.000000 +vn 0.923856 -0.382672 0.000000 +vn 0.977874 -0.209052 0.000000 +vn 0.991974 -0.126347 0.000000 +vn 0.923856 0.382672 0.000000 +vn 0.831446 0.555559 0.000000 +g Cylinder_Cylinder_Material.001 +usemtl Material.001 +s 1 +f 236//56 297//56 267//57 266//57 +f 248//40 285//40 268//58 265//58 +f 265//58 268//58 269//59 264//59 +f 264//59 269//59 270//60 263//60 +f 263//60 270//60 271//61 262//61 +f 262//61 271//61 272//62 261//62 +f 261//62 272//62 273//63 260//63 +f 260//63 273//63 274//64 259//64 +f 259//64 274//64 275//65 258//65 +f 258//65 275//65 276//30 257//30 +f 257//30 276//30 277//66 256//66 +f 256//66 277//66 278//67 255//67 +f 255//67 278//67 279//68 254//68 +f 254//68 279//68 280//69 253//69 +f 253//69 280//69 281//70 252//70 +f 252//70 281//70 282//71 251//71 +f 250//72 283//72 284//73 249//73 +f 249//73 284//73 285//40 248//40 +f 300//30 233//30 247//74 286//74 +f 246//75 287//75 286//74 247//74 +f 245//76 288//76 287//75 246//75 +f 243//77 290//77 289//78 244//78 +f 242//79 291//79 290//77 243//77 +f 241//45 292//45 291//79 242//79 +f 240//80 293//80 292//45 241//45 +f 239//81 294//81 293//80 240//80 +f 238//82 295//82 294//81 239//81 +f 237//83 296//83 295//82 238//82 +f 235//84 298//84 297//56 236//56 +f 234//85 299//85 298//84 235//84 +f 233//30 300//30 299//85 234//85 diff --git a/make-win32.bat b/make-win32.bat new file mode 100755 index 0000000..2229c2c --- /dev/null +++ b/make-win32.bat @@ -0,0 +1 @@ +mingw32-make WIN32=1 %* diff --git a/ss/LogoBox.cpp b/ss/LogoBox.cpp new file mode 100644 index 0000000..05d9671 --- /dev/null +++ b/ss/LogoBox.cpp @@ -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 +#include +#include "../wfobj/WFObj.hh" +#include "LogoBox.h" +#include "../LoadFile/LoadFile.h" + +#include +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]; +} + diff --git a/ss/LogoBox.h b/ss/LogoBox.h new file mode 100644 index 0000000..07bc93f --- /dev/null +++ b/ss/LogoBox.h @@ -0,0 +1,31 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + * The LogoBox class + */ + +#ifndef LOGOBOX_H +#define LOGOBOX_H + +#include +#include + +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 diff --git a/ss/Makefile b/ss/Makefile new file mode 100644 index 0000000..156aa1b --- /dev/null +++ b/ss/Makefile @@ -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 diff --git a/ss/PlainSpin.cc b/ss/PlainSpin.cc new file mode 100644 index 0000000..759f91d --- /dev/null +++ b/ss/PlainSpin.cc @@ -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 +#include +#include "PlainSpin.h" + +#include +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(); +} diff --git a/ss/PlainSpin.h b/ss/PlainSpin.h new file mode 100644 index 0000000..07527bd --- /dev/null +++ b/ss/PlainSpin.h @@ -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 diff --git a/ss/SSMain.cc b/ss/SSMain.cc new file mode 100644 index 0000000..bfd4d37 --- /dev/null +++ b/ss/SSMain.cc @@ -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 /* srand() */ +#include /* time() */ +#include +#include +#include +#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; +} diff --git a/ss/SSMain.h b/ss/SSMain.h new file mode 100644 index 0000000..6bff636 --- /dev/null +++ b/ss/SSMain.h @@ -0,0 +1,41 @@ + +/* Author: Josh Holtrop + * DornerWorks screensaver + * The main screensaver module + */ + +#ifndef SSMAIN_H +#define SSMAIN_H + +#include +#include + +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 diff --git a/ss/SSMode.cc b/ss/SSMode.cc new file mode 100644 index 0000000..8f85ada --- /dev/null +++ b/ss/SSMode.cc @@ -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); +} diff --git a/ss/SSMode.h b/ss/SSMode.h new file mode 100644 index 0000000..c64b48f --- /dev/null +++ b/ss/SSMode.h @@ -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 +#include + +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 diff --git a/ss/Towers.cc b/ss/Towers.cc new file mode 100644 index 0000000..892f53b --- /dev/null +++ b/ss/Towers.cc @@ -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 /* fmax(), sin() */ +#include /* rand() */ +#include +#include +#include "Towers.h" +#include + +#include +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::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); +} + diff --git a/ss/Towers.h b/ss/Towers.h new file mode 100644 index 0000000..72f6018 --- /dev/null +++ b/ss/Towers.h @@ -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 +#include + +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 m_logos; + Uint32 m_lastElapsed; + GLuint m_groundTexture; + int m_logoToRemove; + Uint32 m_lastRemoveTime; + GLuint m_logosList; +}; + +#endif diff --git a/ss/TumblingLogos.cc b/ss/TumblingLogos.cc new file mode 100644 index 0000000..11575c6 --- /dev/null +++ b/ss/TumblingLogos.cc @@ -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 /* fmax() */ +#include /* rand() */ +#include +#include +#include "TumblingLogos.h" +#include + +#include +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]); +} diff --git a/ss/TumblingLogos.h b/ss/TumblingLogos.h new file mode 100644 index 0000000..f316f8a --- /dev/null +++ b/ss/TumblingLogos.h @@ -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 +#include + +#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 m_logos; + Uint32 m_lastGravityChangeTime; + Uint32 m_lastElapsed; +}; + +#endif