From 4c177f2ddc28dd2733ce17e664ceb745c022330c Mon Sep 17 00:00:00 2001 From: Anakin Date: Wed, 18 Jan 2017 17:01:43 +0100 Subject: [PATCH] adjust light functionality, bugs: - background cannot be changed during runtime --- QtMeshViewer/Header/OglViewerWidget.h | 6 ++- QtMeshViewer/Resources/Resources.qrc | 1 + QtMeshViewer/Resources/about.txt | 1 + QtMeshViewer/Resources/fshader.glsl | 51 ++++++++++++------------ QtMeshViewer/Resources/light.png | Bin 0 -> 3549 bytes QtMeshViewer/Resources/vshader.glsl | 12 +++--- QtMeshViewer/Resources/wireframe.png | Bin 0 -> 3549 bytes QtMeshViewer/Source/MainWindow.cpp | 6 +++ QtMeshViewer/Source/OglViewerWidget.cpp | 33 ++++++++++++++- 9 files changed, 75 insertions(+), 35 deletions(-) create mode 100644 QtMeshViewer/Resources/light.png create mode 100644 QtMeshViewer/Resources/wireframe.png diff --git a/QtMeshViewer/Header/OglViewerWidget.h b/QtMeshViewer/Header/OglViewerWidget.h index 7327253..c4cd9b5 100644 --- a/QtMeshViewer/Header/OglViewerWidget.h +++ b/QtMeshViewer/Header/OglViewerWidget.h @@ -38,7 +38,7 @@ private: } m_rotDirections; struct { - QVector3D position = { 10,10,10 }; + QVector3D position = { 1,1,1 }; QVector3D intensities = { 1,0.25,0.25 }; } m_light; @@ -50,7 +50,7 @@ private: QQuaternion m_rotation; bool m_wireframe = false; - bool m_lightOn = true; + bool m_lightOn = false; protected: void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE; @@ -68,6 +68,7 @@ protected: private: void initShaders(); void setConnections(); + void updateLightPosition(); private slots: void resetView(); @@ -75,5 +76,6 @@ private slots: public slots: void changeDirection(int direction); void toggleWireframe(); + void toggleLight(); }; diff --git a/QtMeshViewer/Resources/Resources.qrc b/QtMeshViewer/Resources/Resources.qrc index 02ae3fc..ee43df8 100644 --- a/QtMeshViewer/Resources/Resources.qrc +++ b/QtMeshViewer/Resources/Resources.qrc @@ -19,5 +19,6 @@ Z.png screenshot.png wireframe.png + light.png diff --git a/QtMeshViewer/Resources/about.txt b/QtMeshViewer/Resources/about.txt index 51047a0..4ff3b5a 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 +L - set light to current position esc - close using the X, Y, Z Button you can activate/deactivate the rotating directions diff --git a/QtMeshViewer/Resources/fshader.glsl b/QtMeshViewer/Resources/fshader.glsl index 19b12fc..f8a9fce 100644 --- a/QtMeshViewer/Resources/fshader.glsl +++ b/QtMeshViewer/Resources/fshader.glsl @@ -15,40 +15,41 @@ uniform struct Light { uniform bool b_transparent; uniform bool b_light; -varying vec2 v_texcoord; -varying vec3 v_position; -varying vec3 v_normal; +varying vec2 v_surfaceUV; +varying vec3 v_surfacePosition; +varying vec3 v_surfaceNormal; void main() { // variables - float brightness; - - if(b_light == true) - { - // calculate normals in worldspace - vec3 normal = normalize(n_matrix * v_normal); - - //get the surface - light vector (cause this is a candel) - vec3 surfaceToLight = light.position - v_position; - - // calculate the brightness depending on the angle - brightness = dot(normal, surfaceToLight) / (length(surfaceToLight) * length(normal)); - brightness = clamp(brightness, 0, 1); - } - else - { - brightness = 1; - light.intensities = vec3(1,1,1); - } + vec3 diffuse; // get fragment color from texture - vec4 surfaceColor = vec4(texture2D(texture, v_texcoord)); + vec4 surfaceColor = vec4(texture2D(texture, v_surfaceUV)); // if not transparent, ignore alpha value and set it to 1 if(!b_transparent) surfaceColor.a = 1.0f; - // pass the data to ogl - gl_FragColor = vec4(brightness * light.intensities * surfaceColor.rgb, surfaceColor.a); + if(b_light) + { + // calculate normals in worldspace + vec3 normalWorld = normalize(n_matrix * v_surfaceNormal); + + //get the surface - light vector (cause this is a point light) + vec3 surfaceToLight = normalize(light.position - v_surfacePosition); + + // calculate the brightness depending on the angle + float diffuseCoefficient = max(0.0, dot(normalWorld, surfaceToLight)); + + // result diffuse color + diffuse = diffuseCoefficient * surfaceColor.rgb * light.intensities; + } + else + { + diffuse = surfaceColor.rgb; + } + + // put all together + gl_FragColor = vec4(diffuse, surfaceColor.a); } diff --git a/QtMeshViewer/Resources/light.png b/QtMeshViewer/Resources/light.png new file mode 100644 index 0000000000000000000000000000000000000000..16f93e6726accafc0c7264564004646d34023c89 GIT binary patch literal 3549 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 Xe@%ltprbuy00000NkvXXu0mjfrGJli literal 0 HcmV?d00001 diff --git a/QtMeshViewer/Resources/vshader.glsl b/QtMeshViewer/Resources/vshader.glsl index 5282e7a..19b792c 100644 --- a/QtMeshViewer/Resources/vshader.glsl +++ b/QtMeshViewer/Resources/vshader.glsl @@ -12,9 +12,9 @@ attribute vec4 a_position; attribute vec2 a_texcoord; attribute vec3 a_normal; -varying vec2 v_texcoord; -varying vec3 v_position; -varying vec3 v_normal; +varying vec2 v_surfaceUV; +varying vec3 v_surfacePosition; +varying vec3 v_surfaceNormal; void main() { @@ -23,7 +23,7 @@ void main() // Pass data to fragment shader // Value will be automatically interpolated to fragments inside polygon faces - v_texcoord = a_texcoord; - v_position = vec3(norm_matrix * m_matrix * a_position); - v_normal = a_normal; + v_surfaceUV = a_texcoord; + v_surfacePosition = vec3(norm_matrix * m_matrix * a_position); + v_surfaceNormal = a_normal; } diff --git a/QtMeshViewer/Resources/wireframe.png b/QtMeshViewer/Resources/wireframe.png new file mode 100644 index 0000000000000000000000000000000000000000..191b7fe7ad025308e01789e9de6820206c9bf7ec GIT binary patch literal 3549 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 XVYGt^6lVd700000NkvXXu0mjfyCtX# literal 0 HcmV?d00001 diff --git a/QtMeshViewer/Source/MainWindow.cpp b/QtMeshViewer/Source/MainWindow.cpp index 250a5c9..c8e0f13 100644 --- a/QtMeshViewer/Source/MainWindow.cpp +++ b/QtMeshViewer/Source/MainWindow.cpp @@ -101,6 +101,12 @@ void MainWindow::setupWidgets() connect(wireframe, &QAction::triggered, viewer, &OglViewerWidget::toggleWireframe); ui->mainToolBar->addAction(wireframe); + QAction *light = new QAction(QIcon(":/images/toolbar/light.png"), "Light", this); + light->setCheckable(true); + light->setChecked(false); + connect(light, &QAction::triggered, viewer, &OglViewerWidget::toggleLight); + ui->mainToolBar->addAction(light); + ui->mainToolBar->addSeparator(); QAction *fileInfo = new QAction(QIcon(":/images/toolbar/info.png"), "File info", this); diff --git a/QtMeshViewer/Source/OglViewerWidget.cpp b/QtMeshViewer/Source/OglViewerWidget.cpp index 2ddd44f..3413548 100644 --- a/QtMeshViewer/Source/OglViewerWidget.cpp +++ b/QtMeshViewer/Source/OglViewerWidget.cpp @@ -173,14 +173,18 @@ void OglViewerWidget::keyPressEvent(QKeyEvent *e) { parentWidget()->close(); } + else if (e->key() == Qt::Key_L) + { + updateLightPosition(); + update(); + } } void OglViewerWidget::initializeGL() { initializeOpenGLFunctions(); - //glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); - glClearColor(0.02f, 0.01f, 0.01f, 0.0000f); + glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); initShaders(); @@ -269,6 +273,13 @@ void OglViewerWidget::setConnections() } +void OglViewerWidget::updateLightPosition() +{ + QMatrix4x4 rotateBack; + rotateBack.rotate(m_rotation.inverted()); + m_light.position = rotateBack * (-m_translation); +} + ///////////////////////////////////////////////////////////////////////// // private slots @@ -305,3 +316,21 @@ void OglViewerWidget::toggleWireframe() m_wireframe = 1 - m_wireframe; update(); } + +void OglViewerWidget::toggleLight() +{ + m_lightOn = 1 - m_lightOn; + + if (m_lightOn) + { + glClearColor(m_light.intensities.x() / 100, m_light.intensities.y() / 100, m_light.intensities.z() / 100, 0.0000f); + + updateLightPosition(); + } + else + { + glClearColor(0.5000f, 0.8000f, 1.0000f, 0.0000f); + } + + update(); +}