This commit is contained in:
Lendemor 2016-06-03 19:40:16 +02:00
commit 4dbec52004
18 changed files with 96 additions and 30 deletions

View File

@ -3,10 +3,10 @@
#include "image.h"
// windows MinGW
// g++ -shared realWorld.cpp -o realWorld.dll -I../include
// g++ -shared realWorld.cpp -o realWorld.dll -I../src -funsigned-char -std=c++11
// linux gcc
// g++ -shared realWorld.cpp -o realWorld.so -I../include -fPIC
// g++ -shared realWorld.cpp -o realWorld.so -I../src -fPIC -funsigned-char -std=c++11
extern "C" void generate(Map *mapPtr)
{

View File

@ -5,7 +5,6 @@ uniform sampler2D backMap;
uniform vec3 camera;
uniform vec2 worldSize;
uniform vec2 screenSize;
uniform float flatSphere;
uniform float surfaceRatio;

View File

@ -5,7 +5,6 @@ layout(location = 2)in vec2 inTexCoord;
layout(location = 1)in vec3 inNormal;
uniform float flatSphere;
uniform vec2 screenSize;
uniform mat4 mvp;
uniform vec3 camera;

View File

@ -4,7 +4,6 @@ uniform sampler2DRect colorMap;
uniform vec3 camera;
uniform vec2 worldSize;
uniform vec2 screenSize;
uniform float flatSphere;
uniform float surfaceRatio;

View File

@ -5,7 +5,6 @@ layout(location = 2)in vec2 inTexCoord;
layout(location = 1)in vec3 inNormal;
uniform float flatSphere;
uniform vec2 screenSize;
uniform mat4 mvp;
uniform vec3 camera;
@ -18,7 +17,7 @@ void main(void)
vec2 flatTexCoord = texCoord;
texCoord = mix(texCoord, flatTexCoord, vec2(flatSphere));
normal = inNormal.xyz;
vec4 flatPos = vec4(inTexCoord.x*2 -1, inTexCoord.y*2 -1, 0.0, 1.0);
vec4 flatPos = vec4((inTexCoord.x*2 -1)*camera.z, (inTexCoord.y*2 -1)*camera.z, 0.0, 1.0);
vec3 position = vec3(inPosition.xy, inPosition.z - 1);
vec4 projPos = mvp * vec4(position*camera.z, 1.0);
gl_Position = mix(projPos, flatPos, vec4(flatSphere));

View File

@ -33,6 +33,8 @@ struct Coord
default : x= 0; y= 0; break;
}
}
bool operator==(const Coord &c) const
{ return x==c.x&&y==c.y;}
Coord operator+(const Coord &c) const
{ return Coord(x+c.x, y+c.y);}
Coord& operator+=(const Coord &c)
@ -69,6 +71,13 @@ struct Coord
{ return dist(*this, c); }
int dist(int x, int y) const
{ return dist(*this, Coord(x, y)); }
};
struct CoordHash{
size_t operator()(const Coord& val) const{
return val.x+10000*val.y;
}
};
#endif // COORD_H

View File

@ -13,6 +13,8 @@
DrawWidget::DrawWidget(QWidget *parent) :
QOpenGLWidget(parent),
m_grabbedMouseLeft(false),
m_grabbedMouseRight(false),
m_Qt_fbo(NULL),
m_pipeline(NULL)
{
@ -94,11 +96,15 @@ void DrawWidget::stopSimulation()
void DrawWidget::mouseMoveEvent(QMouseEvent *event)
{
if(grabbedMouse && m_pipeline != NULL)
if(m_grabbedMouseLeft && m_pipeline != NULL)
{
m_pipeline->cameraMove(event->globalX() - lastMousePos.x(), event->globalY() - lastMousePos.y());
repaint();
}
if(m_grabbedMouseRight && m_pipeline != NULL)
{
m_pipeline->getToreillerPos(event->x(), event->y());
}
lastMousePos = event->globalPos();
}
@ -107,7 +113,10 @@ void DrawWidget::mousePressEvent(QMouseEvent* event)
switch(event->button())
{
case Qt::LeftButton :
grabbedMouse = true;
m_grabbedMouseLeft = true;
break;
case Qt::RightButton :
m_grabbedMouseRight = true;
break;
default:
break;
@ -125,7 +134,10 @@ void DrawWidget::mouseReleaseEvent(QMouseEvent* event)
switch(event->button())
{
case Qt::LeftButton :
grabbedMouse = false;
m_grabbedMouseLeft = false;
break;
case Qt::RightButton :
m_grabbedMouseRight = false;
break;
default:
break;

View File

@ -21,7 +21,8 @@ class DrawWidget : public QOpenGLWidget
// camera handling variables
QPoint lastMousePos;
bool grabbedMouse;
bool m_grabbedMouseLeft;
bool m_grabbedMouseRight;
MapScene *m_map;
MapScene *m_dummyMap;
FrameBuffer *m_Qt_fbo;

View File

@ -30,6 +30,7 @@ MainWindow::MainWindow(QWidget *parent) :
connect(ui->actionPlayPause, SIGNAL(toggled(bool)), this, SLOT(pauseSimu(bool)));
connect(ui->actionAction_step, SIGNAL(triggered(bool)), this, SLOT(stepSimu()));
connect(ui->actionStop, SIGNAL(triggered(bool)), this, SLOT(stopSimu()));
connect(ui->resetToDefaultAdvanced, SIGNAL(pressed()), this, SLOT(resetAdvancedToDefault()));
changeSimSpeed(ui->simSpeedSlider->value());
ui->advancedGroupBox->hide();
}
@ -75,6 +76,8 @@ void MainWindow::updateSimu()
ui->dateLabel->setText(QString::number(++m_date));
ui->populationLabel->setText(QString::number(p_simu->getPopulation()));
ui->drawWidget->updateDudesBehavior();
ui->drawWidget->setFlatSphere(ui->flatSphereSlider->value());
ui->drawWidget->setSurfaceRatio(ui->surfaceRatioSlider->value());
ui->drawWidget->repaint();
}
if(m_simSpeedChanged)
@ -100,6 +103,12 @@ void MainWindow::stopSimu()
delete p_simu;
}
void MainWindow::resetAdvancedToDefault()
{
ui->flatSphereSlider->setValue(0);
ui->surfaceRatioSlider->setValue(50);
}
void MainWindow::pauseSimu(bool pause)
{
m_paused = pause;

View File

@ -32,6 +32,7 @@ private slots:
void updateSimu();
void stepSimu();
void stopSimu();
void resetAdvancedToDefault();
void pauseSimu(bool);
};

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>744</width>
<height>490</height>
<width>683</width>
<height>499</height>
</rect>
</property>
<property name="windowTitle">
@ -190,14 +190,14 @@
<property name="bottomMargin">
<number>5</number>
</property>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Spherical / Flat</string>
</property>
</widget>
</item>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QSlider" name="flatSphereSlider">
<property name="enabled">
<bool>true</bool>
@ -225,14 +225,14 @@
</property>
</widget>
</item>
<item row="1" column="0">
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>surface ratio</string>
</property>
</widget>
</item>
<item row="1" column="1">
<item row="2" column="1">
<widget class="QSlider" name="surfaceRatioSlider">
<property name="enabled">
<bool>true</bool>
@ -263,6 +263,13 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QPushButton" name="resetToDefaultAdvanced">
<property name="text">
<string>Reset to default</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@ -66,6 +66,10 @@ public:
Coord &toreillerLoop(Coord &c)
{
while(c.x < 0)
c.x += m_width;
while(c.y < 0)
c.y += m_width;
// this is the shader implementation of the toreiller
Coord nbRevolutions(c.x/m_width, c.y/m_height);
if(std::abs(nbRevolutions.y % 2))

View File

@ -104,5 +104,6 @@ void MapScene::draw()
// clearing temporary data structures
m_updatedCoordMap.clear();
m_updatedCoordMap.rehash(0);
m_pixels.clear();
}

View File

@ -6,7 +6,7 @@
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <QMutex>
#include <map>
#include <unordered_map>
struct MapScene : public Map, public BasicScene
{
@ -48,7 +48,7 @@ private:
Pix(glm::vec2 p, glm::vec3 c) : pos(p), color(c) {}
};
std::vector<Pix> m_pixels;
std::map<Coord, int> m_updatedCoordMap;
std::unordered_map<Coord, int, CoordHash> m_updatedCoordMap;
};
#endif // MAPSCENE_H

View File

@ -8,7 +8,6 @@
#include "mapscene.h"
#include <parametricmesh.h>
#include <glm/ext.hpp>
#define SCROLL_SPEED 0.998f
class ToreillerGenerator : public MeshGenerator
@ -37,7 +36,7 @@ PixelPipeline::PixelPipeline(MapScene *map) :
{
m_width = 256;
m_height = 256;
m_surfaceRatio = 1;
m_surfaceRatio = 0;
m_flatSphere = 0;
m_map->setPipeline(this);
m_targetFBO = FrameBuffer::screen;
@ -72,14 +71,19 @@ PixelPipeline::PixelPipeline(MapScene *map) :
PixelPipeline::~PixelPipeline()
{
delete m_mapFBO;
delete m_mapTex;
// shaders
delete m_texMapShader;
delete m_renderShader;
delete m_map;
delete m_skyboxShader;
// textures
delete m_mapTex;
delete m_skyTexBack;
delete m_skyTexFront;
// framebuffers
delete m_mapFBO;
// meshes
delete m_toreiller;
delete m_map;
}
void PixelPipeline::updateChanges()
@ -108,7 +112,6 @@ void PixelPipeline::renderGL(Scene *scene)
m_skyboxShader->bind();
m_skyboxShader->bindVec3(m_skyboxShader->getLocation("camera"), m_camera);
m_renderShader->bindVec2(m_skyboxShader->getLocation("worldSize"), glm::vec2(m_mapWidth, m_mapHeight));
m_skyboxShader->bindVec2(m_skyboxShader->getLocation("screenSize"), glm::vec2(m_width, m_height));
m_skyboxShader->bindFloat(m_skyboxShader->getLocation("surfaceRatio"), m_surfaceRatio);
m_skyboxShader->bindFloat(m_skyboxShader->getLocation("flatSphere"), m_flatSphere);
m_skyTexFront->bind(0);
@ -125,7 +128,6 @@ void PixelPipeline::renderGL(Scene *scene)
m_renderShader->bind();
m_renderShader->bindVec3(m_renderShader->getLocation("camera"), m_camera);
m_renderShader->bindVec2(m_renderShader->getLocation("worldSize"), glm::vec2(m_mapWidth, m_mapHeight));
m_renderShader->bindVec2(m_renderShader->getLocation("screenSize"), glm::vec2(m_width, m_height));
m_renderShader->bindFloat(m_renderShader->getLocation("surfaceRatio"), m_surfaceRatio);
m_renderShader->bindFloat(m_renderShader->getLocation("flatSphere"), m_flatSphere);
m_mapTex->bind(0);
@ -145,6 +147,12 @@ void PixelPipeline::resizeGL(int w, int h)
m_view = glm::translate(glm::mat4(), glm::vec3(0, 0, -3));
}
void PixelPipeline::cameraMove(int x, int y)
{
m_camera.x -= 2*x/(m_camera.z*m_width);
m_camera.y += 2*y/(m_camera.z*m_height);
}
void PixelPipeline::cameraZoom(int nbScrolls)
{
while(nbScrolls != 0)
@ -162,6 +170,15 @@ void PixelPipeline::cameraZoom(int nbScrolls)
}
if(m_camera.z > m_mapHeight/4)
m_camera.z = m_mapHeight/4;
else if(m_camera.z < 0.4f)
m_camera.z = 0.4f;
else if(m_camera.z < 1)
m_camera.z = 1;
}
Coord PixelPipeline::getToreillerPos(int mouseX, int mouseY)
{
glm::vec2 pos(mouseX, mouseY);
pos /= glm::vec2(m_width, m_height); // part that depends on resolution
pos = (pos - glm::vec2(0.5f))*m_mapHeight/m_camera.z; // part that depends on camera zoom
pos += glm::vec2(m_camera.x + 0.5f, -m_camera.y + 0.5f)*m_mapHeight; // part that depends on camera offset
return Coord(pos.x, pos.y);
}

View File

@ -10,6 +10,7 @@ class Shader;
class PixelMesh;
class MapScene;
class Mesh;
class Coord;
class PixelPipeline : public Pipeline
{
@ -46,12 +47,14 @@ public:
virtual void renderGL(Scene *scene);
virtual void resizeGL(int w, int h);
void cameraMove(int x, int y) { m_camera.x -= x/(m_camera.z*m_width); m_camera.y += y/(m_camera.z*m_width); }
void cameraMove(int x, int y);
void cameraZoom(int nbScrolls);
void setSurfaceRatio(float surfaceRatio) { m_surfaceRatio = surfaceRatio; }
void setFlatSphere(float flatSphere) { m_flatSphere = flatSphere; }
void setShowToreiller(bool showToreiller) { m_showToreiller = showToreiller; }
Coord getToreillerPos(int mouseX, int mouseY);
};
#endif // PIXELPIPELINE_H

View File

@ -23,6 +23,12 @@ Simulation::Simulation(MapScene *_map, std::vector<BehaviorFunction> &_behaviors
}
}
Simulation::~Simulation()
{
for(Dude* d : m_dudes)
delete d;
}
void Simulation::update()
{
std::random_shuffle(m_dudes.begin(), m_dudes.end());
@ -55,7 +61,6 @@ void Simulation::handleAction(Dude *dude)
// initialisation
Coord currentPos(dude->getPos());
Coord targetPos = p_map->toreillerLoop(currentPos + Coord(action.dir));
Pixel &source = p_map->getPixel(currentPos);
Pixel &target = p_map->getPixel(targetPos);
dude->setSuccess(false);

View File

@ -15,6 +15,7 @@ private:
std::vector<Team> m_teams;
public:
Simulation(MapScene *_map, std::vector<BehaviorFunction> &_behaviors);
~Simulation();
MapScene* getMap() { return (MapScene*) p_map; }
int getPopulation(){return m_dudes.size();}