611 lines
19 KiB
C++
611 lines
19 KiB
C++
/*
|
|
QGLView
|
|
Copyright (C) 2012 Ivan Pelipenko peri4ko@gmail.com
|
|
|
|
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/>.
|
|
*/
|
|
|
|
#include "qglview.h"
|
|
|
|
|
|
QGLView::QGLView(QWidget * parent): QGraphicsView(parent), fbo_selection(3) {
|
|
setFrameShape(QFrame::NoFrame);
|
|
setViewportUpdateMode(FullViewportUpdate);
|
|
setCacheMode(CacheNone);
|
|
setViewport(new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers)));
|
|
setMouseTracking(true);
|
|
setFocusPolicy(Qt::WheelFocus);
|
|
setScene(new QGraphicsScene());
|
|
setInteractive(true);
|
|
painter_ = 0;
|
|
backColor_ = Qt::black;
|
|
hoverHaloColor_ = QColor(195, 140, 255, 96);
|
|
selectionHaloColor_ = QColor(175, 255, 140);
|
|
ambientColor_ = QColor(10, 10, 10);
|
|
lastPos = QPoint(-1, -1);
|
|
lineWidth_ = 1.;
|
|
linearFiltering_ = cameraOrbit_ = lightEnabled_ = true;
|
|
shaders_supported = selecting_ = customMouseMove_ = false;
|
|
sel_button = Qt::LeftButton;
|
|
sel_mod = Qt::NoModifier;
|
|
anisotropicLevel_ = 8;
|
|
renderer_ = 0;
|
|
fps_cnt = 0;
|
|
fps_tm = fps_ = 0.;
|
|
sel_obj = hov_obj = 0;
|
|
fogDensity_ = fogEnd_ = 1.;
|
|
fogStart_ = 0.;
|
|
fogMode_ = Exp;
|
|
hoverHaloFill_ = 0.333;
|
|
selectionHaloFill_ = 0.5;
|
|
shadow_map_size = dynamic_cubemap_size = 512;
|
|
//lmode = Simple;
|
|
shader_select = shader_halo = shader_rope = 0;
|
|
cur_luminance = 1.;
|
|
accom_time = 32.;
|
|
accom_max_speed = 0.1;
|
|
mouse_first = mouseSelect_ = accomodation_ = hoverHalo_ = selectionHalo_ = true;
|
|
fogEnabled_ = is_init = grabMouse_ = mouseRotate_ = mouseThis_ = shaders_bind = shadows_ = shadows_soft = dynamic_reflections = hdr_ = bloom_ = msaa_ = fxaa_ = changed_ = false;
|
|
rmode = GLObjectBase::Fill;
|
|
sel_mode = QGLView::SingleSelection;
|
|
sel_pen = QPen(Qt::black, 1, Qt::DashLine);
|
|
sel_brush = QBrush(QColor(170, 100, 255, 120));
|
|
camera_.setAim(QVector3D(0,0,5.5));
|
|
camera_.setPos(QVector3D(10, 5, 5.5));
|
|
emit cameraPosChanged(camera_.pos());
|
|
//camera_.aim_ = camera_.pos_;
|
|
ktm_.restart();
|
|
sh_lm_diff << "Phong_diffuse" << "Cook_Torrance_diffuse" << "Minnaert_diffuse" << "Strauss_diffuse" << "Oren_Nayar_diffuse";
|
|
sh_lm_spec << "Phong_specular" << "Cook_Torrance_specular" << "Minnaert_specular" << "Strauss_specular" << "Oren_Nayar_specular";
|
|
}
|
|
|
|
|
|
QGLView::~QGLView() {
|
|
if (shader_select != 0) delete shader_select;
|
|
if (shader_halo != 0) delete shader_halo;
|
|
if (shader_rope != 0) delete shader_rope;
|
|
}
|
|
|
|
|
|
void QGLView::addObject(QWidget * o, Qt::WindowFlags f) {
|
|
scene()->addWidget(o, f)->setCacheMode(QGraphicsItem::ItemCoordinateCache);
|
|
/*QList<QGraphicsItem * > il = collectGraphicItems();
|
|
foreach (QGraphicsItem * i, il) {
|
|
QGraphicsProxyWidget * p = qgraphicsitem_cast<QGraphicsProxyWidget * >(i);
|
|
if (p == 0) continue;
|
|
p->setCacheMode(QGraphicsItem::ItemCoordinateCache);
|
|
}*/
|
|
}
|
|
|
|
|
|
void QGLView::addObject(GLObjectBase * o) {
|
|
o->view_ = this;
|
|
objects_.addChild(o);
|
|
collectLights();
|
|
if (is_init) {
|
|
globMutex.lock();
|
|
o->init();
|
|
globMutex.unlock();
|
|
}
|
|
}
|
|
|
|
|
|
void QGLView::drawBackground(QPainter * painter, const QRectF & rect) {
|
|
static bool f = true;
|
|
painter_ = painter;
|
|
painter_->beginNativePainting();
|
|
if (f) {
|
|
resizeGL(viewport()->width(), viewport()->height());
|
|
initializeGL();
|
|
}
|
|
f = false;
|
|
paintGL();
|
|
painter_->endNativePainting();
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_CULL_FACE);
|
|
glReleaseTextures();
|
|
QGraphicsView::drawBackground(painter_, rect);
|
|
}
|
|
|
|
|
|
void QGLView::initializeGL() {
|
|
//qDebug() << "init glview";
|
|
makeCurrent();
|
|
currentQGLView = (QGLWidget * )viewport();
|
|
currentGLTextureManager = &textures_manager;
|
|
currentCamera = &camera_;
|
|
//glEnable(GL_POLYGON_SMOOTH);
|
|
glEnable(GL_TEXTURE_MAX_ANISOTROPY_EXT);
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
//glEnable(GL_TEXTURE_2D);
|
|
//glEnable(GL_TEXTURE_CUBE_MAP);
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
glEnableClientState(GL_VERTEX_ARRAY);
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);
|
|
|
|
glActiveTextureChannel(3);
|
|
glEnable(GL_TEXTURE_GEN_S);
|
|
glEnable(GL_TEXTURE_GEN_T);
|
|
glEnable(GL_TEXTURE_GEN_R);
|
|
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
|
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
|
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
|
glActiveTextureChannel(0);
|
|
//glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NONE);
|
|
//glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NONE);
|
|
|
|
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
|
glShadeModel(GL_SMOOTH);
|
|
glCullFace(GL_BACK);
|
|
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glColorMaterial(GL_FRONT, GL_DIFFUSE);
|
|
|
|
textures_manager.loadTextures();
|
|
objects_.initInternal();
|
|
checkCaps();
|
|
|
|
shader_select = new QGLShaderProgram(context());
|
|
shader_halo = new QGLShaderProgram(context());
|
|
shader_rope = new QGLShaderProgram(context());
|
|
reloadThisShaders();
|
|
is_init = true;
|
|
|
|
//dynamic_cubemap.loadPathesFromDirectory("e");
|
|
//dynamic_cubemap.load();
|
|
/*dynamic_cubemap.loadFront("e/front.jpg");
|
|
dynamic_cubemap.loadBack("e/back.jpg");
|
|
dynamic_cubemap.loadLeft("e/left.jpg");
|
|
dynamic_cubemap.loadRight("e/right.jpg");
|
|
dynamic_cubemap.loadTop("e/top.jpg");
|
|
dynamic_cubemap.loadBottom("e/bottom.jpg");*/
|
|
//glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
|
//GLuint t = 0;
|
|
//createGLTexture(t, QImage("e/bottom.jpg"));
|
|
//qDebug() << bindTexture(QImage("e/bottom.jpg"));
|
|
|
|
emit glInitializeDone();
|
|
}
|
|
|
|
|
|
void QGLView::paintGL() {
|
|
//QMutexLocker ml_v(&v_mutex);
|
|
glEnable(GL_CULL_FACE);
|
|
camera_.apply(aspect);
|
|
|
|
/// Selection detect
|
|
//glClearFramebuffer(QColor(100, 0, 0, 0));
|
|
if (mouseSelect_) {
|
|
glReleaseTextures();
|
|
glEnable(GL_DEPTH_TEST);
|
|
glDepthFunc(GL_LESS);
|
|
glDepthMask(GL_TRUE);
|
|
glDisable(GL_TEXTURE_1D);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glDisable(GL_TEXTURE_CUBE_MAP);
|
|
glDisable(GL_MULTISAMPLE);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_RESCALE_NORMAL);
|
|
glDisableClientState(GL_NORMAL_ARRAY);
|
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glDisableClientState(GL_COLOR_ARRAY);
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
fbo_selection.bind();
|
|
fbo_selection.setWriteBuffer(0);
|
|
glClearFramebuffer(QColor(0, 0, 0, 0));
|
|
if (shaders_supported) shader_select->bind();
|
|
renderSelection();
|
|
if (shaders_supported) shader_select->release();
|
|
uchar cgid[4] = {0, 0, 0, 0};
|
|
uint iid;
|
|
GLObjectBase * so = 0;
|
|
if (!rect().contains(lastPos)) {
|
|
if (hov_obj != 0) {
|
|
hov_obj = 0;
|
|
emit hoverChanged(0, hov_obj);
|
|
}
|
|
} else {
|
|
glReadPixels(lastPos.x(), viewport()->height() - lastPos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, cgid);
|
|
iid = (cgid[0] << 24) | (cgid[1] << 16) | (cgid[2] << 8) | cgid[3];
|
|
so = ids[iid];
|
|
//qDebug() <<cgid[0]<<cgid[1]<<cgid[2]<<cgid[3]<< iid;
|
|
if (so != hov_obj) {
|
|
emit hoverChanged(so, hov_obj);
|
|
hov_obj = so;
|
|
}
|
|
//if (so != 0) qDebug() << sel_obj->name() << cgid[3];
|
|
}
|
|
if (hoverHalo_) {
|
|
fbo_selection.setWriteBuffer(1);
|
|
renderHalo(so, iid, hoverHaloColor_, hoverHaloFill_);
|
|
}
|
|
if (selectionHalo_) {
|
|
fbo_selection.setWriteBuffer(2);
|
|
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
|
|
}
|
|
fbo_selection.release();
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_RESCALE_NORMAL);
|
|
glEnableClientState(GL_NORMAL_ARRAY);
|
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
|
glEnableClientState(GL_COLOR_ARRAY);
|
|
}
|
|
|
|
camera_.apply(aspect);
|
|
|
|
static GLRendererBase * prev_rend = 0;
|
|
if (prev_rend != renderer_) {
|
|
prev_rend = renderer_;
|
|
if (renderer_ != 0) {
|
|
renderer_->init(viewport()->width(), viewport()->height());
|
|
renderer_->resize(viewport()->width(), viewport()->height());
|
|
renderer_->reloadShaders();
|
|
}
|
|
}
|
|
emit glBeginPaint();
|
|
if (renderer_ != 0) renderer_->renderScene();
|
|
if (selectionHalo_ || hoverHalo_) {
|
|
glReleaseTextures();
|
|
glReleaseShaders();
|
|
glReleaseFramebuffer();
|
|
glActiveTextureChannel(0);
|
|
glEnable(GL_TEXTURE_2D);
|
|
glEnable(GL_BLEND);
|
|
glDisable(GL_TEXTURE_CUBE_MAP);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
|
if (selectionHalo_) {
|
|
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
|
|
glDrawQuad();
|
|
}
|
|
if (hoverHalo_) {
|
|
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1));
|
|
glDrawQuad();
|
|
}
|
|
}
|
|
|
|
if (selecting_ && painter_) {
|
|
painter_->setPen(sel_pen);
|
|
painter_->setBrush(sel_brush);
|
|
painter_->drawRect(QRect(downPos, lastPos).normalized());
|
|
qDebug() << QRect(downPos, lastPos).normalized();
|
|
}
|
|
|
|
emit glPainting();
|
|
|
|
/*releaseShaders();
|
|
glActiveTextureChannel(0);
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glColor4f(0.3, 0.5, 0.8, 0.5);
|
|
glResetAllTransforms();
|
|
glBegin(GL_QUADS);
|
|
glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f);
|
|
glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.);
|
|
glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f);
|
|
glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f);
|
|
glEnd();*/
|
|
/*
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glDisable(GL_LIGHTING);
|
|
glActiveTextureChannel(0);
|
|
glBindTexture(GL_TEXTURE_2D, fbo->texture());
|
|
glDisable(GL_DEPTH_TEST);
|
|
glBegin(GL_QUADS);
|
|
glColor3f(1.f, 1.f, 1.f);
|
|
glTexCoord2f(0.f, 0.f); glVertex2f(-1.f, -1.f);
|
|
glTexCoord2f(0.f, 1.f); glVertex2f(-1.f, 1.f);
|
|
glTexCoord2f(1.f, 1.f); glVertex2f(1.f, 1.f);
|
|
glTexCoord2f(1.f, 0.f); glVertex2f(1.f, -1.);
|
|
glEnd();
|
|
glEnable(GL_DEPTH_TEST);*/
|
|
fps_tm += time.elapsed();
|
|
time.restart();
|
|
fps_cnt++;
|
|
if (fps_tm < 1000.) return;
|
|
fps_ = fps_cnt / fps_tm * 1000.;
|
|
fps_tm = 0.;
|
|
fps_cnt = 0;
|
|
|
|
//glResetAllTransforms();
|
|
}
|
|
|
|
|
|
void QGLView::renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill) {
|
|
if (!shaders_supported) return;
|
|
if (obj == 0) {
|
|
glClearFramebuffer(Qt::black, false);
|
|
} else {
|
|
glActiveTextureChannel(0);
|
|
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture());
|
|
shader_halo->bind();
|
|
shader_halo->setUniformValue("t0", 0);
|
|
shader_halo->setUniformValue("dt", QVector2D(1. / viewport()->width(), 1. / viewport()->height()));
|
|
shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f,
|
|
float((iid >> 16) & 0xFF) / 255.f,
|
|
float((iid >> 8) & 0xFF) / 255.f,
|
|
float(iid & 0xFF) / 255.f));
|
|
shader_halo->setUniformValue("color", color);
|
|
shader_halo->setUniformValue("fill", GLfloat(fill));
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDepthMask(GL_FALSE);
|
|
glDrawQuad();
|
|
glDepthMask(GL_TRUE);
|
|
shader_halo->release();
|
|
}
|
|
}
|
|
|
|
|
|
void QGLView::renderSelection() {
|
|
cid = 1;
|
|
ids.clear();
|
|
if (shaders_supported) sh_id_loc = shader_select->uniformLocation("id");
|
|
//qDebug() << sh_id_loc;
|
|
renderSingleSelection(objects_);
|
|
}
|
|
|
|
|
|
void QGLView::renderSingleSelection(GLObjectBase & o) {
|
|
if (!o.isInit()) {
|
|
o.init();
|
|
o.loadTextures();
|
|
}
|
|
if (!o.visible_ || !o.select_) return;
|
|
glPushMatrix();
|
|
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
|
|
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
|
|
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
|
|
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
|
|
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
|
|
ids.insert(cid, &o);
|
|
if (shaders_supported) shader_select->setUniformValue(sh_id_loc, QVector4D(float((cid >> 24) & 0xFF) / 255.f,
|
|
float((cid >> 16) & 0xFF) / 255.f,
|
|
float((cid >> 8) & 0xFF) / 255.f,
|
|
float(cid & 0xFF) / 255.f));
|
|
else glColor4f(float((cid >> 24) & 0xFF) / 255.f,
|
|
float((cid >> 16) & 0xFF) / 255.f,
|
|
float((cid >> 8) & 0xFF) / 255.f,
|
|
float(cid & 0xFF) / 255.f);
|
|
//qDebug() << o.name() << "assign to" << sh_id_loc << cid;
|
|
//glColor4f(float((cid >> 24) & 0xFF) / 255.f, float((cid >> 16) & 0xFF) / 255.f, float((cid >> 8) & 0xFF) / 255.f, float(cid & 0xFF) / 255.f);
|
|
++cid;
|
|
o.draw(true);
|
|
foreach (GLObjectBase * i, o.children_)
|
|
renderSingleSelection(*i);
|
|
glPopMatrix();
|
|
}
|
|
|
|
|
|
void QGLView::renderSingleShadow(GLObjectBase & o) {
|
|
if (!o.isInit()) {
|
|
o.init();
|
|
o.loadTextures();
|
|
}
|
|
if (!o.visible_) return;
|
|
glPushMatrix();
|
|
if (o.pos_.x() != 0. || o.pos_.y() != 0. || o.pos_.z() != 0.) qglTranslate(o.pos_);
|
|
if (o.angles_.z() != 0.) glRotated(o.angles_.z(), 0., 0., 1.);
|
|
if (o.angles_.y() != 0.) glRotated(o.angles_.y(), 0., 1., 0.);
|
|
if (o.angles_.x() != 0.) glRotated(o.angles_.x(), 1., 0., 0.);
|
|
if (o.scale_.x() != 1. || o.scale_.y() != 1. || o.scale_.z() != 1.) qglScale(o.scale_);
|
|
glPolygonMode(GL_FRONT_AND_BACK, o.render_mode != GLObjectBase::View ? o.render_mode : (rmode != GLObjectBase::View ? rmode : GL_FILL));
|
|
glLineWidth(o.line_width > 0. ? o.line_width : lineWidth_);
|
|
glPointSize(o.line_width > 0. ? o.line_width : lineWidth_);
|
|
o.draw(true);
|
|
foreach (GLObjectBase * i, o.children_)
|
|
renderSingleSelection(*i);
|
|
glPopMatrix();
|
|
}
|
|
|
|
|
|
void QGLView::collectLights() {
|
|
lights_.clear();
|
|
collectObjectLights(&objects_);
|
|
}
|
|
|
|
|
|
QList<QGraphicsItem * > QGLView::collectGraphicItems() {
|
|
QList<QGraphicsItem * > list = scene()->items();
|
|
foreach (QGraphicsItem * i, list)
|
|
collectGraphicItems(list, i);
|
|
return list;
|
|
}
|
|
|
|
|
|
void QGLView::collectGraphicItems(QList<QGraphicsItem * > & list, QGraphicsItem * o) {
|
|
QList<QGraphicsItem * > cl = o->childItems();
|
|
foreach (QGraphicsItem * i, cl) {
|
|
list << i;
|
|
collectGraphicItems(list, i);
|
|
}
|
|
}
|
|
|
|
|
|
void QGLView::collectObjectLights(GLObjectBase * o) {
|
|
if (o->type_ == GLObjectBase::Light) lights_ << globject_cast<Light * >(o);
|
|
foreach (GLObjectBase * i, o->children())
|
|
collectObjectLights(i);
|
|
}
|
|
|
|
|
|
void QGLView::checkCaps() {
|
|
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropic);
|
|
shaders_supported = QGLShaderProgram::hasOpenGLShaderPrograms();
|
|
}
|
|
|
|
|
|
void QGLView::reloadThisShaders() {
|
|
if (!shaders_supported) return;
|
|
loadShaders(shader_select, "selection", "shaders");
|
|
loadShaders(shader_halo, "selection_halo", "shaders");
|
|
//loadShaders(shader_rope, "rope", "shaders");
|
|
}
|
|
|
|
|
|
inline void QGLView::applyFog() {
|
|
GLfloat fog_col[4] = {float(fogColor_.redF()), float(fogColor_.greenF()), float(fogColor_.blueF()), .0f};
|
|
if (fogEnabled_) {
|
|
glEnable(GL_FOG);
|
|
glFogf(GL_FOG_DENSITY, fogDensity_);
|
|
glFogf(GL_FOG_START, fogStart_);
|
|
glFogf(GL_FOG_END, fogEnd_);
|
|
glFogi(GL_FOG_MODE, fogMode_);
|
|
fog_col[0] = fogColor_.redF();
|
|
fog_col[1] = fogColor_.greenF();
|
|
fog_col[2] = fogColor_.blueF();
|
|
glFogfv(GL_FOG_COLOR, fog_col);
|
|
} else glDisable(GL_FOG);
|
|
}
|
|
|
|
|
|
void QGLView::resizeGL(int width, int height) {
|
|
aspect = double(width) / double(height);
|
|
if (renderer_ != 0) renderer_->resize(width, height);
|
|
fbo_selection.resize(width, height);
|
|
mouse_first = true;
|
|
iaspect = (aspect == 0.) ? 0. : 1 / aspect;
|
|
glViewport(0, 0, width, height);
|
|
emit glResize(width, height);
|
|
}
|
|
|
|
|
|
void QGLView::mouseReleaseEvent(QMouseEvent * e) {
|
|
QGraphicsView::mouseReleaseEvent(e);
|
|
//setCursor(QCursor(Qt::ArrowCursor));
|
|
selecting_ = false;
|
|
if (mouseThis_ && mouseSelect_ && e->button() == Qt::LeftButton) {
|
|
if ((lastPos - downPos).manhattanLength() < 8) {
|
|
if (sel_obj != hov_obj) {
|
|
emit selectionChanged(hov_obj, sel_obj);
|
|
sel_obj = hov_obj;
|
|
}
|
|
}
|
|
}
|
|
emit glMouseReleaseEvent(e);
|
|
}
|
|
|
|
|
|
void QGLView::mousePressEvent(QMouseEvent * e) {
|
|
QGraphicsView::mousePressEvent(e);
|
|
mouseThis_ = (scene()->itemAt(mapToScene(e->pos())) == 0);
|
|
selecting_ = false;
|
|
if (!mouseThis_) return;
|
|
/// TODO select by rect
|
|
//if (e->button() == sel_button && e->modifiers() == sel_mod)
|
|
// selecting_ = true;
|
|
lastPos = e->pos();
|
|
downPos = lastPos;
|
|
//qDebug() << mouseThis_;
|
|
emit glMousePressEvent(e);
|
|
}
|
|
|
|
|
|
void QGLView::mouseMoveEvent(QMouseEvent * e) {
|
|
QGraphicsView::mouseMoveEvent(e);
|
|
//qDebug() << scene()->itemAt(mapToScene(e->pos()));
|
|
//lastPos = e->pos();
|
|
if (selecting_) {
|
|
|
|
return;
|
|
}
|
|
if (!mouseThis_) return;
|
|
//if (scene()->itemAt(mapToScene(e->pos())) != 0) return;
|
|
///qDebug() << e->x() << e->y();
|
|
if (mouseRotate_) {
|
|
double dx = e->x() - lastPos.x();
|
|
double dy = e->y() - lastPos.y();
|
|
if (e->buttons() & Qt::LeftButton) {
|
|
//camera_.angle_z += dx / 4.;
|
|
//camera_.angle_xy += dy / 4.;
|
|
if (cameraOrbit_) {
|
|
camera_.orbitZ(dx / 4.);
|
|
camera_.orbitXY(dy / 4.);
|
|
} else {
|
|
camera_.rotateZ(dx / 4.);
|
|
camera_.rotateXY(dy / 4.);
|
|
}
|
|
emit cameraPosChanged(camera_.pos());
|
|
} else if (e->buttons() & Qt::RightButton) {
|
|
camera_.moveLeft(dx / 100.);
|
|
camera_.moveUp(dy / 100.);
|
|
//camera_.pos.setX(camera_.pos.x() + camera_.pos.z() * dx / 500.);
|
|
//camera_.pos.setY(camera_.pos.y() - camera_.pos.z() * dy / 500.);
|
|
emit cameraPosChanged(camera_.pos());
|
|
}
|
|
//lights[0]->pos_ = camera_.pos();
|
|
}
|
|
if (customMouseMove_) emit customMouseMoveEvent(e->pos(), lastPos, e->buttons());
|
|
lastPos = e->pos();
|
|
if (grabMouse_) {
|
|
//if (!isrunning) return;
|
|
QCursor::setPos(mapToGlobal(rect().center()));
|
|
static bool mouse_sec = false;
|
|
if (mouse_sec) {
|
|
mouse_sec = false;
|
|
return;
|
|
}
|
|
if (mouse_first) {
|
|
mouse_first = false;
|
|
mouse_sec = true;
|
|
//qDebug() << "first" << e->pos();
|
|
return;
|
|
}
|
|
lastPos = rect().center();
|
|
int dx = e->x() - lastPos.x();
|
|
int dy = e->y() - lastPos.y();
|
|
emit glMouseMoveEvent(new QMouseEvent(QEvent::MouseMove, QPoint(dx, dy), e->button(), e->buttons(), e->modifiers()));
|
|
return;
|
|
}
|
|
//emit glMouseMoveEvent(e);
|
|
}
|
|
|
|
|
|
void QGLView::wheelEvent(QWheelEvent * e) {
|
|
QGraphicsView::wheelEvent(e);
|
|
if (scene()->itemAt(mapToScene(e->pos())) != 0) return;
|
|
if (mouseRotate_) {
|
|
if (e->delta() > 0) camera_.flyCloser(0.1); //camera_.pos.setZ(camera_.pos.z() - 0.1 * camera_.pos.z());
|
|
if (e->delta() < 0) camera_.flyFarer(0.1); //camera_.pos.setZ(camera_.pos.z() + 0.1 * camera_.pos.z());
|
|
emit cameraPosChanged(camera_.pos());
|
|
}
|
|
emit glWheelEvent(e);
|
|
}
|
|
|
|
|
|
void QGLView::processKeys() {
|
|
if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return;
|
|
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();
|
|
foreach (int i, keys_)
|
|
emit keyEvent((Qt::Key)i, km);
|
|
}
|