add option to draw trajectories

This commit is contained in:
ccolin 2021-01-03 19:55:04 +01:00
parent ec4017bb0f
commit 5326f294ce
9 changed files with 88 additions and 0 deletions

5
shaders/line.frag Normal file
View File

@ -0,0 +1,5 @@
uniform vec3 color;
void main() {
gl_FragColor = vec4(color, 1);
}

8
shaders/line.vert Normal file
View File

@ -0,0 +1,8 @@
attribute vec3 in_pos;
uniform mat4 proj;
uniform mat4 view;
void main() {
gl_Position = proj * view * vec4(in_pos, 1.0);
}

View File

@ -5,5 +5,7 @@
<file>main.frag</file> <file>main.frag</file>
<file>skybox.vert</file> <file>skybox.vert</file>
<file>skybox.frag</file> <file>skybox.frag</file>
<file>line.vert</file>
<file>line.frag</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -44,6 +44,38 @@ DroneController::DroneController(const QJsonObject &json)
} }
void DroneController::drawTrajectory(QOpenGLExtraFunctions *f, const Drone &d) const {
OpenGLWidget::instance->getLineProgram()->bind();
OpenGLWidget::instance->getLineProgram()->setUniformValue("color", 1, 0, .532);
size_t trajectory_len = 1;
for (const Waypoint &wp : d.getWaypoints()) {
if (wp.frame > frame) break;
trajectory_len++;
}
GLfloat trajectory[trajectory_len * 3] = {0};
size_t i = 0;
for (const Waypoint &wp : d.getWaypoints()) {
if (wp.frame > frame) break;
trajectory[i] = wp.pos.x();
trajectory[i + 1] = wp.pos.y();
trajectory[i + 2] = wp.pos.z();
i += 3;
}
trajectory[i] = d.getPos().x();
trajectory[i + 1] = d.getPos().y();
trajectory[i + 2] = d.getPos().z();
f->glEnableVertexAttribArray(0);
f->glBindBuffer(GL_ARRAY_BUFFER, 0);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, trajectory);
glLineWidth(2);
f->glDisable(GL_CULL_FACE);
f->glDrawArrays(GL_LINE_STRIP, 0, trajectory_len);
f->glEnable(GL_CULL_FACE);
OpenGLWidget::instance->getLineProgram()->release();
OpenGLWidget::instance->getMainProgram()->bind();
}
void DroneController::draw(QOpenGLExtraFunctions *f) const { void DroneController::draw(QOpenGLExtraFunctions *f) const {
const QVector<QPair<int, int>> &col = collisions[frame]; const QVector<QPair<int, int>> &col = collisions[frame];
for (const Drone &d : drones) { for (const Drone &d : drones) {
@ -60,6 +92,9 @@ void DroneController::draw(QOpenGLExtraFunctions *f) const {
sphere->draw(f, mat); sphere->draw(f, mat);
} }
OpenGLWidget::instance->getMainProgram()->setUniformValue("highlight", false); OpenGLWidget::instance->getMainProgram()->setUniformValue("highlight", false);
if (draw_trajectories) {
drawTrajectory(f, d);
}
} }
} }
@ -155,3 +190,9 @@ void DroneController::displaySpheres(double sphere_radius) {
bool DroneController::collides(const Drone &a, const Drone &b, double sqDist) { bool DroneController::collides(const Drone &a, const Drone &b, double sqDist) {
return (b.getPos() - a.getPos()).lengthSquared() < sqDist; return (b.getPos() - a.getPos()).lengthSquared() < sqDist;
} }
void DroneController::setDrawTrajectories(bool enable) {
draw_trajectories = enable;
OpenGLWidget::instance->update();
}

View File

@ -23,12 +23,15 @@ class DroneController : public QObject, public Painter {
double sphere_radius = 0; double sphere_radius = 0;
QTimer sphere_timer; QTimer sphere_timer;
QMap<int, QVector<QPair<int, int>>> collisions; QMap<int, QVector<QPair<int, int>>> collisions;
bool draw_trajectories = false;
static OpenGLMesh *sphere; static OpenGLMesh *sphere;
static const unsigned char sphere_neutral[]; static const unsigned char sphere_neutral[];
static bool collides(const Drone &a, const Drone &b, double radius); static bool collides(const Drone &a, const Drone &b, double radius);
void drawTrajectory(QOpenGLExtraFunctions *f, const Drone &d) const;
public: public:
DroneController(const QJsonObject &json); DroneController(const QJsonObject &json);
int getDuration() const; int getDuration() const;
@ -51,6 +54,7 @@ public slots:
void seek(int frame); void seek(int frame);
void computeCollisions(double sphere_radius); void computeCollisions(double sphere_radius);
void displaySpheres(double sphere_radius); void displaySpheres(double sphere_radius);
void setDrawTrajectories(bool enable);
}; };

View File

@ -89,6 +89,8 @@ void MainWindow::open(const QString &path) {
dc, &DroneController::computeCollisions); dc, &DroneController::computeCollisions);
connect(settings_pane, &SettingsPane::sphereRadiusChanged, connect(settings_pane, &SettingsPane::sphereRadiusChanged,
dc, &DroneController::displaySpheres); dc, &DroneController::displaySpheres);
connect(settings_pane, &SettingsPane::toggledTrajectories,
dc, &DroneController::setDrawTrajectories);
settings_pane->setEnabled(true); settings_pane->setEnabled(true);
glw.setPainter(dc); glw.setPainter(dc);

View File

@ -32,4 +32,5 @@ void OpenGLMesh::draw(QOpenGLExtraFunctions *f, const QMatrix4x4 &mat) const {
if (tex) tex->bind(); if (tex) tex->bind();
f->glDrawArrays(GL_TRIANGLES, 0, nverts); f->glDrawArrays(GL_TRIANGLES, 0, nverts);
if (tex) tex->release(); if (tex) tex->release();
f->glBindVertexArray(0);
} }

View File

@ -144,6 +144,20 @@ void OpenGLWidget::initializeGL() {
main_program.setUniformValue("tex", 0); main_program.setUniformValue("tex", 0);
main_program.release(); main_program.release();
if (!line_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/line.vert")) {
qFatal("Error compiling line.vert: %s", line_program.log().toLocal8Bit().constData());
}
if (!line_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/line.frag")) {
qFatal("Error compiling line.frag: %s", line_program.log().toLocal8Bit().constData());
}
line_program.bindAttributeLocation("in_pos", 0);
if (!line_program.link()) {
qFatal("Error linking the line shader program: %s", line_program.log().toLocal8Bit().constData());
}
line_program.bind();
line_program.setUniformValue("color", 0, 0, 0);
line_program.release();
loadSkybox(); loadSkybox();
loadGround(); loadGround();
@ -183,6 +197,11 @@ void OpenGLWidget::paintGL() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS); glDepthFunc(GL_LESS);
line_program.bind();
line_program.setUniformValue("proj", proj);
line_program.setUniformValue("view", view);
line_program.release();
main_program.bind(); main_program.bind();
main_program.setUniformValue("proj", proj); main_program.setUniformValue("proj", proj);
main_program.setUniformValue("view", view); main_program.setUniformValue("view", view);
@ -232,3 +251,7 @@ void OpenGLWidget::setPainter(const Painter *p) {
QOpenGLShaderProgram *OpenGLWidget::getMainProgram() { QOpenGLShaderProgram *OpenGLWidget::getMainProgram() {
return &main_program; return &main_program;
} }
QOpenGLShaderProgram *OpenGLWidget::getLineProgram() {
return &line_program;
}

View File

@ -28,6 +28,7 @@ class OpenGLWidget : public QOpenGLWidget, public QOpenGLExtraFunctions {
QOpenGLShaderProgram main_program; QOpenGLShaderProgram main_program;
QOpenGLShaderProgram skybox_program; QOpenGLShaderProgram skybox_program;
QOpenGLShaderProgram line_program;
GLuint skybox_tex; GLuint skybox_tex;
GLuint skybox_vao; GLuint skybox_vao;
GLuint skybox_vbo; GLuint skybox_vbo;
@ -56,6 +57,7 @@ public:
void paintGL() override; void paintGL() override;
void setPainter(const Painter *p); void setPainter(const Painter *p);
QOpenGLShaderProgram *getMainProgram(); QOpenGLShaderProgram *getMainProgram();
QOpenGLShaderProgram *getLineProgram();
signals: signals:
void initialized(); void initialized();