shadows basically works
This commit is contained in:
226
src/core/view/glwidget.cpp
Normal file
226
src/core/view/glwidget.cpp
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "glwidget.h"
|
||||
|
||||
#include "qglview.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
|
||||
GLWidget::GLWidget(QWidget * parent): QWidget(parent) {
|
||||
view_ = new QGLView();
|
||||
// view_->setFlags(windowFlags() | Qt::FramelessWindowHint);
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay = new QVBoxLayout(this);
|
||||
lay->addWidget(container);
|
||||
lay->setContentsMargins(0, 0, 0, 0);
|
||||
lay->setSpacing(0);
|
||||
setMouseTracking(true);
|
||||
setWindowIcon(QIcon("://icons/qglview.png"));
|
||||
connect(view_, &QGLView::doubleClick, this, &GLWidget::viewDoubleClicked);
|
||||
}
|
||||
|
||||
|
||||
Renderer * GLWidget::renderer() {
|
||||
return &(view_->renderer_);
|
||||
}
|
||||
|
||||
|
||||
Scene * GLWidget::scene() {
|
||||
return view_->scene();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::lineWidth() const {
|
||||
return view_->lineWidth();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::FOV() const {
|
||||
return view_->FOV();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::depthStart() const {
|
||||
return view_->depthStart();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isLightEnabled() const {
|
||||
return view_->isLightEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isGrabMouseEnabled() const {
|
||||
return view_->isGrabMouseEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseRotateEnabled() const {
|
||||
return view_->isMouseRotateEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isMouseSelectionEnabled() const {
|
||||
return view_->isMouseSelectionEnabled();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isCameraOrbit() const {
|
||||
return view_->isCameraOrbit();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isHoverHaloEnabled() const {
|
||||
return view_->isHoverHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::hoverHaloColor() const {
|
||||
return view_->hoverHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::hoverHaloFillAlpha() const {
|
||||
return view_->hoverHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
bool GLWidget::isSelectionHaloEnabled() const {
|
||||
return view_->isSelectionHaloEnabled();
|
||||
}
|
||||
|
||||
|
||||
QColor GLWidget::selectionHaloColor() const {
|
||||
return view_->selectionHaloColor();
|
||||
}
|
||||
|
||||
|
||||
qreal GLWidget::selectionHaloFillAlpha() const {
|
||||
return view_->selectionHaloFillAlpha();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::addObject(ObjectBase * o) {
|
||||
view_->scene()->addObject(o);
|
||||
}
|
||||
|
||||
|
||||
QByteArray GLWidget::saveCamera() {
|
||||
return view_->saveCamera();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::restoreCamera(const QByteArray & ba) {
|
||||
view_->restoreCamera(ba);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::stop() {
|
||||
view_->stop();
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::start(float freq) {
|
||||
view_->start(freq);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLineWidth(const qreal & arg) {
|
||||
view_->setLineWidth(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setFOV(const qreal & arg) {
|
||||
view_->setFOV(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setDepthStart(const qreal & arg) {
|
||||
view_->setDepthStart(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setLightEnabled(const bool & arg) {
|
||||
view_->setLightEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setGrabMouseEnabled(const bool & arg) {
|
||||
view_->setGrabMouseEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseRotateEnabled(const bool & arg) {
|
||||
view_->setMouseRotateEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setMouseSelectionEnabled(const bool & arg) {
|
||||
view_->setMouseSelectionEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setCameraOrbit(const bool & arg) {
|
||||
view_->setCameraOrbit(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloEnabled(const bool & arg) {
|
||||
view_->setHoverHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloColor(const QColor & arg) {
|
||||
view_->setHoverHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setHoverHaloFillAlpha(const qreal & arg) {
|
||||
view_->setHoverHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloEnabled(const bool & arg) {
|
||||
view_->setSelectionHaloEnabled(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloColor(const QColor & arg) {
|
||||
view_->setSelectionHaloColor(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::setSelectionHaloFillAlpha(const qreal & arg) {
|
||||
view_->setSelectionHaloFillAlpha(arg);
|
||||
}
|
||||
|
||||
|
||||
void GLWidget::viewDoubleClicked() {
|
||||
if (view_->windowState() == Qt::WindowFullScreen) {
|
||||
view_->showNormal();
|
||||
container = QWidget::createWindowContainer(view_, this);
|
||||
lay->addWidget(container);
|
||||
container->show();
|
||||
} else {
|
||||
view_->setParent(nullptr);
|
||||
view_->showFullScreen();
|
||||
lay->removeWidget(container);
|
||||
}
|
||||
}
|
||||
102
src/core/view/glwidget.h
Normal file
102
src/core/view/glwidget.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
QGL GLWidget
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include "qglengine_core_export.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
|
||||
class QGLView;
|
||||
class ObjectBase;
|
||||
class Scene;
|
||||
class Renderer;
|
||||
|
||||
class QGLENGINE_CORE_EXPORT GLWidget: public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY(qreal FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY(qreal depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY(qreal hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY(qreal selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
|
||||
public:
|
||||
explicit GLWidget(QWidget * parent = nullptr);
|
||||
QGLView * view() { return view_; }
|
||||
Renderer * renderer();
|
||||
Scene * scene();
|
||||
|
||||
QColor backColor() const;
|
||||
qreal lineWidth() const;
|
||||
qreal FOV() const;
|
||||
qreal depthStart() const;
|
||||
QColor ambientColor() const;
|
||||
bool isLightEnabled() const;
|
||||
bool isGrabMouseEnabled() const;
|
||||
bool isMouseRotateEnabled() const;
|
||||
bool isMouseSelectionEnabled() const;
|
||||
bool isCameraOrbit() const;
|
||||
bool isHoverHaloEnabled() const;
|
||||
QColor hoverHaloColor() const;
|
||||
qreal hoverHaloFillAlpha() const;
|
||||
bool isSelectionHaloEnabled() const;
|
||||
QColor selectionHaloColor() const;
|
||||
qreal selectionHaloFillAlpha() const;
|
||||
|
||||
void addObject(ObjectBase * o);
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
|
||||
public slots:
|
||||
void stop();
|
||||
void start(float freq = 0.0);
|
||||
void setLineWidth(const qreal & arg);
|
||||
void setFOV(const qreal & arg);
|
||||
void setDepthStart(const qreal & arg);
|
||||
void setLightEnabled(const bool & arg);
|
||||
void setGrabMouseEnabled(const bool & arg);
|
||||
void setMouseRotateEnabled(const bool & arg);
|
||||
void setMouseSelectionEnabled(const bool & arg);
|
||||
void setCameraOrbit(const bool & arg);
|
||||
void setHoverHaloEnabled(const bool & arg);
|
||||
void setHoverHaloColor(const QColor & arg);
|
||||
void setHoverHaloFillAlpha(const qreal & arg);
|
||||
void setSelectionHaloEnabled(const bool & arg);
|
||||
void setSelectionHaloColor(const QColor & arg);
|
||||
void setSelectionHaloFillAlpha(const qreal & arg);
|
||||
|
||||
private slots:
|
||||
void viewDoubleClicked();
|
||||
|
||||
private:
|
||||
QWidget * container;
|
||||
QGLView * view_;
|
||||
QLayout * lay;
|
||||
};
|
||||
|
||||
#endif // GLWIDGET_H
|
||||
300
src/core/view/mouse_controller.cpp
Normal file
300
src/core/view/mouse_controller.cpp
Normal file
@@ -0,0 +1,300 @@
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mouse_controller.h"
|
||||
|
||||
#include "glmesh.h"
|
||||
#include "qglview.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <qad_types.h>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
MouseController::MouseController(QGLView * view_): view(view_) {
|
||||
app_scale = 1;
|
||||
lastPos = QPoint(-1, -1);
|
||||
cur_action = RendererService::haNoAction;
|
||||
sel_button = Qt::LeftButton;
|
||||
sel_mod = Qt::ControlModifier;
|
||||
mouse_first = mouseSelect_ = mouseRotate_ = cameraOrbit_ = canSelect_ = true;
|
||||
grabMouse_ = mouse_sec = selecting_ = customMouseMove_ = false;
|
||||
}
|
||||
|
||||
|
||||
MouseController::~MouseController() {}
|
||||
|
||||
|
||||
void MouseController::resize() {
|
||||
mouse_first = true;
|
||||
app_scale = appScale();
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseReleaseEvent(QMouseEvent * e) {
|
||||
if (cur_action != RendererService::haNoAction) {
|
||||
mouseMoveEvent(e);
|
||||
return;
|
||||
}
|
||||
bool add_ts = e->modifiers().testFlag(sel_mod);
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
canSelect_ = true;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
view->scene()->selectObjects(hov_objects.toList(), add_ts);
|
||||
return;
|
||||
}
|
||||
if (canSelect_ && mouseSelect_) {
|
||||
if ((lastPos - downPos).manhattanLength() < QApplication::startDragDistance()) {
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
// qDebug() << hov_objects << hov_aims;
|
||||
if (hov_objects.isEmpty() && hov_aims.isEmpty()) {
|
||||
view->scene()->clearSelection();
|
||||
} else {
|
||||
if (!hov_objects.isEmpty()) view->scene()->selectObject(hov_objects[0], add_ts);
|
||||
if (!hov_aims.isEmpty()) {
|
||||
view->scene()->selectObject(hov_aims[0], add_ts);
|
||||
hov_aims[0]->setAimSelected(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e->button() == Qt::RightButton) {
|
||||
if (view->renderer_.edit_mode && !view->scene()->selectedObjects().isEmpty())
|
||||
view->popupMenu(
|
||||
#if QT_VERSION_MAJOR <= 5
|
||||
((QMouseEvent *)e)->globalPos()
|
||||
#else
|
||||
((QMouseEvent *)e)->globalPosition().toPoint()
|
||||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
canSelect_ = e->buttons() == 0;
|
||||
emit view->glMouseReleaseEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mousePressEvent(QMouseEvent * e) {
|
||||
QPoint cpos = e->pos() * view->devicePixelRatio();
|
||||
downPos = cpos;
|
||||
if (cur_action != RendererService::haNoAction && e->buttons() == Qt::LeftButton) {
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
selecting_ = false;
|
||||
view->renderer_.mouse_rect = QRect();
|
||||
return;
|
||||
}
|
||||
if (!QRect(QPoint(), view->pixelSize()).contains(cpos)) return;
|
||||
lastPos = cpos;
|
||||
downPos = cpos;
|
||||
emit view->glMousePressEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseMoveEvent(QMouseEvent * e) {
|
||||
QPoint cpos = e->pos() * view->devicePixelRatio();
|
||||
if (cur_action != RendererService::haNoAction && (e->buttons() == Qt::LeftButton)) {
|
||||
RendererService & rs(view->renderer_.rend_service);
|
||||
ObjectBaseList objects = view->scene()->selectedObjects(true);
|
||||
QVector<int> axis;
|
||||
switch (cur_action) {
|
||||
case RendererService::haMove:
|
||||
if (cur_handle.testFlag(RendererService::hmMoveX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmMoveZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haRotate:
|
||||
if (cur_handle.testFlag(RendererService::hmRotateX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmRotateZ)) axis << 2;
|
||||
break;
|
||||
case RendererService::haScale:
|
||||
if (cur_handle.testFlag(RendererService::hmScaleX)) axis << 0;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleY)) axis << 1;
|
||||
if (cur_handle.testFlag(RendererService::hmScaleZ)) axis << 2;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
QVector<QVector3D> scales;
|
||||
foreach(int a, axis) {
|
||||
QVector3D axe_vector;
|
||||
axe_vector[a] = 1.;
|
||||
QMatrix4x4 axis_mat = view->camera()->fullViewMatrix() * rs.axis_mat;
|
||||
QVector3D center_screen = axis_mat.map(rs.selection_center);
|
||||
QVector3D axe_screen = (axis_mat.map(rs.selection_center + axe_vector) - center_screen).normalized();
|
||||
QVector3D mouse_vector(cpos - lastPos);
|
||||
mouse_vector[1] *= -1.;
|
||||
if (cur_action == RendererService::haMove) {
|
||||
double len_scl = 1. / QVector3D(axe_screen.x(), axe_screen.y(), 1.E-6).length();
|
||||
mouse_vector /= QVector3D(view->pixelWidth(), view->pixelHeight(), 1);
|
||||
mouse_vector *= -center_screen.z() * len_scl;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
QMatrix4x4 pmat;
|
||||
foreach(ObjectBase * o, objects) {
|
||||
pmat.setToIdentity();
|
||||
if (o->parent()) pmat = o->parent()->worldTransform().inverted();
|
||||
QVector3D dv = pmat.mapVector(axe_vector);
|
||||
if (o->isAimSelected()) {
|
||||
AimedObject * ao = (AimedObject *)o;
|
||||
ao->setAim(ao->aim() + dv);
|
||||
} else
|
||||
o->move(dv);
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haRotate) {
|
||||
axe_screen.setZ(0.);
|
||||
axe_screen.normalize();
|
||||
QVector3D norm = QVector3D(axe_screen.y(), -axe_screen.x(), 0.);
|
||||
axe_vector *= QVector3D::dotProduct(mouse_vector, norm) / 2. / app_scale;
|
||||
foreach(ObjectBase * o, objects)
|
||||
o->setRotation(o->rotation() + axe_vector);
|
||||
}
|
||||
if (cur_action == RendererService::haScale) {
|
||||
mouse_vector /= QVector3D(view->pixelWidth(), view->pixelHeight(), 1);
|
||||
mouse_vector *= 3. / app_scale;
|
||||
axe_vector *= QVector3D::dotProduct(axe_screen, mouse_vector);
|
||||
scales << axe_vector;
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haScale) {
|
||||
double sc = 0., max = 0.;
|
||||
foreach(const QVector3D & s, scales) {
|
||||
double v = QVector3D::dotProduct(s, QVector3D(1, 1, 1));
|
||||
sc += v;
|
||||
max = qMax(max, qAbs(v));
|
||||
}
|
||||
sc = max * (sc > 0. ? 1. : -1);
|
||||
QVector3D axe_vector;
|
||||
foreach(int a, axis)
|
||||
axe_vector[a] = 1.;
|
||||
foreach(ObjectBase * o, objects)
|
||||
o->scale(QVector3D(1, 1, 1) + (axe_vector * sc));
|
||||
QCursor::setPos(view->mapToGlobal(downPos / view->devicePixelRatio()));
|
||||
} else {
|
||||
lastPos = cpos;
|
||||
}
|
||||
emit view->objectsPositionChanged();
|
||||
return;
|
||||
}
|
||||
if (selecting_) {
|
||||
view->renderer_.mouse_rect = QRect(downPos, cpos).normalized();
|
||||
return;
|
||||
}
|
||||
if (e->buttons().testFlag(Qt::LeftButton)) {
|
||||
if ((cpos - downPos).manhattanLength() >= QApplication::startDragDistance()) {
|
||||
selecting_ = true;
|
||||
canSelect_ = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
QRect g_rect(QPoint(), view->pixelSize());
|
||||
if (mouseRotate_) {
|
||||
float dx = cpos.x() - lastPos.x();
|
||||
float dy = cpos.y() - lastPos.y();
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON)) {
|
||||
if (cameraOrbit_) {
|
||||
view->camera()->orbitZ(dx / 4.f);
|
||||
view->camera()->orbitXY(dy / 4.f);
|
||||
} else {
|
||||
view->camera()->rotateZ(-dx / 4.f);
|
||||
view->camera()->rotateX(-dy / 4.f);
|
||||
}
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
} else if (e->buttons().testFlag(Qt::RightButton)) {
|
||||
float ad = view->camera()->distance();
|
||||
view->camera()->moveLeft(dx / 1000.f * ad);
|
||||
view->camera()->moveUp(dy / 1000.f * ad);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
}
|
||||
if (customMouseMove_) emit view->customMouseMoveEvent(cpos, lastPos, e->buttons());
|
||||
lastPos = cpos;
|
||||
if (e->buttons() == 0) {
|
||||
cur_handle = QFlags<RendererService::HandleMesh>();
|
||||
cur_action = RendererService::haNoAction;
|
||||
Qt::CursorShape cs = Qt::CrossCursor;
|
||||
if (view->renderer_.edit_mode) {
|
||||
uint hid = view->renderer_.rend_selection.id_hover;
|
||||
cur_handle = (RendererService::HandleMesh)hid;
|
||||
if (hid >= RendererService::hmMoveX && hid <= RendererService::hmMaxMove) {
|
||||
cur_action = RendererService::haMove;
|
||||
cs = Qt::SizeAllCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmRotateX && hid <= RendererService::hmMaxRotate) {
|
||||
cur_action = RendererService::haRotate;
|
||||
cs = Qt::PointingHandCursor;
|
||||
}
|
||||
if (hid >= RendererService::hmScaleX && hid <= RendererService::hmMaxScale) {
|
||||
cur_action = RendererService::haScale;
|
||||
cs = Qt::SplitHCursor;
|
||||
}
|
||||
}
|
||||
if (cur_action == RendererService::haNoAction) cur_handle = QFlags<RendererService::HandleMesh>();
|
||||
view->setCursor(cs);
|
||||
view->renderer_.rend_service.current_handle = cur_handle;
|
||||
}
|
||||
if (grabMouse_) {
|
||||
QCursor::setPos(view->mapToGlobal(QRect(QPoint(), view->size()).center()));
|
||||
if (mouse_sec) {
|
||||
mouse_sec = false;
|
||||
return;
|
||||
}
|
||||
if (mouse_first) {
|
||||
mouse_first = false;
|
||||
mouse_sec = true;
|
||||
return;
|
||||
}
|
||||
lastPos = g_rect.center();
|
||||
int dx = cpos.x() - lastPos.x();
|
||||
int dy = cpos.y() - lastPos.y();
|
||||
emit view->glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
||||
return;
|
||||
}
|
||||
emit view->glMouseMoveEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::wheelEvent(QWheelEvent * e) {
|
||||
if (mouseRotate_) {
|
||||
double ang =
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
e->delta();
|
||||
#else
|
||||
e->angleDelta().y();
|
||||
#endif
|
||||
if (ang > 0) view->camera()->flyCloser(0.1f);
|
||||
if (ang < 0) view->camera()->flyFarer(0.1f);
|
||||
emit view->cameraPosChanged(view->camera()->pos());
|
||||
}
|
||||
emit view->glWheelEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void MouseController::leaveEvent(QEvent *) {
|
||||
lastPos = QPoint(-1, -1);
|
||||
// qDebug() << lastPos;
|
||||
}
|
||||
|
||||
|
||||
void MouseController::mouseDoubleClickEvent(QMouseEvent * e) {
|
||||
if (e->buttons().testFlag(QT_MID_BUTTON)) emit view->doubleClick();
|
||||
}
|
||||
87
src/core/view/mouse_controller.h
Normal file
87
src/core/view/mouse_controller.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
QGL MouseController
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef MOUSE_CONTROLLER_H
|
||||
#define MOUSE_CONTROLLER_H
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "glprimitives.h"
|
||||
#include "renderer_service.h"
|
||||
|
||||
#include <QMouseEvent>
|
||||
#include <QTime>
|
||||
|
||||
|
||||
class QGLENGINE_CORE_EXPORT MouseController: public QObject {
|
||||
friend class QGLView;
|
||||
friend class RendererSelection;
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MouseController(QGLView * view_);
|
||||
virtual ~MouseController();
|
||||
|
||||
bool isGrabMouseEnabled() const { return grabMouse_; }
|
||||
bool isMouseRotateEnabled() const { return mouseRotate_; }
|
||||
bool isMouseSelectionEnabled() const { return mouseSelect_; }
|
||||
bool isCameraOrbit() const { return cameraOrbit_; }
|
||||
|
||||
Qt::MouseButton selectionButton() const { return sel_button; }
|
||||
Qt::KeyboardModifier selectionModifier() const { return sel_mod; }
|
||||
|
||||
void setSelectionButton(Qt::MouseButton v) { sel_button = v; }
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) { sel_mod = v; }
|
||||
|
||||
protected:
|
||||
void resize();
|
||||
void mousePressEvent(QMouseEvent * e);
|
||||
void mouseMoveEvent(QMouseEvent * e);
|
||||
void mouseReleaseEvent(QMouseEvent * e);
|
||||
void wheelEvent(QWheelEvent * e);
|
||||
void leaveEvent(QEvent *);
|
||||
void mouseDoubleClickEvent(QMouseEvent * e);
|
||||
|
||||
private:
|
||||
QGLView * view;
|
||||
QPoint lastPos, downPos;
|
||||
QSet<int> keys_;
|
||||
QVector<ObjectBase *> hov_objects, hov_aims;
|
||||
Qt::MouseButton sel_button;
|
||||
Qt::KeyboardModifier sel_mod;
|
||||
RendererService::HandleAction cur_action;
|
||||
QFlags<RendererService::HandleMesh> cur_handle;
|
||||
float app_scale;
|
||||
bool grabMouse_, mouse_first, mouseRotate_, mouseSelect_, customMouseMove_, canSelect_;
|
||||
bool cameraOrbit_, selecting_, mouse_sec;
|
||||
|
||||
private slots:
|
||||
|
||||
public slots:
|
||||
void setGrabMouseEnabled(const bool & arg) {
|
||||
grabMouse_ = arg;
|
||||
mouse_first = true;
|
||||
}
|
||||
void setMouseRotateEnabled(const bool & arg) { mouseRotate_ = arg; }
|
||||
void setMouseSelectionEnabled(const bool & arg) { mouseSelect_ = arg; }
|
||||
void setCustomMouseMove(const bool & arg) { customMouseMove_ = arg; }
|
||||
void setCameraOrbit(const bool & arg) { cameraOrbit_ = arg; }
|
||||
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
118
src/core/view/openglwindow.cpp
Normal file
118
src/core/view/openglwindow.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include "openglwindow.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QOpenGLContext>
|
||||
#include <QOpenGLPaintDevice>
|
||||
#include <QPainter>
|
||||
#include <qopenglext.h>
|
||||
|
||||
|
||||
OpenGLWindow::OpenGLWindow(QWindow * parent): QWindow(parent) {
|
||||
setFlags(flags() | Qt::FramelessWindowHint);
|
||||
setSurfaceType(QWindow::OpenGLSurface);
|
||||
QSurfaceFormat format = QSurfaceFormat::defaultFormat();
|
||||
#ifdef QT_OPENGL_ES_2
|
||||
format.setRenderableType(QSurfaceFormat::OpenGLES);
|
||||
#else
|
||||
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGL) {
|
||||
format.setVersion(4, 0);
|
||||
format.setProfile(QSurfaceFormat::CoreProfile);
|
||||
}
|
||||
#endif
|
||||
format.setDepthBufferSize(24);
|
||||
format.setSamples(8);
|
||||
setFormat(format);
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::renderLater() {
|
||||
requestUpdate();
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLWindow::event(QEvent * event) {
|
||||
switch (event->type()) {
|
||||
case QEvent::UpdateRequest: renderNow(); return true;
|
||||
default: return QWindow::event(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::exposeEvent(QExposeEvent * event) {
|
||||
if (isExposed()) renderNow();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLWindow::setVSync(bool on) {
|
||||
QSurfaceFormat f = requestedFormat();
|
||||
if (on) {
|
||||
if (f.swapInterval() != 1) {
|
||||
f.setSwapInterval(1);
|
||||
setFormat(f);
|
||||
format_change = true;
|
||||
}
|
||||
} else {
|
||||
if (f.swapInterval() != 0) {
|
||||
f.setSwapInterval(0);
|
||||
setFormat(f);
|
||||
format_change = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool OpenGLWindow::getVSync() const {
|
||||
return (requestedFormat().swapInterval() == 1);
|
||||
}
|
||||
|
||||
|
||||
int OpenGLWindow::pixelWidth() const {
|
||||
return devicePixelRatio() * width();
|
||||
}
|
||||
|
||||
|
||||
int OpenGLWindow::pixelHeight() const {
|
||||
return devicePixelRatio() * height();
|
||||
}
|
||||
|
||||
|
||||
QSize OpenGLWindow::pixelSize() const {
|
||||
return QSize(pixelWidth(), pixelHeight());
|
||||
}
|
||||
|
||||
|
||||
// void OpenGLWindow::setSamples(int samples) {
|
||||
// QSurfaceFormat f = requestedFormat();
|
||||
// if (f.samples() != samples) {
|
||||
// f.setSamples(samples);
|
||||
// setFormat(f);
|
||||
// format_change = true;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// int OpenGLWindow::getSamples() const {
|
||||
// return requestedFormat().samples();
|
||||
// }
|
||||
|
||||
|
||||
void OpenGLWindow::renderNow() {
|
||||
if (!isExposed()) return;
|
||||
bool needsInitialize = false;
|
||||
if (!m_context || format_change) {
|
||||
if (m_context) delete m_context;
|
||||
m_context = new QOpenGLContext(this);
|
||||
m_context->setFormat(requestedFormat());
|
||||
m_context->create();
|
||||
needsInitialize = true;
|
||||
format_change = false;
|
||||
}
|
||||
m_context->makeCurrent(this);
|
||||
if (needsInitialize) {
|
||||
initializeOpenGLFunctions();
|
||||
initialize();
|
||||
}
|
||||
render();
|
||||
m_context->swapBuffers(this);
|
||||
frame_cnt++;
|
||||
}
|
||||
46
src/core/view/openglwindow.h
Normal file
46
src/core/view/openglwindow.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "qglengine_core_export.h"
|
||||
|
||||
#include <QOpenGLExtraFunctions>
|
||||
#include <QWindow>
|
||||
|
||||
class QPainter;
|
||||
class QOpenGLContext;
|
||||
class QOpenGLPaintDevice;
|
||||
|
||||
|
||||
class QGLENGINE_CORE_EXPORT OpenGLWindow
|
||||
: public QWindow
|
||||
, public QOpenGLExtraFunctions {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit OpenGLWindow(QWindow * parent = nullptr);
|
||||
virtual ~OpenGLWindow() {}
|
||||
|
||||
virtual void render() {}
|
||||
virtual void initialize() {}
|
||||
|
||||
QOpenGLContext * context() { return m_context; }
|
||||
void setVSync(bool on);
|
||||
bool getVSync() const;
|
||||
// void setSamples(int samples);
|
||||
// int getSamples() const;
|
||||
int getFrameCounter() const { return frame_cnt; }
|
||||
|
||||
int pixelWidth() const;
|
||||
int pixelHeight() const;
|
||||
QSize pixelSize() const;
|
||||
|
||||
public slots:
|
||||
void renderLater();
|
||||
void renderNow();
|
||||
|
||||
protected:
|
||||
bool event(QEvent * event) override;
|
||||
void exposeEvent(QExposeEvent * event) override;
|
||||
|
||||
private:
|
||||
QOpenGLContext * m_context = nullptr;
|
||||
bool format_change = false;
|
||||
int frame_cnt = 0;
|
||||
};
|
||||
269
src/core/view/qglview.cpp
Normal file
269
src/core/view/qglview.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qglview.h"
|
||||
|
||||
#include "glmesh.h"
|
||||
#include "gltexture_manager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QKeyEvent>
|
||||
#include <QOpenGLTexture>
|
||||
#include <chunkstream.h>
|
||||
#include <qad_types.h>
|
||||
|
||||
using namespace QGLEngineShaders;
|
||||
|
||||
|
||||
QGLView::QGLView(): OpenGLWindow(), renderer_(this), mouse(this) {
|
||||
setIcon(QIcon(":/icons/qglview.png"));
|
||||
is_init = false;
|
||||
timer = 0;
|
||||
hoverHaloColor_ = QColor(195, 140, 255);
|
||||
selectionHaloColor_ = QColor(175, 255, 140);
|
||||
lineWidth_ = 1.;
|
||||
max_anisotropic = 1;
|
||||
max_texture_chanels = 8;
|
||||
lightEnabled_ = true;
|
||||
shaders_supported = false;
|
||||
FXAA_ = false;
|
||||
fps_cnt = 0;
|
||||
fps_tm = fps_ = 0.;
|
||||
fogColor_ = Qt::darkGray;
|
||||
fogDensity_ = 0.;
|
||||
fogDecay_ = 10.;
|
||||
hoverHaloFill_ = selectionHaloFill_ = 0.15f;
|
||||
render_mode = rmFill;
|
||||
shadow_map_size = QSize(512, 512);
|
||||
// setFeature(qglFXAA, false);
|
||||
// setFeature(qglAnisotropicLevel, 8);
|
||||
// setFeature(qglEyeAccomodationEnabled, false);
|
||||
// setFeature(qglEyeAccomodationTime, 16.);
|
||||
// setFeature(qglEyeAccomodationMaxSpeed, 0.2);
|
||||
// setFeature(qglBloomEnabled, false);
|
||||
// setFeature(qglBloomThreshold, 0.9);
|
||||
// setFeature(qglBloomFactor, 1.);
|
||||
// setFeature(qglBloomRadius, 8);
|
||||
// setFeature(qglMotionBlurEnabled, false);
|
||||
// setFeature(qglMotionBlurFactor, 1.);
|
||||
// setFeature(qglMotionBlurSteps, 8);
|
||||
// setFeature(qglShadowsEnabled, false);
|
||||
// setFeature(qglShadowsMapSize, 512);
|
||||
// setFeature(qglShadowsSoftEnabled, true);
|
||||
// setFeature(qglReflectionsEnabled, false);
|
||||
// setFeature(qglReflectionsBlur, true);
|
||||
// setFeature(qglSSAOEnabled, false);
|
||||
// setFeature(qglSSAORadius, 5);
|
||||
// setFeature(qglDepthOfFieldEnabled, false);
|
||||
// setFeature(qglDepthOfFieldAutoFocusEnabled, true);
|
||||
// setFeature(qglDepthOfFieldAutoFocusSpeed, 0.1);
|
||||
// setFeature(qglDepthOfFieldFocus, 1.);
|
||||
// setFeature(qglDepthOfFieldDiaphragm, 8.);
|
||||
hoverHalo_ = selectionHalo_ = true;
|
||||
fogEnabled_ = shaders_bind = false;
|
||||
scene_ = new Scene();
|
||||
connect(scene_, SIGNAL(selectionChanged()), this, SIGNAL(selectionChanged()));
|
||||
connect(scene_, SIGNAL(__destroyed()), this, SLOT(__destroyed()));
|
||||
connect(scene_, SIGNAL(__objectDeleted(ObjectBase *)), this, SLOT(__objectDeleted(ObjectBase *)));
|
||||
default_camera = new Camera();
|
||||
default_camera->setPos(QVector3D(2, 2, 2));
|
||||
default_camera->setAim(QVector3D());
|
||||
camera_ = default_camera;
|
||||
// qDebug() << camera_->aim();
|
||||
default_camera->setName("Camera");
|
||||
emit cameraPosChanged(default_camera->pos());
|
||||
|
||||
Mesh * m = Primitive::cube(10, 10, 10);
|
||||
m->flipNormals();
|
||||
ObjectBase * o = new ObjectBase(m);
|
||||
o->setColor(Qt::cyan);
|
||||
scene()->addObject(o);
|
||||
delete m;
|
||||
}
|
||||
|
||||
|
||||
QGLView::~QGLView() {
|
||||
stop();
|
||||
scene_->clear();
|
||||
delete scene_;
|
||||
delete default_camera;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::stop() {
|
||||
if (timer) killTimer(timer);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::start(float freq) {
|
||||
timer = startTimer(freq <= 0.f ? 0 : int(1000.f / freq));
|
||||
}
|
||||
|
||||
|
||||
QList<Light *> QGLView::selectedLights() const {
|
||||
QList<Light *> ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
foreach(ObjectBase * o, sol)
|
||||
if (o->type() == ObjectBase::glLight) ret << (Light *)o;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
QList<Camera *> QGLView::selectedCameras() const {
|
||||
QList<Camera *> ret;
|
||||
ObjectBaseList sol = scene_->selectedObjects();
|
||||
for (ObjectBase * o: sol) {
|
||||
if (o->type() == ObjectBase::glCamera) ret << (Camera *)o;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::resizeEvent(QResizeEvent * e) {
|
||||
renderLater();
|
||||
mouse.resize();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::timerEvent(QTimerEvent *) {
|
||||
renderNow();
|
||||
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
|
||||
foreach(int i, keys_)
|
||||
emit keyEvent((Qt::Key)i, km);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::render() {
|
||||
resizeGL(pixelWidth(), pixelHeight());
|
||||
emit glBeginPaint();
|
||||
renderer_.mouse_pos = mapFromGlobal(QCursor::pos()) * devicePixelRatio();
|
||||
renderer_.renderScene();
|
||||
emit glEndPaint();
|
||||
fps_tm = time.elapsed();
|
||||
fps_cnt++;
|
||||
if (fps_tm < 1000.) return;
|
||||
time.restart();
|
||||
fps_ = fps_cnt / fps_tm * 1000.;
|
||||
fps_tm = 0.;
|
||||
fps_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
void QGLView::initialize() {
|
||||
checkCaps();
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable(GL_MULTISAMPLE);
|
||||
glDisable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
glCullFace(GL_BACK);
|
||||
renderer_.reloadShaders();
|
||||
renderer_.init(pixelWidth(), pixelHeight());
|
||||
scene_->reinitAll();
|
||||
is_init = true;
|
||||
prev_size = QSize();
|
||||
emit glInitializeDone();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::checkCaps() {
|
||||
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic);
|
||||
shaders_supported = QOpenGLShaderProgram::hasOpenGLShaderPrograms();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__destroyed() {
|
||||
renderer_.rend_mat.mat_thumbnails.clear();
|
||||
mouse.hov_objects.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::__objectDeleted(ObjectBase * o) {
|
||||
if (o == camera_) setDefaultCamera();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::resizeGL(int width, int height) {
|
||||
if (!is_init) return;
|
||||
if (width <= 0 || height <= 0) return;
|
||||
if (prev_size == QSize(width, height)) return;
|
||||
prev_size = QSize(width, height);
|
||||
aspect = float(width) / float(height);
|
||||
renderer_.resize(width, height);
|
||||
// qDebug() << "resize" << width << height;
|
||||
iaspect = (aspect == 0.f) ? 0. : 1 / aspect;
|
||||
glViewport(0, 0, width, height);
|
||||
emit glResize(width, height);
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyPressEvent(QKeyEvent * e) {
|
||||
emit glKeyPressEvent(e);
|
||||
if (e->key() > 0) keys_.insert(e->key());
|
||||
if (e->key() == Qt::Key_F11) {
|
||||
emit doubleClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QGLView::keyReleaseEvent(QKeyEvent * e) {
|
||||
emit glKeyReleaseEvent(e);
|
||||
keys_.remove(e->key());
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOutEvent(QFocusEvent *) {
|
||||
keys_.clear();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::focusOn(const Box3D & bb) {
|
||||
if (bb.isEmpty() || !camera()) return;
|
||||
double size = qMax(qMax(bb.width, bb.length), bb.height);
|
||||
camera()->setAim(bb.center());
|
||||
camera()->flyToDistance(size * 1.25);
|
||||
}
|
||||
|
||||
|
||||
QByteArray QGLView::saveCamera() {
|
||||
ChunkStream cs;
|
||||
const Camera * c = default_camera;
|
||||
cs.add(1, c->pos()).add(2, c->aim()).add(3, c->rotation()).add(4, c->FOV());
|
||||
return cs.data();
|
||||
}
|
||||
|
||||
|
||||
void QGLView::restoreCamera(const QByteArray & ba) {
|
||||
if (ba.isEmpty()) return;
|
||||
setDefaultCamera();
|
||||
Camera * c = default_camera;
|
||||
QVector3D pos(c->pos()), aim(c->aim()), ang(c->rotation());
|
||||
float fov(c->FOV());
|
||||
ChunkStream cs(ba);
|
||||
cs.readAll();
|
||||
cs.get(1, pos).get(2, aim).get(3, ang).get(4, fov);
|
||||
camera()->setPos(pos);
|
||||
camera()->setAim(aim);
|
||||
camera()->setAngles(ang);
|
||||
camera()->setFOV(fov);
|
||||
}
|
||||
262
src/core/view/qglview.h
Normal file
262
src/core/view/qglview.h
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
QGLView
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QGLVIEW_H
|
||||
#define QGLVIEW_H
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "glframebuffer.h"
|
||||
#include "glprimitives.h"
|
||||
#include "glscene.h"
|
||||
#include "mouse_controller.h"
|
||||
#include "openglwindow.h"
|
||||
#include "qglengine_core_export.h"
|
||||
#include "renderer.h"
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QMenu>
|
||||
|
||||
class QGLENGINE_CORE_EXPORT QGLView
|
||||
: public OpenGLWindow
|
||||
, public ParameteredObject {
|
||||
friend class Renderer;
|
||||
friend class RendererSelection;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float lineWidth READ lineWidth WRITE setLineWidth)
|
||||
Q_PROPERTY(float FOV READ FOV WRITE setFOV)
|
||||
Q_PROPERTY(float depthStart READ depthStart WRITE setDepthStart)
|
||||
Q_PROPERTY(float gamma READ gamma WRITE setGamma)
|
||||
Q_PROPERTY(bool autoExposure READ autoExposure WRITE setAutoExposure)
|
||||
Q_PROPERTY(QColor fogColor READ fogColor WRITE setFogColor)
|
||||
Q_PROPERTY(bool fogEnabled READ isFogEnabled WRITE setFogEnabled)
|
||||
Q_PROPERTY(float fogDensity READ fogDensity WRITE setFogDensity)
|
||||
Q_PROPERTY(float fogDecay READ fogDecay WRITE setFogDecay)
|
||||
Q_PROPERTY(int renderMode READ renderMode WRITE setRenderMode)
|
||||
Q_PROPERTY(bool grabMouse READ isGrabMouseEnabled WRITE setGrabMouseEnabled)
|
||||
Q_PROPERTY(bool mouseRotate READ isMouseRotateEnabled WRITE setMouseRotateEnabled)
|
||||
Q_PROPERTY(bool mouseSelection READ isMouseSelectionEnabled WRITE setMouseSelectionEnabled)
|
||||
Q_PROPERTY(bool cameraOrbit READ isCameraOrbit WRITE setCameraOrbit)
|
||||
Q_PROPERTY(bool hoverHalo READ isHoverHaloEnabled WRITE setHoverHaloEnabled)
|
||||
Q_PROPERTY(QColor hoverHaloColor READ hoverHaloColor WRITE setHoverHaloColor)
|
||||
Q_PROPERTY(float hoverHaloFillAlpha READ hoverHaloFillAlpha WRITE setHoverHaloFillAlpha)
|
||||
Q_PROPERTY(bool selectionHalo READ isSelectionHaloEnabled WRITE setSelectionHaloEnabled)
|
||||
Q_PROPERTY(QColor selectionHaloColor READ selectionHaloColor WRITE setSelectionHaloColor)
|
||||
Q_PROPERTY(float selectionHaloFillAlpha READ selectionHaloFillAlpha WRITE setSelectionHaloFillAlpha)
|
||||
Q_PROPERTY(Qt::MouseButton selectionButton READ selectionButton WRITE setSelectionButton)
|
||||
Q_PROPERTY(Qt::KeyboardModifier selectionModifier READ selectionModifier WRITE setSelectionModifier)
|
||||
Q_PROPERTY(Scene::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
|
||||
|
||||
public:
|
||||
QGLView();
|
||||
virtual ~QGLView();
|
||||
|
||||
enum CameraLightMode {
|
||||
clmOff,
|
||||
clmAuto,
|
||||
clmOn,
|
||||
};
|
||||
enum RenderMode {
|
||||
rmPoint = GL_POINT,
|
||||
rmLine = GL_LINE,
|
||||
rmFill = GL_FILL
|
||||
};
|
||||
|
||||
Q_ENUM(CameraLightMode)
|
||||
|
||||
void stop();
|
||||
void start(float freq = 0.);
|
||||
|
||||
float lineWidth() const { return lineWidth_; }
|
||||
float FOV() const { return camera()->FOV(); }
|
||||
float depthStart() const { return camera()->depthStart(); }
|
||||
float currentFPS() const { return fps_; }
|
||||
float gamma() const { return renderer_.gamma_; }
|
||||
bool autoExposure() const { return renderer_.tone_proc.enabled; }
|
||||
int maxAnisotropicLevel() const { return max_anisotropic; }
|
||||
QString environmentMapFile() const { return renderer_.tex_env.fileHDR(); }
|
||||
bool FXAA() const { return FXAA_; }
|
||||
void setFXAA(bool on) { FXAA_ = on; }
|
||||
|
||||
QColor fogColor() const { return fogColor_; }
|
||||
float fogDensity() const { return fogDensity_; }
|
||||
float fogDecay() const { return fogDecay_; }
|
||||
bool isFogEnabled() const { return fogEnabled_; }
|
||||
bool isLightEnabled() const { return lightEnabled_; }
|
||||
bool isGrabMouseEnabled() const { return mouse.isGrabMouseEnabled(); }
|
||||
bool isMouseRotateEnabled() const { return mouse.isMouseRotateEnabled(); }
|
||||
bool isMouseSelectionEnabled() const { return mouse.isMouseSelectionEnabled(); }
|
||||
bool isCameraOrbit() const { return mouse.isCameraOrbit(); }
|
||||
bool isHoverHaloEnabled() const { return hoverHalo_; }
|
||||
QColor hoverHaloColor() const { return hoverHaloColor_; }
|
||||
float hoverHaloFillAlpha() const { return hoverHaloFill_; }
|
||||
bool isSelectionHaloEnabled() const { return selectionHalo_; }
|
||||
QColor selectionHaloColor() const { return selectionHaloColor_; }
|
||||
float selectionHaloFillAlpha() const { return selectionHaloFill_; }
|
||||
|
||||
int renderMode() const { return (int)render_mode; }
|
||||
void setRenderMode(int mode) { render_mode = (RenderMode)mode; }
|
||||
|
||||
bool isServiceMode() const { return renderer_.edit_mode; }
|
||||
void setServiceMode(bool yes) { renderer_.edit_mode = yes; }
|
||||
|
||||
|
||||
Scene::SelectionMode selectionMode() const { return scene_->selectionMode(); }
|
||||
Qt::MouseButton selectionButton() const { return mouse.selectionButton(); }
|
||||
Qt::KeyboardModifier selectionModifier() const { return mouse.selectionModifier(); }
|
||||
|
||||
void setSelectionMode(Scene::SelectionMode m) { scene_->setSelectionMode(m); }
|
||||
void setSelectionButton(Qt::MouseButton v) { mouse.setSelectionButton(v); }
|
||||
void setSelectionModifier(Qt::KeyboardModifier v) { mouse.setSelectionModifier(v); }
|
||||
|
||||
void selectObject(ObjectBase * o, bool add_to_selection = false) { scene_->selectObject(o, add_to_selection); }
|
||||
void clearSelection() { scene_->clearSelection(); }
|
||||
ObjectBaseList selectedObjects(bool top_only = false) const { return scene_->selectedObjects(top_only); }
|
||||
QList<Light *> selectedLights() const;
|
||||
QList<Camera *> selectedCameras() const;
|
||||
ObjectBase * selectedObject() const { return scene_->selectedObject(); }
|
||||
|
||||
TextureManager * textureManager() { return renderer_.textures_manager; }
|
||||
void reloadTextures() { renderer_.markReloadTextures(); }
|
||||
|
||||
Scene * scene() { return scene_; }
|
||||
void focusOn(const Box3D & bb);
|
||||
void setCameraLightMode(CameraLightMode m) { renderer_.setCameraLightMode(m); }
|
||||
CameraLightMode cameraLightMode() const { return (CameraLightMode)renderer_.cameraLightMode(); }
|
||||
|
||||
Camera * camera() { return camera_; }
|
||||
const Camera * camera() const { return camera_; }
|
||||
void setCamera(Camera * camera) { camera_ = camera; }
|
||||
void setDefaultCamera() { camera_ = default_camera; }
|
||||
bool isDefaultCamera() const { return camera_ == default_camera; }
|
||||
QByteArray saveCamera();
|
||||
void restoreCamera(const QByteArray & ba);
|
||||
|
||||
QImage materialThumbnail(Material * m) { return renderer_.materialThumbnail(m); }
|
||||
void setCurrentAction(RendererService::HandleAction ha) { renderer_.rend_service.setCurrentAction(ha); }
|
||||
void setContextActions(QList<QAction *> al) {
|
||||
context_menu.clear();
|
||||
context_menu.addActions(al);
|
||||
}
|
||||
void popupMenu(const QPoint & pos, QAction * at = nullptr) { context_menu.popup(pos, at); }
|
||||
void setGrabImage(bool on) { renderer_.setGrabImage(on); }
|
||||
bool isGrabImage() const { return renderer_.isGrabImage(); }
|
||||
QImage getImage() const { return renderer_.getImage(); }
|
||||
|
||||
GLfloat aspect, iaspect;
|
||||
Renderer renderer_;
|
||||
|
||||
protected:
|
||||
void render();
|
||||
void resizeEvent(QResizeEvent * e);
|
||||
|
||||
void timerEvent(QTimerEvent *);
|
||||
void initialize();
|
||||
void resizeGL(int width, int height);
|
||||
void mousePressEvent(QMouseEvent * e) { mouse.mousePressEvent(e); }
|
||||
void mouseMoveEvent(QMouseEvent * e) { mouse.mouseMoveEvent(e); }
|
||||
void mouseReleaseEvent(QMouseEvent * e) { mouse.mouseReleaseEvent(e); }
|
||||
void wheelEvent(QWheelEvent * e) { mouse.wheelEvent(e); }
|
||||
void mouseDoubleClickEvent(QMouseEvent * e) { mouse.mouseDoubleClickEvent(e); }
|
||||
void leaveEvent(QEvent *);
|
||||
|
||||
void keyPressEvent(QKeyEvent * e);
|
||||
void keyReleaseEvent(QKeyEvent * e);
|
||||
void focusOutEvent(QFocusEvent *);
|
||||
|
||||
void checkCaps();
|
||||
|
||||
private:
|
||||
void processKeys();
|
||||
bool setupViewport();
|
||||
|
||||
Scene * scene_;
|
||||
Camera *camera_, *default_camera;
|
||||
MouseController mouse;
|
||||
QMenu context_menu;
|
||||
QSet<int> keys_;
|
||||
QColor fogColor_, hoverHaloColor_, selectionHaloColor_;
|
||||
QElapsedTimer time;
|
||||
GLint max_anisotropic, max_texture_chanels;
|
||||
RenderMode render_mode;
|
||||
QSize prev_size, shadow_map_size;
|
||||
float lineWidth_;
|
||||
float fps_, fps_tm, fogDensity_, fogDecay_;
|
||||
float hoverHaloFill_, selectionHaloFill_, m_motionBlurFactor;
|
||||
int timer, fps_cnt, sh_id_loc;
|
||||
bool fogEnabled_, lightEnabled_, FXAA_;
|
||||
bool shaders_supported, shaders_bind;
|
||||
bool hoverHalo_, selectionHalo_;
|
||||
bool is_init;
|
||||
|
||||
private slots:
|
||||
void __destroyed();
|
||||
void __objectDeleted(ObjectBase * o);
|
||||
|
||||
public slots:
|
||||
void setLineWidth(const float & arg) { lineWidth_ = arg; }
|
||||
void setFOV(const float & arg) { camera()->setFOV(arg); }
|
||||
void setDepthStart(const float & arg) { camera()->setDepthStart(arg); }
|
||||
void setGamma(const float & arg) { renderer_.gamma_ = arg; }
|
||||
void setAutoExposure(bool arg) { renderer_.tone_proc.enabled = arg; }
|
||||
void setEnvironmentMapFile(QString file) {
|
||||
renderer_.tex_env.setFileHDR(file);
|
||||
renderer_.recreateMaterialThumbnails(true);
|
||||
}
|
||||
void setFogColor(const QColor & arg) { fogColor_ = arg; }
|
||||
void setFogDensity(const float & arg) { fogDensity_ = arg; }
|
||||
void setFogDecay(const float & arg) { fogDecay_ = arg; }
|
||||
void setFogEnabled(const bool & arg) { fogEnabled_ = arg; }
|
||||
void setLightEnabled(const bool & arg) { lightEnabled_ = arg; }
|
||||
void setGrabMouseEnabled(const bool & arg) { mouse.setGrabMouseEnabled(arg); }
|
||||
void setMouseRotateEnabled(const bool & arg) { mouse.setMouseRotateEnabled(arg); }
|
||||
void setMouseSelectionEnabled(const bool & arg) { mouse.setMouseSelectionEnabled(arg); }
|
||||
void setCustomMouseMove(const bool & arg) { mouse.setCustomMouseMove(arg); }
|
||||
void setCameraOrbit(const bool & arg) { mouse.setCameraOrbit(arg); }
|
||||
void setHoverHaloEnabled(const bool & arg) { hoverHalo_ = arg; }
|
||||
void setHoverHaloColor(const QColor & arg) { hoverHaloColor_ = arg; }
|
||||
void setHoverHaloFillAlpha(const float & arg) { hoverHaloFill_ = arg; }
|
||||
void setSelectionHaloEnabled(const bool & arg) { selectionHalo_ = arg; }
|
||||
void setSelectionHaloColor(const QColor & arg) { selectionHaloColor_ = arg; }
|
||||
void setSelectionHaloFillAlpha(const float & arg) { selectionHaloFill_ = arg; }
|
||||
|
||||
void reloadShaders() { renderer_.reloadShaders(); }
|
||||
|
||||
signals:
|
||||
void glBeginPaint();
|
||||
void glEndPaint();
|
||||
void glKeyPressEvent(QKeyEvent * e);
|
||||
void glKeyReleaseEvent(QKeyEvent * e);
|
||||
void glMousePressEvent(QMouseEvent * e);
|
||||
void glMouseMoveEvent(QMouseEvent * e);
|
||||
void glMouseReleaseEvent(QMouseEvent * e);
|
||||
void glWheelEvent(QWheelEvent * e);
|
||||
void glResize(int, int);
|
||||
void glInitializeDone();
|
||||
void cameraPosChanged(QVector3D pos);
|
||||
void keyEvent(Qt::Key key, Qt::KeyboardModifiers mod);
|
||||
void customMouseMoveEvent(QPoint curpos, QPoint lastpos, Qt::MouseButtons buttons);
|
||||
|
||||
void hoverChanged(ObjectBase * cur, ObjectBase * prev);
|
||||
void selectionChanged();
|
||||
void objectsPositionChanged();
|
||||
void materialsChanged();
|
||||
void materialThumbnailCreated(Material *);
|
||||
void doubleClick();
|
||||
};
|
||||
|
||||
#endif // QGLVIEW_H
|
||||
Reference in New Issue
Block a user