diff --git a/gui.cpp b/gui.cpp index 3ab72d2..74f4865 100644 --- a/gui.cpp +++ b/gui.cpp @@ -28,44 +28,35 @@ #include "gui.hpp" #include "ogl.hpp" -static const int REFRESH_MS = 0.016; // for 60 fps. - static void redraw_callback(void * arg) { GlGui * window = static_cast(arg); window->redraw(); - if(!window->isFinished()) - Fl::repeat_timeout(REFRESH_MS, redraw_callback, window); } GlGui::GlGui(Fl_Window * parent, int x, int y, int w, int h, const char * l, PheromoneMap * phero_map) : Fl_Gl_Window(x, y, w, h, l) { + mode(FL_RGB | FL_DOUBLE); + this->parent = parent; this->phero_map = phero_map; title += l; initialized = false; - done = false; + + Fl::add_idle(redraw_callback, this); } void GlGui::draw() { if(!valid()) { if(!initialized) { ogl::initialize(phero_map); - Fl::add_timeout(REFRESH_MS, redraw_callback, this); initialized = true; } ogl::reshape(w(), h()); } + phero_map->s_update(); ogl::display(); } int GlGui::handle(int event) { return Fl_Gl_Window::handle(event); } - -void GlGui::finish() { - done = true; -} - -bool GlGui::isFinished() { - return done; -} diff --git a/gui.hpp b/gui.hpp index c1c9c09..10d6a7d 100644 --- a/gui.hpp +++ b/gui.hpp @@ -37,8 +37,6 @@ class GlGui : public Fl_Gl_Window { public: GlGui(Fl_Window * parent, int x, int y, int w, int h, const char * l, PheromoneMap * phero_map); - void finish(); - bool isFinished(); protected: virtual void draw(); @@ -48,7 +46,6 @@ private: Fl_Window * parent; std::string title; bool initialized; - bool done; PheromoneMap * phero_map; }; diff --git a/ias_robot.cpp b/ias_robot.cpp index 9fa5cf1..bc78b31 100644 --- a/ias_robot.cpp +++ b/ias_robot.cpp @@ -32,7 +32,8 @@ static const float TURN_DEG_PER_SEC = 40.0f; static const float METERS_PER_SEC = 0.4f; static const long HALF_SECOND_USEC = 500000; static const double MIN_DIST_M = 1.5; -static const double CRIT_DIST_M = 1.0; +static const double CRIT_DIST_M = 1.0; +static const float MAP_SIZE = 16.0f; IASSS_Robot::IASSS_Robot(std::string hostname, uint32_t port, PheromoneMap * phero_map) : Robot(hostname, port) { _phero_map = phero_map; @@ -45,6 +46,7 @@ IASSS_Robot::~IASSS_Robot() { void IASSS_Robot::run() { int rv; + float x, y; long then, now, delta, wait; struct timeval tv; double dist = std::numeric_limits::infinity(); @@ -71,7 +73,13 @@ void IASSS_Robot::run() { rv = gettimeofday(&tv, NULL); now = tv.tv_usec; delta = now - then; - + + if(_phero_map != NULL) { + x = (_p_proxy->GetXPos() + (MAP_SIZE / 2)) / MAP_SIZE; + y = (_p_proxy->GetYPos() + (MAP_SIZE / 2)) / MAP_SIZE; + _phero_map->s_draw_point(x, y); + } + // Sleep for a bit before finishing this control iteration. wait = rv == 0 ? HALF_SECOND_USEC - delta : HALF_SECOND_USEC; usleep(wait); diff --git a/ias_ss.cpp b/ias_ss.cpp index f245096..7c7600c 100644 --- a/ias_ss.cpp +++ b/ias_ss.cpp @@ -44,11 +44,6 @@ static PheromoneMap * phero_map = NULL; extern "C" void handler(int signal) { done = true; - - if(window != NULL) { - glWindow->finish(); - window->hide(); - } } extern "C" void * robot_thread(void * arg) { @@ -56,8 +51,10 @@ extern "C" void * robot_thread(void * arg) { std::cout << "Running robot thread." << std::endl; - while(!done) + while(!done) { robot->run(); + pthread_testcancel(); + } return NULL; } @@ -92,7 +89,10 @@ int main(int argc, char **argv) { create_gui(argc, argv); Fl::run(); - // Wait for all the robots to finish. + // Finish all the robots. + for(uint32_t i = 0; i < NUM_ROBOTS; ++i) + pthread_cancel(robot_threads[i]); + for(uint32_t i = 0; i < NUM_ROBOTS; ++i) { if(pthread_join(robot_threads[i], NULL) != 0) { perror("Could not join robot thread"); diff --git a/maps/cave_mask.png b/maps/cave_mask.png index 32518d2..7e06d6b 100644 Binary files a/maps/cave_mask.png and b/maps/cave_mask.png differ diff --git a/maps/gradient.png b/maps/gradient.png deleted file mode 100644 index 45f217c..0000000 Binary files a/maps/gradient.png and /dev/null differ diff --git a/ogl.cpp b/ogl.cpp index 63e54a8..af0a69f 100644 --- a/ogl.cpp +++ b/ogl.cpp @@ -28,7 +28,6 @@ #include #include #include -#include #include "ogl.hpp" #include "GLSLProgram.hpp" @@ -41,21 +40,24 @@ namespace ogl static CGLSLProgram m_program; static PheromoneMap * m_phero_map = NULL; static GLuint m_textureHandle; + static GLuint m_gradientHandle; // Quad definition static glm::vec4 vec_points[6]; static glm::vec2 vec_tex_coords[6]; static void quad() { - vec_tex_coords[0] = glm::vec2( 0.0f, 0.0f); vec_points[0] = glm::vec4( -0.5f, -0.5f, 0.0f, 1.0f ); - vec_tex_coords[1] = glm::vec2( 0.0f, 1.0f); vec_points[1] = glm::vec4( -0.5f, 0.5f, 0.0f, 1.0f ); - vec_tex_coords[2] = glm::vec2( 1.0f, 0.0f); vec_points[2] = glm::vec4( 0.5f, -0.5f, 0.0f, 1.0f ); - vec_tex_coords[3] = glm::vec2( 1.0f, 0.0f); vec_points[3] = glm::vec4( 0.5f, -0.5f, 0.0f, 1.0f ); - vec_tex_coords[4] = glm::vec2( 0.0f, 1.0f); vec_points[4] = glm::vec4( -0.5f, 0.5f, 0.0f, 1.0f ); - vec_tex_coords[5] = glm::vec2( 1.0f, 1.0f); vec_points[5] = glm::vec4( 0.5f, 0.5f, 0.0f, 1.0f ); + vec_tex_coords[0] = glm::vec2( 0.0f, 1.0f); vec_points[0] = glm::vec4( -0.5f, -0.5f, 0.0f, 1.0f ); + vec_tex_coords[1] = glm::vec2( 0.0f, 0.0f); vec_points[1] = glm::vec4( -0.5f, 0.5f, 0.0f, 1.0f ); + vec_tex_coords[2] = glm::vec2( 1.0f, 1.0f); vec_points[2] = glm::vec4( 0.5f, -0.5f, 0.0f, 1.0f ); + vec_tex_coords[3] = glm::vec2( 1.0f, 1.0f); vec_points[3] = glm::vec4( 0.5f, -0.5f, 0.0f, 1.0f ); + vec_tex_coords[4] = glm::vec2( 0.0f, 0.0f); vec_points[4] = glm::vec4( -0.5f, 0.5f, 0.0f, 1.0f ); + vec_tex_coords[5] = glm::vec2( 1.0f, 0.0f); vec_points[5] = glm::vec4( 0.5f, 0.5f, 0.0f, 1.0f ); } void initialize(PheromoneMap * phero_map) { + glEnable(GL_TEXTURE_2D); + glewInit(); quad(); @@ -74,7 +76,7 @@ namespace ogl void display() { glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.15f, 0.15f, 0.15f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); if(m_phero_map != NULL) m_textureHandle = m_phero_map->s_build_texture(); // Good grief! @@ -82,7 +84,7 @@ namespace ogl m_program.enable(); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_textureHandle); - glUniform1i(m_program.getLocation("sTexture"), 0); + glUniform1i(m_program.getLocation("sTexture"), GL_TEXTURE0); glBegin(GL_TRIANGLES); { for(int i = 0; i < 6; i++) { diff --git a/pheromone.cpp b/pheromone.cpp index d5f2f7d..6171c57 100644 --- a/pheromone.cpp +++ b/pheromone.cpp @@ -8,6 +8,7 @@ PheromoneMap::PheromoneMap(const char * file_name) { load_map(file_name); sem_init(&map_semaphore, 0, 1); tex_created = false; + then = 0; } PheromoneMap::~PheromoneMap() { @@ -26,7 +27,7 @@ void PheromoneMap::load_map(const char * file_name) { png_init(0, 0); png_open_file_read(&tex, file_name); - data = (unsigned char*) malloc(tex.width * tex.height * tex.bpp); + data = static_cast(malloc(tex.width * tex.height * tex.bpp)); png_get_data(&tex, data); std::cout << "Loaded map \"" << file_name << "\" :: " << tex.width << "x" << tex.height << "x" << (int)tex.bpp << std::endl; @@ -48,7 +49,7 @@ GLuint PheromoneMap::s_build_texture() { glGenTextures(1, &handle); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, m_width, m_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -57,3 +58,56 @@ GLuint PheromoneMap::s_build_texture() { return handle; } + +void PheromoneMap::s_draw_point(float x, float y) { + int _x = m_width * x; + int _y = m_height - (m_height * y); + + sem_wait(&map_semaphore); { + data[(_y * m_height) + _x] = 249; + } sem_post(&map_semaphore); +} + +void PheromoneMap::s_update() { + clock_t now = clock(); + + if(static_cast(now - then) / CLOCKS_PER_SEC < 0.005) { + return; + } + + then = now; + + sem_wait(&map_semaphore); { + for(int i = 1; i < m_height - 1; i++) { + for(int j = 1; j < m_width - 1; j++) { + if(data[(i * m_height) + j] > 10 && data[(i * m_height) + j] < 250){ + data[(i * m_height) + j] -= 1; + + if(data[((i - 1) * m_height) + (j - 1)] < 250) + data[((i - 1) * m_height) + (j - 1)] = data[(i * m_height) + j]; + + if(data[((i - 1) * m_height) + j] < 250) + data[((i - 1) * m_height) + j] = data[(i * m_height) + j]; + + if(data[((i - 1) * m_height) + (j + 1)] < 250) + data[((i - 1) * m_height) + (j + 1)] = data[(i * m_height) + j]; + + if(data[(i * m_height) + (j - 1)] < 250) + data[(i * m_height) + (j - 1)] = data[(i * m_height) + j]; + + if(data[(i * m_height) + (j + 1)] < 250) + data[(i * m_height) + (j + 1)] = data[(i * m_height) + j]; + + if(data[((i + 1) * m_height) + (j - 1)] < 250) + data[((i + 1) * m_height) + (j - 1)] = data[(i * m_height) + j]; + + if(data[((i + 1) * m_height) + j] < 250) + data[((i + 1) * m_height) + j] = data[(i * m_height) + j]; + + if(data[((i + 1) * m_height) + (j + 1)] < 250) + data[((i + 1) * m_height) + (j + 1)] = data[(i * m_height) + j]; + } + } + } + } sem_post(&map_semaphore); +} diff --git a/pheromone.hpp b/pheromone.hpp index 2a1262b..ce6ec76 100644 --- a/pheromone.hpp +++ b/pheromone.hpp @@ -1,8 +1,9 @@ #ifndef PHEROMONE_HPP #define PHEROMONE_HPP -#include +#include #include +#include class PheromoneMap { public: @@ -10,15 +11,18 @@ public: ~PheromoneMap(); GLuint s_build_texture(); + void s_draw_point(float x, float y); + void s_update(); private: unsigned char * data; unsigned m_width; unsigned m_height; unsigned char m_bpp; - sem_t map_semaphore; - bool tex_created; - GLuint handle; + sem_t map_semaphore; + bool tex_created; + GLuint handle; + clock_t then; void load_map(const char * file_name); }; diff --git a/shaders/basic.frag b/shaders/basic.frag index 808ef44..8d85ca2 100644 --- a/shaders/basic.frag +++ b/shaders/basic.frag @@ -2,8 +2,7 @@ uniform sampler2D sTexture; -void main(void) { +void main() { vec4 tex = texture2D(sTexture, gl_TexCoord[0].st); gl_FragColor = clamp(tex, 0.0, 1.0); - //gl_FragColor = vec4(gl_TexCoord[0].s, gl_TexCoord[0].t, 0.0, 1.0); }