draw overlay hover bar

draw border around overlay map

Changed from refptr<map<U8, Player> > to map<U8, refptr<player> >

minor bugfix - using more memory on sky than needed

Fixed some bugs with multiplayer

CCFS: print error when unable to find file by default

simplify GLProgram creation with stdarg
This commit is contained in:
Josh Holtrop 2012-09-23 15:17:45 -04:00 committed by xethm55
parent abd731f3ca
commit eacfd38e15
19 changed files with 486 additions and 421 deletions

View File

@ -0,0 +1,18 @@
varying vec3 pos_i;
const vec4 red = vec4(1, 0, 0, 1);
const vec4 yellow = vec4(1, 1, 0, 1);
const vec4 green = vec4(0, 1, 0, 1);
void main(void)
{
if (pos_i.x < 0)
{
gl_FragColor = mix(red, yellow, pos_i.x + 1);
}
else
{
gl_FragColor = mix(yellow, green, pos_i.x);
}
}

View File

@ -47,6 +47,8 @@ def main(argv):
c_file = open(out_fname, 'w') c_file = open(out_fname, 'w')
h_file = open(header_fname, 'w') h_file = open(header_fname, 'w')
c_file.write('#include <string.h>\n') c_file.write('#include <string.h>\n')
c_file.write('#include <iostream>\n')
c_file.write('using namespace std;\n')
c_file.write('#include "%s"\n' % os.path.basename(header_fname)) c_file.write('#include "%s"\n' % os.path.basename(header_fname))
for p in paths: for p in paths:
c_name = cname(p) c_name = cname(p)
@ -77,7 +79,8 @@ def main(argv):
c_file.write('};\n') c_file.write('};\n')
c_file.write(''' c_file.write('''
const unsigned char *CCFSClass::get_file(const char *fname, unsigned int *length) const unsigned char *CCFSClass::get_file(const char *fname,
unsigned int *length, bool err_on_not_found)
{ {
int i; int i;
for (i = 0; store[i].fname != NULL; i++) for (i = 0; store[i].fname != NULL; i++)
@ -89,6 +92,8 @@ const unsigned char *CCFSClass::get_file(const char *fname, unsigned int *length
return store[i].data; return store[i].data;
} }
} }
if (err_on_not_found)
cerr << "Error loading file \\"" << fname << '"' << endl;
return NULL; return NULL;
} }
@ -100,7 +105,8 @@ CCFSClass %s;
class CCFSClass class CCFSClass
{ {
public: public:
const unsigned char *get_file(const char *fname, unsigned int *length); const unsigned char *get_file(const char *fname,
unsigned int *length = NULL, bool err_on_not_found = true);
}; };
extern CCFSClass %s; extern CCFSClass %s;

View File

@ -1,4 +1,3 @@
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
#include GL_INCLUDE_FILE #include GL_INCLUDE_FILE
@ -42,6 +41,12 @@ static const struct
{{-0.5, -0.5, 0.0}, {0.0, 0.0}}, {{-0.5, -0.5, 0.0}, {0.0, 0.0}},
{{0.5, -0.5, 0.0}, {1.0, 0.0}} {{0.5, -0.5, 0.0}, {1.0, 0.0}}
}; };
static const float quad_attributes[][3] = {
{0.5, 0.5, 0.0},
{-0.5, 0.5, 0.0},
{-0.5, -0.5, 0.0},
{0.5, -0.5, 0.0}
};
static bool load_file(const char *fname, WFObj::Buffer & buff) static bool load_file(const char *fname, WFObj::Buffer & buff)
{ {
@ -87,91 +92,37 @@ bool Client::initgl()
return false; return false;
} }
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
GLProgram::AttributeBinding obj_attrib_bindings[] = { if (!m_obj_program.create(
{0, "pos"}, CFS.get_file("shaders/obj.v.glsl"),
{1, "normal"} CFS.get_file("shaders/obj.f.glsl"),
}; "pos", 0, "normal", 1, NULL,
GLProgram::AttributeBinding sky_attrib_bindings[] = { "ambient", "diffuse", "specular", "shininess",
{0, "pos"}, "projection", "modelview", NULL))
{1, "color"}
};
GLProgram::AttributeBinding lava_attrib_bindings[] = {
{0, "pos"},
{1, "tex_coord"}
};
const char *obj_uniforms[] = {
"ambient",
"diffuse",
"specular",
"shininess",
"projection",
"modelview"
};
const char *overlay_uniforms[] = {
"projection",
"modelview",
"color"
};
const char *sky_uniforms[] = {
"projection",
"modelview"
};
const char *lava_uniforms[] = {
"projection",
"modelview",
"tex",
"shift"
};
const char *obj_v_source =
(const char *) CFS.get_file("shaders/obj.v.glsl", NULL);
const char *obj_f_source =
(const char *) CFS.get_file("shaders/obj.f.glsl", NULL);
const char *overlay_f_source =
(const char *) CFS.get_file("shaders/overlay.f.glsl", NULL);
const char *sky_v_source =
(const char *) CFS.get_file("shaders/sky.v.glsl", NULL);
const char *sky_f_source =
(const char *) CFS.get_file("shaders/sky.f.glsl", NULL);
const char *lava_v_source =
(const char *) CFS.get_file("shaders/lava.v.glsl", NULL);
const char *lava_f_source =
(const char *) CFS.get_file("shaders/lava.f.glsl", NULL);
if (obj_v_source == NULL || obj_f_source == NULL ||
overlay_f_source == NULL ||
sky_v_source == NULL || sky_f_source == NULL ||
lava_v_source == NULL || lava_f_source == NULL)
{
cerr << "Error loading shader sources" << endl;
return false; return false;
} if (!m_overlay_program.create(
if (!m_obj_program.create(obj_v_source, obj_f_source, CFS.get_file("shaders/obj.v.glsl"),
obj_attrib_bindings, LEN(obj_attrib_bindings), CFS.get_file("shaders/overlay.f.glsl"),
obj_uniforms, LEN(obj_uniforms))) "pos", 0, "normal", 1, NULL,
{ "projection", "modelview", "color", NULL))
cerr << "Error creating obj program" << endl;
return false; return false;
} if (!m_overlay_hover_program.create(
if (!m_overlay_program.create(obj_v_source, overlay_f_source, CFS.get_file("shaders/obj.v.glsl"),
obj_attrib_bindings, LEN(obj_attrib_bindings), CFS.get_file("shaders/overlay_hover.f.glsl"),
overlay_uniforms, LEN(overlay_uniforms))) "pos", 0, "normal", 1, NULL,
{ "projection", "modelview", NULL))
cerr << "Error creating overlay program" << endl;
return false; return false;
} if (!m_sky_program.create(
if (!m_sky_program.create(sky_v_source, sky_f_source, CFS.get_file("shaders/sky.v.glsl"),
sky_attrib_bindings, LEN(sky_attrib_bindings), CFS.get_file("shaders/sky.f.glsl"),
sky_uniforms, LEN(sky_uniforms))) "pos", 0, "color", 1, NULL,
{ "projection", "modelview", NULL))
cerr << "Error creating sky program" << endl;
return false; return false;
} if (!m_lava_program.create(
if (!m_lava_program.create(lava_v_source, lava_f_source, CFS.get_file("shaders/lava.v.glsl"),
lava_attrib_bindings, LEN(lava_attrib_bindings), CFS.get_file("shaders/lava.f.glsl"),
lava_uniforms, LEN(lava_uniforms))) "pos", 0, "tex_coord", 1, NULL,
{ "projection", "modelview", "tex", "shift", NULL))
cerr << "Error creating lava program" << endl;
return false; return false;
}
if (!m_tank_obj.load("models/tank.obj", load_file)) if (!m_tank_obj.load("models/tank.obj", load_file))
{ {
cerr << "Error loading tank model" << endl; cerr << "Error loading tank model" << endl;
@ -197,10 +148,16 @@ bool Client::initgl()
if (!m_tex_quad_attributes.create(GL_ARRAY_BUFFER, GL_STATIC_DRAW, if (!m_tex_quad_attributes.create(GL_ARRAY_BUFFER, GL_STATIC_DRAW,
tex_quad_attributes, sizeof(tex_quad_attributes))) tex_quad_attributes, sizeof(tex_quad_attributes)))
{ {
cerr << "Error creating tex quad attribute buffer" << endl; cerr << "Error creating tex quad attributes buffer" << endl;
return false; return false;
} }
vector<GLfloat> sky_attributes((NUM_SKY_STEPS + 1) * 2 * (3 * 3)); if (!m_quad_attributes.create(GL_ARRAY_BUFFER, GL_STATIC_DRAW,
quad_attributes, sizeof(quad_attributes)))
{
cerr << "Error creating quad attributes buffer" << endl;
return false;
}
vector<GLfloat> sky_attributes((NUM_SKY_STEPS + 1) * 2 * (3 + 3));
for (int i = 0, idx = 0; i <= NUM_SKY_STEPS; i++) for (int i = 0, idx = 0; i <= NUM_SKY_STEPS; i++)
{ {
GLfloat x = SKY_DIST * sin(M_PI_4 + i * M_PI_2 / NUM_SKY_STEPS); GLfloat x = SKY_DIST * sin(M_PI_4 + i * M_PI_2 / NUM_SKY_STEPS);
@ -258,16 +215,16 @@ void Client::redraw()
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
double dir_x = cos((*m_players)[current_player].direction); double dir_x = cos(m_players[current_player]->direction);
double dir_y = sin((*m_players)[current_player].direction); double dir_y = sin(m_players[current_player]->direction);
m_modelview.load_identity(); m_modelview.load_identity();
m_modelview.look_at( m_modelview.look_at(
(*m_players)[current_player].x - dir_x * 25, (*m_players)[current_player].y - dir_y * 25, 30, m_players[current_player]->x - dir_x * 25, m_players[current_player]->y - dir_y * 25, 30,
(*m_players)[current_player].x, (*m_players)[current_player].y, 20, m_players[current_player]->x, m_players[current_player]->y, 20,
0, 0, 1); 0, 0, 1);
// TODO: call draw_player() for each networked player // TODO: call draw_player() for each networked player
for(std::map<sf::Uint8, Player>::iterator piter = m_players->begin(); piter != m_players->end(); piter++) for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
{ {
draw_player(piter->second); draw_player(piter->second);
} }
@ -282,12 +239,12 @@ void Client::redraw()
m_window->display(); m_window->display();
} }
void Client::draw_player(Player player) void Client::draw_player(refptr<Player> player)
{ {
m_obj_program.use(); m_obj_program.use();
m_modelview.push(); m_modelview.push();
m_modelview.translate(player.x, player.y, 4); m_modelview.translate(player->x, player->y, 4);
m_modelview.rotate(player.direction * 180.0 / M_PI, 0, 0, 1); m_modelview.rotate(player->direction * 180.0 / M_PI, 0, 0, 1);
m_modelview.scale(2, 2, 2); m_modelview.scale(2, 2, 2);
m_tank_obj.bindBuffers(); m_tank_obj.bindBuffers();
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -391,6 +348,7 @@ void Client::draw_map()
void Client::draw_overlay() void Client::draw_overlay()
{ {
/* draw overlay map */
int overlay_size = (int)(m_width * 0.15); int overlay_size = (int)(m_width * 0.15);
glViewport(m_width - overlay_size - 50, m_height - overlay_size - 50, glViewport(m_width - overlay_size - 50, m_height - overlay_size - 50,
overlay_size, overlay_size); overlay_size, overlay_size);
@ -403,8 +361,8 @@ void Client::draw_overlay()
proj.ortho(-span, span, -span, span, -1, 1); proj.ortho(-span, span, -span, span, -1, 1);
proj.to_uniform(m_overlay_program.uniform("projection")); proj.to_uniform(m_overlay_program.uniform("projection"));
GLMatrix modelview; GLMatrix modelview;
modelview.rotate(90 - (*m_players)[current_player].direction * 180 / M_PI, 0, 0, 1); modelview.rotate(90 - m_players[current_player]->direction * 180 / M_PI, 0, 0, 1);
modelview.translate(-(*m_players)[current_player].x, -(*m_players)[current_player].y, 0); modelview.translate(-m_players[current_player]->x, -m_players[current_player]->y, 0);
m_overlay_hex_attributes.bind(); m_overlay_hex_attributes.bind();
m_overlay_hex_indices.bind(); m_overlay_hex_indices.bind();
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
@ -446,9 +404,48 @@ void Client::draw_overlay()
glPointSize(3); glPointSize(3);
glDrawArrays(GL_POINTS, 0, 1); glDrawArrays(GL_POINTS, 0, 1);
/* draw hover bar */
glViewport(m_width - 200, 100, 150, 25);
m_overlay_hover_program.use();
m_quad_attributes.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
GLMatrix::Identity.to_uniform(
m_overlay_hover_program.uniform("projection"));
modelview.load_identity();
modelview.translate(m_players[current_player]->hover - 1, 0, 0);
modelview.scale(m_players[current_player]->hover * 2, 2.0, 1.0);
modelview.to_uniform(m_overlay_hover_program.uniform("modelview"));
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
/* draw map border */
glViewport(0, 0, m_width, m_height);
m_overlay_program.use();
m_quad_attributes.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL);
GLMatrix::Identity.to_uniform(m_overlay_program.uniform("projection"));
modelview.load_identity();
modelview.ortho(0, m_width, 0, m_height, -1, 1);
modelview.translate(m_width - overlay_size / 2 - 50,
m_height - overlay_size / 2 - 50, 0);
modelview.scale(overlay_size + 0.1, overlay_size + 0.1, 1);
modelview.to_uniform(m_overlay_program.uniform("modelview"));
glUniform4f(m_overlay_program.uniform("color"), 1, 1, 1, 1);
glDrawArrays(GL_LINE_LOOP, 0, 4);
/* draw hover bar border */
modelview.load_identity();
modelview.ortho(0, m_width, 0, m_height, -1, 1);
modelview.translate(m_width - 200 + 150 / 2, 100 + 25 / 2, 0);
modelview.scale(150.1, 25.1, 1);
modelview.to_uniform(m_overlay_program.uniform("modelview"));
glDrawArrays(GL_LINE_LOOP, 0, 4);
/* reset GL to normal state */
glDisableVertexAttribArray(0);
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND); glDisable(GL_BLEND);
glViewport(0, 0, m_width, m_height);
} }
void Client::draw_sky() void Client::draw_sky()
@ -457,8 +454,8 @@ void Client::draw_sky()
m_sky_attributes.bind(); m_sky_attributes.bind();
m_projection.to_uniform(m_sky_program.uniform("projection")); m_projection.to_uniform(m_sky_program.uniform("projection"));
m_modelview.push(); m_modelview.push();
m_modelview.translate((*m_players)[current_player].x, (*m_players)[current_player].y, 0); m_modelview.translate(m_players[current_player]->x, m_players[current_player]->y, 0);
m_modelview.rotate((*m_players)[current_player].direction * 180.0 / M_PI, 0, 0, 1); m_modelview.rotate(m_players[current_player]->direction * 180.0 / M_PI, 0, 0, 1);
m_modelview.to_uniform(m_sky_program.uniform("modelview")); m_modelview.to_uniform(m_sky_program.uniform("modelview"));
m_modelview.pop(); m_modelview.pop();
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE,

View File

@ -1,14 +1,14 @@
#include <math.h> #include <math.h>
#include "Client.h" #include "Client.h"
#include "Types.h" #include "Types.h"
#include "Timer.h"
Client::Client() Client::Client()
{ {
m_net_client = new Network(); m_net_client = new Network();
m_net_client->Create(59243, "127.0.0.1"); // Just connect to local host for now - testing m_net_client->Create(59243, "127.0.0.1"); // Just connect to local host for now - testing
client_has_focus = true; client_has_focus = true;
m_players = new std::map<sf::Uint8, Player>; m_players.clear();
m_players->clear();
current_player = 0; current_player = 0;
} }
@ -20,7 +20,8 @@ Client::~Client()
void Client::run(bool fullscreen, int width, int height, std::string pname) void Client::run(bool fullscreen, int width, int height, std::string pname)
{ {
Timer client_timer;
client_timer.Init();
current_player_name = pname; current_player_name = pname;
if (!create_window(fullscreen, width, height)) if (!create_window(fullscreen, width, height))
return; return;
@ -65,8 +66,13 @@ void Client::run(bool fullscreen, int width, int height, std::string pname)
} }
} }
// Time must be updated before any messages are sent
// Especially guaranteed messages, since the time needs to be
// non zero.
client_timer.Update();
update(elapsed_time); update(elapsed_time);
if(m_players->size() > 0) if(m_players.size() > 0)
{ {
redraw(); redraw();
} }
@ -94,17 +100,27 @@ void Client::update(double elapsed_time)
{ {
case PLAYER_CONNECT: case PLAYER_CONNECT:
{ {
Player p;
sf::Uint8 pindex; sf::Uint8 pindex;
std::string name = ""; std::string name = "";
client_packet >> pindex; client_packet >> pindex;
client_packet >> name; client_packet >> name;
// Should be a much better way of doing this.
// Perhaps generate a random number
if(name == current_player_name) if(name == current_player_name)
{ {
current_player = pindex; current_player = pindex;
} }
p.name = name;
(*m_players)[pindex] = p; // Create a new player if one does not exist.
if(m_players.end() == m_players.find(pindex))
{
refptr<Player> p = new Player();
p->name = name;
client_packet >> p->direction;
client_packet >> p->x;
client_packet >> p->y;
m_players[pindex] = p;
}
break; break;
} }
case PLAYER_UPDATE: case PLAYER_UPDATE:
@ -112,11 +128,11 @@ void Client::update(double elapsed_time)
sf::Uint8 player_index; sf::Uint8 player_index;
// Update player position as calculated from the server. // Update player position as calculated from the server.
client_packet >> player_index; client_packet >> player_index;
if(m_players->end() != m_players->find(player_index)) if(m_players.end() != m_players.find(player_index))
{ {
client_packet >> (*m_players)[player_index].direction; client_packet >> m_players[player_index]->direction;
client_packet >> (*m_players)[player_index].x; client_packet >> m_players[player_index]->x;
client_packet >> (*m_players)[player_index].y; client_packet >> m_players[player_index]->y;
} }
break; break;
} }
@ -141,7 +157,7 @@ void Client::update(double elapsed_time)
// For now, we are going to do a very crude shove data into // For now, we are going to do a very crude shove data into
// packet from keyboard and mouse events. // packet from keyboard and mouse events.
// TODO: Clean this up and make it more robust // TODO: Clean this up and make it more robust
if(m_players->size() > 0) if(m_players.size() > 0)
{ {
sf::Uint8 w_pressed = KEY_NOT_PRESSED; sf::Uint8 w_pressed = KEY_NOT_PRESSED;
sf::Uint8 a_pressed = KEY_NOT_PRESSED; sf::Uint8 a_pressed = KEY_NOT_PRESSED;
@ -175,11 +191,11 @@ void Client::update(double elapsed_time)
} }
// Send an update to the server if something has changed // Send an update to the server if something has changed
if(((*m_players)[current_player].w_pressed != w_pressed) || if((m_players[current_player]->w_pressed != w_pressed) ||
((*m_players)[current_player].a_pressed != a_pressed) || (m_players[current_player]->a_pressed != a_pressed) ||
((*m_players)[current_player].s_pressed != s_pressed) || (m_players[current_player]->s_pressed != s_pressed) ||
((*m_players)[current_player].d_pressed != d_pressed) || (m_players[current_player]->d_pressed != d_pressed) ||
((*m_players)[current_player].rel_mouse_movement != rel_mouse_movement)) (m_players[current_player]->rel_mouse_movement != rel_mouse_movement))
{ {
sf::Uint8 packet_type = PLAYER_UPDATE; sf::Uint8 packet_type = PLAYER_UPDATE;
client_packet.clear(); client_packet.clear();
@ -193,11 +209,11 @@ void Client::update(double elapsed_time)
m_net_client->sendData(client_packet); m_net_client->sendData(client_packet);
(*m_players)[current_player].w_pressed = w_pressed; m_players[current_player]->w_pressed = w_pressed;
(*m_players)[current_player].a_pressed = a_pressed; m_players[current_player]->a_pressed = a_pressed;
(*m_players)[current_player].s_pressed = s_pressed; m_players[current_player]->s_pressed = s_pressed;
(*m_players)[current_player].d_pressed = d_pressed; m_players[current_player]->d_pressed = d_pressed;
(*m_players)[current_player].rel_mouse_movement = rel_mouse_movement; m_players[current_player]->rel_mouse_movement = rel_mouse_movement;
} }
} }
else if(!registered_player) else if(!registered_player)
@ -207,8 +223,12 @@ void Client::update(double elapsed_time)
client_packet << packet_type; client_packet << packet_type;
client_packet << current_player; client_packet << current_player;
client_packet << current_player_name; client_packet << current_player_name;
m_net_client->sendData(client_packet); m_net_client->sendData(client_packet, true);
registered_player = true; registered_player = true;
} }
else
{
// Do nothing.
}
m_net_client->Transmit(); m_net_client->Transmit();
} }

View File

@ -1,4 +1,3 @@
#ifndef CLIENT_H #ifndef CLIENT_H
#define CLIENT_H #define CLIENT_H
@ -25,7 +24,7 @@ class Client
void resize_window(int width, int height); void resize_window(int width, int height);
void update(double elapsed_time); void update(double elapsed_time);
void redraw(); void redraw();
void draw_player(Player player); void draw_player(refptr<Player> player);
void draw_map(); void draw_map();
void draw_overlay(); void draw_overlay();
void draw_sky(); void draw_sky();
@ -36,11 +35,12 @@ class Client
Map m_map; Map m_map;
sf::Uint8 current_player; sf::Uint8 current_player;
std::string current_player_name; std::string current_player_name;
refptr< std::map<sf::Uint8, Player> > m_players; std::map<sf::Uint8, refptr<Player> > m_players;
int m_width; int m_width;
int m_height; int m_height;
GLProgram m_obj_program; GLProgram m_obj_program;
GLProgram m_overlay_program; GLProgram m_overlay_program;
GLProgram m_overlay_hover_program;
GLProgram m_sky_program; GLProgram m_sky_program;
GLProgram m_lava_program; GLProgram m_lava_program;
WFObj m_tank_obj; WFObj m_tank_obj;
@ -51,6 +51,7 @@ class Client
GLBuffer m_overlay_hex_indices; GLBuffer m_overlay_hex_indices;
GLBuffer m_sky_attributes; GLBuffer m_sky_attributes;
GLBuffer m_tex_quad_attributes; GLBuffer m_tex_quad_attributes;
GLBuffer m_quad_attributes;
refptr<Network> m_net_client; refptr<Network> m_net_client;
bool client_has_focus; bool client_has_focus;
sf::Texture m_lava_texture; sf::Texture m_lava_texture;

View File

@ -1,5 +1,6 @@
#include "GLProgram.h" #include "GLProgram.h"
#include <stdint.h>
#include <iostream> #include <iostream>
using namespace std; using namespace std;
@ -7,7 +8,6 @@ using namespace std;
GLProgram::GLProgram() GLProgram::GLProgram()
{ {
m_id = 0; m_id = 0;
m_uniform_locations = NULL;
} }
GLProgram::~GLProgram() GLProgram::~GLProgram()
@ -16,29 +16,50 @@ GLProgram::~GLProgram()
{ {
glDeleteProgram(m_id); glDeleteProgram(m_id);
} }
if (m_uniform_locations != NULL)
{
delete[] m_uniform_locations;
}
} }
bool GLProgram::create(const char *v_source, const char *f_source, bool GLProgram::create(const char *v_source, const char *f_source, ...)
GLProgram::AttributeBinding *bindings, int n_bindings,
const char **uniforms, int n_uniforms)
{ {
va_list va;
va_start(va, f_source);
bool rv = createv(v_source, f_source, va);
va_end(va);
return rv;
}
bool GLProgram::create(const uint8_t *v_source, const uint8_t *f_source, ...)
{
va_list va;
va_start(va, f_source);
bool rv = createv((const char *) v_source, (const char *) f_source, va);
va_end(va);
return rv;
}
bool GLProgram::createv(const char *v_source, const char *f_source, va_list va)
{
if (v_source == NULL || f_source == NULL)
return false;
if (!m_v_shader.create(GL_VERTEX_SHADER, v_source)) if (!m_v_shader.create(GL_VERTEX_SHADER, v_source))
return false; return false;
if (!m_f_shader.create(GL_FRAGMENT_SHADER, f_source)) if (!m_f_shader.create(GL_FRAGMENT_SHADER, f_source))
return false; return false;
m_id = glCreateProgram(); m_id = glCreateProgram();
if (m_id <= 0) if (m_id <= 0)
{
cerr << "Error allocating GL program object" << endl;
return false; return false;
}
glAttachShader(m_id, m_v_shader.get_id()); glAttachShader(m_id, m_v_shader.get_id());
glAttachShader(m_id, m_f_shader.get_id()); glAttachShader(m_id, m_f_shader.get_id());
for (int i = 0; i < n_bindings; i++) for (;;)
{ {
glBindAttribLocation(m_id, bindings[i].index, bindings[i].name); const char *attribute_name = va_arg(va, const char *);
if (attribute_name == NULL)
break;
GLuint attribute_index = va_arg(va, uint32_t);
glBindAttribLocation(m_id, attribute_index, attribute_name);
} }
glLinkProgram(m_id); glLinkProgram(m_id);
@ -59,14 +80,14 @@ bool GLProgram::create(const char *v_source, const char *f_source,
return false; return false;
} }
if (n_uniforms > 0) for (;;)
{ {
m_uniform_locations = new GLint[n_uniforms]; const char *uniform_name = va_arg(va, const char *);
for (int i = 0; i < n_uniforms; i++) if (uniform_name == NULL)
{ break;
m_uniform_locations[i] = glGetUniformLocation(m_id, uniforms[i]); GLint loc = glGetUniformLocation(m_id, uniform_name);
m_uniform_location_names[uniforms[i]] = m_uniform_locations[i]; m_uniform_locations.push_back(loc);
} m_uniform_location_names[uniform_name] = loc;
} }
return true; return true;

View File

@ -2,23 +2,20 @@
#ifndef GLPROGRAM_H #ifndef GLPROGRAM_H
#define GLPROGRAM_H #define GLPROGRAM_H
#include <stdarg.h>
#include "GLShader.h" #include "GLShader.h"
#include <map> #include <map>
#include <string> #include <string>
#include <vector>
class GLProgram class GLProgram
{ {
public: public:
typedef struct
{
GLuint index;
const char *name;
} AttributeBinding;
GLProgram(); GLProgram();
~GLProgram(); ~GLProgram();
bool create(const char *v_source, const char *f_source, bool create(const char *v_source, const char *f_source, ...);
AttributeBinding *bindings = NULL, int n_bindings = 0, bool create(const uint8_t *v_source, const uint8_t *f_source, ...);
const char **uniforms = NULL, int n_uniforms = 0); bool createv(const char *v_source, const char *f_source, va_list va);
GLuint get_id() { return m_id; } GLuint get_id() { return m_id; }
GLint get_uniform_location(const char *name); GLint get_uniform_location(const char *name);
void get_uniform_locations(const char **names, int num, GLint *locs); void get_uniform_locations(const char **names, int num, GLint *locs);
@ -29,7 +26,7 @@ class GLProgram
GLuint m_id; GLuint m_id;
GLShader m_v_shader; GLShader m_v_shader;
GLShader m_f_shader; GLShader m_f_shader;
GLint * m_uniform_locations; std::vector<GLint> m_uniform_locations;
std::map<std::string, GLint> m_uniform_location_names; std::map<std::string, GLint> m_uniform_location_names;
}; };

View File

@ -1,4 +1,3 @@
#include <stdlib.h> #include <stdlib.h>
#include <getopt.h> #include <getopt.h>
#include "Client.h" #include "Client.h"

View File

@ -1,4 +1,3 @@
#include <math.h> #include <math.h>
#include "HexTile.h" #include "HexTile.h"

View File

@ -1,4 +1,3 @@
#ifndef HEXTILE_H #ifndef HEXTILE_H
#define HEXTILE_H #define HEXTILE_H

View File

@ -1,4 +1,3 @@
#include "Map.h" #include "Map.h"
#include "HexTile.h" #include "HexTile.h"

View File

@ -1,4 +1,3 @@
#ifndef MAP_H #ifndef MAP_H
#define MAP_H #define MAP_H

View File

@ -1,4 +1,3 @@
#include "Player.h" #include "Player.h"
#include <math.h> #include <math.h>

View File

@ -1,4 +1,3 @@
#ifndef PLAYER_H #ifndef PLAYER_H
#define PLAYER_H #define PLAYER_H

View File

@ -23,7 +23,6 @@ void Timer::Update(void)
{ {
// Record the time step // Record the time step
stepTime = ((myClock.getElapsedTime().asSeconds() / 1000.0f) * gameSpeed); stepTime = ((myClock.getElapsedTime().asSeconds() / 1000.0f) * gameSpeed);
//stepTime = ((((sf::Window*)screen)->GetFrameTime() / 1000.0f) * gameSpeed);
myClock.restart(); myClock.restart();
// Add the time to the total time // Add the time to the total time

View File

@ -1,4 +1,3 @@
#ifndef REFPTR_H #ifndef REFPTR_H
#define REFPTR_H REFPTR_H #define REFPTR_H REFPTR_H

View File

@ -1,13 +1,13 @@
#include "Server.h" #include "Server.h"
#include "Types.h" #include "Types.h"
#include <math.h> #include <math.h>
#include "Timer.h"
Server::Server(sf::Uint16 port) Server::Server(sf::Uint16 port)
{ {
m_net_server = new Network(); m_net_server = new Network();
m_net_server->Create(port, sf::IpAddress::None); m_net_server->Create(port, sf::IpAddress::None);
m_players = new std::map<sf::Uint8, Player>; m_players.clear();
m_players->clear();
} }
Server::~Server() Server::~Server()
@ -20,10 +20,18 @@ void Server::run( void )
double current_time; double current_time;
double elapsed_time; double elapsed_time;
double last_time = 0.0; double last_time = 0.0;
Timer server_timer;
server_timer.Init();
while(1) while(1)
{ {
current_time = m_clock.getElapsedTime().asSeconds(); current_time = m_clock.getElapsedTime().asSeconds();
elapsed_time = current_time - last_time; elapsed_time = current_time - last_time;
// Time must be updated before any messages are sent
// Especially guaranteed messages, since the time needs to be
// non zero.
server_timer.Update();
update( elapsed_time ); update( elapsed_time );
last_time = current_time; last_time = current_time;
@ -50,7 +58,7 @@ void Server::update( double elapsed_time )
{ {
case PLAYER_CONNECT: case PLAYER_CONNECT:
{ {
Player p; refptr<Player> p = new Player();
std::string pname; std::string pname;
sf::Uint8 pindex; sf::Uint8 pindex;
@ -63,21 +71,29 @@ void Server::update( double elapsed_time )
{ {
for(pindex = 1u; pindex < 255u; pindex++ ) for(pindex = 1u; pindex < 255u; pindex++ )
{ {
if(m_players->end() == m_players->find(pindex)) if(m_players.end() == m_players.find(pindex))
{ {
break; break;
} }
} }
p.name = pname; p->name = pname;
(*m_players)[pindex] = p; m_players[pindex] = p;
// Send a response to the newly added player // Alert all connected clients of all the connected players.
for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
{
server_packet.clear(); server_packet.clear();
server_packet << ptype; server_packet << ptype;
server_packet << pindex; server_packet << piter->first;
server_packet << p.name; server_packet << piter->second->name;
// Send correct starting locations so that they match
// the other players screens.
server_packet << piter->second->direction;
server_packet << piter->second->x;
server_packet << piter->second->y;
m_net_server->sendData(server_packet, true); m_net_server->sendData(server_packet, true);
} }
}
break; break;
} }
case PLAYER_UPDATE: case PLAYER_UPDATE:
@ -86,13 +102,13 @@ void Server::update( double elapsed_time )
// then update the stored contents. // then update the stored contents.
sf::Uint8 pindex; sf::Uint8 pindex;
server_packet >> pindex; server_packet >> pindex;
if(m_players->end() != m_players->find(pindex)) if(m_players.end() != m_players.find(pindex))
{ {
server_packet >> (*m_players)[pindex].w_pressed; server_packet >> m_players[pindex]->w_pressed;
server_packet >> (*m_players)[pindex].a_pressed; server_packet >> m_players[pindex]->a_pressed;
server_packet >> (*m_players)[pindex].s_pressed; server_packet >> m_players[pindex]->s_pressed;
server_packet >> (*m_players)[pindex].d_pressed; server_packet >> m_players[pindex]->d_pressed;
server_packet >> (*m_players)[pindex].rel_mouse_movement; server_packet >> m_players[pindex]->rel_mouse_movement;
} }
break; break;
} }
@ -116,58 +132,56 @@ void Server::update( double elapsed_time )
} }
} }
for(std::map<sf::Uint8, Player>::iterator piter = m_players->begin(); piter != m_players->end(); piter++) for(std::map<sf::Uint8, refptr<Player> >::iterator piter = m_players.begin(); piter != m_players.end(); piter++)
{ {
sf::Uint8 pindex = piter->first; sf::Uint8 pindex = piter->first;
double direction = (*m_players)[pindex].direction; if (KEY_PRESSED == m_players[pindex]->a_pressed)
direction -= M_PI * 0.5 * (*m_players)[pindex].rel_mouse_movement / 1000;
if(direction != (*m_players)[pindex].direction)
{ {
(*m_players)[pindex].direction = direction; double direction = m_players[pindex]->direction + M_PI_2;
(*m_players)[pindex].updated = true; m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
m_players[pindex]->updated = true;
} }
if (KEY_PRESSED == (*m_players)[pindex].a_pressed) if (KEY_PRESSED == m_players[pindex]->d_pressed)
{ {
direction = (*m_players)[pindex].direction + M_PI_2; double direction = m_players[pindex]->direction - M_PI_2;
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time; m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time; m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
(*m_players)[pindex].updated = true; m_players[pindex]->updated = true;
} }
if (KEY_PRESSED == (*m_players)[pindex].d_pressed) if (KEY_PRESSED == m_players[pindex]->w_pressed)
{ {
direction = (*m_players)[pindex].direction - M_PI_2; double direction = m_players[pindex]->direction;
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time; m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time; m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
(*m_players)[pindex].updated = true; m_players[pindex]->updated = true;
} }
if (KEY_PRESSED == (*m_players)[pindex].w_pressed) if (KEY_PRESSED == m_players[pindex]->s_pressed)
{ {
direction = (*m_players)[pindex].direction; double direction = m_players[pindex]->direction + M_PI;
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time; m_players[pindex]->x += cos(direction) * move_speed * elapsed_time;
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time; m_players[pindex]->y += sin(direction) * move_speed * elapsed_time;
(*m_players)[pindex].updated = true; m_players[pindex]->updated = true;
} }
if (KEY_PRESSED == (*m_players)[pindex].s_pressed) if(0 != m_players[pindex]->rel_mouse_movement)
{ {
direction = (*m_players)[pindex].direction + M_PI; m_players[pindex]->direction -= M_PI * 0.5 * m_players[pindex]->rel_mouse_movement / 1000;
(*m_players)[pindex].x += cos(direction) * move_speed * elapsed_time; m_players[pindex]->updated = true;
(*m_players)[pindex].y += sin(direction) * move_speed * elapsed_time;
(*m_players)[pindex].updated = true;
} }
server_packet.clear(); server_packet.clear();
// Send the player update if there were changes // Send the player update if there were changes
if((*m_players)[pindex].updated) if(m_players[pindex]->updated)
{ {
sf::Uint8 ptype = PLAYER_UPDATE; sf::Uint8 ptype = PLAYER_UPDATE;
server_packet << ptype; server_packet << ptype;
server_packet << pindex; server_packet << pindex;
server_packet << (*m_players)[pindex].direction; server_packet << m_players[pindex]->direction;
server_packet << (*m_players)[pindex].x; server_packet << m_players[pindex]->x;
server_packet << (*m_players)[pindex].y; server_packet << m_players[pindex]->y;
m_net_server->sendData(server_packet); m_net_server->sendData(server_packet);
(*m_players)[pindex].updated = false; m_players[pindex]->updated = false;
} }
} }
m_net_server->Transmit(); m_net_server->Transmit();

View File

@ -12,6 +12,6 @@ class Server{
protected: protected:
void update(double elapsed_time); void update(double elapsed_time);
refptr<Network> m_net_server; refptr<Network> m_net_server;
refptr< std::map<sf::Uint8, Player> > m_players; std::map<sf::Uint8, refptr<Player> > m_players;
sf::Clock m_clock; sf::Clock m_clock;
}; };