Gravity: Big code changes

* Reworked code style completely.
* Improved the behaviour of the particles.
* Made particles smaller (2,5x performance gain).
* Cleaned unnecessary includes.
* Tried improving performance with glCallList - performance dropped even more.
* Tried improving performance with glDrawArrays - no noticeable performance changes.
This commit is contained in:
Tri-Edge AI 2012-12-31 07:42:51 +00:00 committed by threedeyes
parent 776c58b2b5
commit 8cd10c710f
21 changed files with 592 additions and 612 deletions

View File

@ -0,0 +1,104 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "ConfigView.h"
#include "Constants.h"
#include "Gravity.h"
#include <GroupLayoutBuilder.h>
#include <ListView.h>
#include <ScrollView.h>
#include <Slider.h>
#include <StringView.h>
#include <View.h>
ConfigView::ConfigView(Gravity* parent, BRect rect)
:
BView(rect, B_EMPTY_STRING, B_FOLLOW_ALL_SIDES, B_WILL_DRAW)
{
fParent = parent;
SetLayout(new BGroupLayout(B_HORIZONTAL));
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
fTitleString = new BStringView(RECT_0, B_EMPTY_STRING,
"OpenGL Gravity Effect", B_FOLLOW_LEFT);
fAuthorString = new BStringView(RECT_0, B_EMPTY_STRING,
"by Tri-Edge AI", B_FOLLOW_LEFT);
fCountSlider = new BSlider(RECT_0, B_EMPTY_STRING, "Particle Count: ",
new BMessage(MSG_COUNT), 0, 4, B_BLOCK_THUMB);
fShadeString = new BStringView(RECT_0, B_EMPTY_STRING, "Shade: ",
B_FOLLOW_LEFT);
fShadeList = new BListView(RECT_0, B_EMPTY_STRING, B_SINGLE_SELECTION_LIST,
B_FOLLOW_ALL);
fShadeList->SetSelectionMessage(new BMessage(MSG_SHADE));
fShadeList->AddItem(new BStringItem("Red"));
fShadeList->AddItem(new BStringItem("Green"));
fShadeList->AddItem(new BStringItem("Blue"));
fShadeList->AddItem(new BStringItem("Orange"));
fShadeList->AddItem(new BStringItem("Purple"));
fShadeList->AddItem(new BStringItem("White"));
fShadeList->AddItem(new BStringItem("Rainbow"));
fShadeList->Select(parent->Config.ShadeID);
fShadeScroll = new BScrollView(B_EMPTY_STRING, fShadeList,
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
fCountSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
fCountSlider->SetHashMarkCount(5);
fCountSlider->SetLimitLabels("128", "2048");
fCountSlider->SetValue(parent->Config.ParticleCount);
AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(fTitleString)
.Add(fAuthorString)
)
.Add(fShadeString)
.Add(fShadeScroll)
.Add(fCountSlider)
.SetInsets(B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING)
);
}
void
ConfigView::AttachedToWindow()
{
fShadeList->SetTarget(this);
fCountSlider->SetTarget(this);
}
void
ConfigView::MessageReceived(BMessage* msg)
{
switch (msg->what) {
case MSG_COUNT:
fParent->Config.ParticleCount = fCountSlider->Value();
break;
case MSG_SHADE:
fParent->Config.ShadeID = fShadeList->CurrentSelection();
break;
default:
BView::MessageReceived(msg);
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef GRAVITY_CONFIG_VIEW_H
#define GRAVITY_CONFIG_VIEW_H
#include <View.h>
class Gravity;
class BListView;
class BScrollView;
class BSlider;
class BStringView;
class ConfigView : public BView
{
public:
ConfigView(Gravity* parent, BRect rect);
void AttachedToWindow();
void MessageReceived(BMessage* pbmMessage);
private:
Gravity* fParent;
BStringView* fTitleString;
BStringView* fAuthorString;
BListView* fShadeList;
BStringView* fShadeString;
BScrollView* fShadeScroll;
BSlider* fCountSlider;
};
#endif

View File

@ -0,0 +1,15 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef CONSTANTS_H
#define CONSTANTS_H
#define MSG_SHADE 'm000'
#define MSG_COUNT 'm001'
#define RECT_0 BRect(0, 0, 0, 0)
#endif

View File

@ -1,17 +1,91 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#include "GravityScreenSaver.hpp"
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
extern "C" _EXPORT BScreenSaver*
instantiate_screen_saver(BMessage* pbmPrefs, image_id iidImage)
#include "Gravity.h"
#include "ConfigView.h"
#include "GravityView.h"
#include <ScreenSaver.h>
#include <View.h>
#include <stdlib.h>
Gravity::Gravity(BMessage* prefs, image_id imageID)
:
BScreenSaver(prefs, imageID)
{
return new GravityScreenSaver(pbmPrefs, iidImage);
srand(time(NULL));
if (prefs->IsEmpty()) {
Config.ParticleCount = 1;
Config.ShadeID = 2;
} else {
if (prefs->FindInt32("ParticleCount", &Config.ParticleCount) != B_OK)
Config.ParticleCount = 1;
if (prefs->FindInt32("ShadeID", &Config.ShadeID) != B_OK)
Config.ShadeID = 2;
}
}
status_t
Gravity::SaveState(BMessage* prefs) const
{
prefs->AddInt32("ParticleCount", Config.ParticleCount);
prefs->AddInt32("ShadeID", Config.ShadeID);
return B_OK;
}
void
Gravity::StartConfig(BView* view)
{
view->AddChild(new ConfigView(this, view->Bounds()));
}
status_t
Gravity::StartSaver(BView* view, bool preview)
{
if (preview) {
fView = NULL;
return B_ERROR;
} else {
SetTickSize((1000 / 20) * 1000);
// ~20 FPS
fView = new GravityView(this, view->Bounds());
view->AddChild(fView);
return B_OK;
}
}
void
Gravity::StopSaver()
{
if (fView != NULL)
fView->EnableDirectMode(false);
}
void
Gravity::DirectConnected(direct_buffer_info* info)
{
if (fView != NULL) {
// TODO: Find out why I had to uncomment this.
// view->DirectConnected(pdbiInfo);
// view->EnableDirectMode(true);
}
}
void
Gravity::DirectDraw(int32 frame)
{
fView->DirectDraw();
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef GRAVITY_SCREEN_SAVER_H
#define GRAVITY_SCREEN_SAVER_H
#include <ScreenSaver.h>
class GravityView;
class BMessage;
class BView;
class Gravity : public BScreenSaver
{
public:
struct
{
int32 ShadeID;
int32 ParticleCount;
} Config;
Gravity(BMessage* prefs, image_id imageID);
status_t SaveState(BMessage* prefs) const;
void StartConfig(BView* view);
status_t StartSaver(BView* view, bool preview);
void StopSaver();
void DirectConnected(direct_buffer_info* info);
void DirectDraw(int32 frame);
private:
GravityView* fView;
};
#endif

View File

@ -1,94 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#include "GravityConfigView.hpp"
class GravityScreenSaver;
GravityConfigView::GravityConfigView(GravityScreenSaver* parent, BRect frame)
:
BView(frame, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW)
{
this->parent = parent;
SetLayout(new BGroupLayout(B_HORIZONTAL));
SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
BStringView* pbsvTitle = new BStringView(frame, B_EMPTY_STRING,
"OpenGL Gravity Effect", B_FOLLOW_LEFT);
BStringView* pbsvAuthor = new BStringView(frame, B_EMPTY_STRING,
"by Tri-Edge AI", B_FOLLOW_LEFT);
pbsParticleCount = new BSlider(frame, B_EMPTY_STRING, "Particle Count: ",
new BMessage('pcnt'), 0, 4, B_BLOCK_THUMB);
pbsvShadeText = new BStringView(frame, B_EMPTY_STRING, "Shade: ",
B_FOLLOW_LEFT);
pblvShade = new BListView(frame, B_EMPTY_STRING, B_SINGLE_SELECTION_LIST,
B_FOLLOW_ALL);
pblvShade->SetSelectionMessage(new BMessage('shds'));
pblvShade->AddItem(new BStringItem("Red"));
pblvShade->AddItem(new BStringItem("Green"));
pblvShade->AddItem(new BStringItem("Blue"));
pblvShade->AddItem(new BStringItem("Orange"));
pblvShade->AddItem(new BStringItem("Purple"));
pblvShade->AddItem(new BStringItem("White"));
pblvShade->AddItem(new BStringItem("Rainbow"));
pblvShade->Select(parent->Config.ShadeID);
BScrollView* scroll = new BScrollView(B_EMPTY_STRING, pblvShade,
B_WILL_DRAW | B_FRAME_EVENTS, false, true);
pbsParticleCount->SetHashMarks(B_HASH_MARKS_BOTTOM);
pbsParticleCount->SetHashMarkCount(5);
pbsParticleCount->SetLimitLabels("128", "2048");
pbsParticleCount->SetValue(parent->Config.ParticleCount);
AddChild(BGroupLayoutBuilder(B_VERTICAL, B_USE_DEFAULT_SPACING)
.Add(BGroupLayoutBuilder(B_VERTICAL, 0)
.Add(pbsvTitle)
.Add(pbsvAuthor)
)
.Add(pbsvShadeText)
.Add(scroll)
.Add(pbsParticleCount)
.SetInsets(B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING,
B_USE_DEFAULT_SPACING)
);
}
void
GravityConfigView::AttachedToWindow()
{
pblvShade->SetTarget(this);
pbsParticleCount->SetTarget(this);
}
void
GravityConfigView::MessageReceived(BMessage* pbmMessage)
{
if (pbmMessage->what == 'pcnt') {
parent->Config.ParticleCount = pbsParticleCount->Value();
} else if (pbmMessage->what == 'shds') {
parent->Config.ShadeID = pblvShade->CurrentSelection();
} else {
BView::MessageReceived(pbmMessage);
}
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#ifndef _GRAVITY_CONFIG_VIEW_HPP_
#define _GRAVITY_CONFIG_VIEW_HPP_
#include "GravityScreenSaver.hpp"
#include <GroupLayout.h>
#include <GroupLayoutBuilder.h>
#include <ListView.h>
#include <ScrollView.h>
#include <Slider.h>
#include <StringItem.h>
#include <StringView.h>
#include <View.h>
class GravityScreenSaver;
class GravityConfigView : public BView
{
public:
GravityConfigView(GravityScreenSaver* parent, BRect frame);
void AttachedToWindow();
void MessageReceived(BMessage* pbmMessage);
private:
GravityScreenSaver* parent;
BListView* pblvShade;
BStringView* pbsvShadeText;
BSlider* pbsParticleCount;
};
#endif /* _GRAVITY_CONFIG_VIEW_HPP_ */

View File

@ -1,79 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#include "Particle.hpp"
#include "GravityHole.hpp"
#include <math.h>
#include <stdlib.h>
#define frand() ((float)rand() / (float)RAND_MAX)
GravityHole::GravityHole()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
vx = 0.0f;
vy = 0.0f;
vz = 0.0f;
ax = frand() * 30.0f - 15.0f;
ay = frand() * 30.0f - 15.0f;
az = frand() * 10.0f - 5.0f;
}
void
GravityHole::Run()
{
float dx = ax - x;
float dy = ay - y;
float dz = az - z;
float d = dx * dx + dy * dy + dz * dz;
vx += dx * 0.005f;
vy += dy * 0.005f;
vz += dz * 0.005f;
x += vx;
y += vy;
z += vz;
vx *= 0.95f;
vy *= 0.95f;
vz *= 0.95f;
if (dx * dx + dy * dy + dz * dz < 10.0f) {
ax = frand() * 30.0f - 15.0f;
ay = frand() * 30.0f - 15.0f;
az = frand() * 10.0f - 5.0f;
}
for (uint32 i = 0; i < Particle::list.size(); i++) {
dx = x - Particle::list[i]->x;
dy = y - Particle::list[i]->y;
dz = z - Particle::list[i]->z;
d = dx * dx + dy * dy + dz * dz;
Particle::list[i]->vx += dx / d * 0.5f;
Particle::list[i]->vy += dy / d * 0.5f;
Particle::list[i]->vz += dz / d * 0.5f;
Particle::list[i]->vr += 1.0f / d;
}
}
void
GravityHole::Draw()
{
//...
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#ifndef _GRAVITY_HOLE_HPP_
#define _GRAVITY_HOLE_HPP_
#include <GLView.h>
class GravityHole
{
public:
float x;
float y;
float z;
float vx;
float vy;
float vz;
float ax;
float ay;
float az;
GravityHole();
void Run();
void Draw();
};
#endif /* _GRAVITY_HOLE_HPP */

View File

@ -1,95 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#include <View.h>
#include <StringView.h>
#include "GravityScreenSaver.hpp"
GravityScreenSaver::GravityScreenSaver(BMessage* pbmPrefs, image_id iidImage)
:
BScreenSaver(pbmPrefs, iidImage)
{
srand(time(NULL));
if (pbmPrefs->IsEmpty()) {
Config.ParticleCount = 1;
Config.ShadeID = 2;
} else {
if (pbmPrefs->FindInt32("ParticleCount", &Config.ParticleCount) != B_OK)
Config.ParticleCount = 1;
if (pbmPrefs->FindInt32("ShadeID", &Config.ShadeID) != B_OK)
Config.ShadeID = 2;
}
}
status_t
GravityScreenSaver::SaveState(BMessage* pbmPrefs) const
{
pbmPrefs->AddInt32("ParticleCount", Config.ParticleCount);
pbmPrefs->AddInt32("ShadeID", Config.ShadeID);
return B_OK;
}
void
GravityScreenSaver::StartConfig(BView* pbvView)
{
pbvView->AddChild(new GravityConfigView(this, pbvView->Bounds()));
}
status_t
GravityScreenSaver::StartSaver(BView* pbvView, bool bPreview)
{
if (bPreview) {
view = NULL;
return B_ERROR;
} else {
SetTickSize((1000 / 30) * 1000); // ~30 FPS
view = new GravityView(this, pbvView->Bounds());
pbvView->AddChild(view);
return B_OK;
}
}
void
GravityScreenSaver::StopSaver()
{
if (view != NULL) {
view->EnableDirectMode(false);
}
}
void
GravityScreenSaver::DirectConnected(direct_buffer_info* pdbiInfo)
{
if (view != NULL) {
// TODO: Find out why I had to uncomment this.
// view->DirectConnected(pdbiInfo);
// view->EnableDirectMode(true);
}
}
void
GravityScreenSaver::DirectDraw(int32 iFrame)
{
view->Run();
// Dummy rect
BRect rect;
view->Draw(rect);
}

View File

@ -1,53 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#ifndef _GRAVITY_SCREEN_SAVER_HPP_
#define _GRAVITY_SCREEN_SAVER_HPP_
#include "GravityConfigView.hpp"
#include "GravityView.hpp"
#include <OS.h>
#include <ScreenSaver.h>
#include <View.h>
#include <GLView.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
class GravityView;
class GravityScreenSaver : public BScreenSaver
{
public:
struct
{
int32 ShadeID;
int32 ParticleCount;
} Config;
GravityScreenSaver(BMessage* pbmPrefs, image_id iidImage);
status_t SaveState(BMessage* pbmPrefs) const;
void StartConfig(BView* pbvView);
status_t StartSaver(BView* pbvView, bool bPreview);
void StopSaver();
void DirectConnected(direct_buffer_info* pdbiInfo);
void DirectDraw(int32 iFrame);
private:
GravityView* view;
};
#endif /* _GRAVITY_SCREEN_SAVER_HPP_ */

View File

@ -0,0 +1,74 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "GravitySource.h"
#include "Particle.h"
#include <stdlib.h>
#define frand() ((float)rand() / (float)RAND_MAX)
GravitySource::GravitySource()
{
x = 0.0f;
y = 0.0f;
z = 0.0f;
r = 0.0f;
vx = 0.0f;
vy = 0.0f;
vz = 0.0f;
tx = frand() * 30.0f - 15.0f;
ty = frand() * 30.0f - 15.0f;
tz = frand() * 10.0f - 5.0f;
}
void
GravitySource::Tick()
{
float dx = tx - x;
float dy = ty - y;
float dz = tz - z;
float d = dx * dx + dy * dy + dz * dz;
vx += dx * 0.003f;
vy += dy * 0.003f;
vz += dz * 0.003f;
x += vx;
y += vy;
z += vz;
vx *= 0.98f;
vy *= 0.98f;
vz *= 0.98f;
if (dx * dx + dy * dy + dz * dz < 1.0f) {
tx = frand() * 20.0f - 10.0f;
ty = frand() * 20.0f - 10.0f;
tz = frand() * 10.0f - 5.0f;
}
for (int32 i = 0; i < Particle::list->CountItems(); i++) {
Particle* p = (Particle*)Particle::list->ItemAt(i);
dx = x - p->x;
dy = y - p->y;
dz = z - p->z;
d = dx * dx + dy * dy + dz * dz;
p->vx += dx / d * 0.25f;
p->vy += dy / d * 0.25f;
p->vz += dz / d * 0.25f;
p->vr += 1.0f / d;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef GRAVITY_SOURCE_H
#define GRAVITY_SOURCE_H
class GravitySource
{
public:
float x;
float y;
float z;
float r;
float vx;
float vy;
float vz;
float tx;
float ty;
float tz;
GravitySource();
void Tick();
private:
};
#endif

View File

@ -1,70 +1,69 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "GravityView.hpp"
#include "GravityView.h"
#include "Gravity.h"
#include "GravitySource.h"
#include "Particle.h"
#include <GL/glu.h>
GravityView::GravityView(GravityScreenSaver* parent, BRect rect)
GravityView::GravityView(Gravity* parent, BRect rect)
:
BGLView(rect, B_EMPTY_STRING, B_FOLLOW_NONE, 0,
BGL_RGB | BGL_DEPTH | BGL_DOUBLE),
fRect(rect)
BGLView(rect, B_EMPTY_STRING, B_FOLLOW_NONE, 0,
BGL_RGB | BGL_DEPTH | BGL_DOUBLE)
{
this->parent = parent;
fParent = parent;
int realCount;
if (parent->Config.ParticleCount == 0)
realCount = 128;
else if (parent->Config.ParticleCount == 1)
realCount = 256;
realCount = 256;
else if (parent->Config.ParticleCount == 2)
realCount = 512;
realCount = 512;
else if (parent->Config.ParticleCount == 3)
realCount = 1024;
realCount = 1024;
else if (parent->Config.ParticleCount == 4)
realCount = 2048;
realCount = 2048;
else
realCount = 128; // This shouldn't be happening either.
realCount = 128;
Particle::Initialize(realCount, parent->Config.ShadeID);
LockGL();
glClearDepth(1.0f);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, rect.Width() / rect.Height(), 2.0f, 20000.0f);
glTranslatef(0.0f, 0.0f, -30.0f);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -30.0f);
glDepthMask(GL_FALSE);
UnlockGL();
ghole = new GravityHole();
fGravSource = new GravitySource();
}
GravityView::~GravityView()
{
delete ghole;
Particle::Terminate();
delete fGravSource;
}
@ -78,24 +77,18 @@ GravityView::AttachedToWindow()
void
GravityView::Draw(BRect rect)
GravityView::DirectDraw()
{
LockGL();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Particle::DrawAll();
ghole->Draw();
Particle::Tick();
fGravSource->Tick();
SwapBuffers();
UnlockGL();
}
void
GravityView::Run()
{
Particle::RunAll();
ghole->Run();
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef GRAVITY_VIEW_H
#define GRAVITY_VIEW_H
#include <GLView.h>
class Gravity;
class GravitySource;
class GravityView : public BGLView
{
public:
GravityView(Gravity* parent, BRect rect);
~GravityView();
void AttachedToWindow();
void DirectDraw();
private:
Gravity* fParent;
GravitySource* fGravSource;
};
#endif

View File

@ -1,40 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#ifndef _GRAVITY_VIEW_HPP_
#define _GRAVITY_VIEW_HPP_
#include <GLView.h>
#include "Particle.hpp"
#include "GravityHole.hpp"
#include "GravityScreenSaver.hpp"
class GravityScreenSaver;
class GravityView : public BGLView
{
public:
GravityView(GravityScreenSaver* parent, BRect rect);
~GravityView();
void AttachedToWindow();
void Draw(BRect rect);
void Run();
private:
BRect fRect;
GravityScreenSaver* parent;
GravityHole* ghole;
};
#endif /* _GRAVITY_VIEW_HPP_ */

View File

@ -3,19 +3,19 @@ SubDirSysHdrs $(HAIKU_GLU_HEADERS) ;
SubDirSysHdrs $(HAIKU_MESA_HEADERS) ;
# For GCC2
if $(HAIKU_GCC_VERSION[1]) < 3 {
if $(HAIKU_GCC_VERSION[1]) < 3 {
SubDirC++Flags --no-warnings ;
}
AddResources Gravity : Gravity.rdef ;
local sources =
ConfigView.cpp
Gravity.cpp
GravityConfigView.cpp
GravityHole.cpp
GravityScreenSaver.cpp
GravitySource.cpp
GravityView.cpp
Particle.cpp
main.cpp
;
Includes [ FGristFiles $(sources) ] : $(HAIKU_MESA_HEADERS_DEPENDENCY) ;

View File

@ -1,66 +1,81 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "Particle.hpp"
#include "Particle.h"
#include <List.h>
#include <stdlib.h>
#define frand() ((float)rand() / (float)RAND_MAX)
vector<Particle*> Particle::list;
BList* Particle::list;
void
Particle::Initialize(int32 size, int32 shade)
{
{
list = new BList();
for (int32 i = 0; i < size; i++) {
Particle* p = new Particle(frand() * 30.0f - 15.0f,
frand() * 30.0f - 15.0f, frand() * 5.0f, frand() * 360.0f);
Particle* p = new Particle();
p->x = frand() * 30.0f - 15.0f;
p->y = frand() * 30.0f - 15.0f;
p->z = frand() * 5.0f;
p->r = frand() * 360.0f;
p->vx = frand() - 0.5f;
p->vy = frand() - 0.5f;
p->vz = frand() - 0.5f;
p->vr = (frand() - 0.5f) * 180.0f;
if (shade == 0) { // Red
if (shade == 0) {
// Red
p->red = 0.1f + frand() * 0.2f;
p->green = 0.0f;
p->blue = frand() * 0.05f;
} else if (shade == 1) { // Green
p->blue = frand() * 0.05f;
} else if (shade == 1) {
// Green
p->red = 0;
p->green = 0.1f + frand() * 0.2f;
p->blue = frand() * 0.05f;
} else if (shade == 2) { // Blue
} else if (shade == 2) {
// Blue
p->red = 0;
p->green = frand() * 0.05f;
p->blue = 0.1f + frand() * 0.2f;
} else if (shade == 3) { // Orange
} else if (shade == 3) {
// Orange
p->red = 0.1f + frand() * 0.1f;
p->green = 0.05f + frand() * 0.1f;
p->blue = 0.0f;
} else if (shade == 4) { // Purple
} else if (shade == 4) {
// Purple
p->red = 0.1f + frand() * 0.2f;
p->green = 0.0f;
p->blue = 0.1f + frand() * 0.2f;
} else if (shade == 5) { // White
} else if (shade == 5) {
// White
p->red = p->green = p->blue = 0.1f + frand() * 0.2f;
} else if (shade == 6) { // Rainbow
} else if (shade == 6) {
// Rainbow
p->red = 0.1f + frand() * 0.2f;
p->green = 0.1f + frand() * 0.2f;
p->blue = 0.1f + frand() * 0.2f;
} else {
// Man, this shouldn't even happen.. Blue.
// Man, this shouldn't even happen.. Blue.
p->red = 0;
p->green = frand() * 0.05f;
p->blue = 0.1f + frand() * 0.2f;
}
list.push_back(p);
list->AddItem(p);
}
}
@ -68,46 +83,35 @@ Particle::Initialize(int32 size, int32 shade)
void
Particle::Terminate()
{
for (uint32 i = 0; i < list.size(); i++)
delete list[i];
list.clear();
for (int32 i = 0; i < list->CountItems(); i++)
delete (Particle*)list->ItemAt(i);
list->MakeEmpty();
delete list;
}
void
Particle::RunAll()
Particle::Tick()
{
for (uint32 i = 0; i < list.size(); i++)
list[i]->Run();
for (int32 i = 0; i < list->CountItems(); i++) {
Particle* p = (Particle*)list->ItemAt(i);
p->_Logic();
p->_Render();
}
}
void
Particle::DrawAll()
{
for (uint32 i = 0; i < list.size(); i++)
list[i]->Draw();
}
Particle::Particle(float x, float y, float z, float r)
{
this->x = x;
this->y = y;
this->z = z;
this->r = r;
}
void
Particle::Run()
Particle::_Logic()
{
// Motion
x += vx;
y += vy;
z += vz;
r += vr;
// Friction
vx *= 0.98f;
vy *= 0.98f;
vz *= 0.98f;
@ -116,17 +120,17 @@ Particle::Run()
void
Particle::Draw() const
Particle::_Render() const
{
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(r, 0.0f, 0.0f, 1.0f);
glBegin(GL_QUADS);
glColor3f(red, green, blue);
glVertex3f(-0.5f, 0.5f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.0f);
glVertex3f( 0.5f, -0.5f, 0.0f);
glVertex3f( 0.5f, 0.5f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-0.25f, 0.25f, 0.0f);
glVertex3f(-0.25f, -0.25f, 0.0f);
glVertex3f( 0.25f, -0.25f, 0.0f);
glVertex3f( 0.25f, 0.25f, 0.0f);
glEnd();
glPopMatrix();
}

View File

@ -0,0 +1,44 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#ifndef PARTICLE_H
#define PARTICLE_H
#include <GLView.h>
class BList;
class Particle
{
public:
static BList* list;
static void Initialize(int32 size, int32 shade);
static void Terminate();
static void Tick();
float x;
float y;
float z;
float r;
float vx;
float vy;
float vz;
float vr;
float red;
float green;
float blue;
private:
void _Logic();
void _Render() const;
};
#endif

View File

@ -1,54 +0,0 @@
/*
* Copyright 2012, Haiku, Inc.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tri-Edge AI <triedgeai@gmail.com>
*/
#ifndef _PARTICLE_HPP_
#define _PARTICLE_HPP_
#include <GLView.h>
#include <math.h>
#include <vector>
#include <cstdlib>
using namespace std;
class Particle
{
public:
static vector<Particle*> list;
static void Initialize(int32 size, int32 shade);
static void Terminate();
static void RunAll();
static void DrawAll();
float x;
float y;
float z;
float r;
float vx;
float vy;
float vz;
float vr;
float red;
float green;
float blue;
Particle(float x, float y, float z, float r);
private:
void Run();
void Draw() const;
};
#endif /* _PARTICLE_HPP_ */

View File

@ -0,0 +1,14 @@
/*
* Copyright 2012-2013 Tri-Edge AI <triedgeai@gmail.com>
* All rights reserved. Distributed under the terms of the MIT license.
*/
#include "Gravity.h"
extern "C" _EXPORT BScreenSaver*
instantiate_screen_saver(BMessage* prefs, image_id imageID)
{
return new Gravity(prefs, imageID);
}