* port of known OSX screensaver done by Calum Robinson called Flurry (the default one on OSX)

* add to build but not to the image since

 - misses some configuration stuff
 - does not look as good as it could be because of missing double buffering
 - does crash screen_blanker on hide (as all GL screensaver did that i tested)



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29718 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Karsten Heimrich 2009-03-25 23:49:41 +00:00
parent ea1bae881b
commit 82d2e399b4
13 changed files with 1757 additions and 0 deletions

View File

@ -1,6 +1,8 @@
SubDir HAIKU_TOP src add-ons screen_savers ;
SubInclude HAIKU_TOP src add-ons screen_savers debugnow ;
SubInclude HAIKU_TOP src add-ons screen_savers flurry ;
SubInclude HAIKU_TOP src add-ons screen_savers GLife ;
SubInclude HAIKU_TOP src add-ons screen_savers haiku ;
SubInclude HAIKU_TOP src add-ons screen_savers ifs ;
SubInclude HAIKU_TOP src add-ons screen_savers message ;

View File

@ -0,0 +1,388 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "Flurry.h"
#include "Shared.h"
#include "Smoke.h"
#include "Spark.h"
#include "Star.h"
#include "Texture.h"
#include <new>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
using namespace BPrivate;
FlurryView::FlurryView(BRect bounds)
: BGLView(bounds, NULL, B_FOLLOW_ALL, B_FRAME_EVENTS | B_WILL_DRAW,
BGL_RGB | BGL_ALPHA | BGL_DEPTH | BGL_DOUBLE),
fOldFrameTime(-1.0),
fFlurryInfo_t(NULL)
{
fWidth = bounds.Width();
fHeight = bounds.Height();
fStartTime = _CurrentTime();
LockGL();
_SetupFlurryBaseInfo();
UnlockGL();
}
FlurryView::~FlurryView()
{
if (fFlurryInfo_t) {
LockGL();
free(fFlurryInfo_t->s);
free(fFlurryInfo_t->star);
for (int32 i = 0; i < MAX_SPARKS; ++i)
free(fFlurryInfo_t->spark[i]);
free(fFlurryInfo_t);
UnlockGL();
}
}
status_t
FlurryView::InitCheck() const
{
return (fFlurryInfo_t != NULL) ? B_OK : B_ERROR;
}
void
FlurryView::AttachedToWindow()
{
LockGL();
BGLView::AttachedToWindow();
MakeTexture();
glDisable(GL_DEPTH_TEST);
glAlphaFunc(GL_GREATER, 0.0);
glEnable(GL_ALPHA_TEST);
glShadeModel(GL_FLAT);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glViewport(0, 0, int(fWidth), int(fHeight));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, fWidth, 0.0, fHeight);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
UnlockGL();
}
void
FlurryView::DrawFlurryScreenSaver()
{
double deltaFrameTime = 0.0;
const double newFrameTime = _CurrentTime();
GLfloat alpha = 1.0;
if (fOldFrameTime >= 0.0) {
deltaFrameTime = newFrameTime - fOldFrameTime;
alpha = 5.0 * deltaFrameTime;
if (alpha > 0.2)
alpha = 0.2;
}
fOldFrameTime = newFrameTime;
LockGL();
// TODO: enable once double buffering is supported
//glDrawBuffer(GL_BACK);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(0.0, 0.0, 0.0, alpha);
glRectd(0.0, 0.0, fWidth, fHeight);
fFlurryInfo_t->dframe++;
fFlurryInfo_t->fOldTime = fFlurryInfo_t->fTime;
fFlurryInfo_t->fTime = _SecondsSinceStart() + fFlurryInfo_t->randomSeed;
fFlurryInfo_t->fDeltaTime = fFlurryInfo_t->fTime - fFlurryInfo_t->fOldTime;
fFlurryInfo_t->drag = (float)pow(0.9965, fFlurryInfo_t->fDeltaTime * 85.0);
UpdateStar(fFlurryInfo_t, fFlurryInfo_t->star);
glEnable(GL_BLEND);
glShadeModel(GL_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (int32 i = 0; i < fFlurryInfo_t->numStreams; ++i) {
fFlurryInfo_t->spark[i]->color[0] = 1.0;
fFlurryInfo_t->spark[i]->color[1] = 1.0;
fFlurryInfo_t->spark[i]->color[2] = 1.0;
fFlurryInfo_t->spark[i]->color[3] = 1.0;
UpdateSpark(fFlurryInfo_t, fFlurryInfo_t->spark[i]);
}
UpdateSmoke_ScalarBase(fFlurryInfo_t, fFlurryInfo_t->s);
glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
const double brite = pow(deltaFrameTime, 0.75) * 10.0;
DrawSmoke_Scalar(fFlurryInfo_t, fFlurryInfo_t->s,
brite * fFlurryInfo_t->briteFactor);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glFinish();
SwapBuffers();
UnlockGL();
}
void
FlurryView::FrameResized(float newWidth, float newHeight)
{
LockGL();
BGLView::FrameResized(newWidth, newHeight);
if (fFlurryInfo_t) {
fWidth = newWidth;
fHeight = newHeight;
fFlurryInfo_t->sys_glWidth = fWidth;
fFlurryInfo_t->sys_glHeight = fHeight;
glViewport(0, 0, int(fWidth), int(fHeight));
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, fWidth, 0.0, fHeight);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
UnlockGL();
}
void
FlurryView::_SetupFlurryBaseInfo()
{
fFlurryInfo_t = (flurry_info_t *)malloc(sizeof(flurry_info_t));
if (!fFlurryInfo_t)
return;
fFlurryInfo_t->next = NULL;
fFlurryInfo_t->randomSeed = RandFlt(0.0, 300.0);
fFlurryInfo_t->dframe = 0;
fFlurryInfo_t->fOldTime = 0.0;
fFlurryInfo_t->sys_glWidth = fWidth;
fFlurryInfo_t->sys_glHeight = fHeight;
fFlurryInfo_t->fTime = _SecondsSinceStart() + fFlurryInfo_t->randomSeed;
fFlurryInfo_t->fDeltaTime = fFlurryInfo_t->fTime - fFlurryInfo_t->fOldTime;
fFlurryInfo_t->numStreams = 5;
fFlurryInfo_t->briteFactor = 1.0;
fFlurryInfo_t->streamExpansion = 10000.0;
fFlurryInfo_t->currentColorMode = tiedyeColorMode;
fFlurryInfo_t->s = (SmokeV*)malloc(sizeof(SmokeV));
InitSmoke(fFlurryInfo_t->s);
fFlurryInfo_t->star = (Star*)malloc(sizeof(Star));
InitStar(fFlurryInfo_t->star);
fFlurryInfo_t->star->rotSpeed = 1.0;
for (int32 i = 0; i < MAX_SPARKS; ++i) {
fFlurryInfo_t->spark[i] = (Spark*)malloc(sizeof(Spark));
InitSpark(fFlurryInfo_t->spark[i]);
fFlurryInfo_t->spark[i]->mystery = 1800 * (i + 1) / 13;
UpdateSpark(fFlurryInfo_t, fFlurryInfo_t->spark[i]);
}
for (int32 i = 0; i < NUMSMOKEPARTICLES / 4; ++i) {
for (int32 k = 0; k < 4; ++k)
fFlurryInfo_t->s->p[i].dead.i[k] = 1;
}
}
double
FlurryView::_CurrentTime() const
{
return double(fDateTime.CurrentDateTime(B_LOCAL_TIME).Time_t() +
double(fTime.CurrentTime(B_LOCAL_TIME).Millisecond() / 1000.0));
}
double
FlurryView::_SecondsSinceStart() const
{
return _CurrentTime() - fStartTime;
}
// #pragma mark - Flurry
extern "C" BScreenSaver*
instantiate_screen_saver(BMessage* archive, image_id imageId)
{
return new Flurry(archive, imageId);
}
Flurry::Flurry(BMessage* archive, image_id imageId)
: BScreenSaver(archive, imageId),
fFlurryView(NULL)
{
struct timeval tv;
gettimeofday(&tv, NULL);
srand((999 * tv.tv_sec) + (1001 * tv.tv_usec) + (1003 * getpid()));
}
Flurry::~Flurry()
{
}
status_t
Flurry::InitCheck()
{
return B_OK;
}
status_t
Flurry::StartSaver(BView* view, bool preview)
{
status_t status = B_ERROR;
if (preview)
return status;
SetTickSize(50000);
fFlurryView = new (std::nothrow) FlurryView(view->Bounds());
if (fFlurryView) {
if (fFlurryView->InitCheck() != B_OK) {
delete fFlurryView;
fFlurryView = NULL;
} else {
status = B_OK;
view->AddChild(fFlurryView);
}
}
return status;
}
void
Flurry::StopSaver()
{
if (fFlurryView)
fFlurryView->EnableDirectMode(false);
}
void
Flurry::DirectDraw(int32 frame)
{
fFlurryView->DrawFlurryScreenSaver();
}
void
Flurry::DirectConnected(direct_buffer_info* info)
{
if (fFlurryView) {
fFlurryView->DirectConnected(info);
fFlurryView->EnableDirectMode(true);
}
}
void
Flurry::StartConfig(BView* configView)
{
}
void
Flurry::StopConfig()
{
}
status_t
Flurry::SaveState(BMessage* into) const
{
return B_ERROR;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright Karsten Heimrich, host.haiku@gmx.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FLURRY_H_
#define _FLURRY_H_
#include <DateTime.h>
#include <GLView.h>
#include <ScreenSaver.h>
struct flurry_info_t;
class FlurryView : public BGLView {
public:
FlurryView(BRect bounds);
virtual ~FlurryView();
status_t InitCheck() const;
virtual void AttachedToWindow();
virtual void DrawFlurryScreenSaver();
virtual void FrameResized(float width, float height);
private:
void _SetupFlurryBaseInfo();
double _CurrentTime() const;
double _SecondsSinceStart() const;
private:
float fWidth;
float fHeight;
double fStartTime;
double fOldFrameTime;
flurry_info_t* fFlurryInfo_t;
BPrivate::BTime fTime;
BPrivate::BDateTime fDateTime;
};
class Flurry : public BScreenSaver {
public:
Flurry(BMessage* archive, image_id imageId);
virtual ~Flurry();
virtual status_t InitCheck();
virtual status_t StartSaver(BView* view, bool preview);
virtual void StopSaver();
virtual void DirectDraw(int32 frame);
virtual void DirectConnected(direct_buffer_info* info);
virtual void StartConfig(BView* configView);
virtual void StopConfig();
virtual status_t SaveState(BMessage* into) const;
private:
FlurryView* fFlurryView;
};
#endif // _FLURRY_H_

View File

@ -0,0 +1,13 @@
SubDir HAIKU_TOP src add-ons screen_savers flurry ;
UsePrivateHeaders shared ;
ScreenSaver Flurry :
Flurry.cpp
Smoke.cpp
Spark.cpp
Star.cpp
Texture.cpp
: be screensaver GL libshared.a
;

View File

@ -0,0 +1,93 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SHARED_H_
#define _SHARED_H_
#include <math.h>
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
struct SmokeV;
struct Spark;
struct Star;
#define MAX_SPARKS 64
#define seraphDistance 2000.0f
/* used to compute the min and max of two expresions */
#define MIN_(a, b) (((a) < (b)) ? (a) : (b))
#define MAX_(a, b) (((a) > (b)) ? (a) : (b))
#define random() rand()
#define RandFlt(min, max) (min + (max - min) * rand() / (float) RAND_MAX)
#define RandBell(scale) (scale * (1.0f - (rand() + rand() + rand()) / ((float) RAND_MAX * 1.5f)))
typedef enum _ColorModes
{
redColorMode = 0,
magentaColorMode,
blueColorMode,
cyanColorMode,
greenColorMode,
yellowColorMode,
slowCyclicColorMode,
cyclicColorMode,
tiedyeColorMode,
rainbowColorMode,
whiteColorMode,
multiColorMode,
darkColorMode
} ColorModes;
typedef struct flurry_info_t {
flurry_info_t *next;
ColorModes currentColorMode;
SmokeV *s;
Star *star;
Spark *spark[MAX_SPARKS];
float streamExpansion;
int numStreams;
double randomSeed;
double fTime;
double fOldTime;
double fDeltaTime;
double briteFactor;
float drag;
int dframe;
float sys_glWidth;
float sys_glHeight;
} flurry_info_t;
#endif // _SHARED_H_

View File

@ -0,0 +1,375 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Smoke.h"
#include "Shared.h"
#include "Star.h"
#include "Spark.h"
#define MAXANGLES 16384
#define NOT_QUITE_DEAD 3
#define streamBias 7.0f
#define incohesion 0.07f
#define streamSpeed 450.0
#define gravity 1500000.0f
#define intensity 75000.0f;
#define streamSize 25000.0f
#define colorIncoherence 0.15f
static float FastDistance2D(float x, float y)
{
/* this function computes the distance from 0,0 to x,y with ~3.5% error */
float mn;
/* first compute the absolute value of x,y */
x = (x < 0.0f) ? -x : x;
y = (y < 0.0f) ? -y : y;
/* compute the minimum of x,y */
mn = x<y?x:y;
/* return the distance */
return(x+y-(mn*0.5f)-(mn*0.25f)+(mn*0.0625f));
}
void InitSmoke(SmokeV *s)
{
int i;
s->nextParticle = 0;
s->nextSubParticle = 0;
s->lastParticleTime = 0.25f;
s->firstTime = 1;
s->frame = 0;
for (i=0;i<3;i++) {
s->old[i] = RandFlt(-100.0, 100.0);
}
}
void UpdateSmoke_ScalarBase(flurry_info_t *info, SmokeV *s)
{
int i,j,k;
float sx = info->star->position[0];
float sy = info->star->position[1];
float sz = info->star->position[2];
double frameRate;
double frameRateModifier;
s->frame++;
if(!s->firstTime) {
/* release 12 puffs every frame */
if(info->fTime - s->lastParticleTime >= 1.0f / 121.0f) {
float dx,dy,dz,deltax,deltay,deltaz;
float f;
float rsquared;
float mag;
dx = s->old[0] - sx;
dy = s->old[1] - sy;
dz = s->old[2] - sz;
mag = 5.0f;
deltax = (dx * mag);
deltay = (dy * mag);
deltaz = (dz * mag);
for(i=0;i<info->numStreams;i++) {
float streamSpeedCoherenceFactor;
s->p[s->nextParticle].delta[0].f[s->nextSubParticle] = deltax;
s->p[s->nextParticle].delta[1].f[s->nextSubParticle] = deltay;
s->p[s->nextParticle].delta[2].f[s->nextSubParticle] = deltaz;
s->p[s->nextParticle].position[0].f[s->nextSubParticle] = sx;
s->p[s->nextParticle].position[1].f[s->nextSubParticle] = sy;
s->p[s->nextParticle].position[2].f[s->nextSubParticle] = sz;
s->p[s->nextParticle].oldposition[0].f[s->nextSubParticle] = sx;
s->p[s->nextParticle].oldposition[1].f[s->nextSubParticle] = sy;
s->p[s->nextParticle].oldposition[2].f[s->nextSubParticle] = sz;
streamSpeedCoherenceFactor = MAX_(0.0f,1.0f + RandBell(0.25f*incohesion));
dx = s->p[s->nextParticle].position[0].f[s->nextSubParticle] - info->spark[i]->position[0];
dy = s->p[s->nextParticle].position[1].f[s->nextSubParticle] - info->spark[i]->position[1];
dz = s->p[s->nextParticle].position[2].f[s->nextSubParticle] - info->spark[i]->position[2];
rsquared = (dx*dx+dy*dy+dz*dz);
f = streamSpeed * streamSpeedCoherenceFactor;
mag = f / (float) sqrt(rsquared);
s->p[s->nextParticle].delta[0].f[s->nextSubParticle] -= (dx * mag);
s->p[s->nextParticle].delta[1].f[s->nextSubParticle] -= (dy * mag);
s->p[s->nextParticle].delta[2].f[s->nextSubParticle] -= (dz * mag);
s->p[s->nextParticle].color[0].f[s->nextSubParticle] = info->spark[i]->color[0] * (1.0f + RandBell(colorIncoherence));
s->p[s->nextParticle].color[1].f[s->nextSubParticle] = info->spark[i]->color[1] * (1.0f + RandBell(colorIncoherence));
s->p[s->nextParticle].color[2].f[s->nextSubParticle] = info->spark[i]->color[2] * (1.0f + RandBell(colorIncoherence));
s->p[s->nextParticle].color[3].f[s->nextSubParticle] = 0.85f * (1.0f + RandBell(0.5f*colorIncoherence));
s->p[s->nextParticle].time.f[s->nextSubParticle] = info->fTime;
s->p[s->nextParticle].dead.i[s->nextSubParticle] = 0;
s->p[s->nextParticle].animFrame.i[s->nextSubParticle] = random()&63;
s->nextSubParticle++;
if (s->nextSubParticle==4) {
s->nextParticle++;
s->nextSubParticle=0;
}
if (s->nextParticle >= NUMSMOKEPARTICLES/4) {
s->nextParticle = 0;
s->nextSubParticle = 0;
}
}
s->lastParticleTime = info->fTime;
}
} else {
s->lastParticleTime = info->fTime;
s->firstTime = 0;
}
for(i=0;i<3;i++) {
s->old[i] = info->star->position[i];
}
frameRate = ((double) info->dframe)/(info->fTime);
frameRateModifier = 42.5f / frameRate;
for(i=0;i<NUMSMOKEPARTICLES/4;i++) {
for(k=0; k<4; k++) {
float dx,dy,dz;
float f;
float rsquared;
float mag;
float deltax;
float deltay;
float deltaz;
if (s->p[i].dead.i[k]) {
continue;
}
deltax = s->p[i].delta[0].f[k];
deltay = s->p[i].delta[1].f[k];
deltaz = s->p[i].delta[2].f[k];
for(j=0;j<info->numStreams;j++) {
dx = s->p[i].position[0].f[k] - info->spark[j]->position[0];
dy = s->p[i].position[1].f[k] - info->spark[j]->position[1];
dz = s->p[i].position[2].f[k] - info->spark[j]->position[2];
rsquared = (dx*dx+dy*dy+dz*dz);
f = (gravity/rsquared) * frameRateModifier;
if ((((i*4)+k) % info->numStreams) == j) {
f *= 1.0f + streamBias;
}
mag = f / (float) sqrt(rsquared);
deltax -= (dx * mag);
deltay -= (dy * mag);
deltaz -= (dz * mag);
}
/* slow this particle down by info->drag */
deltax *= info->drag;
deltay *= info->drag;
deltaz *= info->drag;
if((deltax*deltax+deltay*deltay+deltaz*deltaz) >= 25000000.0f) {
s->p[i].dead.i[k] = 1;
continue;
}
/* update the position */
s->p[i].delta[0].f[k] = deltax;
s->p[i].delta[1].f[k] = deltay;
s->p[i].delta[2].f[k] = deltaz;
for(j=0;j<3;j++) {
s->p[i].oldposition[j].f[k] = s->p[i].position[j].f[k];
s->p[i].position[j].f[k] += (s->p[i].delta[j].f[k])*info->fDeltaTime;
}
}
}
}
void DrawSmoke_Scalar(flurry_info_t *info, SmokeV *s, float brightness)
{
int svi = 0;
int sci = 0;
int sti = 0;
int si = 0;
float width;
float sx,sy;
float u0,v0,u1,v1;
float w,z;
float screenRatio = info->sys_glWidth / 1024.0f;
float hslash2 = info->sys_glHeight * 0.5f;
float wslash2 = info->sys_glWidth * 0.5f;
int i,k;
width = (streamSize+2.5f*info->streamExpansion) * screenRatio;
for (i=0;i<NUMSMOKEPARTICLES/4;i++)
{
for (k=0; k<4; k++) {
float thisWidth;
float oldz;
if (s->p[i].dead.i[k]) {
continue;
}
thisWidth = (streamSize + (info->fTime - s->p[i].time.f[k])*info->streamExpansion) * screenRatio;
if (thisWidth >= width)
{
s->p[i].dead.i[k] = 1;
continue;
}
z = s->p[i].position[2].f[k];
sx = s->p[i].position[0].f[k] * info->sys_glWidth / z + wslash2;
sy = s->p[i].position[1].f[k] * info->sys_glWidth / z + hslash2;
oldz = s->p[i].oldposition[2].f[k];
if (sx > info->sys_glWidth+50.0f || sx < -50.0f || sy > info->sys_glHeight+50.0f || sy < -50.0f || z < 25.0f || oldz < 25.0f)
{
continue;
}
w = MAX_(1.0f,thisWidth/z);
{
float oldx = s->p[i].oldposition[0].f[k];
float oldy = s->p[i].oldposition[1].f[k];
float oldscreenx = (oldx * info->sys_glWidth / oldz) + wslash2;
float oldscreeny = (oldy * info->sys_glWidth / oldz) + hslash2;
float dx = (sx-oldscreenx);
float dy = (sy-oldscreeny);
float d = FastDistance2D(dx, dy);
float sm, os, ow;
if (d)
{
sm = w/d;
}
else
{
sm = 0.0f;
}
ow = MAX_(1.0f,thisWidth/oldz);
if (d)
{
os = ow/d;
}
else
{
os = 0.0f;
}
{
floatToVector cmv;
float cm;
float m = 1.0f + sm;
float dxs = dx*sm;
float dys = dy*sm;
float dxos = dx*os;
float dyos = dy*os;
float dxm = dx*m;
float dym = dy*m;
s->p[i].animFrame.i[k]++;
if (s->p[i].animFrame.i[k] >= 64)
{
s->p[i].animFrame.i[k] = 0;
}
u0 = (s->p[i].animFrame.i[k]&&7) * 0.125f;
v0 = (s->p[i].animFrame.i[k]>>3) * 0.125f;
u1 = u0 + 0.125f;
v1 = v0 + 0.125f;
u1 = u0 + 0.125f;
v1 = v0 + 0.125f;
cm = (1.375f - thisWidth/width);
if (s->p[i].dead.i[k] == 3)
{
cm *= 0.125f;
s->p[i].dead.i[k] = 1;
}
si++;
cm *= brightness;
cmv.f[0] = s->p[i].color[0].f[k]*cm;
cmv.f[1] = s->p[i].color[1].f[k]*cm;
cmv.f[2] = s->p[i].color[2].f[k]*cm;
cmv.f[3] = s->p[i].color[3].f[k]*cm;
#if 0
/* MDT we can't use vectors in the Scalar routine */
s->seraphimColors[sci++].v = cmv.v;
s->seraphimColors[sci++].v = cmv.v;
s->seraphimColors[sci++].v = cmv.v;
s->seraphimColors[sci++].v = cmv.v;
#else
{
int ii, jj;
for (jj = 0; jj < 4; jj++) {
for (ii = 0; ii < 4; ii++) {
s->seraphimColors[sci].f[ii] = cmv.f[ii];
}
sci += 1;
}
}
#endif
s->seraphimTextures[sti++] = u0;
s->seraphimTextures[sti++] = v0;
s->seraphimTextures[sti++] = u0;
s->seraphimTextures[sti++] = v1;
s->seraphimTextures[sti++] = u1;
s->seraphimTextures[sti++] = v1;
s->seraphimTextures[sti++] = u1;
s->seraphimTextures[sti++] = v0;
s->seraphimVertices[svi].f[0] = sx+dxm-dys;
s->seraphimVertices[svi].f[1] = sy+dym+dxs;
s->seraphimVertices[svi].f[2] = sx+dxm+dys;
s->seraphimVertices[svi].f[3] = sy+dym-dxs;
svi++;
s->seraphimVertices[svi].f[0] = oldscreenx-dxm+dyos;
s->seraphimVertices[svi].f[1] = oldscreeny-dym-dxos;
s->seraphimVertices[svi].f[2] = oldscreenx-dxm-dyos;
s->seraphimVertices[svi].f[3] = oldscreeny-dym+dxos;
svi++;
}
}
}
}
glColorPointer(4,GL_FLOAT,0,s->seraphimColors);
glVertexPointer(2,GL_FLOAT,0,s->seraphimVertices);
glTexCoordPointer(2,GL_FLOAT,0,s->seraphimTextures);
glDrawArrays(GL_QUADS,0,si*4);
}

View File

@ -0,0 +1,76 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SMOKE_H_
#define _SMOKE_H_
struct flurry_info_t;
#define NUMSMOKEPARTICLES 3600
typedef union {
float f[4];
} floatToVector;
typedef union {
unsigned int i[4];
} intToVector;
typedef struct SmokeParticleV
{
floatToVector color[4];
floatToVector position[3];
floatToVector oldposition[3];
floatToVector delta[3];
intToVector dead;
floatToVector time;
intToVector animFrame;
} SmokeParticleV;
typedef struct SmokeV
{
SmokeParticleV p[NUMSMOKEPARTICLES/4];
int nextParticle;
int nextSubParticle;
float lastParticleTime;
int firstTime;
long frame;
float old[3];
floatToVector seraphimVertices[NUMSMOKEPARTICLES*2+1];
floatToVector seraphimColors[NUMSMOKEPARTICLES*4+1];
float seraphimTextures[NUMSMOKEPARTICLES*2*4];
} SmokeV;
void InitSmoke(SmokeV *s);
void UpdateSmoke_ScalarBase(flurry_info_t *flurry, SmokeV *s);
void DrawSmoke_Scalar(flurry_info_t *flurry, SmokeV *s, float);
#endif // _SMOKE_H_

View File

@ -0,0 +1,298 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Spark.h"
#include "Shared.h"
#define BIGMYSTERY 1800.0
#define MAXANGLES 16384
#define fieldCoherence 0
#define fieldSpeed 12.0f
#define fieldRange 1000.0f
void InitSpark(Spark *s)
{
int i;
for (i=0;i<3;i++)
{
s->position[i] = RandFlt(-100.0, 100.0);
}
}
void DrawSpark(flurry_info_t *info, Spark *s)
{
const float black[4] = {0.0f,0.0f,0.0f,1.0f};
float width,sx,sy;
float a;
float c = 0.0625f;
float screenx;
float screeny;
float w,z, scale;
int k;
width = 60000.0f * info->sys_glWidth / 1024.0f;
z = s->position[2];
sx = s->position[0] * info->sys_glWidth / z + info->sys_glWidth * 0.5f;
sy = s->position[1] * info->sys_glWidth / z + info->sys_glHeight * 0.5f;
w = width*4.0f / z;
screenx = sx;
screeny = sy;
glPushMatrix();
glTranslatef(screenx,screeny,0.0f);
scale = w/50.0f;
glScalef(scale,scale,0.0f);
for (k=0;k<12;k++)
{
a = ((float) (random() % 3600)) / 10.0f;
glRotatef(a,0.0f,0.0f,1.0f);
glBegin(GL_QUAD_STRIP);
glColor4fv(black);
glVertex2f(-3.0f,0.0f);
a = 2.0f + (float) (random() & 255) * c;
glVertex2f(-3.0f,a);
glColor4fv(s->color);
glVertex2f(0.0f,0.0f);
glColor4fv(black);
glVertex2f(0.0f,a);
glVertex2f(3.0f,0.0f);
glVertex2f(3.0f,a);
glEnd();
}
glPopMatrix();
}
void UpdateSparkColour(flurry_info_t *info, Spark *s)
{
const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
double thisPointInRadians;
double thisAngle = info->fTime*rotationsPerSecond;
float cf;
float cycleTime = 20.0f;
float colorRot;
float redPhaseShift;
float greenPhaseShift;
float bluePhaseShift;
float baseRed;
float baseGreen;
float baseBlue;
float colorTime;
if (info->currentColorMode == rainbowColorMode)
{
cycleTime = 1.5f;
}
else if (info->currentColorMode == tiedyeColorMode)
{
cycleTime = 4.5f;
}
else if (info->currentColorMode == cyclicColorMode)
{
cycleTime = 20.0f;
}
else if (info->currentColorMode == slowCyclicColorMode)
{
cycleTime = 120.0f;
}
colorRot = (float) (2.0*M_PI/cycleTime);
redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
greenPhaseShift = cycleTime / 3.0f;
bluePhaseShift = cycleTime * 2.0f / 3.0f ;
colorTime = info->fTime;
if (info->currentColorMode == whiteColorMode)
{
baseRed = 0.1875f;
baseGreen = 0.1875f;
baseBlue = 0.1875f;
}
else if (info->currentColorMode == multiColorMode)
{
baseRed = 0.0625f;
baseGreen = 0.0625f;
baseBlue = 0.0625f;
}
else if (info->currentColorMode == darkColorMode)
{
baseRed = 0.0f;
baseGreen = 0.0f;
baseBlue = 0.0f;
}
else
{
if (info->currentColorMode < slowCyclicColorMode)
{
colorTime = (info->currentColorMode / 6.0f) * cycleTime;
}
else
{
colorTime = info->fTime + info->randomSeed;
}
baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f);
baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f);
baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f);
}
cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) +
cos(3.0*((info->fTime)*rotationsPerSecond)) +
cos(13.0*((info->fTime)*rotationsPerSecond))));
cf /= 6.0f;
cf += 2.0f;
thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
s->color[0] = baseRed + 0.0625f *
(0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) +
(float) sin((7.0 * (thisPointInRadians + thisAngle))));
s->color[1] = baseGreen + 0.0625f *
(0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
s->color[2] = baseBlue + 0.0625f *
(0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
}
void UpdateSpark(flurry_info_t *info, Spark *s)
{
const float rotationsPerSecond = (float) (2.0*M_PI*fieldSpeed/MAXANGLES);
double thisPointInRadians;
double thisAngle = info->fTime*rotationsPerSecond;
float cf;
int i;
double tmpX1,tmpY1,tmpZ1;
double tmpX2,tmpY2,tmpZ2;
double tmpX3,tmpY3,tmpZ3;
double tmpX4,tmpY4,tmpZ4;
double rotation;
double cr;
double sr;
float cycleTime = 20.0f;
float colorRot;
float redPhaseShift;
float greenPhaseShift;
float bluePhaseShift;
float baseRed;
float baseGreen;
float baseBlue;
float colorTime;
float old[3];
if (info->currentColorMode == rainbowColorMode) {
cycleTime = 1.5f;
} else if (info->currentColorMode == tiedyeColorMode) {
cycleTime = 4.5f;
} else if (info->currentColorMode == cyclicColorMode) {
cycleTime = 20.0f;
} else if (info->currentColorMode == slowCyclicColorMode) {
cycleTime = 120.0f;
}
colorRot = (float) (2.0*M_PI/cycleTime);
redPhaseShift = 0.0f; /* cycleTime * 0.0f / 3.0f */
greenPhaseShift = cycleTime / 3.0f;
bluePhaseShift = cycleTime * 2.0f / 3.0f ;
colorTime = info->fTime;
if (info->currentColorMode == whiteColorMode) {
baseRed = 0.1875f;
baseGreen = 0.1875f;
baseBlue = 0.1875f;
} else if (info->currentColorMode == multiColorMode) {
baseRed = 0.0625f;
baseGreen = 0.0625f;
baseBlue = 0.0625f;
} else if (info->currentColorMode == darkColorMode) {
baseRed = 0.0f;
baseGreen = 0.0f;
baseBlue = 0.0f;
} else {
if(info->currentColorMode < slowCyclicColorMode) {
colorTime = (info->currentColorMode / 6.0f) * cycleTime;
} else {
colorTime = info->fTime + info->randomSeed;
}
baseRed = 0.109375f * ((float) cos((colorTime+redPhaseShift)*colorRot)+1.0f);
baseGreen = 0.109375f * ((float) cos((colorTime+greenPhaseShift)*colorRot)+1.0f);
baseBlue = 0.109375f * ((float) cos((colorTime+bluePhaseShift)*colorRot)+1.0f);
}
for (i=0;i<3;i++) {
old[i] = s->position[i];
}
cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) +
cos(3.0*((info->fTime)*rotationsPerSecond)) +
cos(13.0*((info->fTime)*rotationsPerSecond))));
cf /= 6.0f;
cf += 2.0f;
thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
s->color[0] = baseRed + 0.0625f *
(0.5f + (float) cos((15.0 * (thisPointInRadians + 3.0*thisAngle))) +
(float) sin((7.0 * (thisPointInRadians + thisAngle))));
s->color[1] = baseGreen + 0.0625f *
(0.5f + (float) sin(((thisPointInRadians) + thisAngle)));
s->color[2] = baseBlue + 0.0625f *
(0.5f + (float) cos((37.0 * (thisPointInRadians + thisAngle))));
s->position[0] = fieldRange * cf *
(float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle)));
s->position[1] = fieldRange * cf *
(float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle)));
s->position[2] = fieldRange *
(float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle))));
rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY;
cr = cos(rotation);
sr = sin(rotation);
tmpX1 = s->position[0] * cr - s->position[1] * sr;
tmpY1 = s->position[1] * cr + s->position[0] * sr;
tmpZ1 = s->position[2];
tmpX2 = tmpX1 * cr - tmpZ1 * sr;
tmpY2 = tmpY1;
tmpZ2 = tmpZ1 * cr + tmpX1 * sr;
tmpX3 = tmpX2;
tmpY3 = tmpY2 * cr - tmpZ2 * sr;
tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance;
rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (double) BIGMYSTERY;
cr = cos(rotation);
sr = sin(rotation);
tmpX4 = tmpX3 * cr - tmpY3 * sr;
tmpY4 = tmpY3 * cr + tmpX3 * sr;
tmpZ4 = tmpZ3;
s->position[0] = (float) tmpX4 + RandBell(5.0f*fieldCoherence);
s->position[1] = (float) tmpY4 + RandBell(5.0f*fieldCoherence);
s->position[2] = (float) tmpZ4 + RandBell(5.0f*fieldCoherence);
for (i=0;i<3;i++) {
s->delta[i] = (s->position[i] - old[i])/info->fDeltaTime;
}
}

View File

@ -0,0 +1,50 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SPARK_H_
#define _SPARK_H_
struct flurry_info_t;
typedef struct Spark
{
float position[3];
int mystery;
float delta[3];
float color[4];
} Spark;
void InitSpark(Spark *s);
void DrawSpark(flurry_info_t *info, Spark *s);
void UpdateSparkColour(flurry_info_t *info, Spark *s);
void UpdateSpark(flurry_info_t *info, Spark *s);
#endif // _SPARK_H_

View File

@ -0,0 +1,102 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Star.h"
#include "Shared.h"
#define BIGMYSTERY 1800.0
#define MAXANGLES 16384
/* Construction/Destruction */
void InitStar(Star *s)
{
int i;
for (i=0;i<3;i++) {
s->position[i] = RandFlt(-10000.0, 10000.0);
}
s->rotSpeed = RandFlt(0.4, 0.9);
s->mystery = RandFlt(0.0, 10.0);
}
void UpdateStar(flurry_info_t *info, Star *s)
{
/* speed control */
float rotationsPerSecond = (float) (2.0*M_PI*12.0/MAXANGLES) * s->rotSpeed;
double thisPointInRadians;
double thisAngle = info->fTime*rotationsPerSecond;
float cf;
double tmpX1,tmpY1,tmpZ1;
double tmpX2,tmpY2,tmpZ2;
double tmpX3,tmpY3,tmpZ3;
double tmpX4,tmpY4,tmpZ4;
double rotation;
double cr;
double sr;
s->ate = 0;
cf = ((float) (cos(7.0*((info->fTime)*rotationsPerSecond)) +
cos(3.0*((info->fTime)*rotationsPerSecond)) +
cos(13.0*((info->fTime)*rotationsPerSecond))));
cf /= 6.0f;
cf += 0.75f;
thisPointInRadians = 2.0 * M_PI * (double) s->mystery / (double) BIGMYSTERY;
s->position[0] = 250.0f * cf * (float) cos(11.0 * (thisPointInRadians + (3.0*thisAngle)));
s->position[1] = 250.0f * cf * (float) sin(12.0 * (thisPointInRadians + (4.0*thisAngle)));
s->position[2] = 250.0f * (float) cos((23.0 * (thisPointInRadians + (12.0*thisAngle))));
rotation = thisAngle*0.501 + 5.01 * (double) s->mystery / (double) BIGMYSTERY;
cr = cos(rotation);
sr = sin(rotation);
tmpX1 = s->position[0] * cr - s->position[1] * sr;
tmpY1 = s->position[1] * cr + s->position[0] * sr;
tmpZ1 = s->position[2];
tmpX2 = tmpX1 * cr - tmpZ1 * sr;
tmpY2 = tmpY1;
tmpZ2 = tmpZ1 * cr + tmpX1 * sr;
tmpX3 = tmpX2;
tmpY3 = tmpY2 * cr - tmpZ2 * sr;
tmpZ3 = tmpZ2 * cr + tmpY2 * sr + seraphDistance;
rotation = thisAngle*2.501 + 85.01 * (double) s->mystery / (double) BIGMYSTERY;
cr = cos(rotation);
sr = sin(rotation);
tmpX4 = tmpX3 * cr - tmpY3 * sr;
tmpY4 = tmpY3 * cr + tmpX3 * sr;
tmpZ4 = tmpZ3;
s->position[0] = (float) tmpX4;
s->position[1] = (float) tmpY4;
s->position[2] = (float) tmpZ4;
}

View File

@ -0,0 +1,48 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _STAR_H_
#define _STAR_H_
struct flurry_info_t;
typedef struct Star
{
float position[3];
float mystery;
float rotSpeed;
int ate;
} Star;
void InitStar(Star *s);
void UpdateStar(flurry_info_t *flurry, Star *s);
#endif // _STAR_H

View File

@ -0,0 +1,205 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "Texture.h"
#include "Shared.h"
static GLubyte smallTextureArray[32][32];
static GLubyte bigTextureArray[256][256][2];
GLuint theTexture = 0;
/* simple smoothing routine */
static void SmoothTexture(void)
{
GLubyte filter[32][32];
int i,j;
float t;
for (i=1;i<31;i++)
{
for (j=1;j<31;j++)
{
t = (float) smallTextureArray[i][j]*4;
t += (float) smallTextureArray[i-1][j];
t += (float) smallTextureArray[i+1][j];
t += (float) smallTextureArray[i][j-1];
t += (float) smallTextureArray[i][j+1];
t /= 8.0f;
filter[i][j] = (GLubyte) t;
}
}
for (i=1;i<31;i++)
{
for (j=1;j<31;j++)
{
smallTextureArray[i][j] = filter[i][j];
}
}
}
/* add some randomness to texture data */
static void SpeckleTexture(void)
{
int i,j;
int speck;
float t;
for (i=2;i<30;i++)
{
for (j=2;j<30;j++)
{
speck = 1;
while (speck <= 32 && random() % 2)
{
t = (float) MIN_(255,smallTextureArray[i][j]+speck);
smallTextureArray[i][j] = (GLubyte) t;
speck+=speck;
}
speck = 1;
while (speck <= 32 && random() % 2)
{
t = (float) MAX_(0,smallTextureArray[i][j]-speck);
smallTextureArray[i][j] = (GLubyte) t;
speck+=speck;
}
}
}
}
static void MakeSmallTexture(void)
{
static int firstTime = 1;
int i,j;
float r,t;
if (firstTime)
{
firstTime = 0;
for (i=0;i<32;i++)
{
for (j=0;j<32;j++)
{
r = (float) sqrt((i-15.5)*(i-15.5)+(j-15.5)*(j-15.5));
if (r > 15.0f)
{
smallTextureArray[i][j] = 0;
}
else
{
t = 255.0f * (float) cos(r*M_PI/31.0);
smallTextureArray[i][j] = (GLubyte) t;
}
}
}
}
else
{
for (i=0;i<32;i++)
{
for (j=0;j<32;j++)
{
r = (float) sqrt((i-15.5)*(i-15.5)+(j-15.5)*(j-15.5));
if (r > 15.0f)
{
t = 0.0f;
}
else
{
t = 255.0f * (float) cos(r*M_PI/31.0);
}
smallTextureArray[i][j] = (GLubyte) MIN_(255,(t+smallTextureArray[i][j]+smallTextureArray[i][j])/3);
}
}
}
SpeckleTexture();
SmoothTexture();
SmoothTexture();
}
static void CopySmallTextureToBigTexture(int k, int l)
{
int i,j;
for (i=0;i<32;i++)
{
for (j=0;j<32;j++)
{
bigTextureArray[i+k][j+l][0] = smallTextureArray[i][j];
bigTextureArray[i+k][j+l][1] = smallTextureArray[i][j];
}
}
}
static void AverageLastAndFirstTextures(void)
{
int i,j;
int t;
for (i=0;i<32;i++)
{
for (j=0;j<32;j++)
{
t = (smallTextureArray[i][j] + bigTextureArray[i][j][0]) / 2;
smallTextureArray[i][j] = (GLubyte) MIN_(255,t);
}
}
}
void MakeTexture()
{
int i,j;
for (i=0;i<8;i++)
{
for (j=0;j<8;j++)
{
if (i==7 && j==7)
{
AverageLastAndFirstTextures();
}
else
{
MakeSmallTexture();
}
CopySmallTextureToBigTexture(i*32,j*32);
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1, &theTexture);
glBindTexture(GL_TEXTURE_2D, theTexture);
/* Set the tiling mode (this is generally always GL_REPEAT). */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
/* Set the filtering. */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 2, 256, 256, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, bigTextureArray);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
}

View File

@ -0,0 +1,37 @@
/*
Copyright (c) 2002, Calum Robinson
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its contributors may be used
to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _TEXTURE_H_
#define _TEXTURE_H_
void MakeTexture();
#endif // _TEXTURE_H_