dust3d/src/modelofflinerender.cpp

117 lines
2.9 KiB
C++

#include <QOpenGLFramebufferObjectFormat>
#include <QThread>
#include <QDebug>
#include "modelofflinerender.h"
ModelOfflineRender::ModelOfflineRender(QScreen *targetScreen) :
QOffscreenSurface(targetScreen),
m_context(nullptr),
m_mesh(nullptr)
{
create();
m_context = new QOpenGLContext();
QSurfaceFormat fmt = format();
fmt.setAlphaBufferSize(8);
fmt.setSamples(4);
setFormat(fmt);
m_context->setFormat(fmt);
m_context->create();
}
ModelOfflineRender::~ModelOfflineRender()
{
delete m_context;
m_context = nullptr;
destroy();
delete m_mesh;
}
void ModelOfflineRender::updateMesh(Mesh *mesh)
{
delete m_mesh;
m_mesh = mesh;
}
void ModelOfflineRender::setRenderThread(QThread *thread)
{
m_context->moveToThread(thread);
}
QImage ModelOfflineRender::toImage(const QSize &size)
{
QImage image;
m_context->makeCurrent(this);
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(16);
QOpenGLFramebufferObject *renderFbo = new QOpenGLFramebufferObject(size, format);
renderFbo->bind();
m_context->functions()->glViewport(0, 0, size.width(), size.height());
if (nullptr != m_mesh) {
int xRot = -30 * 16;
int yRot = 45 * 16;
int zRot = 0;
QMatrix4x4 proj;
QMatrix4x4 camera;
QMatrix4x4 world;
ModelShaderProgram *program = new ModelShaderProgram;
ModelMeshBinder meshBinder;
meshBinder.initialize();
meshBinder.hideFrames();
program->setUniformValue(program->lightPosLoc(), QVector3D(0, 0, 70));
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_LINE_SMOOTH);
camera.setToIdentity();
camera.translate(0, 0, -2.1);
world.setToIdentity();
world.rotate(180.0f - (xRot / 16.0f), 1, 0, 0);
world.rotate(yRot / 16.0f, 0, 1, 0);
world.rotate(zRot / 16.0f, 0, 0, 1);
proj.setToIdentity();
proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
program->bind();
program->setUniformValue(program->projMatrixLoc(), proj);
program->setUniformValue(program->mvMatrixLoc(), camera * world);
QMatrix3x3 normalMatrix = world.normalMatrix();
program->setUniformValue(program->normalMatrixLoc(), normalMatrix);
meshBinder.updateMesh(m_mesh);
meshBinder.paint();
meshBinder.cleanup();
program->release();
delete program;
m_mesh = nullptr;
}
m_context->functions()->glFlush();
image = renderFbo->toImage();
qDebug() << "Generated image size:" << image.size();
renderFbo->bindDefault();
delete renderFbo;
m_context->doneCurrent();
return image;
}