#include "fish_painter.h" #include "OBJ_Loader.h" #include #include #include FishPainter::~FishPainter() { if (texture) delete texture; } 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(); } texture = new QOpenGLTexture(QImage(":/textures/fish.jpg").mirrored()); vao.create(); {QOpenGLVertexArrayObject::Binder bind(&vao); vbo.create(); vbo.bind(); std::locale old_locale = std::locale::global(std::locale::classic()); // lmao posix sucks so much objl::Loader loader; if (!loader.LoadFile(":/meshes/fish.obj")) { qCritical() << "Unable to load fish mesh."; } std::locale::global(old_locale); std::vector verts = loader.LoadedMeshes[0].Vertices; n_verts = verts.size(); vbo.allocate(verts.data(), verts.size() * sizeof (objl::Vertex)); program.bind(); program.setAttributeBuffer("position", GL_FLOAT, offsetof(objl::Vertex, Position), 3, sizeof (objl::Vertex)); program.setAttributeBuffer("uv", GL_FLOAT, offsetof(objl::Vertex, TextureCoordinate), 2, sizeof (objl::Vertex)); program.enableAttributeArray("position"); program.enableAttributeArray("uv"); } } 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); texture->bind(); 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, n_verts); } } }