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_selection.cpp

219 lines
6.7 KiB
C++

/*
QGLView
Copyright (C) 2020 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_selection.h"
#include "qglview.h"
#include "glmesh.h"
#include <qad_types.h>
using namespace QGLEngineShaders;
RendererSelection::RendererSelection(Renderer * r_): r(r_),
fbo_selection(r->view, 6) {
sel_frame = Primitive::plane(2., 2.);
id_hover = 0;
line_thick_ = 2.;
scale_ = 0.5;
}
RendererSelection::~RendererSelection() {
delete sel_frame;
}
void RendererSelection::init(int width, int height) {
resize(width, height);
}
void RendererSelection::resize(int width, int height) {
line_thick_ = lineThickness() + 1.;
scale_ = 0.5 / appScale();
fbo_selection.enablePixelBuffer();
fbo_selection.resize(width * scale_, height * scale_);
//fbo_selection.setColorTextureFiltering(sbrSrcHover , GL_LINEAR);
//fbo_selection.setColorTextureFiltering(sbrSrcSelect, GL_LINEAR);
}
void RendererSelection::generateObjectsID(Scene & scene) {
ids.clear();
aim_ids.clear();
QList<int> passes = scene.geometries_used.keys();
foreach (int p, passes) {
QMapIterator<Mesh*, ObjectBaseList> it(scene.geometries_used[p]);
while (it.hasNext()) {
it.next();
foreach (ObjectBase * o, it.value()) {
uint id = qHash(o);
ids[id] = o;
o->id_ = id;
}
}
QMapIterator<int, QList<Light*>> lit(scene.lights_used);
while (lit.hasNext()) {
lit.next();
foreach (ObjectBase * o, lit.value()) {
uint id = qHash(o);
ids[id] = o;
aim_ids[id + 1] = o;
o->id_ = id;
}
}
foreach (Camera * o, scene.cameras_used) {
uint id = qHash(o);
ids[id] = o;
aim_ids[id + 1] = o;
o->id_ = id;
}
}
}
void RendererSelection::renderSelection(Scene & scene) {
QOpenGLShaderProgram * prog = 0;
QGLView * view = r->view;
MouseController & mc(view->mouse);
if (r->bindShader(Renderer::srSelectionFill, &prog)) {
mc.hov_objects.clear();
mc.hov_aims.clear();
id_hover = 0;
if (fbo_selection.queriedPoints() > 0) {
if (fbo_selection.queriedPoints() == 1) {
id_hover = fbo_selection.getPoint();
ObjectBase * o = ids.value(id_hover);
if (o)
mc.hov_objects << o;
else {
o = aim_ids.value(id_hover);
if (o)
mc.hov_aims << o;
}
//qDebug() << id_hover;
} else {
QVector<uint> points = fbo_selection.getPointsByte();
QSet<uint> ids_hover;
foreach (uint i, points)
ids_hover << i;
foreach (uint i, ids_hover) {
ObjectBase * o = ids.value(i);
if (o) mc.hov_objects << o;
o = aim_ids.value(i);
if (o) mc.hov_aims << o;
}
//qDebug() << ids_hover;
}
}
fbo_selection.bind();
fbo_selection.setWriteBuffers();
glEnableDepth();
glClearFramebuffer(QColor(0,0,0,0));
r->setUniformCamera(prog, view->camera());
r->renderObjects(scene, rpSolid);
r->renderObjects(scene, rpTransparent);
view->glClear(GL_DEPTH_BUFFER_BIT);
RendererService & rs(r->rend_service);
rs.drawLights();
rs.drawCameras();
rs.drawCurrentHandleObjects();
//mouse_rect = fbo_selection.rect();
if (r->mouse_rect.isNull())
fbo_selection.queryPoint(0, r->mouse_pos * scale_);
else
fbo_selection.queryPoints(0, QRect(r->mouse_rect.topLeft() * scale_,
r->mouse_rect.size() * scale_));
//qDebug() << id_hover;
fbo_selection.bindColorTexture(sbrSrcHover , sbrSrcHover );
fbo_selection.bindColorTexture(sbrSrcSelect, sbrSrcSelect);
fbo_selection.setWriteBuffers(QVector<int>() << sbrHovered << sbrSelected);
if (!view->hoverHalo_ && !view->selectionHalo_)
glClearFramebuffer(QColor(0,0,0,0), false);
else {
r->bindShader(Renderer::srSelectionHalo, &prog);
r->setUniformHalo(prog, "hover" , view->hoverHaloColor() , view->hoverHaloFillAlpha());
r->setUniformHalo(prog, "selection", view->selectionHaloColor(), view->selectionHaloFillAlpha());
prog->setUniformValue("has_hover" , view->hoverHalo_ && (id_hover > 0) ? 1.f : 0.f);
prog->setUniformValue("has_selection", view->selectionHalo_ ? 1.f : 0.f);
prog->setUniformValue("fb_hover" , (int)sbrSrcHover);
prog->setUniformValue("fb_selection", (int)sbrSrcSelect);
prog->setUniformValue("hover_id", QVector4D(float( id_hover & 0xFF) / 255.f,
float((id_hover >> 8 ) & 0xFF) / 255.f,
float((id_hover >> 16) & 0xFF) / 255.f,
float((id_hover >> 24) & 0xFF) / 255.f));
r->renderQuad(prog, r->quad, view->camera());
}
prog = r->shader_fxaa;
if (r->bindShader(prog)) {
r->setUniformCamera(prog, 0, true, fbo_selection.size());
fbo_selection.bindColorTexture(sbrHovered);
fbo_selection.setWriteBuffer(sbrHoveredFXAA);
r->renderQuad(prog, r->quad, 0, false);
fbo_selection.bindColorTexture(sbrSelected);
fbo_selection.setWriteBuffer(sbrSelectedFXAA);
r->renderQuad(prog, r->quad, 0, false);
}
fbo_selection.release();
}
}
void RendererSelection::renderSelectionFrame() {
QOpenGLShaderProgram * prog = 0;
if (r->bindShader(Renderer::srSelectionFrame, &prog)) {
QMatrix4x4 mat;
double mrx = r->mouse_rect.x(), mrw = r->mouse_rect.width() , vw = r->view->width();
double mry = r->mouse_rect.y(), mrh = r->mouse_rect.height(), vh = r->view->height();
mat.translate(-1. + (mrw + mrx*2) / vw, 1. - (mrh + mry*2) / vh, 0.);
mat.scale(mrw / vw, mrh / vh, 0.);
r->initQuad(sel_frame, mat);
prog->setUniformValue("size", QVector2D(mrw / vw, mrh / vh));
prog->setUniformValue("thickness", line_thick_);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
r->renderQuad(prog, sel_frame);
glDisable(GL_BLEND);
}
}
void RendererSelection::drawSelection(Framebuffer & fbo_out, int index_out) {
QOpenGLShaderProgram * prog = 0;
if (r->bindShader(Renderer::srSelectionApply, &prog)) {
fbo_selection.bindColorTextures();
fbo_out.bindColorTexture(index_out);
prog->setUniformValue("fb_out" , 0);
prog->setUniformValue("fb_hover" , (int)sbrHoveredFXAA );
prog->setUniformValue("fb_select", (int)sbrSelectedFXAA);
r->renderQuad(prog, r->quad, r->view->camera());
if (!r->mouse_rect.isNull()) {
renderSelectionFrame();
}
}
}