diff --git a/CMakeLists.txt b/CMakeLists.txt index d885937..e21df28 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8) # choose source file file(GLOB EXEC_SRC_LIST src/*.cpp) -file(GLOB RESOURCES_FILES resources.qrc src/*.ui shaders/*.glsl) +file(GLOB RESOURCES_FILES src/*.h resources.qrc src/*.ui shaders/*.glsl) set(EXTRA_INCLUDES src) diff --git a/generators/anselme.cpp b/generators/anselme.cpp new file mode 100644 index 0000000..9d0b6d7 --- /dev/null +++ b/generators/anselme.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +// g++ -shared anselme.cpp -o anselme.dll -I../src + +// functions +int distance_manhattan(int x1,int y1, int x2, int y2) +{ + return abs(x1-x2) + abs(y1-y2); +} + +inline int custom_min(int a, int b) +{ + return a < b ? a : b; +} + +inline int custom_max(int a, int b) +{ + return a > b ? a : b; +} + +extern "C" void generate(Map *mapPtr) +{ + Map &map = *mapPtr; + int w = map.getWidth(); + int h = map.getHeight(); + int n = map.getNbTeams(); + int i,j, k; + int r = (w/n < h ? w/n : h)/2; + int *teamCoord = new int[n*2]; + + 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; + } + } + } + } + } +} diff --git a/generators/anselme.dll b/generators/anselme.dll new file mode 100644 index 0000000..19e2264 Binary files /dev/null and b/generators/anselme.dll differ diff --git a/generators/bis.c b/generators/bis.c new file mode 100644 index 0000000..a0af3c4 --- /dev/null +++ b/generators/bis.c @@ -0,0 +1,131 @@ +#include "main.h" + +#include + +#ifndef MAX + #define max( a,b ) ( ((a) > (b) ) ? (a) : (b) ) +#endif + +//variables +int width, height, size; +float corner_value[4]; + +//functions +int closest_pow_2(int); +void init_height_map(float**); +void start_diamond_square(float**); +void diamond_square(float**,int,int,int,int); +float average(float,float); +float average_noisy(float,float); +float average_t(float*, int); +void apply_noise(float*); + +void create_map(int w, int h){ + width = w; + height = h; + + int i; + float** height_map; + + size=closest_pow_2(max(w,h)); + + height_map = (float**) malloc(sizeof(float*)*(size+1)); + for(i=0;i<=size;i++) + height_map[i]=malloc(sizeof(float)*(size+1)); + + printf("init height map...\n"); + init_height_map(height_map); + + printf("generate height map...\n"); + //generate height map + start_diamond_square(height_map); + + printf("erosion\n"); + + + + printf("finished generation! \n"); + +} + +int closest_pow_2(int x){ + return pow(2,floor(log(x)/log(2))+1); +} + +void init_height_map(float** h_map){ + h_map[0][0]=0.7; + h_map[size][0]=0.3; + h_map[size][size]=0.9; + h_map[0][size]=0.8; +} + +void start_diamond_square(float ** h_map){ + diamond_square(h_map,0,size,0,size); +} + +void dummy(int x1, int y1, int x2, int y2, int avg_x,int avg_y){ +} + +void diamond_square(float** h_map,int x1,int x2,int y1, int y2){ + int avg_x, avg_y; + float avg_value; + + //get value of corner from h_map + corner_value[0] = h_map[x1][y1]; //up_left + corner_value[1] = h_map[x2][y1]; //up_right + corner_value[2] = h_map[x2][y2]; //down_right + corner_value[3] = h_map[x1][y2]; //down_left + + //process coordinate of center + avg_x = average(x1,x2); + avg_y = average(y1,y2); + + //dummy(x1,y1,x2,y2,avg_x,avg_y); + //Diamond Step + //process average value of the corner + avg_value = average_t(corner_value,4); + + apply_noise(&avg_value); + //affect value + h_map[avg_x][avg_y]=avg_value; + + // Square Step + //update value of the four mid-point between corner, following clockwise orde, and adding noise + h_map[avg_x][y1] = average_noisy(corner_value[0], corner_value[1]); // up + h_map[x2][avg_y] = average_noisy(corner_value[1], corner_value[2]); // right + h_map[avg_x][y2] = average_noisy(corner_value[2], corner_value[3]); // down + h_map[x1][avg_y] = average_noisy(corner_value[3], corner_value[0]); // left + + //recursive call to diamond_square + int offset = x2-x1; + + if (offset > 2){ + diamond_square(h_map, x1, avg_x, y1, avg_y); //up_left square + diamond_square(h_map, avg_x, x2, y1, avg_y); // up_right square + diamond_square(h_map, avg_x, x2, avg_y, y2); // down_right square + diamond_square(h_map, x1, avg_x, avg_y, y2); // down_left square + } +} + +float average(float a, float b){ + return (a+b)/2; +} + +float average_noisy(float a, float b){ + float value = average(a,b); + apply_noise(&value); + return value; +} + +float average_t(float* tab, int size){ + int i; + float avg_value=0; + for(i=0;i not used for now +enum{ + FLAT, VALLEY, +}; + +//biome type +enum{ + VILLAGE, PLAINS, FOREST,MOUNTAINS,NB_BIOMES +}; + +// probability for each biomes +// in following order {GRASS,TREE,BERRIES, ROCK, IRON_ORE} +char proba_table[NB_BIOMES][5] = {{97,2,1,0,0},{85,13,2,0,0},{40,40,20,0,0},{0,0,0,80,20}}; + +typedef struct{ + int x; + int y; + int type; + int power; + int radius; +} t_biome; + +// variables +int sp_x[NB_TEAMS], sp_y[NB_TEAMS]; +t_biome* l_biomes; +int size_biomes; +int nb_plains, nb_forests, nb_mountains; +int cpt_biome = 0; +int width, height; + +// functions +int distance_manhattan(int x1,int y1, int x2, int y2); +int absolute(int val); +void set_spawns(t_pixel** map, t_team* teams); +void create_biome(int x, int y, int type); +void create_biome_random(int type); +int check_nears_biomes(int x, int y); +int check_nears_spawn(int x, int y); +int in_radius(int x,int y,t_biome e); +int generate(int x, int y); +void init_generator(); + +void create_map(int w, int h){ + int i,j; + + //biome variable + + width = w; + height = h; + + init_generator(); + + //Epicenters generation + // random choice for numbers of biomes + nb_plains = (rand()%MAX_EPICENTER_BY_TYPE)+3; + nb_forests = (rand()%MAX_EPICENTER_BY_TYPE)+3; + nb_mountains = (rand()%MAX_EPICENTER_BY_TYPE)+3; + + size_biomes = nb_plains+ nb_forests + nb_mountains + NB_TEAMS; + + l_biomes = malloc(sizeof(t_biome)*size_biomes); + + // Spawn generations + set_spawns(map,teams); + + for(i=0;ix=x; + biome->y=y; + biome->type = type; + + switch(type){ + case VILLAGE: + biome->power = (rand()%MAX_POWER)+1; + biome->radius = (rand()%(25-10))+10; + break; + case PLAINS: + case FOREST: + case MOUNTAINS: + default: + biome->power = (rand()%MAX_POWER)+1; + biome->radius = (rand()%(OFFSET_RADIUS))+MIN_RADIUS; + break; + } + + l_biomes[cpt_biome++]=*biome; +} + +void create_biome_random(int type){ + int x,y; + do { + x=rand()%width; + y=rand()%height; + } while ((check_nears_biomes(x,y) != 0) || (check_nears_spawn(x,y) != 0)); //prevent biome superposition + + create_biome(x,y,type); +} + +int check_nears_biomes(int x, int y){ + int i, c=0; + for(i=0;i 0 ? val : -val; +} diff --git a/generators/hello.dll b/generators/hello.dll new file mode 100644 index 0000000..d39bc3c Binary files /dev/null and b/generators/hello.dll differ diff --git a/shaders/pixel.vert.glsl b/shaders/pixel.vert.glsl index 1e8ac51..79b97b0 100644 --- a/shaders/pixel.vert.glsl +++ b/shaders/pixel.vert.glsl @@ -10,5 +10,5 @@ out vec3 color; void main(void) { color = inColor; - gl_Position = vec4(inTexPosition.x*texRatio.x, inTexPosition.y*texRatio.y, 0.0, 1.0); + gl_Position = vec4(inTexPosition.x*texRatio.x -1, inTexPosition.y*texRatio.y -1, 0.0, 1.0); } diff --git a/shaders/world.frag.glsl b/shaders/world.frag.glsl index 073a536..10131f5 100644 --- a/shaders/world.frag.glsl +++ b/shaders/world.frag.glsl @@ -1,6 +1,6 @@ #version 330 core -uniform sampler2D colorMap; +uniform sampler2DRect colorMap; uniform vec3 camera; uniform vec2 worldSize; @@ -14,8 +14,5 @@ void main() vec2 screenPos = gl_FragCoord.xy/gl_FragCoord.w + camera.xy; vec2 texCoord = (screenPos-halfScreen)/200; vec3 texColor = texture(colorMap, texCoord).xyz; - if(length(screenPos-halfScreen)*camera.z < 200) - outColor = vec4(texColor, 1.0); - else - outColor = vec4(0.0, 0.5, 0.5, 1.0); + outColor = vec4(texColor, 1.0); } diff --git a/src/drawwidget.cpp b/src/drawwidget.cpp index 38eac2f..c508127 100644 --- a/src/drawwidget.cpp +++ b/src/drawwidget.cpp @@ -1,13 +1,12 @@ #include "drawwidget.h" #include #include -#include #include #include #include #include #include -#include "map.h" +#include "mapscene.h" #include "pixelpipeline.h" #include @@ -17,20 +16,20 @@ DrawWidget::DrawWidget(QWidget *parent) : { connect(&openglRefreshTimer, SIGNAL(timeout()), this, SLOT(repaint())); openglRefreshTimer.start(16); - m_map = new Map(200, 100); +} + +DrawWidget::~DrawWidget() +{ + delete m_pipeline; + delete m_map; + if(m_Qt_fbo != NULL && m_Qt_fbo != FrameBuffer::screen) + delete(m_Qt_fbo); } void DrawWidget::initializeGL() { renderer.initGL(width(), height()); - - m_pipeline = new PixelPipeline(200, 100); - m_map->setPipeline(m_pipeline); - - m_pipeline->pushChange(glm::vec2(50, 50), glm::vec3(0, 1, 0)); - m_pipeline->pushChange(glm::vec2(150, 50), glm::vec3(0, 0, 1)); - m_pipeline->updateChanges(); - + m_map = NULL; renderer.setScene(m_map); } @@ -41,13 +40,34 @@ void DrawWidget::paintGL() void DrawWidget::resizeGL(int w, int h) { + m_width = w; + m_height = h; renderer.resizeGL(w, h); if(m_Qt_fbo != NULL && m_Qt_fbo != FrameBuffer::screen) delete(m_Qt_fbo); m_Qt_fbo = new FrameBuffer(defaultFramebufferObject()); - m_pipeline->setTargetFBO(m_Qt_fbo); + if(m_map != NULL) + m_pipeline->setTargetFBO(m_Qt_fbo); } +void DrawWidget::startSimulation(GenerateFunction genFunc, std::vector behaveFuncs) +{ + if(m_map != NULL) + { + delete m_map; + delete m_pipeline; + m_map = NULL; + } + m_map = new MapScene(behaveFuncs.size(), 200, 100); + genFunc((Map*)m_map); + m_pipeline = new PixelPipeline(m_map); + m_pipeline->setTargetFBO(m_Qt_fbo); + m_pipeline->resizeGL(m_width, m_height); + renderer.setScene(m_map); +} + +// INPUT EVENTS + void DrawWidget::mouseMoveEvent(QMouseEvent *event) { if(grabbedMouse) diff --git a/src/drawwidget.h b/src/drawwidget.h index 7c750f1..484771b 100644 --- a/src/drawwidget.h +++ b/src/drawwidget.h @@ -5,8 +5,11 @@ #include #include +#include "map.h" +#include "team.h" + class PixelPipeline; -class Map; +class MapScene; class FrameBuffer; class DrawWidget : public QOpenGLWidget @@ -20,9 +23,11 @@ class DrawWidget : public QOpenGLWidget // camera handling variables QPoint lastMousePos; bool grabbedMouse; - Map *m_map; + MapScene *m_map; FrameBuffer *m_Qt_fbo; PixelPipeline *m_pipeline; + int m_width; + int m_height; protected: // Output @@ -39,6 +44,10 @@ class DrawWidget : public QOpenGLWidget public: DrawWidget(QWidget *parent = 0); + ~DrawWidget(); + + public slots: + void startSimulation(GenerateFunction, std::vector); }; #endif // DRAWWIDGET_H diff --git a/src/dude.cpp b/src/dude.cpp new file mode 100644 index 0000000..4db8303 --- /dev/null +++ b/src/dude.cpp @@ -0,0 +1,6 @@ +#include "dude.h" + +Dude::Dude() +{ + +} diff --git a/src/dude.h b/src/dude.h new file mode 100644 index 0000000..0578438 --- /dev/null +++ b/src/dude.h @@ -0,0 +1,20 @@ +#ifndef DUDE_H +#define DUDE_H + +#include "team.h" + +class Dude +{ +private: + Coord pos; + Info info; + bool dead; + char memory[DUDE_MEMORY_SIZE]; + BehaviorFunction behavior; + +public: + + Dude(); +}; + +#endif // DUDE_H diff --git a/src/libwidget.cpp b/src/libwidget.cpp index eae7f26..be6594f 100644 --- a/src/libwidget.cpp +++ b/src/libwidget.cpp @@ -10,15 +10,16 @@ #define LIB_SUFFIX "so" #endif -typedef void (*ThinkFunction)(void); - LibWidget::LibWidget(QWidget *parent) : QWidget(parent), ui(new Ui::LibWidget) { ui->setupUi(this); - refreshLibs(); - connect(ui->pushButton, SIGNAL(pressed()), this, SLOT(refreshLibs())); + 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() @@ -26,10 +27,10 @@ LibWidget::~LibWidget() delete ui; } -void LibWidget::refreshLibs() +void LibWidget::refreshBehaviors() { - while(ui->listWidget->count() > 0) - ui->listWidget->takeItem(0); + while(ui->behaviorsList->count() > 0) + ui->behaviorsList->takeItem(0); QDir teamDir(QCoreApplication::applicationDirPath()); if(teamDir.cd("../teams")) { @@ -40,10 +41,11 @@ void LibWidget::refreshLibs() QLibrary lib(info.absoluteFilePath()); if(lib.load()) { - ThinkFunction func = lib.resolve("think"); + BehaviorFunction func = (BehaviorFunction)lib.resolve("think"); if(func) { - ui->listWidget->addItem(info.baseName()); + ui->behaviorsList->addItem(info.baseName()); + m_behaviorList.push_back(func); } } } @@ -52,3 +54,40 @@ void LibWidget::refreshLibs() 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); + 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); +} + +void LibWidget::launchSimulation() +{ + GenerateFunction genFunc = m_genList[ui->generatorsList->currentRow()]; + std::vector behaveFuncs; + for(QListWidgetItem *item : ui->generatorsList->selectedItems()) + behaveFuncs.push_back(m_behaviorList[ui->behaviorsList->row(item)]); + emit createSimulation(genFunc, behaveFuncs); +} diff --git a/src/libwidget.h b/src/libwidget.h index 61f691c..57885d8 100644 --- a/src/libwidget.h +++ b/src/libwidget.h @@ -4,9 +4,12 @@ #include namespace Ui { -class LibWidget; + class LibWidget; } +#include "team.h" +#include "map.h" + class LibWidget : public QWidget { Q_OBJECT @@ -16,13 +19,18 @@ public: ~LibWidget(); private slots: - void refreshLibs(); + void refreshBehaviors(); + void refreshGenerators(); + void launchSimulation(); private: Ui::LibWidget *ui; + std::vector m_genList; + std::vector m_behaviorList; signals: - sendError(QString, int); + void sendError(QString, int); + void createSimulation(GenerateFunction, std::vector); }; #endif // LIBWIDGET_H diff --git a/src/libwidget.ui b/src/libwidget.ui index 6aa1c0b..646dc25 100644 --- a/src/libwidget.ui +++ b/src/libwidget.ui @@ -13,10 +13,7 @@ Form - - - 5 - + 5 @@ -29,7 +26,42 @@ 5 - + + + + QAbstractItemView::SelectRows + + + + + + + Refresh + + + + + + + Refresh + + + + + + + Terrain generators + + + + + + + Pixel behaviors + + + + @@ -47,18 +79,25 @@ 0 - - - - Refresh - - - - - + + + + QAbstractItemView::MultiSelection + + + QAbstractItemView::SelectRows + + + + + + + Launch + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 576fbd1..1f17cdc 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -9,6 +9,8 @@ MainWindow::MainWindow(QWidget *parent) : { 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))); } MainWindow::~MainWindow() diff --git a/src/map.cpp b/src/map.cpp index 4ab6345..836f3b2 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1,10 +1,21 @@ #include "map.h" +#include -Map::Map(int width, int height) : +Map::Map(int nbTeams, int width, int height) : m_width(width), - m_height(height) + m_height(height), + m_nbTeams(nbTeams) { - if(!height) - height = width/2; - // TODO allocating map + if(m_height == 0) + m_height = m_width/2; + map = new Pixel*[m_width]; + Pixel *ptr = new Pixel[m_width*m_height]; + for(int i=0; i - struct Pixel { - enum Type { - BEDROCK, GRASS, TREE, BERRIES, ROCK, IRON_ORE, // nature - FOOD, WOOD, STONE, IRON, SWORD, // resources - DUDE, DEAD_DUDE, // humans - SPAWN, WALL, ROAD, MARK, LIBRARY // buildings - }; - - union PixelData { - int nbRes; - void* knowledge; - }; - - int type; - PixelData data; + enum Type { + BEDROCK, GRASS, TREE, BERRIES, ROCK, IRON_ORE, // nature + FOOD, WOOD, STONE, IRON, SWORD, // resources + DUDE, DEAD_DUDE, // humans + SPAWN, WALL, ROAD, MARK, LIBRARY // buildings + }; + + union PixelData { + int nbRes; + void* knowledge; + }; + + int type; + PixelData data; + + Pixel() : type(GRASS) {} }; -class Map : public BasicScene +class Map { - MapData map; + Pixel **map; int m_width; int m_height; + int m_nbTeams; public: - Map(int width, int height = 0); - - int getWidth() { return m_width; } - int getHeight() { return m_height; } + Map(int nbTeams, int width, int height = 0); + ~Map(); + + int getWidth() const { return m_width; } + int getHeight() const { return m_height; } + int getNbTeams() const { return m_nbTeams; } + + /** + * @brief operator [] allows to access a pixel of the map with the following syntax : + * Pixel &p = map[x][y]; + */ + Pixel* operator[](int i) + { return map[i]; } }; +typedef void (*GenerateFunction)(Map *map); + #endif // MAP_H diff --git a/src/mapscene.h b/src/mapscene.h new file mode 100644 index 0000000..1a4ff60 --- /dev/null +++ b/src/mapscene.h @@ -0,0 +1,12 @@ +#ifndef MAPSCENE_H +#define MAPSCENE_H + +#include "map.h" +#include + +struct MapScene : public Map, public BasicScene +{ + MapScene(int n, int w, int h = 0) : Map(n, w, h) {} +}; + +#endif // MAPSCENE_H diff --git a/src/pixelpipeline.cpp b/src/pixelpipeline.cpp index a40d570..ff04b0c 100644 --- a/src/pixelpipeline.cpp +++ b/src/pixelpipeline.cpp @@ -1,56 +1,84 @@ #include "pixelpipeline.h" #include #include -#include #include #include #include #include +#include "mapscene.h" #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 + } +} + + // MESH (2D points) class PixelMesh { private: GLuint m_vao; - - void updateBuffer() - { - TBuffer::BufferEditor editor(pixBuffer); - std::memcpy(editor.getPointer(), m_pixels.data(), m_pixels.size()*sizeof(Pix)); - m_pixels.clear(); - } + GLuint m_vbo; public: - struct Pix - { - glm::vec2 pos; - glm::vec3 color; - }; + struct Pix + { + glm::vec2 pos; + glm::vec3 color; + }; + + std::vector m_pixels; - std::vector m_pixels; - TBuffer *pixBuffer; - - PixelMesh() - { - m_pixels.push_back({glm::vec2(0), glm::vec3(0)}); // buffer must not be empty - glGenVertexArrays(1, &m_vao); - glBindVertexArray(m_vao); - - pixBuffer = new TBuffer(m_pixels, Buffer::VBO, true); - pixBuffer->setVertexAttrib(0, 2); - pixBuffer->setVertexAttrib(1, 3, sizeof(glm::vec2)); - - glBindVertexArray(0); - } + 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) { - delete(pixBuffer); + glDeleteBuffers(1, &m_vbo); glDeleteVertexArrays(1, &m_vao); m_vao = 0; } @@ -58,20 +86,29 @@ public: void draw() { - glBindVertexArray(m_vao); - updateBuffer(); - glDrawArrays(GL_POINTS, 0, m_pixels.size()); - glBindVertexArray(0); + 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(int mapWidth, int mapHeight) : - m_mapWidth(mapWidth), - m_mapHeight(mapHeight), - m_camera(0, 0, 1) +PixelPipeline::PixelPipeline(MapScene *map) : + m_mapWidth(map->getWidth()), + m_mapHeight(map->getHeight()), + m_camera(0, 0, 1) { + m_width = 256; + m_height = 256; + 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); @@ -93,14 +130,27 @@ PixelPipeline::PixelPipeline(int mapWidth, int mapHeight) : glBufferData(GL_ARRAY_BUFFER, 3 * 2 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, NULL); glEnableVertexAttribArray(0); - + std::string vertSource = QtUtils::fileToString(":shaders/shaders/pixel.vert.glsl").toStdString(); std::string fragSource = QtUtils::fileToString(":shaders/shaders/pixel.frag.glsl").toStdString(); m_texMapShader = new Shader(vertSource, fragSource); 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(); + 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(); +} + +PixelPipeline::~PixelPipeline() +{ + delete m_mapFBO; + delete m_mapTex; + delete m_texMapShader; + delete m_renderShader; + delete m_changes; } void PixelPipeline::pushChange(const glm::vec2 &pos, const glm::vec3 &color) @@ -115,6 +165,7 @@ void PixelPipeline::updateChanges() 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(); } } @@ -122,6 +173,8 @@ void PixelPipeline::updateChanges() void PixelPipeline::renderGL(Scene *scene) { m_targetFBO->bindFBO(); + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, m_width, m_height); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); diff --git a/src/pixelpipeline.h b/src/pixelpipeline.h index 38e07e8..25720ee 100644 --- a/src/pixelpipeline.h +++ b/src/pixelpipeline.h @@ -7,6 +7,7 @@ class FrameBuffer; class Texture; class Shader; class PixelMesh; +class MapScene; class PixelPipeline : public Pipeline { @@ -26,7 +27,8 @@ private: unsigned int m_vao, m_vbo; public: - PixelPipeline(int mapWidth, int mapHeight); + PixelPipeline(MapScene *map); + ~PixelPipeline(); void pushChange(const glm::vec2 &pos, const glm::vec3 &color); void updateChanges(); diff --git a/src/team.cpp b/src/team.cpp new file mode 100644 index 0000000..9c318e5 --- /dev/null +++ b/src/team.cpp @@ -0,0 +1,3 @@ +#include "team.h" + +// TODO Info functions diff --git a/src/team.h b/src/team.h new file mode 100644 index 0000000..7b9a747 --- /dev/null +++ b/src/team.h @@ -0,0 +1,115 @@ +#ifndef BEHAVIOR_H +#define BEHAVIOR_H + +#include + +#define DUDE_MEMORY_SIZE 128 +#define LIBRARY_SIZE 128 +#define COM_SIZE 32 + +enum Dir { + NORTH, + EAST, + SOUTH, + WEST, + NO_DIR = -1 +}; + +struct Coord +{ + int x; + int y; + + Coord(const Coord &c) : + x(c.x), y(c.y) {} + Coord(int x, int y) : + x(x), y(y) {} + Coord(Dir d = NO_DIR) + { + switch(d) + { + case NORTH : x= 0; y=-1; break; + case SOUTH : x= 0; y= 1; break; + case WEST : x=-1; y= 0; break; + case EAST : x= 1; y= 0; break; + default : x= 0; y= 0; break; + } + } + Coord operator+(const Coord &c) const + { return Coord(x+c.x, y+c.y);} + Coord& operator+=(const Coord &c) + { x+=c.x; y+=c.y; return *this; } + Coord operator+(Dir d) const + { return *this + Coord(d); } + Coord& operator+=(Dir d) + { return *this += Coord(d); } + Coord operator-(const Coord &c) const + { return Coord(x-c.x, y-c.y); } + Coord& operator-=(const Coord &c) + { x-=c.x; y-=c.y; return *this; } + Coord operator*(const Coord &c) const + { return Coord(x*c.x, y*c.y); } + Coord& operator*=(const Coord &c) + { x*=c.x; y*=c.y; return *this; } + Coord operator/(const Coord &c) const + { return Coord(x/c.x, y/c.y); } + Coord& operator/=(const Coord &c) + { x/=c.x; y/=c.y; return *this; } + int dist() const // manhatthan distance + { return abs(x) + abs(y); } + int operator~() const + { return dist(); } + static dist(const Coord &c1, const Coord &c2) + { return ~(c1-c2); } + int dist(const Coord &c) const + { return dist(*this, c); } +}; + +struct Com +{ + enum Flags { + BOOK1 = 0, + BOOK2 = 1, + BOOK3 = 2, + BOOK4 = 3, + + READ = 0, + WRITE = 4 + }; + + int flag; + char data[COM_SIZE]; +}; + +struct Action +{ + enum Type { + MOVE, + ATTACK, + PICK, + PUT, + WORK, + WAIT, + COLOR, + COMMUNICATE + }; + + Type type; + Dir dir; + Com com_data; +}; + +class Info +{ + // TODO +public: + bool success; + int inventory; + const Com& getCom(); + int getNear(Dir d); + int getInfo(Dir d); +}; + +typedef void (*BehaviorFunction)(Action *action, char *memory, const Info *info); + +#endif // BEHAVIOR_H diff --git a/teams/hello.cpp b/teams/hello.cpp index 6ee1d48..133a7b6 100644 --- a/teams/hello.cpp +++ b/teams/hello.cpp @@ -1,5 +1,4 @@ #include -#include // g++ -shared hello.cpp -o hello.dll diff --git a/teams/hello.dll b/teams/hello.dll new file mode 100644 index 0000000..d3f0b3a Binary files /dev/null and b/teams/hello.dll differ diff --git a/teams/plop.dll b/teams/plop.dll new file mode 100644 index 0000000..d3f0b3a Binary files /dev/null and b/teams/plop.dll differ diff --git a/teams/truc.dll b/teams/truc.dll new file mode 100644 index 0000000..d3f0b3a Binary files /dev/null and b/teams/truc.dll differ