#include "fish_painter.h" #include const GLfloat vertices[] = { 1, 0, 0, -1, .5, 0, -1, -.5, 0, }; void FishPainter::create(QOpenGLExtraFunctions *glf) { (void) glf; if (!program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/fish.vert")) { qCritical() << program.log(); } if (!program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/fish.frag")) { qCritical() << program.log(); } if (!program.link()) { qCritical() << program.log(); } vao.create(); {QOpenGLVertexArrayObject::Binder bind(&vao); vbo.create(); vbo.bind(); vbo.allocate(vertices, 9 * sizeof (GLfloat)); program.bind(); program.setAttributeBuffer("position", GL_FLOAT, 0, 3); program.enableAttributeArray("position"); } } void FishPainter::paint(QOpenGLExtraFunctions *glf, const QMatrix4x4 &projection, const QMatrix4x4 &view, const std::vector fishes) { const QVector3D X(1, 0, 0); {QOpenGLVertexArrayObject::Binder bind(&vao); program.setUniformValue("projection", projection); program.setUniformValue("view", view); QMatrix4x4 model; for (const Fish &fish : fishes) { model.setToIdentity(); model.translate(fish.position); if (!fish.velocity.isNull()) { double dot = QVector3D::dotProduct(X, fish.velocity); double angle = qAcos(dot / fish.velocity.length()); if (angle != 0) { model.rotate(qRadiansToDegrees(angle), QVector3D::crossProduct(X, fish.velocity)); } } program.setUniformValue("model", model); glf->glDrawArrays(GL_TRIANGLES, 0, 3); } } }