From c4444bcefd843247fd3aafb2621a21d5d38a9cec Mon Sep 17 00:00:00 2001 From: Anakin Date: Sat, 21 Jan 2017 15:22:43 +0100 Subject: [PATCH] fixed background bug, support directional light, zoom speed can be adjust via +/- --- QtMeshViewer/Header/OglViewerWidget.h | 7 ++++++- QtMeshViewer/Resources/about.txt | 1 + QtMeshViewer/Resources/fshader.glsl | 26 +++++++++++++++++++------ QtMeshViewer/Source/MainWindow.cpp | 1 + QtMeshViewer/Source/OglViewerWidget.cpp | 26 ++++++++++++++++++++----- 5 files changed, 49 insertions(+), 12 deletions(-) diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 02e4a4a..56e59f2 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -38,7 +38,7 @@ private: } m_rotDirections; struct { - QVector3D position = { 1,1,1 }; + QVector4D position = { 1,1,1,0 }; QVector3D intensities = { 1.0,1.0,1.0 }; float attenuationFactor = 0.2f; float ambientCoefficient = 0.005f; @@ -56,6 +56,8 @@ private: bool m_wireframe = false; bool m_lightOn = false; + double m_zSpeed = 1.0; + protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE; @@ -81,5 +83,8 @@ public slots: void changeDirection(int direction); void toggleWireframe(); void toggleLight(); + +signals: + void sendMessage(QString message, int severity); }; diff --git a/QtMeshViewer/Resources/about.txt b/QtMeshViewer/Resources/about.txt index 4ff3b5a..fb7b8cc 100644 --- a/QtMeshViewer/Resources/about.txt +++ b/QtMeshViewer/Resources/about.txt @@ -8,6 +8,7 @@ left mouse - rotate right mouse - move scroll - zoom space - reset view ++/- - adjust zoom speed L - set light to current position esc - close diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index c3abb84..3864f6c 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -15,7 +15,7 @@ uniform bool b_transparent; uniform bool b_light; uniform struct Light { - vec3 position; + vec4 position; vec3 intensities; float attenuationFactor; float ambientCoefficient; @@ -31,11 +31,29 @@ void main() { // some values vec3 normalWorld = normalize(n_matrix * v_surfaceNormal); + vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); surfaceColor.rgb = pow(surfaceColor.rgb, vec3(2.2)); if(!b_transparent) surfaceColor.a = 1.0f; - vec3 surfaceToLight = normalize(light.position - v_surfacePosition); + + vec3 surfaceToLight; + float attenuation; + // directional light + if(light.position.w == 0) + { + surfaceToLight = normalize(light.position.xyz); + attenuation = 1; + } + // point light + else + { + surfaceToLight = normalize(light.position.xyz - v_surfacePosition); + + float distanceToLight = length(light.position.xyz - v_surfacePosition); + attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2)); + } + vec3 surfaceToCamera = normalize(cameraPosition - v_surfacePosition); // ambient @@ -51,10 +69,6 @@ void main() specularCoefficient = pow(max(0.0, dot(surfaceToCamera, reflect(-surfaceToLight, normalWorld))), materialShininess); vec3 specular = specularCoefficient * materialSpecularColor * light.intensities; - // attenuation - float distanceToLight = length(light.position - v_surfacePosition); - float attenuation = 1.0 / (1.0 + light.attenuationFactor * pow(distanceToLight, 2)); - // linear color before gamma correction) vec3 linearColor = ambient + attenuation * (diffuse + specular); diff --git a/QtMeshViewer/Source/MainWindow.cpp b/QtMeshViewer/Source/MainWindow.cpp index beafc2a..08ef03d 100644 --- a/QtMeshViewer/Source/MainWindow.cpp +++ b/QtMeshViewer/Source/MainWindow.cpp @@ -55,6 +55,7 @@ void MainWindow::setupWidgets() { OglViewerWidget* viewer = new OglViewerWidget(this); setCentralWidget(viewer); + connect(viewer, &OglViewerWidget::sendMessage, this, &MainWindow::printMessage); QAction *openFile = new QAction(QIcon(":/images/toolbar/open.png"), "Open file", this); connect(openFile, &QAction::triggered, this, &MainWindow::openFile); diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index bf46dad..51fd12d 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -145,7 +145,7 @@ void OglViewerWidget::mouseMoveEvent(QMouseEvent *e) void OglViewerWidget::wheelEvent(QWheelEvent *e) { - m_translation += {0.0, 0.0, (float)e->angleDelta().y() / 240}; + m_translation += {0.0, 0.0, (float)m_zSpeed * e->angleDelta().y() / 240}; update(); } @@ -178,6 +178,17 @@ void OglViewerWidget::keyPressEvent(QKeyEvent *e) updateLightPosition(); update(); } + else if (e->key() == Qt::Key_Minus) + { + m_zSpeed -= 0.1; + m_zSpeed < 0.09 ? m_zSpeed = 0 : NULL; + emit sendMessage(QString("Zoom speed = %1%").arg(m_zSpeed * 100), 0); + } + else if (e->key() == Qt::Key_Plus) + { + m_zSpeed += 0.1; + emit sendMessage(QString("Zoom speed = %1%").arg(m_zSpeed * 100), 0); + } } void OglViewerWidget::initializeGL() @@ -219,15 +230,15 @@ void OglViewerWidget::resizeGL(int w, int h) void OglViewerWidget::paintGL() { - // Clear color and depth buffer - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if (m_backgroundColor[3] == 1.0) { glClearColor(m_backgroundColor[0], m_backgroundColor[1], m_backgroundColor[2], 0.0000f); m_backgroundColor[3] = 0.0; } + // Clear color and depth buffer + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // Calculate model view transformation QMatrix4x4 view; view.translate(m_translation); @@ -290,7 +301,11 @@ void OglViewerWidget::updateLightPosition() { QMatrix4x4 rotateBack; rotateBack.rotate(m_rotation.inverted()); - m_light.position = rotateBack * (-m_translation); + QVector3D cameraPosition = rotateBack * (-m_translation); + + m_light.position.setX(cameraPosition.x()); + m_light.position.setY(cameraPosition.y()); + m_light.position.setZ(cameraPosition.z()); } @@ -301,6 +316,7 @@ void OglViewerWidget::resetView() { m_rotation = QQuaternion(); m_translation = { 0.0, 0.0, DEFAULT_Z_DISTANCE }; + m_zSpeed = 1; update(); }