/* 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 . */ #define GL_GLEXT_PROTOTYPES #include #include "renderer_service.h" #include "renderer.h" #include "qglview.h" #include "glmesh.h" #include 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 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 & 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); } }