This repository has been archived on 2020-09-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
libs/qglengine/renderer_service.cpp

137 lines
3.8 KiB
C++

/*
QGLView
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define GL_GLEXT_PROTOTYPES
#include <QOpenGLExtraFunctions>
#include "renderer_service.h"
#include "renderer.h"
#include "qglview.h"
#include "glmesh.h"
#include <qad_types.h>
using namespace QGLEngineShaders;
RendererService::RendererService(Renderer * r_): r(r_) {
line_width = 1;
axis_camera = new Camera();
axis_camera->setAim(QVector3D());
axis_camera->setFOV(45.);
axis_mesh = Primitive::arrow(12);
axis_objects.resize(3);
const QVector3D _rot[3] = {QVector3D(0,1,0), QVector3D(-1,0,0), QVector3D(0,0,1)};
for (int i = 0; i < 3; ++i) {
axis_objects[i].color = QVector4D(0,0,0,1);
axis_objects[i].color[i] = 1.;
QMatrix4x4 m; m.rotate(90., _rot[i]);
m.transposed().copyDataTo(axis_objects[i].modelmatrix);
}
box_vp_scale = 1.;
box_mesh = Primitive::cube();
}
RendererService::~RendererService() {
delete box_mesh;
delete axis_camera;
delete axis_mesh;
}
void RendererService::init(int width, int height) {
axis_mesh->loadObjects(r->view, axis_objects);
resize(width, height);
}
void RendererService::resize(int width, int height) {
axis_viewport = preferredIconSize(10.);
line_width = lineThickness();
box_vp_scale = 30. * appScale() / qMax(qMin(width, height), 1);
//qDebug() << axis_viewport;
}
void RendererService::fillBoxObjects() {
box_objects.clear();
Object o;
QList<Light*> ll = r->view->scene()->lights_used;
QMatrix4x4 v_mat = r->view->camera()->viewMatrix() * r->view->camera()->offsetMatrix();
QMatrix4x4 lmat;
double vps = tan(r->view->camera()->FOV() / 2. * deg2rad) * box_vp_scale;
foreach (Light * l, ll) {
QVector4D lpos = QVector4D(l->worldPos(), 1.);
double dist = -(v_mat * lpos).z();
lmat.translate(lpos.toVector3D());
lmat.scale(dist * vps);
lmat.transposed().copyDataTo(o.modelmatrix);
box_objects << o;
}
}
void RendererService::setObjectsColor(QVector<Object> & ol, QColor col) {
QVector4D cv = QColor2QVector(col);
for (int i = 0; i < ol.size(); ++i)
ol[i].color = cv;
}
void RendererService::renderService() {
QOpenGLShaderProgram * prog = 0;
QOpenGLExtraFunctions * f = r->view;
if (r->bindShader(Renderer::srService, &prog)) {
f->glEnable(GL_MULTISAMPLE);
glEnableDepth();
f->glClear(GL_DEPTH_BUFFER_BIT);
glEnableDepth();
/// lights
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_CULL_FACE);
r->setUniformCamera(prog, r->view->camera());
fillBoxObjects();
setObjectsColor(box_objects, Qt::white);
glLineWidth(line_width*3);
box_mesh->loadObjects(f, box_objects);
box_mesh->draw(f, box_objects.size());
setObjectsColor(box_objects, Qt::black);
glLineWidth(line_width);
box_mesh->loadObjects(f, box_objects);
box_mesh->draw(f, box_objects.size());
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
/// axis
f->glViewport(0, 0, axis_viewport.width(), axis_viewport.height());
axis_camera->setPos(-r->view->camera()->direction() * 3.);
r->setUniformCamera(prog, axis_camera, true, axis_viewport);
//axis_mesh->loadObjects(f, axis_objects);
axis_mesh->draw(f, axis_objects.size());
f->glViewport(0, 0, r->view->width(), r->view->height());
f->glDisable(GL_MULTISAMPLE);
}
}