84 lines
2.3 KiB
C++
84 lines
2.3 KiB
C++
#include "fish_painter.h"
|
|
|
|
#include "OBJ_Loader.h"
|
|
#include <QtMath>
|
|
#include <locale>
|
|
#include <QImage>
|
|
|
|
|
|
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<objl::Vertex> 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<Fish> 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);
|
|
}
|
|
}
|
|
}
|