add sparkle explosions

This commit is contained in:
gmueller
2011-01-05 23:02:10 +01:00
parent b19f44ec32
commit a02ad6bd34
106 changed files with 19753 additions and 88 deletions

View File

@ -4,6 +4,7 @@ find_package(OpenGL)
# set includes
include_directories (${GREMLIN_SOURCE_DIR}/libs/glfw/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/enet/include)
include_directories (${GREMLIN_SOURCE_DIR}/libs/spark/include)
include_directories (${GREMLIN_SOURCE_DIR}/src)
@ -11,11 +12,12 @@ include_directories (${GREMLIN_SOURCE_DIR}/src)
add_executable( gremlin
main
game
Explosion
)
# set dependencies
add_dependencies( gremlin
glfw enet
glfw enet spark
)
if (WIN32)
@ -27,6 +29,6 @@ if(UNIX)
endif(UNIX)
target_link_libraries(gremlin
glfw enet ${OPENGL_LIBRARY} ${PLATFORM_LIBRARIES}
glfw enet spark ${OPENGL_LIBRARY} ${PLATFORM_LIBRARIES}
)

351
src/Explosion.cpp Normal file
View File

@ -0,0 +1,351 @@
/*
* Explosion.cpp
*
* Created on: 05.01.2011
* Author: gmueller
*/
#include "Explosion.h"
using namespace SPK;
using namespace SPK::GL;
Explosion::~Explosion() {
SPKFactory::getInstance().destroyAll();
}
void Explosion::initialize(GLuint textureExplosion, GLuint textureFlash,
GLuint textureSpark, GLuint texturePoint, GLuint textureWave) {
///////////////
// Renderers //
///////////////
double scale = 50.0;
// smoke renderer
GLQuadRenderer* smokeRenderer = GLQuadRenderer::create();
smokeRenderer->setTexturingMode(TEXTURE_2D);
smokeRenderer->setTexture(textureExplosion);
smokeRenderer->setTextureBlending(GL_MODULATE);
smokeRenderer->setAtlasDimensions(2, 2); // uses 4 different patterns in the texture
smokeRenderer->setBlending(BLENDING_ALPHA);
smokeRenderer->enableRenderingHint(DEPTH_WRITE, false);
smokeRenderer->setShared(true);
smokeRenderer->setScale(scale, scale);
// flame renderer
GLQuadRenderer* flameRenderer = GLQuadRenderer::create();
flameRenderer->setTexturingMode(TEXTURE_2D);
flameRenderer->setTexture(textureExplosion);
flameRenderer->setTextureBlending(GL_MODULATE);
flameRenderer->setAtlasDimensions(2, 2);
flameRenderer->setBlending(BLENDING_ADD);
flameRenderer->enableRenderingHint(DEPTH_WRITE, false);
flameRenderer->setShared(true);
flameRenderer->setScale(scale, scale);
// flash renderer
GLQuadRenderer* flashRenderer = GLQuadRenderer::create();
flashRenderer->setTexturingMode(TEXTURE_2D);
flashRenderer->setTexture(textureFlash);
flashRenderer->setTextureBlending(GL_REPLACE);
flashRenderer->setBlending(BLENDING_ADD);
flashRenderer->enableRenderingHint(DEPTH_WRITE, false);
flashRenderer->setShared(true);
flashRenderer->setScale(scale,scale);
// spark 1 renderer
GLQuadRenderer* spark1Renderer = GLQuadRenderer::create();
spark1Renderer->setTexturingMode(TEXTURE_2D);
spark1Renderer->setTexture(textureSpark);
spark1Renderer->setTextureBlending(GL_REPLACE);
spark1Renderer->setBlending(BLENDING_ADD);
spark1Renderer->enableRenderingHint(DEPTH_WRITE, false);
spark1Renderer->setOrientation(DIRECTION_ALIGNED); // sparks are oriented function o their velocity
spark1Renderer->setScale(0.05f * scale, 1.0f * scale); // thin rectangles
spark1Renderer->setShared(true);
// spark 2 renderer
GLRenderer* spark2Renderer = NULL;
if (GLPointRenderer::loadGLExtPointSprite()
&& GLPointRenderer::loadGLExtPointParameter()) // uses point sprite if possible
{
//GLPointRenderer::setPixelPerUnit(45.0f * PI / 180.f, scale * 1024);
GLPointRenderer* pointRenderer = GLPointRenderer::create();
pointRenderer->setType(POINT_SPRITE);
pointRenderer->setTexture(texturePoint);
pointRenderer->setTextureBlending(GL_MODULATE);
pointRenderer->enableWorldSize(true);
pointRenderer->setSize(0.02f * scale);
spark2Renderer = pointRenderer;
} else {
GLQuadRenderer* quadRenderer = GLQuadRenderer::create();
quadRenderer->setTexturingMode(TEXTURE_2D);
quadRenderer->setTexture(texturePoint);
quadRenderer->setTextureBlending(GL_MODULATE);
quadRenderer->setScale(0.02f * scale, 0.02f * scale);
spark2Renderer = quadRenderer;
}
spark2Renderer->setBlending(BLENDING_ADD);
spark2Renderer->enableRenderingHint(DEPTH_WRITE, false);
spark2Renderer->setShared(true);
// wave renderer
GLQuadRenderer* waveRenderer = GLQuadRenderer::create();
waveRenderer->setTexturingMode(TEXTURE_2D);
waveRenderer->setTexture(textureWave);
waveRenderer->setTextureBlending(GL_MODULATE);
waveRenderer->setBlending(BLENDING_ALPHA);
waveRenderer->enableRenderingHint(DEPTH_WRITE, false);
waveRenderer->enableRenderingHint(ALPHA_TEST, true); // uses the alpha test
waveRenderer->setAlphaTestThreshold(0.0f);
waveRenderer->setOrientation(FIXED_ORIENTATION); // the orientatin is fixed
waveRenderer->lookVector.set(0.0f, 1.0f, 0.0f);
waveRenderer->upVector.set(1.0f, 0.0f, 0.0f); // we dont really care about the up axis
waveRenderer->setShared(true);
waveRenderer->setScale(scale, scale);
////////////
// Models //
////////////
Interpolator* interpolator = NULL; // pointer to an interpolator that is used to retrieve interpolators
// smoke model
Model* smokeModel = Model::create(FLAG_RED | FLAG_GREEN | FLAG_BLUE
| FLAG_ALPHA | FLAG_SIZE | FLAG_ANGLE | FLAG_TEXTURE_INDEX,
FLAG_SIZE | FLAG_ANGLE,
FLAG_SIZE | FLAG_ANGLE | FLAG_TEXTURE_INDEX, FLAG_ALPHA);
smokeModel->setParam(PARAM_RED, 0.2f);
smokeModel->setParam(PARAM_GREEN, 0.2f);
smokeModel->setParam(PARAM_BLUE, 0.2f);
smokeModel->setParam(PARAM_SIZE, 0.6f, 0.8f, 1.0f, 1.4f);
smokeModel->setParam(PARAM_TEXTURE_INDEX, 0.0f, 4.0f);
smokeModel->setParam(PARAM_ANGLE, 0.0f, M_PI * 0.5f, 0.0f, M_PI * 0.5f);
smokeModel->setLifeTime(2.5f, 3.0f);
smokeModel->setShared(true);
interpolator = smokeModel->getInterpolator(PARAM_ALPHA);
interpolator->addEntry(0.0f, 0.0f);
interpolator->addEntry(0.4f, 0.4f, 0.6f);
interpolator->addEntry(0.6f, 0.4f, 0.6f);
interpolator->addEntry(1.0f, 0.0f);
// flame model
Model* flameModel = Model::create(FLAG_RED | FLAG_GREEN | FLAG_BLUE
| FLAG_ALPHA | FLAG_SIZE | FLAG_ANGLE | FLAG_TEXTURE_INDEX,
FLAG_ANGLE | FLAG_RED | FLAG_GREEN | FLAG_BLUE, FLAG_ANGLE
| FLAG_TEXTURE_INDEX, FLAG_SIZE | FLAG_ALPHA);
flameModel->setParam(PARAM_RED, 1.0f, 0.2f);
flameModel->setParam(PARAM_GREEN, 0.5f, 0.2f);
flameModel->setParam(PARAM_BLUE, 0.2f, 0.2f);
flameModel->setParam(PARAM_TEXTURE_INDEX, 0.0f, 4.0f);
flameModel->setParam(PARAM_ANGLE, 0.0f, M_PI * 0.5f, 0.0f, M_PI * 0.5f);
flameModel->setLifeTime(1.5f, 2.0f);
flameModel->setShared(true);
interpolator = flameModel->getInterpolator(PARAM_SIZE);
interpolator->addEntry(0.0f, 0.25f);
interpolator->addEntry(0.02f, 0.6f, 0.8f);
interpolator->addEntry(1.0f, 1.0f, 1.4f);
interpolator = flameModel->getInterpolator(PARAM_ALPHA);
interpolator->addEntry(0.5f, 1.0f);
interpolator->addEntry(1.0f, 0.0f);
// flash model
Model* flashModel = Model::create(FLAG_ALPHA | FLAG_SIZE | FLAG_ANGLE,
FLAG_NONE, FLAG_ANGLE, FLAG_ALPHA | FLAG_SIZE);
flashModel->setParam(PARAM_ANGLE, 0.0f, 2.0f * M_PI);
flashModel->setLifeTime(0.5f, 0.5f);
flashModel->setShared(true);
interpolator = flashModel->getInterpolator(PARAM_SIZE);
interpolator->addEntry(0.0f, 0.25f);
interpolator->addEntry(0.1f, 1.0f, 2.0f);
interpolator = flashModel->getInterpolator(PARAM_ALPHA);
interpolator->addEntry(0.0f, 1.0f);
interpolator->addEntry(0.4f, 0.0f);
// spark 1 model
Model* spark1Model = Model::create(FLAG_SIZE | FLAG_ALPHA, FLAG_ALPHA,
FLAG_SIZE);
spark1Model->setParam(PARAM_ALPHA, 1.0f, 0.0f);
spark1Model->setParam(PARAM_SIZE, 0.2f, 0.4f);
spark1Model->setLifeTime(0.2f, 1.0f);
spark1Model->setShared(true);
// spark 2 model
Model* spark2Model = Model::create(FLAG_RED | FLAG_GREEN | FLAG_BLUE
| FLAG_ALPHA, FLAG_GREEN | FLAG_BLUE | FLAG_ALPHA, FLAG_GREEN);
spark2Model->setParam(PARAM_ALPHA, 1.0f, 0.0f);
spark2Model->setParam(PARAM_RED, 1.0f);
spark2Model->setParam(PARAM_GREEN, 1.0f, 1.0f, 0.3f, 1.0f);
spark2Model->setParam(PARAM_BLUE, 0.7f, 0.3f);
spark2Model->setLifeTime(1.0f, 3.0f);
spark2Model->setShared(true);
// wave model
Model* waveModel = Model::create(FLAG_ALPHA | FLAG_SIZE, FLAG_SIZE
| FLAG_ALPHA);
waveModel->setParam(PARAM_SIZE, 0.0f, 4.0f);
waveModel->setParam(PARAM_ALPHA, 0.2f, 0.0f);
waveModel->setLifeTime(0.8f, 0.8f);
waveModel->setShared(true);
//////////////
// Emitters //
//////////////
// This zone will be used by several emitters
Sphere* explosionSphere = Sphere::create(Vector3D(0.0f, 0.0f, 0.0f), 0.4f * scale);
Sphere* explosionSphere2 = Sphere::create(Vector3D(0.0f, 0.0f, 0.0f), 0.4f * 2.5* scale);
// smoke emitter
RandomEmitter* smokeEmitter = RandomEmitter::create();
smokeEmitter->setZone(Sphere::create(Vector3D(0.0f, 0.0f, 0.0f), 0.6f),
false);
smokeEmitter->setFlow(-1);
smokeEmitter->setTank(1);
smokeEmitter->setForce(0.02f, 10.04f);
// flame emitter
NormalEmitter* flameEmitter = NormalEmitter::create();
flameEmitter->setZone(explosionSphere);
flameEmitter->setFlow(-1);
flameEmitter->setTank(1);
flameEmitter->setForce(0.06f, 10.1f);
// flash emitter
StaticEmitter* flashEmitter = StaticEmitter::create();
flashEmitter->setZone(Sphere::create(Vector3D(0.0f, 0.0f, 0.0f), 0.1f));
flashEmitter->setFlow(-1);
flashEmitter->setTank(2);
// spark 1 emitter
NormalEmitter* spark1Emitter = NormalEmitter::create();
spark1Emitter->setZone(explosionSphere2);
spark1Emitter->setFlow(-1);
spark1Emitter->setTank(5);
spark1Emitter->setForce(2.0f, 3.0f);
// spark 2 emitter
NormalEmitter* spark2Emitter = NormalEmitter::create();
spark2Emitter->setZone(explosionSphere);
spark2Emitter->setFlow(-1);
spark2Emitter->setTank(2);
spark2Emitter->setForce(0.4f, 0.8f);
// wave emitter
StaticEmitter* waveEmitter = StaticEmitter::create();
waveEmitter->setZone(Point::create());
waveEmitter->setFlow(-1);
waveEmitter->setTank(1);
////////////
// Groups //
////////////
// smoke group
Group* smokeGroup = Group::create(smokeModel, 15);
smokeGroup->addEmitter(smokeEmitter);
smokeGroup->setRenderer(smokeRenderer);
// flame group
Group* flameGroup = Group::create(flameModel, 15);
flameGroup->addEmitter(flameEmitter);
flameGroup->setRenderer(flameRenderer);
// flash group
Group* flashGroup = Group::create(flashModel, 3);
flashGroup->addEmitter(flashEmitter);
flashGroup->setRenderer(flashRenderer);
// spark 1 group
Group* spark1Group = Group::create(spark1Model, 20);
spark1Group->addEmitter(spark1Emitter);
spark1Group->setRenderer(spark1Renderer);
// spark 2 group
Group* spark2Group = Group::create(spark2Model, 400);
spark2Group->addEmitter(spark2Emitter);
spark2Group->setRenderer(spark2Renderer);
// wave group
Group* waveGroup = Group::create(waveModel, 1);
waveGroup->addEmitter(waveEmitter);
waveGroup->setRenderer(waveRenderer);
////////////
// System //
////////////
System* system = System::create();
system->addGroup(waveGroup);
system->addGroup(smokeGroup);
system->addGroup(flameGroup);
system->addGroup(flashGroup);
system->addGroup(spark1Group);
system->addGroup(spark2Group);
// Gets a pointer to the base
system_id = system->getSPKID();
// Sets the update step
// clamp the step to 100 ms
System::setClampStep(true, 0.1f);
// use an adaptive step from 1ms to 10ms (1000fps to 100fps)
System::useAdaptiveStep(0.001f, 0.01f);
}
// Renders the scene
void Explosion::render() {
GLRenderer::saveGLStates();
// Renders all the particle systems
for (std::list<System*>::const_iterator it = particleSystems.begin(); it
!= particleSystems.end(); ++it)
(*it)->render();
GLRenderer::restoreGLStates();
}
void Explosion::add(double x, double y, double z) {
Vector3D pos(x, y, z);
// Creates a copy of the base system
System* system = SPK_Copy(System,system_id);
// Locates the system at the given position
system->setTransformPosition(pos);
// updates the world transform of system and its children
system->updateTransform();
particleSystems.push_back(system);
}
// This function is used to sort the systems from front to back
struct cmpDistToCamera {
Vector3D camera;
bool operator()(System* &system0, System* &system1) {
return getSqrDist(system0->getWorldTransformPos(), camera)
> getSqrDist(system1->getWorldTransformPos(), camera);
}
};
void Explosion::update(double dt, double cx, double cy, double cz) {
cmpDistToCamera cmp;
cmp.camera.x = cx;
cmp.camera.y = cy;
cmp.camera.z = cz;
particleSystems.sort(cmp);
std::list<System*>::iterator it = particleSystems.begin();
while (it != particleSystems.end()) {
// Updates the particle systems
if (!(*it)->update(dt * 0.001f)) {
// If a system is sleeping, destroys it
SPK_Destroy(*it);
// And erases its entry in the container
it = particleSystems.erase(it);
} else
++it;
}
}

27
src/Explosion.h Normal file
View File

@ -0,0 +1,27 @@
/*
* Explosion.h
*
* Created on: 05.01.2011
* Author: gmueller
*/
#ifndef EXPLOSION_H_
#define EXPLOSION_H_
#include "SPK.h"
#include "SPK_GL.h"
class Explosion {
public:
~Explosion();
void initialize(GLuint textureExplosion, GLuint textureFlash,
GLuint textureSpark, GLuint texturePoint, GLuint textureWave);
void add(double x, double y, double z);
void update(double dt, double cx, double cy, double cz);
void render();
private:
SPK::SPK_ID system_id;
std::list<SPK::System*> particleSystems;
};
#endif /* EXPLOSION_H_ */

View File

@ -8,11 +8,13 @@
#include "common.h"
#include "game.h"
#include "Explosion.h"
GLUquadricObj *quadratic;
ENetHost *host;
ENetPeer *client_peer;
player_t *local_player;
Explosion explosion;
void key_callback(int key, int state) {
@ -38,14 +40,14 @@ void setup_opengl() {
glfwEnable(GLFW_STICKY_KEYS);
// general settings
glShadeModel(GL_SMOOTH);
glShadeModel( GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_CULL_FACE);
glEnable( GL_CULL_FACE);
// setup depth buffer
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable( GL_DEPTH_TEST);
glDepthFunc( GL_LEQUAL);
GLfloat LightAmbient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
@ -55,8 +57,8 @@ void setup_opengl() {
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glEnable( GL_LIGHT1);
glEnable( GL_LIGHTING);
// Enable vertical sync (on cards that support it)
glfwSwapInterval(1);
@ -65,7 +67,7 @@ void setup_opengl() {
void draw_team(team_t *team) {
size_t i = 0;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, team->color);
glMatrixMode(GL_MODELVIEW);
glMatrixMode( GL_MODELVIEW);
glPushMatrix();
glTranslated(team->x, team->y, team->z);
gluSphere(quadratic, 50.f, 32, 32);
@ -76,7 +78,7 @@ void draw_player(player_t *player) {
if (player->status == 0)
return;
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, player->team->color);
glMatrixMode(GL_MODELVIEW);
glMatrixMode( GL_MODELVIEW);
glPushMatrix();
glTranslated(player->x, player->y, player->z);
gluSphere(quadratic, 10.f, 32, 32);
@ -194,7 +196,7 @@ void send_player_updates(game_t *game) {
msg.vx = game->player[i].vx;
msg.vy = game->player[i].vy;
msg.vz = game->player[i].vz;
ENetPacket * packet = enet_packet_create (&msg, sizeof(msg), 0);
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg), 0);
enet_host_broadcast(host, 0, packet);
}
}
@ -218,8 +220,9 @@ void service_network(game_t *game) {
player_spawn_message_t spwan_msg;
spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN;
spwan_msg.team_id = game->player[i].team->id;
spwan_msg.player_id = game->player[i].id;
ENetPacket * packet = enet_packet_create (&spwan_msg, sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
spwan_msg.player_id = game->player[i].id;
ENetPacket * packet = enet_packet_create(&spwan_msg,
sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet);
}
@ -233,15 +236,17 @@ void service_network(game_t *game) {
spwan_msg.msg_id = MESSAGE_PLAYER_SPAWN;
spwan_msg.team_id = team->id;
spwan_msg.player_id = player->id;
ENetPacket * packet = enet_packet_create (&spwan_msg, sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
ENetPacket * packet = enet_packet_create(&spwan_msg,
sizeof(spwan_msg), ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet);
// send team and player
accept_message_t msg;
msg.msg_id = MESSAGE_ACCEPT;
msg.player_id = player->id;
packet = enet_packet_create (&msg, sizeof(msg), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send (event.peer, 0, packet);
packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(event.peer, 0, packet);
// send state
}
@ -255,71 +260,73 @@ void service_network(game_t *game) {
event.peer->data, event.channelID);
#endif
/* Clean up the packet now that we're done using it. */
message_t *msg = (message_t *)event.packet->data;
switch(msg->msg_id) {
case MESSAGE_PLAYER_SPAWN:
{
player_spawn_message_t *sm = (player_spawn_message_t *)event.packet->data;
team_t *team = game_team(game, sm->team_id);
player_t *player = game_spawn_player_id(game, team, sm->player_id);
}
message_t *msg = (message_t *) event.packet->data;
switch (msg->msg_id) {
case MESSAGE_PLAYER_SPAWN: {
player_spawn_message_t *sm =
(player_spawn_message_t *) event.packet->data;
team_t *team = game_team(game, sm->team_id);
player_t *player = game_spawn_player_id(game, team,
sm->player_id);
}
break;
case MESSAGE_PLAYER_KILL:
{
player_kill_message_t *sm = (player_kill_message_t *)event.packet->data;
player_t *player = game_player(game, sm->player_id);
player->status = 0;
player->team = 0;
}
case MESSAGE_PLAYER_KILL: {
player_kill_message_t *sm =
(player_kill_message_t *) event.packet->data;
player_t *player = game_player(game, sm->player_id);
player->status = 0;
player->team = 0;
}
break;
case MESSAGE_ACCEPT:
{
accept_message_t *am = (accept_message_t *)event.packet->data;
local_player = game_player(game, am->player_id);
printf("Spwan as %d.%d\n", local_player->team->id, local_player->id);
}
case MESSAGE_ACCEPT: {
accept_message_t *am = (accept_message_t *) event.packet->data;
local_player = game_player(game, am->player_id);
printf("Spwan as %d.%d\n", local_player->team->id,
local_player->id);
}
break;
case MESSAGE_PLAYER_UPDATE:
{
player_update_message_t *um = (player_update_message_t *)event.packet->data;
player_t *player = game_player(game, um->player_id);
player->x = um->x;
player->y = um->y;
player->z = um->z;
player->vx = um->vx;
player->vy = um->vy;
player->vz = um->vz;
}
case MESSAGE_PLAYER_UPDATE: {
player_update_message_t *um =
(player_update_message_t *) event.packet->data;
player_t *player = game_player(game, um->player_id);
player->x = um->x;
player->y = um->y;
player->z = um->z;
player->vx = um->vx;
player->vy = um->vy;
player->vz = um->vz;
}
break;
case MESSAGE_PLAYER_ACCELERATE:
{
player_accelerate_message_t *um = (player_accelerate_message_t *)event.packet->data;
player_t *player = game_player(game, um->player_id);
player->vx += um->x;
player->vy += um->y;
player->vz += um->z;
}
case MESSAGE_PLAYER_ACCELERATE: {
player_accelerate_message_t *um =
(player_accelerate_message_t *) event.packet->data;
player_t *player = game_player(game, um->player_id);
player->vx += um->x;
player->vy += um->y;
player->vz += um->z;
}
break;
};
enet_packet_destroy(event.packet);
break;
}
}
case ENET_EVENT_TYPE_DISCONNECT:
printf("%s disconected.\n", event.peer -> data);
{
/* Reset the peer's client information. */
player_t *player = (player_t *)event.peer->data;
player->status = 0;
player->team = 0;
/* Reset the peer's client information. */
player_t *player = (player_t *) event.peer->data;
player->status = 0;
player->team = 0;
// send player spawn message
player_kill_message_t msg;
msg.msg_id = MESSAGE_PLAYER_KILL;
msg.player_id = player->id;
ENetPacket * packet = enet_packet_create (&msg, sizeof(msg), ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet);
// send player spawn message
player_kill_message_t msg;
msg.msg_id = MESSAGE_PLAYER_KILL;
msg.player_id = player->id;
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE);
enet_host_broadcast(host, 0, packet);
}
event.peer->data = NULL;
break;
@ -339,11 +346,58 @@ void accelerate(double x, double y, double z) {
msg.x = x;
msg.y = y;
msg.z = z;
ENetPacket * packet = enet_packet_create (&msg, sizeof(msg), ENET_PACKET_FLAG_RELIABLE);
enet_peer_send (client_peer, 0, packet);
ENetPacket * packet = enet_packet_create(&msg, sizeof(msg),
ENET_PACKET_FLAG_RELIABLE);
enet_peer_send(client_peer, 0, packet);
}
}
void setup_explosion() {
// Loads particle texture
GLuint textures[5];
glGenTextures(5, textures);
glBindTexture(GL_TEXTURE_2D, textures[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glfwLoadTexture2D("data/explosion/explosion.tga", GLFW_ALPHA_MAP_BIT);
glBindTexture(GL_TEXTURE_2D, textures[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glfwLoadTexture2D("data/explosion/flash.tga", 0);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glfwLoadTexture2D("data/explosion/spark.tga", 0);
glBindTexture(GL_TEXTURE_2D, textures[3]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glfwLoadTexture2D("data/explosion/point.tga", GLFW_ALPHA_MAP_BIT);
glBindTexture(GL_TEXTURE_2D, textures[4]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glfwLoadTexture2D("data/explosion/wave.tga", 0);
explosion.initialize(textures[0], textures[1], textures[2], textures[3],
textures[4]);
}
int main(int argc, char ** argv) {
int width, height, x, y, last_x, last_y;
double time, last_time, phi = 0.0, theta = 0.0, last_player_update;
@ -358,9 +412,10 @@ int main(int argc, char ** argv) {
game_setup(&game);
setup_opengl();
setup_explosion();
if (argc > 1) {
server = 0;
setup_network(argv[1]);
@ -370,7 +425,7 @@ int main(int argc, char ** argv) {
team_t *team = game_team(&game, 0);
local_player = game_spawn_player(&game, team);
}
float plane_color[] = {0.2f, 0.3f, 0.4f, 1.0f};
float plane_color[] = { 0.2f, 0.3f, 0.4f, 1.0f };
size_t i;
running = GL_TRUE;
last_time = glfwGetTime();
@ -400,10 +455,21 @@ int main(int argc, char ** argv) {
accelerate(rx * v, ry * v, rz * v);
} else if (glfwGetKey('S')) {
accelerate(rx * -v, ry * -v, rz * -v);
} else if (glfwGetKey('A')) {
}
if (glfwGetKey('A')) {
accelerate(rz * v, 0, -rx * v);
} else if (glfwGetKey('D')) {
accelerate(-rz * v, 0, rx *v);
accelerate(-rz * v, 0, rx * v);
}
if (glfwGetKey(GLFW_KEY_SPACE)) {
accelerate(local_player->vx * -dt, local_player->vy * -dt,
local_player->vz * -dt);
}
if (glfwGetKey(GLFW_KEY_ENTER)) {
explosion.add(200.0, 200.0, 200.0);
}
// Get window size (may be different than the requested size)
@ -418,13 +484,13 @@ int main(int argc, char ** argv) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Select and setup the projection matrix
glMatrixMode(GL_PROJECTION);
glMatrixMode( GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (GLfloat) width / (GLfloat) height, 1.0f,
10000.0f);
// Select and setup the modelview matrix
glMatrixMode(GL_MODELVIEW);
glMatrixMode( GL_MODELVIEW);
glLoadIdentity();
if (local_player) {
gluLookAt(local_player->x, local_player->y,
@ -440,19 +506,9 @@ int main(int argc, char ** argv) {
0.0f, 1.0f, 0.0f); // Up-vector
}
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plane_color);
// Draw a textured quad
glBegin(GL_QUADS);
glVertex3f(-5000.0f, 5000.0f, -5000.0f);
glVertex3f(5000.0f, 5000.0f, -5000.0f);
glVertex3f(5000.0f, 5000.0f, 5000.0f);
glVertex3f(-5000.0f, 5000.0f, 5000.0f);
glEnd();
service_network(&game);
if (server) {
if (time > last_player_update + 0.1)
{
if (time > last_player_update + 0.1) {
send_player_updates(&game);
last_player_update = time;
}
@ -460,16 +516,34 @@ int main(int argc, char ** argv) {
game_update_players(&game, dt);
glEnable( GL_LIGHT0);
glEnable( GL_LIGHTING);
glEnable( GL_CULL_FACE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, plane_color);
// Draw a textured quad
glBegin( GL_QUADS);
glVertex3f(-5000.0f, 5000.0f, -5000.0f);
glVertex3f(5000.0f, 5000.0f, -5000.0f);
glVertex3f(5000.0f, 5000.0f, 5000.0f);
glVertex3f(-5000.0f, 5000.0f, 5000.0f);
glEnd();
for (i = 0; i < GAME_TEAM_COUNT; i++)
draw_team(&game.team[i]);
for (i = 0; i < GAME_PLAYER_COUNT; i++)
draw_player(&game.player[i]);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
explosion.update(dt * 1000.0, local_player->x, local_player->y,
local_player->z);
explosion.render();
// Swap buffers
glfwSwapBuffers();
// Check if the ESC key was pressed or the window was closed
running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam(GLFW_OPENED);
@ -484,6 +558,6 @@ int main(int argc, char ** argv) {
// Close OpenGL window and terminate GLFW
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}