aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorccolin2021-01-03 12:30:16 +0100
committerccolin2021-01-03 12:30:16 +0100
commit928d45c3fbfb6b00d8e0b79b63934ebd080b9456 (patch)
tree9e6b4f457d3c3130aa57b183f868e378e9810f5a
parent8ad1cf1b89b8acae55e36d6bd4562dffd1bcc714 (diff)
refactor drawing code
-rw-r--r--src/drone.cc18
-rw-r--r--src/drone.hh4
-rw-r--r--src/drone_controller.cc32
-rw-r--r--src/drone_controller.hh6
-rw-r--r--src/main_window.cc3
-rw-r--r--src/opengl_mesh.cc15
-rw-r--r--src/opengl_mesh.hh7
-rw-r--r--src/opengl_widget.cc43
-rw-r--r--src/opengl_widget.hh12
9 files changed, 101 insertions, 39 deletions
diff --git a/src/drone.cc b/src/drone.cc
index 0be11a6..2c0fad8 100644
--- a/src/drone.cc
+++ b/src/drone.cc
@@ -4,6 +4,7 @@
#include "opengl_widget.hh"
#include <QJsonArray>
+#include <QDebug>
bool Drone::mesh_initialized = false;
@@ -11,14 +12,15 @@ OpenGLMesh *Drone::mesh = nullptr;
Drone::Drone(int id)
:id(id) {
+ OpenGLWidget *glw = OpenGLWidget::instance;
if (!mesh_initialized) {
+ glw->makeCurrent();
QVector<GLfloat> verts = load_obj(":/mdl/dji600.obj", LOAD_OBJ_NORMALS | LOAD_OBJ_UVS);
QOpenGLTexture *texture = new QOpenGLTexture(QImage(":/img/dji600.jpg").mirrored());
- mesh = new OpenGLMesh(verts, texture);
+ mesh = new OpenGLMesh(verts, texture, glw->getMainProgram());
mesh_initialized = true;
+ glw->doneCurrent();
}
- OpenGLWidget::instance->meshes.append(*mesh);
- mesh_id = OpenGLWidget::instance->meshes.size() - 1;
}
@@ -51,8 +53,6 @@ void Drone::setTo(int frame) {
break;
}
}
- OpenGLMesh &mesh = OpenGLWidget::instance->meshes[mesh_id];
- mesh.mat = QMatrix4x4();
if (next > -1 && prev == -1) {
pos = next_wp->pos;
} else if (prev > -1 && next == -1) {
@@ -60,11 +60,10 @@ void Drone::setTo(int frame) {
} else {
pos = lerp(prev_wp->pos, next_wp->pos, (double) (frame-prev) / (next-prev));
}
- mesh.mat.translate(pos);
}
-QVector3D Drone::getPos() const {
+const QVector3D Drone::getPos() const {
return pos;
}
@@ -72,3 +71,8 @@ QVector3D Drone::getPos() const {
int Drone::getId() const {
return id;
}
+
+
+const OpenGLMesh *Drone::getMesh() const {
+ return mesh;
+}
diff --git a/src/drone.hh b/src/drone.hh
index 6c43cc1..873bb27 100644
--- a/src/drone.hh
+++ b/src/drone.hh
@@ -20,7 +20,6 @@ class Drone {
static bool mesh_initialized;
QVector<Waypoint> waypoints;
- int mesh_id;
QVector3D pos;
int id;
@@ -29,8 +28,9 @@ public:
Drone(const QJsonObject &json);
const QVector<Waypoint> getWaypoints() const;
void setTo(int frame);
- QVector3D getPos() const;
+ const QVector3D getPos() const;
int getId() const;
+ const OpenGLMesh *getMesh() const;
};
diff --git a/src/drone_controller.cc b/src/drone_controller.cc
index f6edfb6..0be9844 100644
--- a/src/drone_controller.cc
+++ b/src/drone_controller.cc
@@ -3,6 +3,7 @@
#include <QJsonArray>
#include <QDebug>
+#include <QOpenGLShaderProgram>
DroneController::DroneController(const QJsonObject &json)
@@ -19,33 +20,26 @@ DroneController::DroneController(const QJsonObject &json)
}
}
- OpenGLWidget::instance->makeCurrent();
- QOpenGLTexture *ground_tex = new QOpenGLTexture(QImage(":/img/ground.jpg").mirrored());
- ground_tex->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear);
- ground_tex->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
- ground_tex->setWrapMode(QOpenGLTexture::MirroredRepeat);
- OpenGLMesh *ground = new OpenGLMesh({
- -1000, 0, -1000, 0, 1000, 0, 0, 0,
- 1000, 0, -1000, 0, 1000, 0, 1000, 0,
- -1000, 0, 1000, 0, 1000, 0, 0, 1000,
- 1000, 0, -1000, 0, 1000, 0, 1000, 0,
- -1000, 0, 1000, 0, 1000, 0, 0, 1000,
- 1000, 0, 1000, 0, 1000, 0, 1000, 1000,
- }, ground_tex);
- OpenGLWidget::instance->meshes.append(*ground);
- OpenGLWidget::instance->doneCurrent();
-
connect(&timer, &QTimer::timeout, this, &DroneController::step);
}
+void DroneController::draw(QOpenGLExtraFunctions *f) const {
+ for (const Drone &d : drones) {
+ QMatrix4x4 mat;
+ mat.translate(d.getPos());
+ d.getMesh()->draw(f, mat);
+ }
+}
+
+
int DroneController::getDuration() const {
return duration;
}
void DroneController::step() {
- for (Drone d : drones) {
+ for (Drone &d : drones) {
d.setTo(frame);
}
OpenGLWidget::instance->update();
@@ -111,7 +105,9 @@ void DroneController::computeCollisions(double sphere_radius) {
}
}
}
- seek(frame);
+ for (Drone &d : drones) {
+ d.setTo(frame);
+ }
}
diff --git a/src/drone_controller.hh b/src/drone_controller.hh
index 08dac42..bcf1a1a 100644
--- a/src/drone_controller.hh
+++ b/src/drone_controller.hh
@@ -3,11 +3,14 @@
#include "drone.hh"
+#include "opengl_widget.hh"
+
#include <QJsonObject>
#include <QTimer>
+#include <QOpenGLExtraFunctions>
-class DroneController : public QObject {
+class DroneController : public QObject, public Painter {
Q_OBJECT
int framerate;
@@ -22,6 +25,7 @@ class DroneController : public QObject {
public:
DroneController(const QJsonObject &json);
int getDuration() const;
+ void draw(QOpenGLExtraFunctions *f) const;
signals:
void frameChanged(int frame);
diff --git a/src/main_window.cc b/src/main_window.cc
index 26d9601..cd85ae7 100644
--- a/src/main_window.cc
+++ b/src/main_window.cc
@@ -81,6 +81,7 @@ void MainWindow::open(const QString &path) {
slider, &QSlider::setValue);
slider->setEnabled(true);
+ // Settings pane
connect(dc, &DroneController::collision, settings_pane, &SettingsPane::addCollision);
connect(settings_pane, &SettingsPane::sphereRadiusChanged,
[&](double _) { settings_pane->clearCollisions(); });
@@ -88,6 +89,8 @@ void MainWindow::open(const QString &path) {
dc, &DroneController::computeCollisions);
settings_pane->setEnabled(true);
+ glw.setPainter(dc);
+
dc->computeCollisions(.1);
pause();
}
diff --git a/src/opengl_mesh.cc b/src/opengl_mesh.cc
index 01a73ff..a1f5a23 100644
--- a/src/opengl_mesh.cc
+++ b/src/opengl_mesh.cc
@@ -4,8 +4,9 @@
#include <QOpenGLFunctions>
-OpenGLMesh::OpenGLMesh(QVector<float> verts, QOpenGLTexture *tex)
- :tex(tex) {
+OpenGLMesh::OpenGLMesh(QVector<float> verts, QOpenGLTexture *tex, QOpenGLShaderProgram *program)
+ :tex(tex),
+ program(program) {
OpenGLWidget::instance->makeCurrent();
QOpenGLExtraFunctions *glf = OpenGLWidget::instance;
nverts = verts.size() / 8;
@@ -24,3 +25,13 @@ OpenGLMesh::OpenGLMesh(QVector<float> verts, QOpenGLTexture *tex)
glf->glBindVertexArray(0);
OpenGLWidget::instance->doneCurrent();
}
+
+
+void OpenGLMesh::draw(QOpenGLExtraFunctions *f, const QMatrix4x4 &mat) const {
+ program->bind();
+ program->setUniformValue("model", mat);
+ f->glBindVertexArray(vao);
+ tex->bind();
+ f->glDrawArrays(GL_TRIANGLES, 0, nverts);
+ tex->release();
+}
diff --git a/src/opengl_mesh.hh b/src/opengl_mesh.hh
index 5038816..7cffece 100644
--- a/src/opengl_mesh.hh
+++ b/src/opengl_mesh.hh
@@ -4,15 +4,18 @@
#include <QMatrix4x4>
#include <QVector>
#include <QOpenGLTexture>
+#include <QOpenGLShaderProgram>
+#include <QOpenGLExtraFunctions>
struct OpenGLMesh {
GLuint vao, vbo;
unsigned nverts;
- QMatrix4x4 mat;
QOpenGLTexture *tex;
+ QOpenGLShaderProgram *program;
- OpenGLMesh(QVector<float> verts, QOpenGLTexture *tex);
+ OpenGLMesh(QVector<float> verts, QOpenGLTexture *tex, QOpenGLShaderProgram *program);
+ void draw(QOpenGLExtraFunctions *f, const QMatrix4x4 &mat) const;
};
diff --git a/src/opengl_widget.cc b/src/opengl_widget.cc
index adc851e..d69af61 100644
--- a/src/opengl_widget.cc
+++ b/src/opengl_widget.cc
@@ -96,6 +96,22 @@ void OpenGLWidget::loadSkybox() {
}
+void OpenGLWidget::loadGround() {
+ QOpenGLTexture *ground_tex = new QOpenGLTexture(QImage(":/img/ground.jpg").mirrored());
+ ground_tex->setMagnificationFilter(QOpenGLTexture::LinearMipMapLinear);
+ ground_tex->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);
+ ground_tex->setWrapMode(QOpenGLTexture::MirroredRepeat);
+ ground = new OpenGLMesh({
+ -1000, 0, -1000, 0, 1000, 0, 0, 0,
+ 1000, 0, -1000, 0, 1000, 0, 1000, 0,
+ -1000, 0, 1000, 0, 1000, 0, 0, 1000,
+ 1000, 0, -1000, 0, 1000, 0, 1000, 0,
+ -1000, 0, 1000, 0, 1000, 0, 0, 1000,
+ 1000, 0, 1000, 0, 1000, 0, 1000, 1000,
+ }, ground_tex, &main_program);
+}
+
+
void OpenGLWidget::initializeGL() {
initializeOpenGLFunctions();
GLint major, minor;
@@ -123,6 +139,7 @@ void OpenGLWidget::initializeGL() {
main_program.release();
loadSkybox();
+ loadGround();
glClearColor(1, 1, 1, 0);
glEnable(GL_DEPTH_TEST);
@@ -163,13 +180,15 @@ void OpenGLWidget::paintGL() {
main_program.setUniformValue("view", view);
glActiveTexture(GL_TEXTURE0);
- for (const OpenGLMesh &mesh : meshes) {
- main_program.setUniformValue("model", mesh.mat);
- glBindVertexArray(mesh.vao);
- mesh.tex->bind();
- glDrawArrays(GL_TRIANGLES, 0, mesh.nverts);
- mesh.tex->release();
- }
+ ground->draw(this, QMatrix4x4());
+ if (painter) painter->draw(this);
+ // for (const OpenGLMesh &mesh : meshes) {
+ // main_program.setUniformValue("model", mesh.mat);
+ // glBindVertexArray(mesh.vao);
+ // mesh.tex->bind();
+ // glDrawArrays(GL_TRIANGLES, 0, mesh.nverts);
+ // mesh.tex->release();
+ // }
main_program.release();
}
@@ -203,3 +222,13 @@ void OpenGLWidget::wheelEvent(QWheelEvent *e) {
cam_dist -= e->angleDelta().y() / 1000. * cam_dist;
update();
}
+
+
+void OpenGLWidget::setPainter(const Painter *p) {
+ painter = p;
+}
+
+
+QOpenGLShaderProgram *OpenGLWidget::getMainProgram() {
+ return &main_program;
+}
diff --git a/src/opengl_widget.hh b/src/opengl_widget.hh
index 785a17f..1bc2bbc 100644
--- a/src/opengl_widget.hh
+++ b/src/opengl_widget.hh
@@ -13,6 +13,12 @@
#define FOV 70
+class Painter {
+public:
+ virtual void draw(QOpenGLExtraFunctions *f) const = 0;
+};
+
+
class OpenGLWidget : public QOpenGLWidget, public QOpenGLExtraFunctions {
Q_OBJECT
@@ -25,8 +31,12 @@ class OpenGLWidget : public QOpenGLWidget, public QOpenGLExtraFunctions {
GLuint skybox_tex;
GLuint skybox_vao;
GLuint skybox_vbo;
+ OpenGLMesh *ground;
void loadSkybox();
+ void loadGround();
+
+ const Painter *painter = nullptr;
protected:
virtual void mousePressEvent(QMouseEvent *e);
@@ -44,6 +54,8 @@ public:
void initializeGL() override;
void resizeGL(int w, int h) override;
void paintGL() override;
+ void setPainter(const Painter *p);
+ QOpenGLShaderProgram *getMainProgram();
signals:
void initialized();