1
0
forked from 0ad/0ad

First commit of APE files

This was SVN commit r479.
This commit is contained in:
Ben 2004-06-11 03:24:25 +00:00
parent 101e6d4fa0
commit 434888d7f1

502
source/ape/main.cpp Executable file
View File

@ -0,0 +1,502 @@
/*=============================================================
|
| APE - Another Particle Editor
|==============================================================
|
| Desc: main.cpp
|
| Author: Ben Vinegar
| Contact benvinegar () hotmail ! com
|
| Last Modified: 3/11/04
|
| www.wildfiregames.com/0ad
=============================================================*/
//--------------------------------------------------------
// Includes / Compiler directives
//--------------------------------------------------------
#include "ParticleSystem.h"
#include "ParticleEmitter.h"
#include "Vector3D.h"
#include "Sprite.h"
#include "timer_.h"
#include "tex_.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <GL/glui.h>
//--------------------------------------------------------
// Defines
//--------------------------------------------------------
#define APE_TITLE "APE: Another Particle Editor v0.3.0"
#define APE_CREDITS "By Ben Vinegar, ben@0ad.wildfiregames.com"
#define APE_SPRITE_DIR "./sprites"
#define APE_DEFAULT_SPRITE "1.bmp"
#define APE_MAX_PARTICLES 10000
#define APE_MIN_PARTICLES 10
#define APE_MAX_LIFETIME 20.0f
#define APE_MIN_LIFETIME 1.0f
//--------------------------------------------------------
// Global Variables
//--------------------------------------------------------
int main_window;
CSprite g_Sprite;
CParticleEmitter * g_Emitter[1];
CParticleSystem g_PSystem;
// index of currently active/editable particle
int g_pIndex = 0;
// A convenient global structure for holding all
// the GLUI widget pointers.
struct {
GLUI *mainWindow;
// GLUI *aboutWindow;
GLUI_Spinner *origin[3];
GLUI_Spinner *originSpread[3];
GLUI_Spinner *velocity[3];
GLUI_Spinner *veloSpread[3];
GLUI_Spinner *gravity[3];
GLUI_Spinner *colorStart[3];
GLUI_Spinner *colorEnd[3];
GLUI_Spinner *lifetime[2];
GLUI_Spinner *spriteSize[2];
GLUI_Spinner *numParticles;
} g_GLUI;
char g_loadedSpriteFilename[30];
GLUI_EditText *g_spriteTextBox;
unsigned int g_frames = 0;
//--------------------------------------------------------
// Declarations
//--------------------------------------------------------
// Event functions linked to by GLUI
void loadSprite(int param);
void clearSpriteTextBox(int param);
void writeToFile(int param);
void showAboutWindow(int param);
void colorStartEvent(int index);
void colorEndEvent(int index);
void lifetimeEvent(int param);
void minParticlesEvent(int param);
void gravityEvent(int param);
void veloEvent(int param);
void veloSpreadEvent(int param);
void originEvent(int param);
void originSpreadEvent(int param);
void spriteSizeEvent(int param);
void quit(int retVal);
// GLUT specific
void myGlutIdle();
void myGlutReshape(int x, int y);
void myGlutIdle();
void myGlutDisplay();
// Initialize all GLUI windows, set callbacks, etc.
void initGLUI();
//--------------------------------------------------------
// Implementation
//--------------------------------------------------------
void loadSprite(int param) {
char filename[30];
// build path name
strcpy(filename, APE_SPRITE_DIR);
strcat(filename, "/");
strcat(filename, g_spriteTextBox->get_text());
// check if file exists first
FILE *in = fopen(filename, "r");
if (in == NULL) {
printf("Error: %s does not exist.\n", filename);
g_spriteTextBox->set_text(g_loadedSpriteFilename);
return;
}
// load texture
GLuint tex;
tex_load(filename, &tex);
if (tex < 1) {
printf("Error: %s is not a bitmap.\n", filename);
g_spriteTextBox->set_text(g_loadedSpriteFilename);
return;
}
g_Emitter[g_pIndex]->SetTexture(tex);
//g_Sprite.SetTexture(tex);
strcpy(g_loadedSpriteFilename, g_spriteTextBox->get_text());
}
void clearSpriteTextBox(int param) {
g_spriteTextBox->set_text("");
}
void writeToFile(int param) {
FILE *out = fopen("new.ape", "w");
fwrite(&g_Emitter[g_pIndex], sizeof(CParticleEmitter), 1, out);
fclose(out);
}
void quit(int retVal) {
float fps = g_frames / get_time();
FILE *out = fopen("out.txt", "w");
fprintf(out, "%f\n", fps);
exit(retVal);
}
// called during color start spinner event
void colorStartEvent(int param) {
for (int i = 0; i < 3; i++) {
if (g_GLUI.colorStart[i]->get_float_val() < g_GLUI.colorEnd[i]->get_float_val()) {
g_GLUI.colorStart[i]->set_float_val(g_GLUI.colorEnd[i]->get_float_val());
}
}
float r, g, b;
r = g_GLUI.colorStart[0]->get_float_val();
g = g_GLUI.colorStart[1]->get_float_val();
b = g_GLUI.colorStart[2]->get_float_val();
g_Emitter[g_pIndex]->SetStartColour(r, g, b, 1.0f);
}
// called during color end spinner event
void colorEndEvent(int index) {
for (int i = 0; i < 3; i++) {
if (g_GLUI.colorEnd[i]->get_float_val() > g_GLUI.colorStart[i]->get_float_val()) {
g_GLUI.colorEnd[i]->set_float_val(g_GLUI.colorStart[i]->get_float_val());
}
}
float r, g, b;
r = g_GLUI.colorEnd[0]->get_float_val();
g = g_GLUI.colorEnd[1]->get_float_val();
b = g_GLUI.colorEnd[2]->get_float_val();
g_Emitter[g_pIndex]->SetEndColour(r, g, b, 1.0f);
}
// called during lifetime spinner event
void lifetimeEvent(int param) {
if (g_GLUI.lifetime[0]->get_float_val() > g_GLUI.lifetime[1]->get_float_val())
g_GLUI.lifetime[1]->set_float_val(g_GLUI.lifetime[0]->get_float_val());
else if (g_GLUI.lifetime[1]->get_float_val() < g_GLUI.lifetime[0]->get_float_val())
g_GLUI.lifetime[0]->set_float_val(g_GLUI.lifetime[1]->get_float_val());
g_Emitter[g_pIndex]->SetMinLifetime(g_GLUI.lifetime[0]->get_float_val());
g_Emitter[g_pIndex]->SetMaxLifetime(g_GLUI.lifetime[1]->get_float_val());
}
void numParticlesEvent(int param) {
float numParticles;
numParticles = g_GLUI.numParticles->get_float_val();
g_Emitter[g_pIndex]->SetMinParticles(numParticles);
}
void gravityEvent(int param) {
CVector3D grav;
grav.X = g_GLUI.gravity[0]->get_float_val();
grav.Y = g_GLUI.gravity[1]->get_float_val();
grav.Z = g_GLUI.gravity[2]->get_float_val();
g_Emitter[g_pIndex]->SetGravity(grav);
}
void veloEvent(int param) {
CVector3D velo;
velo.X = g_GLUI.velocity[0]->get_float_val();
velo.Y = g_GLUI.velocity[1]->get_float_val();
velo.Z = g_GLUI.velocity[2]->get_float_val();
g_Emitter[g_pIndex]->SetVelocity(velo);
}
void veloSpreadEvent(int param) {
CVector3D spread;
spread.X = g_GLUI.veloSpread[0]->get_float_val();
spread.Y = g_GLUI.veloSpread[1]->get_float_val();
spread.Z = g_GLUI.veloSpread[2]->get_float_val();
g_Emitter[g_pIndex]->SetVelocitySpread(spread);
}
void originEvent(int param) {
CVector3D origin;
origin.X = g_GLUI.origin[0]->get_float_val();
origin.Y = g_GLUI.origin[1]->get_float_val();
origin.Z = g_GLUI.origin[2]->get_float_val();
g_Emitter[g_pIndex]->SetOrigin(origin);
}
void originSpreadEvent(int param) {
CVector3D spread;
spread.X = g_GLUI.originSpread[0]->get_float_val();
spread.Y = g_GLUI.originSpread[1]->get_float_val();
spread.Z = g_GLUI.originSpread[2]->get_float_val();
g_Emitter[g_pIndex]->SetOriginSpread(spread);
}
void spriteSizeEvent(int param) {
float width, height;
width = g_GLUI.spriteSize[0]->get_float_val();
height = g_GLUI.spriteSize[1]->get_float_val();
g_Emitter[g_pIndex]->SetWidth(width);
g_Emitter[g_pIndex]->SetHeight(height);
}
/***************************************** myGlutIdle() ***********/
void myGlutIdle( void )
{
/* According to the GLUT specification, the current window is
undefined during an idle callback. So we need to explicitly change
it if necessary */
if ( glutGetWindow() != main_window )
glutSetWindow(main_window);
glutPostRedisplay();
}
/**************************************** myGlutReshape() *************/
void myGlutReshape( int x, int y )
{
float xy_aspect;
xy_aspect = (float)x / (float)y;
glViewport( 0, 0, x, y );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum( -xy_aspect*.08, xy_aspect*.08, -.08, .08, .1, 15.0 );
glutPostRedisplay();
}
/***************************************** myGlutDisplay() *****************/
void myGlutDisplay( void )
{
colorStartEvent(0);
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0.0, 0.0, -7.0 );
//g_Emitter[g_pIndex]->SetMinLifetime(g_minLifetime);
//g_Emitter[g_pIndex]->SetMaxLifetime(g_maxLifetime);
//g_Sprite.Render();
//g_Emitter[g_pIndex]->Frame();
g_PSystem.Frame();
++g_frames;
glutSwapBuffers();
}
/**************************************** main() ********************/
void main(int argc, char* argv[])
{
/****************************************/
/* Initialize GLUT and create window */
/****************************************/
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowPosition( 50, 50 );
glutInitWindowSize( 600, 600 );
main_window = glutCreateWindow(APE_TITLE);
glutDisplayFunc( myGlutDisplay );
glutReshapeFunc( myGlutReshape );
glDisable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
/****************************************/
/* Here's the GLUI code */
/****************************************/
initGLUI();
// have the system create a new emitter
g_Emitter[g_pIndex] = g_PSystem.CreateNewEmitter();
// load default sprite
g_spriteTextBox->set_text(APE_DEFAULT_SPRITE);
loadSprite(-1);
g_Sprite.SetSize(1.0f, 1.0f);
// g_Emitter[g_pIndex]->SetSprite(&g_Sprite);
g_Emitter[g_pIndex]->Init();
glutMainLoop();
}
void initGLUI() {
// create master window
g_GLUI.mainWindow = GLUI_Master.create_glui( "Control Panel" );
GLUI* glui = g_GLUI.mainWindow;
// create origin panel and spinner contents
GLUI_Panel *origin_panel = glui->add_panel("Origin");
g_GLUI.origin[0] = glui->add_spinner_to_panel(origin_panel, "X",
GLUI_SPINNER_FLOAT, NULL, -1, originEvent);
g_GLUI.origin[1] = glui->add_spinner_to_panel(origin_panel, "Y",
GLUI_SPINNER_FLOAT, NULL, -1, originEvent);
g_GLUI.origin[2] = glui->add_spinner_to_panel(origin_panel, "Z",
GLUI_SPINNER_FLOAT, NULL, -1, originEvent);
// create origin spread panel and spinner contents
GLUI_Panel *origin_spread_panel = glui->add_panel("Origin Spread");
g_GLUI.originSpread[0] = glui->add_spinner_to_panel(origin_spread_panel, "X",
GLUI_SPINNER_FLOAT, NULL, -1, originSpreadEvent);
g_GLUI.originSpread[1] = glui->add_spinner_to_panel(origin_spread_panel, "Y",
GLUI_SPINNER_FLOAT, NULL, -1, originSpreadEvent);
g_GLUI.originSpread[2] = glui->add_spinner_to_panel(origin_spread_panel, "Z",
GLUI_SPINNER_FLOAT, NULL, -1, originSpreadEvent);
// create velocity panel and spinner contents
GLUI_Panel *velo_panel = glui->add_panel("Velocity");
g_GLUI.velocity[0] = glui->add_spinner_to_panel(velo_panel, "X",
GLUI_SPINNER_FLOAT, NULL, -1, veloEvent);
g_GLUI.velocity[1] = glui->add_spinner_to_panel(velo_panel, "Y",
GLUI_SPINNER_FLOAT, NULL, -1, veloEvent);
g_GLUI.velocity[2] = glui->add_spinner_to_panel(velo_panel, "Z",
GLUI_SPINNER_FLOAT, NULL, -1, veloEvent);
// create velocity spread panel and spinner contents
GLUI_Panel *velo_spread_panel = glui->add_panel("Velocity Spread");
g_GLUI.veloSpread[0] = glui->add_spinner_to_panel(velo_spread_panel, "X",
GLUI_SPINNER_FLOAT, NULL, -1, veloSpreadEvent);
g_GLUI.veloSpread[1] = glui->add_spinner_to_panel(velo_spread_panel, "Y",
GLUI_SPINNER_FLOAT, NULL, -1, veloSpreadEvent);
g_GLUI.veloSpread[2] = glui->add_spinner_to_panel(velo_spread_panel, "Z",
GLUI_SPINNER_FLOAT, NULL, -1, veloSpreadEvent);
// create gravity panel and spinner contents
GLUI_Panel *grav_panel = glui->add_panel("Gravity");
g_GLUI.gravity[0] = glui->add_spinner_to_panel(grav_panel, "X",
GLUI_SPINNER_FLOAT, NULL, -1, gravityEvent);
g_GLUI.gravity[1] = glui->add_spinner_to_panel(grav_panel, "Y",
GLUI_SPINNER_FLOAT, NULL, -1, gravityEvent);
g_GLUI.gravity[2] = glui->add_spinner_to_panel(grav_panel, "Z",
GLUI_SPINNER_FLOAT, NULL, -1, gravityEvent);
// add separator
glui->add_column(true);
// create start colour panels and spinners
GLUI_Panel *start_color_panel = glui->add_panel("Start Colour");
g_GLUI.colorStart[0] = glui->add_spinner_to_panel(start_color_panel, "R",
GLUI_SPINNER_FLOAT, NULL, -1, colorStartEvent);
g_GLUI.colorStart[1] = glui->add_spinner_to_panel(start_color_panel, "G",
GLUI_SPINNER_FLOAT, NULL, -1, colorStartEvent);
g_GLUI.colorStart[2] = glui->add_spinner_to_panel(start_color_panel, "B",
GLUI_SPINNER_FLOAT, NULL, -1, colorStartEvent);
// create end colour panel and spinners
GLUI_Panel *end_color_panel = glui->add_panel("End Colour");
g_GLUI.colorEnd[0] = glui->add_spinner_to_panel(end_color_panel, "R",
GLUI_SPINNER_FLOAT, NULL, -1, colorEndEvent);
g_GLUI.colorEnd[1] = glui->add_spinner_to_panel(end_color_panel, "G",
GLUI_SPINNER_FLOAT, NULL, -1, colorEndEvent);
g_GLUI.colorEnd[2] = glui->add_spinner_to_panel(end_color_panel, "B",
GLUI_SPINNER_FLOAT, NULL, -1, colorEndEvent);
// set limits, speed for all colour spinners
for (int i = 0; i < 3; i++) {
g_GLUI.colorStart[i]->set_float_limits(0.0f, 1.0f);
g_GLUI.colorEnd[i]->set_float_limits(0.0f, 1.0f);
g_GLUI.colorStart[i]->set_speed(0.5);
g_GLUI.colorEnd[i]->set_speed(0.5);
g_GLUI.colorStart[i]->set_float_val(1.0f);
g_GLUI.colorEnd[i]->set_float_val(1.0f);
}
// create lifetime panel and spinners
GLUI_Panel *lifetimes = glui->add_panel("Lifetimes");
g_GLUI.lifetime[0] = glui->add_spinner_to_panel(lifetimes, "Min",
GLUI_SPINNER_FLOAT, NULL, -1, lifetimeEvent);
g_GLUI.lifetime[1] = glui->add_spinner_to_panel(lifetimes, "Max",
GLUI_SPINNER_FLOAT, NULL, -1, lifetimeEvent);
// set lifetime limits
for (i = 0; i < 2; i++) {
g_GLUI.lifetime[i]->set_float_limits(1.0f, 20.0f);
}
// create number of particles panel and spinner
GLUI_Panel *num_part_panel = glui->add_panel("# of Particles");
g_GLUI.numParticles = glui->add_spinner_to_panel(num_part_panel, "",
GLUI_SPINNER_INT, NULL, -1, numParticlesEvent);
g_GLUI.numParticles->set_int_limits(2, APE_MAX_PARTICLES);
// create sprite panel and spinners
GLUI_Panel *sprite_panel = glui->add_panel("Sprite");
g_GLUI.spriteSize[0] = glui->add_spinner_to_panel(sprite_panel, "Width",
GLUI_SPINNER_FLOAT, NULL, -1, spriteSizeEvent);
g_GLUI.spriteSize[0]->set_float_val(1.0f);
g_GLUI.spriteSize[1] = glui->add_spinner_to_panel(sprite_panel, "Height",
GLUI_SPINNER_FLOAT, NULL, -1, spriteSizeEvent);
g_GLUI.spriteSize[1]->set_float_val(1.0f);
g_GLUI.spriteSize[0]->set_float_limits(0.05, 5);
g_GLUI.spriteSize[1]->set_float_limits(0.05, 5);
// load / save panel
glui->add_separator_to_panel(sprite_panel);
g_spriteTextBox = glui->add_edittext_to_panel(sprite_panel, "Filename");
GLUI_Button *load_button = glui->add_button_to_panel(sprite_panel, "Load", -1, loadSprite);
glui->add_button_to_panel(sprite_panel, "Clear", -1, clearSpriteTextBox);
GLUI_Button *save_button = glui->add_button("Save Effect", -1, writeToFile);
save_button->disable();
glui->add_button("Quit", -1, quit);
glui->set_main_gfx_window( main_window );
// register idle callback with GLUI -- NOT GLUT
GLUI_Master.set_glutIdleFunc( myGlutIdle );
}