diff --git a/.gitignore b/.gitignore index ada6103..c43115e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.user build* *.so -*.dll +teams/*.dll +generators/*.dll diff --git a/generators/anselme.cpp b/generators/anselme.cpp index fd40bff..faa5567 100644 --- a/generators/anselme.cpp +++ b/generators/anselme.cpp @@ -16,38 +16,34 @@ extern "C" void generate(Map *mapPtr) for(i=0; i r+15) // mountain - map[i][j].type = rand()%8 ? Pixel::ROCK : Pixel::IRON_ORE; - else if(l < r-15) // plains - map[i][j].type = rand()%15 ? Pixel::GRASS : Pixel::BERRIES; - else // forest - { - l = rand()%10; - map[i][j].type = l > 5 ? Pixel::TREE : l ? Pixel::GRASS : Pixel::BERRIES; - } + int l = (d-20)+(rand()%40); + if(l > r+15) // mountain + map[i][j].type = rand()%8 ? Pixel::ROCK : Pixel::IRON_ORE; + else if(l < r-15) // plains + map[i][j].type = rand()%15 ? Pixel::GRASS : Pixel::BERRIES; + else // forest + { + l = rand()%10; + map[i][j].type = l > 5 ? Pixel::TREE : l ? Pixel::GRASS : Pixel::BERRIES; } } } diff --git a/shaders/world.frag.glsl b/shaders/world.frag.glsl index 990541a..aeea090 100644 --- a/shaders/world.frag.glsl +++ b/shaders/world.frag.glsl @@ -29,7 +29,7 @@ void main() nbRevolutions.x = int(floor(worldCoord.x / worldSize.x)); } worldCoord = worldCoord - nbRevolutions*worldSize; - vec3 texColor = texelFetch(colorMap, ivec2(worldCoord)).xyz; + vec3 texColor = texelFetch(colorMap, ivec2(worldCoord)-1).xyz; vec3 lighting = phongLighting(texColor, vec3(0.5), 50, vec3(1), normalize(normal), lightDir, normalize(lightDir+vec3(0, 0, -1))); outColor = vec4(texColor*0.2 + 0.8*lighting, 1.0); diff --git a/src/behavior.h b/src/behavior.h index 8058aea..b54bc19 100644 --- a/src/behavior.h +++ b/src/behavior.h @@ -45,12 +45,15 @@ struct Action struct Info { virtual bool getSuccess() = 0; - virtual bool getInventory() = 0; + virtual int getInventory() = 0; virtual const Com& getCom() = 0; virtual int getNear(Dir d) = 0; virtual int getInfo(Dir d) = 0; }; +/** + * must be named "think" + */ typedef void (*BehaviorFunction)(Action *action, char *memory, const Info *info); #endif // BEHAVIOR_H diff --git a/src/drawwidget.cpp b/src/drawwidget.cpp index a620f9c..eb11aaf 100644 --- a/src/drawwidget.cpp +++ b/src/drawwidget.cpp @@ -7,12 +7,14 @@ #include #include #include "mapscene.h" +#include "simulation.h" #include "pixelpipeline.h" #include DrawWidget::DrawWidget(QWidget *parent) : QOpenGLWidget(parent), - m_Qt_fbo(NULL) + m_Qt_fbo(NULL), + m_pipeline(NULL) { new_simulation = false; update_needed = false; @@ -20,8 +22,8 @@ DrawWidget::DrawWidget(QWidget *parent) : DrawWidget::~DrawWidget() { - delete m_pipeline; - delete m_map; + if(m_pipeline != NULL) + delete m_pipeline; if(m_Qt_fbo != NULL && m_Qt_fbo != FrameBuffer::screen) delete(m_Qt_fbo); } @@ -29,7 +31,6 @@ DrawWidget::~DrawWidget() void DrawWidget::initializeGL() { renderer.initGL(width(), height()); - m_map = NULL; renderer.setScene(m_map); } @@ -37,6 +38,9 @@ void DrawWidget::paintGL() { if(new_simulation) { + if(m_pipeline != NULL) + delete m_pipeline; + m_map->initDraw(); m_pipeline = new PixelPipeline(m_map); m_pipeline->setTargetFBO(m_Qt_fbo); m_pipeline->resizeGL(m_width, m_height); @@ -65,16 +69,9 @@ void DrawWidget::resizeGL(int w, int h) m_pipeline->setTargetFBO(m_Qt_fbo); } -void DrawWidget::startSimulation(GenerateFunction genFunc, std::vector behaveFuncs) +void DrawWidget::startSimulation(MapScene *map) { - if(m_map != NULL) - { - delete m_map; - delete m_pipeline; - m_map = NULL; - } - m_map = new MapScene(behaveFuncs.size(), 300); - genFunc((Map*)m_map); + m_map = map; new_simulation = true; repaint(); } diff --git a/src/drawwidget.h b/src/drawwidget.h index 41d7ef2..bc07924 100644 --- a/src/drawwidget.h +++ b/src/drawwidget.h @@ -10,6 +10,7 @@ class PixelPipeline; class MapScene; class FrameBuffer; +class Simulation; class DrawWidget : public QOpenGLWidget { @@ -46,10 +47,10 @@ class DrawWidget : public QOpenGLWidget public: DrawWidget(QWidget *parent = 0); ~DrawWidget(); + void startSimulation(MapScene *map); public slots: void updateDudesBehavior(); - void startSimulation(GenerateFunction, std::vector); }; #endif // DRAWWIDGET_H diff --git a/src/dude.cpp b/src/dude.cpp index 9c95dba..3a507a8 100644 --- a/src/dude.cpp +++ b/src/dude.cpp @@ -2,9 +2,9 @@ #include "map.h" #include -Dude::Dude(const Coord &_pos, Map &_map, int &_team) : +Dude::Dude(const Coord &_pos, Map *_map, int &_team) : m_pos(_pos), - m_map(_map), + p_map(_map), m_team(_team), m_dead(false), m_success(true), @@ -21,8 +21,8 @@ char* Dude::getMemory() void Dude::move(Dir d) { m_pos += Coord(d); - m_pos.x %= m_map.getWidth(); - m_pos.y %= m_map.getHeight(); + m_pos.x %= p_map->getWidth(); + m_pos.y %= p_map->getHeight(); } void Dude::receiveComData(const Com &comData) @@ -32,10 +32,10 @@ void Dude::receiveComData(const Com &comData) int Dude::getNear(Dir d) { - return m_map[Coord(d) + m_pos].type; + return p_map->getPixel(Coord(d) + m_pos).type; } int Dude::getInfo(Dir d) { - return m_map[Coord(d) + m_pos].data.nbRes; + return p_map->getPixel(Coord(d) + m_pos).data.nbRes; } diff --git a/src/dude.h b/src/dude.h index bcc3ca8..2891a65 100644 --- a/src/dude.h +++ b/src/dude.h @@ -7,7 +7,7 @@ class Dude : public Info { private: Coord m_pos; - Map &m_map; + Map *p_map; int m_team; bool m_dead; bool m_success; @@ -16,7 +16,7 @@ private: Com m_comData; public: - Dude(const Coord &_pos, Map &map, int &team); + Dude(const Coord &_pos, Map *_map, int &_team); char* getMemory(); int getTeam(){ return m_team; } void setSuccess(bool success) { m_success = success; } @@ -27,7 +27,7 @@ public: void receiveComData(const Com &comData); virtual bool getSuccess() { return m_success; } - virtual bool getInventory() { return m_inventory; } + virtual int getInventory() { return m_inventory; } virtual const Com& getCom() { return m_comData; } virtual int getNear(Dir d); virtual int getInfo(Dir d); diff --git a/src/libwidget.cpp b/src/libwidget.cpp deleted file mode 100644 index 839c7e3..0000000 --- a/src/libwidget.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "libwidget.h" -#include "ui_libwidget.h" - -#include -#include -#include - -#ifdef Q_OS_WIN -#define LIB_SUFFIX "dll" -#else -#define LIB_SUFFIX "so" -#endif - -LibWidget::LibWidget(QWidget *parent) : - QWidget(parent), - ui(new Ui::LibWidget) -{ - ui->setupUi(this); - refreshBehaviors(); - refreshGenerators(); - connect(ui->behaviorsRefreshButton, SIGNAL(pressed()), this, SLOT(refreshBehaviors())); - connect(ui->generatorsRefreshButton, SIGNAL(pressed()), this, SLOT(refreshGenerators())); - connect(ui->launchButton, SIGNAL(pressed()), this, SLOT(launchSimulation())); -} - -LibWidget::~LibWidget() -{ - delete ui; -} - -void LibWidget::refreshBehaviors() -{ - while(ui->behaviorsList->count() > 0) - ui->behaviorsList->takeItem(0); - m_behaviorList.clear(); - QDir teamDir(QCoreApplication::applicationDirPath()); - if(teamDir.cd("../teams")) - { - for(const QFileInfo &info : teamDir.entryInfoList()) - { - if(info.suffix().compare(LIB_SUFFIX) == 0) - { - QLibrary lib(info.absoluteFilePath()); - if(lib.load()) - { - BehaviorFunction func = (BehaviorFunction)lib.resolve("think"); - if(func) - { - ui->behaviorsList->addItem(info.baseName()); - m_behaviorList.push_back(func); - } - } - } - } - } - else - emit sendError(QString("ERROR : can't open the teams folder.\n"), 5000); -} - -void LibWidget::refreshGenerators() -{ - while(ui->generatorsList->count() > 0) - ui->generatorsList->takeItem(0); - m_genList.clear(); - QDir genDir(QCoreApplication::applicationDirPath()); - if(genDir.cd("../generators")) - { - for(const QFileInfo &info : genDir.entryInfoList()) - { - if(info.suffix().compare(LIB_SUFFIX) == 0) - { - QLibrary lib(info.absoluteFilePath()); - if(lib.load()) - { - GenerateFunction func = (GenerateFunction)lib.resolve("generate"); - if(func) - { - ui->generatorsList->addItem(info.baseName()); - m_genList.push_back(func); - } - } - } - } - } - else - emit sendError(QString("ERROR : can't open the generators folder.\n"), 5000); - if(!m_genList.empty()) - ui->generatorsList->item(0)->setSelected(true); -} - -void LibWidget::launchSimulation() -{ - GenerateFunction genFunc = m_genList[ui->generatorsList->currentRow()]; - std::vector behaveFuncs; - for(QListWidgetItem *item : ui->behaviorsList->selectedItems()) - behaveFuncs.push_back(m_behaviorList[ui->behaviorsList->row(item)]); - emit createSimulation(genFunc, behaveFuncs); -} diff --git a/src/libwidget.h b/src/libwidget.h deleted file mode 100644 index 3d31bed..0000000 --- a/src/libwidget.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef LIBWIDGET_H -#define LIBWIDGET_H - -#include - -namespace Ui { - class LibWidget; -} - -#include "behavior.h" -#include "map.h" - -class LibWidget : public QWidget -{ - Q_OBJECT - -public: - explicit LibWidget(QWidget *parent = 0); - ~LibWidget(); - -private slots: - void refreshBehaviors(); - void refreshGenerators(); - void launchSimulation(); - -private: - Ui::LibWidget *ui; - std::vector m_genList; - std::vector m_behaviorList; - -signals: - void sendError(QString, int); - void createSimulation(GenerateFunction, std::vector); -}; - -#endif // LIBWIDGET_H diff --git a/src/libwidget.ui b/src/libwidget.ui deleted file mode 100644 index 646dc25..0000000 --- a/src/libwidget.ui +++ /dev/null @@ -1,106 +0,0 @@ - - - LibWidget - - - - 0 - 0 - 248 - 480 - - - - Form - - - - 5 - - - 5 - - - 5 - - - 5 - - - - - QAbstractItemView::SelectRows - - - - - - - Refresh - - - - - - - Refresh - - - - - - - Terrain generators - - - - - - - Pixel behaviors - - - - - - - - 5 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - QAbstractItemView::MultiSelection - - - QAbstractItemView::SelectRows - - - - - - - Launch - - - - - - - - diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 1f17cdc..0824ebe 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,16 +1,15 @@ #include "mainwindow.h" #include "drawwidget.h" #include "ui_mainwindow.h" - +#include "simulationdialog.h" +#include "simulation.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); - connect(ui->libWidget, SIGNAL(sendError(QString, int)), ui->statusBar, SLOT(showMessage(QString, int))); - connect(ui->libWidget, SIGNAL(createSimulation(GenerateFunction,std::vector)), - ui->drawWidget, SLOT (startSimulation( GenerateFunction,std::vector))); + connect(ui->startButton, SIGNAL(pressed()), this, SLOT(openSimuDialog())); } MainWindow::~MainWindow() @@ -18,3 +17,16 @@ MainWindow::~MainWindow() delete ui; } +void MainWindow::openSimuDialog() +{ + SimulationDialog *dialog = new SimulationDialog(this); + dialog->setWindowTitle("Starting a new Simulation"); + connect(dialog, SIGNAL(sendError(QString, int)), ui->statusBar, SLOT(showMessage(QString, int))); + int ret = dialog->exec(); + if(ret == QDialog::Accepted) + { + Simulation *simu = dialog->getSimulation(); + ui->drawWidget->startSimulation(simu->getMap()); + // TODO set a timer to update the simulation + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h index 112fda1..e9820b1 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -17,6 +17,9 @@ public: private: Ui::MainWindow *ui; + +private slots: + void openSimuDialog(); }; #endif // MAINWINDOW_H diff --git a/src/mainwindow.ui b/src/mainwindow.ui index 995fd34..9d73140 100644 --- a/src/mainwindow.ui +++ b/src/mainwindow.ui @@ -57,7 +57,7 @@ 1 - + 0 @@ -74,7 +74,153 @@ 0 - + + + 1 + + + + + 0 + 0 + 120 + 75 + + + + Settings + + + + + + Qt::Horizontal + + + + + + + Flat / Sphere + + + + + + + surface ratio + + + + + + + Qt::Horizontal + + + + + + + Simulation Speed + + + + + + + Qt::Horizontal + + + + + + + + + 0 + 0 + 260 + 344 + + + + Stats + + + + + + Date + + + + + + + 0 + + + + + + + Population + + + + + + + 0 + + + + + + + + + + + + 5 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + START + + + + + + + STOP + + + + + + + PAUSE + + + + + @@ -93,12 +239,6 @@ QOpenGLWidget
drawwidget.h
- - LibWidget - QWidget -
libwidget.h
- 1 -
diff --git a/src/map.h b/src/map.h index 737efdd..23c2c96 100644 --- a/src/map.h +++ b/src/map.h @@ -17,7 +17,7 @@ struct Pixel void* knowledge; }; - int type; + Type type; PixelData data; Pixel() : type(GRASS) {} @@ -68,6 +68,9 @@ public: { return m_map[m_height*c.x + c.y]; } }; +/** + * must be named "generate" + */ typedef void (*GenerateFunction)(Map *map); #endif // MAP_H diff --git a/src/mapscene.cpp b/src/mapscene.cpp new file mode 100644 index 0000000..f6a199a --- /dev/null +++ b/src/mapscene.cpp @@ -0,0 +1,87 @@ +#include +#include "mapscene.h" + +#define HEX_TO_VEC3(hex) glm::vec3(float((hex & 0xFF0000) >> 16)/255, float((hex & 0x00FF00) >> 8)/255, float(hex & 0x0000FF)/255) + +inline glm::vec3 getColor(Pixel::Type type) +{ + switch(type){ + case Pixel::BEDROCK : return HEX_TO_VEC3(0x101020); + case Pixel::GRASS : return HEX_TO_VEC3(0x719678); + case Pixel::MARK : return HEX_TO_VEC3(0x5D7B62); + case Pixel::ROCK : return HEX_TO_VEC3(0x8C8C8C); + case Pixel::IRON_ORE : return HEX_TO_VEC3(0x917B61); + case Pixel::TREE : return HEX_TO_VEC3(0x003800); + case Pixel::BERRIES : return HEX_TO_VEC3(0x4D6394); + case Pixel::FOOD : return HEX_TO_VEC3(0xFF7A7A); + case Pixel::WOOD : return HEX_TO_VEC3(0x634A22); + case Pixel::STONE : return HEX_TO_VEC3(0x454545); + case Pixel::IRON : return HEX_TO_VEC3(0x4A4036); + case Pixel::DUDE : + // TODO + return HEX_TO_VEC3(0x0000FF); + case Pixel::SPAWN : + // TODO + return HEX_TO_VEC3(0x0000FF); + case Pixel::WALL : return HEX_TO_VEC3(0xE6B2A1); + case Pixel::ROAD : return HEX_TO_VEC3(0xEDB287); + case Pixel::SWORD : return HEX_TO_VEC3(0xEBEBEB); + case Pixel::LIBRARY : return HEX_TO_VEC3(0xA37A50); + case Pixel::DEAD_DUDE : return HEX_TO_VEC3(0xFF0000); + default : return HEX_TO_VEC3(0x0000FF); // bleu absolu = bug + } +} + +MapScene::~MapScene() +{ + if(m_vao != 0) + { + glDeleteBuffers(1, &m_vbo); + glDeleteVertexArrays(1, &m_vao); + m_vao = 0; + } +} + +void MapScene::changePixel(const Coord &c, glm::vec3 color) +{ + m_pixels.push_back(Pix(glm::vec2(c.x, c.y), color)); +} + +void MapScene::changePixel(const Coord &c, Pixel::Type type) +{ + m_pixels.push_back(Pix(glm::vec2(c.x, c.y), getColor(type))); +} + +void MapScene::initDraw() +{ + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + + glGenBuffers(1, &m_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_vbo); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Pix), (void*)(0)); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Pix), (void*)(sizeof(glm::vec2))); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glBindVertexArray(0); + + for(int i=0; i +#include +#include struct MapScene : public Map, public BasicScene { - MapScene(int n, int w, int h = 0) : Map(n, w, h) {} +public: + struct Pix + { + glm::vec2 pos; + glm::vec3 color; + Pix(glm::vec2 p, glm::vec3 c) : pos(p), color(c) {} + }; + + MapScene(int n, int w, int h=0) : Map(n, w, h) {} + + ~MapScene(); + void changePixel(const Coord &c, glm::vec3 color); + void changePixel(const Coord &c, Pixel::Type type); + void initDraw(); + bool updateNecessary() { return !m_pixels.empty(); } + void draw(); + +private: + unsigned int m_vao; + unsigned int m_vbo; + + std::vector m_pixels; }; #endif // MAPSCENE_H diff --git a/src/pixelpipeline.cpp b/src/pixelpipeline.cpp index ce1578f..516e082 100644 --- a/src/pixelpipeline.cpp +++ b/src/pixelpipeline.cpp @@ -11,37 +11,6 @@ #define SCROLL_SPEED 0.998f -#define HEX_TO_VEC3(hex) glm::vec3(float((hex & 0xFF0000) >> 16)/255, float((hex & 0x00FF00) >> 8)/255, float(hex & 0x0000FF)/255) - -inline glm::vec3 getColor(const Pixel &p) -{ - switch(p.type){ - case Pixel::BEDROCK : return HEX_TO_VEC3(0x101020); - case Pixel::GRASS : return HEX_TO_VEC3(0x719678); - case Pixel::MARK : return HEX_TO_VEC3(0x5D7B62); - case Pixel::ROCK : return HEX_TO_VEC3(0x8C8C8C); - case Pixel::IRON_ORE : return HEX_TO_VEC3(0x917B61); - case Pixel::TREE : return HEX_TO_VEC3(0x003800); - case Pixel::BERRIES : return HEX_TO_VEC3(0x4D6394); - case Pixel::FOOD : return HEX_TO_VEC3(0xFF7A7A); - case Pixel::WOOD : return HEX_TO_VEC3(0x634A22); - case Pixel::STONE : return HEX_TO_VEC3(0x454545); - case Pixel::IRON : return HEX_TO_VEC3(0x4A4036); - case Pixel::DUDE : - // TODO - return HEX_TO_VEC3(0x0000FF); - case Pixel::SPAWN : - // TODO - return HEX_TO_VEC3(0x0000FF); - case Pixel::WALL : return HEX_TO_VEC3(0xE6B2A1); - case Pixel::ROAD : return HEX_TO_VEC3(0xEDB287); - case Pixel::SWORD : return HEX_TO_VEC3(0xEBEBEB); - case Pixel::LIBRARY : return HEX_TO_VEC3(0xA37A50); - case Pixel::DEAD_DUDE : return HEX_TO_VEC3(0xFF0000); - default : return HEX_TO_VEC3(0x0000FF); // bleu absolu = bug - } -} - class ToreillerGenerator : public MeshGenerator { public: @@ -57,74 +26,17 @@ public: } }; -// MESH (2D points) - -class PixelMesh -{ -private: - GLuint m_vao; - GLuint m_vbo; - -public: - struct Pix - { - glm::vec2 pos; - glm::vec3 color; - }; - - std::vector m_pixels; - - PixelMesh(int size) - { - glGenVertexArrays(1, &m_vao); - glBindVertexArray(m_vao); - - glGenBuffers(1, &m_vbo); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Pix), (void*)(0)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Pix), (void*)(sizeof(glm::vec2))); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindVertexArray(0); - } - - ~PixelMesh() - { - if(m_vao != 0) - { - glDeleteBuffers(1, &m_vbo); - glDeleteVertexArrays(1, &m_vao); - m_vao = 0; - } - } - - void draw() - { - glDisable(GL_BLEND); - glDisable(GL_DEPTH_TEST); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glBindVertexArray(m_vao); - glBindBuffer(GL_ARRAY_BUFFER, m_vbo); - glBufferData(GL_ARRAY_BUFFER, m_pixels.size() * sizeof(Pix), m_pixels.data(), GL_DYNAMIC_DRAW); - glDrawArrays(GL_POINTS, 0, m_pixels.size()); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - m_pixels.clear(); - } -}; - // PIPELINE PixelPipeline::PixelPipeline(MapScene *map) : + m_map(map), m_mapWidth(map->getWidth()), m_mapHeight(map->getHeight()), m_camera(0, 0, 1) { m_width = 256; m_height = 256; - map->setPipeline(this); + m_map->setPipeline(this); m_targetFBO = FrameBuffer::screen; m_mapFBO = new FrameBuffer(); m_mapTex = new Texture(GL_RGBA, GL_RGBA, m_mapWidth, m_mapHeight, GL_UNSIGNED_BYTE, GL_TEXTURE_RECTANGLE); @@ -147,10 +59,6 @@ PixelPipeline::PixelPipeline(MapScene *map) : vertSource = QtUtils::fileToString(":shaders/shaders/world.vert.glsl").toStdString(); fragSource = QtUtils::fileToString(":shaders/shaders/world.frag.glsl").toStdString(); m_renderShader = new Shader(vertSource, fragSource); - m_changes = new PixelMesh(map->getWidth() * map->getHeight()); - for(int i=0; igetWidth(); ++i) - for(int j=0; jgetHeight(); ++j) - pushChange(glm::vec2(i, j), getColor((*map)[i][j])); updateChanges(); } @@ -160,23 +68,18 @@ PixelPipeline::~PixelPipeline() delete m_mapTex; delete m_texMapShader; delete m_renderShader; - delete m_changes; -} - -void PixelPipeline::pushChange(const glm::vec2 &pos, const glm::vec3 &color) -{ - m_changes->m_pixels.push_back({pos, color}); + delete m_map; } void PixelPipeline::updateChanges() { - if(!m_changes->m_pixels.empty()) + if(m_map->updateNecessary()) { m_mapFBO->bindFBO(); glViewport(0, 0, m_mapWidth, m_mapHeight); m_texMapShader->bind(); m_texMapShader->bindVec2(m_texMapShader->getLocation("texRatio"), glm::vec2(2.0f/m_mapWidth, 2.0f/m_mapHeight)); - m_changes->draw(); + m_map->draw(); } } diff --git a/src/pixelpipeline.h b/src/pixelpipeline.h index 38cc8c4..8eb623a 100644 --- a/src/pixelpipeline.h +++ b/src/pixelpipeline.h @@ -17,7 +17,7 @@ private: FrameBuffer *m_mapFBO; Texture *m_mapTex; Shader *m_texMapShader; - PixelMesh *m_changes; + MapScene *m_map; int m_mapWidth; int m_mapHeight; const FrameBuffer *m_targetFBO; @@ -33,8 +33,7 @@ private: public: PixelPipeline(MapScene *map); ~PixelPipeline(); - - void pushChange(const glm::vec2 &pos, const glm::vec3 &color); + void updateChanges(); void setTargetFBO(FrameBuffer *fbo) {m_targetFBO = fbo;} diff --git a/src/simulation.cpp b/src/simulation.cpp index 3be5f49..40bcd53 100644 --- a/src/simulation.cpp +++ b/src/simulation.cpp @@ -3,9 +3,10 @@ #include #include "map.h" #include "dude.h" +#include "mapscene.h" -Simulation::Simulation(Map &_map, std::vector &_behaviors): - m_map(_map) +Simulation::Simulation(Map *_map, std::vector &_behaviors): + p_map(_map) { int i=0; for(BehaviorFunction &behavior : _behaviors){ @@ -32,15 +33,15 @@ void Simulation::update() if (t.updateSpawn()) { Dir randDir = Dir(rand()%4); - Coord spawnPos = m_map.team(i) + Coord(randDir); - m_dudes.push_back(new Dude(spawnPos,m_map,i)); + Coord spawnPos = p_map->team(i) + Coord(randDir); + m_dudes.push_back(new Dude(spawnPos,p_map,i)); } } } void Simulation::handleAction(Action *action, Dude *dude){ Coord targetPos(dude->getPos() + Coord(action->dir)); - Pixel target = m_map[targetPos]; + Pixel target = p_map->getPixel(targetPos); Dude* targetDude; dude->setSuccess(false); switch(action->type){ @@ -63,7 +64,7 @@ void Simulation::handleAction(Action *action, Dude *dude){ else{ if(target.type == Pixel::SPAWN) m_teams[target.data.nbRes].destroySpawn(); - m_map[targetPos].type = Pixel::GRASS; + p_map->getPixel(targetPos).type = Pixel::GRASS; } } break; @@ -72,7 +73,7 @@ void Simulation::handleAction(Action *action, Dude *dude){ dude->setInventory(target.type); target.data.nbRes--; if (target.data.nbRes < 1){ - m_map[targetPos].type = Pixel::GRASS; + p_map->getPixel(targetPos).type = Pixel::GRASS; // TODO: change color of target } dude->setSuccess(true); @@ -81,7 +82,7 @@ void Simulation::handleAction(Action *action, Dude *dude){ case Action::PUT: if(dude->getInventory() != -1 && (target.type == Pixel::GRASS || target.type == Pixel::MARK || target.type == dude->getInventory())){ if(target.type == Pixel::GRASS || target.type == Pixel::MARK){ - m_map[targetPos].type = dude->getInventory(); + p_map->getPixel(targetPos).type = (Pixel::Type) dude->getInventory(); target.data.nbRes = 1; }else target.data.nbRes++; diff --git a/src/simulation.h b/src/simulation.h index 01a7e67..dc99f22 100644 --- a/src/simulation.h +++ b/src/simulation.h @@ -2,21 +2,21 @@ #define SIMULATION_H #include - -#include #include "behavior.h" #include "team.h" -class Map; +class MapScene; class Simulation { private: - Map &m_map; + Map *p_map; std::vector m_dudes; std::vector m_teams; public: - Simulation(Map &_map, std::vector &_behaviors); + Simulation(Map *_map, std::vector &_behaviors); + MapScene* getMap() { return (MapScene*) p_map; } + /** * @brief update runs one step of simulation */ diff --git a/src/simulationdialog.cpp b/src/simulationdialog.cpp new file mode 100644 index 0000000..458c7b1 --- /dev/null +++ b/src/simulationdialog.cpp @@ -0,0 +1,151 @@ +#include "simulationdialog.h" +#include "ui_simulationdialog.h" +#include "simulation.h" +#include "mapscene.h" +#include +#include +#include +#include + +#ifdef Q_OS_WIN +#define LIB_SUFFIX "dll" +#else +#define LIB_SUFFIX "so" +#endif + +SimulationDialog::SimulationDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SimulationDialog), + m_map(NULL) +{ + ui->setupUi(this); + connect(ui->behaviorsRefreshButton, SIGNAL(pressed()), this, SLOT(refreshBehaviors())); + connect(ui->generatorsRefreshButton, SIGNAL(pressed()), this, SLOT(refreshGenerators())); + connect(ui->generateButton, SIGNAL(pressed()), this, SLOT(generateMap())); + connect(ui->behaviorsList, SIGNAL(clicked(QModelIndex)), this, SLOT(selectBehavior(QModelIndex))); + refreshBehaviors(); + refreshGenerators(); + ui->generatorsList->setCurrentRow(0); +} + +SimulationDialog::~SimulationDialog() +{ + delete ui; +} + +void SimulationDialog::resizeEvent(QResizeEvent *e) +{ + int h = ui->mapPreview->height(); + ui->mapPreview->resize(h*2, h); +} + +void SimulationDialog::refreshBehaviors() +{ + while(ui->behaviorsList->count() > 0) + ui->behaviorsList->takeItem(0); + m_behaviorList.clear(); + m_selectedBehaviors.clear(); + ui->selectedBehaviors->clear(); + QDir teamDir(QCoreApplication::applicationDirPath()); + if(teamDir.cd("../teams")) + { + for(const QFileInfo &info : teamDir.entryInfoList()) + { + if(info.suffix().compare(LIB_SUFFIX) == 0) + { + QLibrary lib(info.absoluteFilePath()); + if(lib.load()) + { + BehaviorFunction func = (BehaviorFunction)lib.resolve("think"); + if(func) + { + ui->behaviorsList->addItem(info.baseName()); + m_behaviorList.push_back(info.absoluteFilePath()); + } + lib.unload(); + } + } + } + } + else + emit sendError(QString("ERROR : can't open the teams folder.\n"), 5000); +} + +void SimulationDialog::refreshGenerators() +{ + while(ui->generatorsList->count() > 0) + ui->generatorsList->takeItem(0); + m_genList.clear(); + QDir genDir(QCoreApplication::applicationDirPath()); + if(genDir.cd("../generators")) + { + for(const QFileInfo &info : genDir.entryInfoList()) + { + if(info.suffix().compare(LIB_SUFFIX) == 0) + { + QLibrary lib(info.absoluteFilePath()); + if(lib.load()) + { + GenerateFunction func = (GenerateFunction)lib.resolve("generate"); + if(func) + { + ui->generatorsList->addItem(info.baseName()); + m_genList.push_back(info.absoluteFilePath()); + } + lib.unload(); + } + } + } + } + else + emit sendError(QString("ERROR : can't open the generators folder.\n"), 5000); + if(!m_genList.empty()) + ui->generatorsList->item(0)->setSelected(true); +} + +void SimulationDialog::generateMap() +{ + if(m_map != NULL) + delete m_map; + m_map = NULL; + QString path = m_genList[ui->generatorsList->currentRow()]; + QLibrary lib(path); + if(lib.load()) + { + GenerateFunction func = (GenerateFunction)lib.resolve("generate"); + if(func) + { + m_map = new MapScene(m_selectedBehaviors.size(), ui->mapSizeSpinBox->value()); + func((Map*)m_map); + // QPixmap preview(); + // TODO : display map in preview + } + lib.unload(); + } +} + +void SimulationDialog::selectBehavior(const QModelIndex &index) +{ + QListWidgetItem* item = ui->behaviorsList->item(index.row()); + QString path = m_behaviorList[ui->behaviorsList->row(item)]; + QLibrary lib(path); + if(lib.load()) + { + BehaviorFunction func = (BehaviorFunction)lib.resolve("think"); + if(func) + { + m_selectedBehaviors.push_back(func); + ui->selectedBehaviors->addItem(item->text()); + } + else + lib.unload(); + } + // TODO : unload later +} + +Simulation* SimulationDialog::getSimulation() +{ + if(m_map == NULL || m_map->getNbTeams() != m_selectedBehaviors.size()) + generateMap(); + return new Simulation(m_map, m_selectedBehaviors); +} diff --git a/src/simulationdialog.h b/src/simulationdialog.h new file mode 100644 index 0000000..cc7b344 --- /dev/null +++ b/src/simulationdialog.h @@ -0,0 +1,48 @@ +#ifndef SIMULATIONDIALOG_H +#define SIMULATIONDIALOG_H + +#include + +#include "behavior.h" +#include "map.h" + +class Simulation; +class MapScene; +class QListWidgetItem; +class QLibrary; + +namespace Ui { +class SimulationDialog; +} + +class SimulationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SimulationDialog(QWidget *parent = 0); + ~SimulationDialog(); + Simulation* getSimulation(); + +protected: + virtual void resizeEvent(QResizeEvent *); + +private slots: + void refreshBehaviors(); + void refreshGenerators(); + void generateMap(); + void selectBehavior(const QModelIndex &index); + +private: + Ui::SimulationDialog *ui; + std::vector m_genList; + std::vector m_behaviorList; + std::vector m_selectedBehaviors; + MapScene *m_map; + QLibrary *m_currentGeneratorLib; + +signals: + void sendError(QString, int); +}; + +#endif // SIMULATIONDIALOG_H diff --git a/src/simulationdialog.ui b/src/simulationdialog.ui new file mode 100644 index 0000000..e33a1f0 --- /dev/null +++ b/src/simulationdialog.ui @@ -0,0 +1,175 @@ + + + SimulationDialog + + + + 0 + 0 + 596 + 483 + + + + Dialog + + + + + + + + + Pixel behaviors + + + + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + + + + + Refresh + + + + + + + QAbstractItemView::NoSelection + + + + + + + + + + Terrain generators + + + + + + Generate + + + + + + + + 0 + 0 + + + + this is a preview + + + false + + + + + + + QAbstractItemView::SelectRows + + + + + + + Refresh + + + + + + + Map size + + + + + + + pixels + + + 50 + + + 10000 + + + 2 + + + 300 + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SimulationDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SimulationDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +